# WebGPU OS Documentation — Full Context > Unified documentation for the WebGPU OS stack — a GPU-first, browser-resident operating system composed of five reusable subsystems: the engine (WebGPU runtime + ECS), the editor (scene/asset IDE), Plauna (hybrid DOM/GPU UI framework), AGI (reinforcement-learning rig + WebGPU tensors), and webgpu-os (kernel + shell + packages + apps). This MD/ folder is the single source of truth; the same Markdown is served by a zero-build HTML viewer, a MkDocs Material site, and a `docs` app inside the OS. This file concatenates the curated, hand-authored pages for full-context ingestion. The generated per-symbol API reference is excluded for size; see the `reference/_index.json` files for that. --- # Overview This page explains what the stack is, who each part is for, and where to go next. Read it first if you are new to the project. ## The five subsystems | Subsystem | What it is | Audience | Source | | --- | --- | --- | --- | | **Engine** | Browser-resident WebGPU runtime: GPU device, frame graph, ECS, rendering, simulation, networking, audio. | Engine/graphics/sim developers | `engine/` | | **Editor** | Scene and asset authoring IDE built on the engine. | Content creators, tools developers | `editor/` | | **Plauna** | Hybrid DOM/GPU UI framework and workbench (panels, widgets, surfaces, theming). | UI/app developers | `plauna/` | | **AGI** | Reinforcement-learning "parasite rig" that learns to control humanoid ragdolls, plus a WebGPU tensor library and AGI Studio. | ML/animation developers | `agi/` | | **WebGPU OS** | Composition glue: a GPU-first compositor, shell, kernel, package system, and app runtime that turns the above into a desktop-like OS in a browser tab. | App/package developers, end users | `webgpu-os/` | ## Design principles (shared across the stack) - **Pure browser runtime** — no Node.js dependency, no build step required to run. - **GPU-first** — heavy work runs on WebGPU compute; a single GPU device is shared. - **ECS-driven** — state lives in components. - **Modular** — each subsystem is independent and testable, consumed by the next as a library. - **Composition, not forking** — `webgpu-os/` consumes `engine/`, `plauna/`, `agi/`, `editor/`; fixes go upstream, not into the glue layer. ## Who should read what - **End users** of the OS: [WebGPU OS Overview](../webgpu-os/overview.md) → [App Catalog](../webgpu-os/app-catalog.md). - **App / package developers**: [WebGPU OS Architecture](../webgpu-os/architecture.md), the kernel **API Reference**, and the [Security & Trust Model](../concepts/security-model.md). - **Engine / UI / ML developers**: the relevant subsystem **Overview** + **Architecture** + **API Reference**. - **Documentation contributors**: [Docs Style Guide](../contributing/docs-style-guide.md) and [Contribution Workflow](../contributing/doc-contribution-workflow.md). ## Next steps 1. [Install & Run](install.md) — get the stack serving locally. 2. [Quickstart](quickstart.md) — boot the OS and open your first app. 3. [Architecture Overview](../concepts/architecture-overview.md) — the big picture. 4. [Glossary](glossary.md) — terms used throughout these docs. --- # Install & Run This page covers prerequisites and how to serve the stack and these docs locally. Everything runs in the browser — there is no compile step. ## Prerequisites - **A current WebGPU-capable browser** — support depends on the browser release, operating system, GPU, and driver. Confirm that `navigator.gpu` exists and that `await navigator.gpu.requestAdapter()` returns an adapter. Localhost is treated as a secure context; deployed sites must use HTTPS. - **Python 3.x** — used only to serve files over HTTP and to run the docs tooling. There is **no Node.js dependency**. - **A dedicated GPU** is recommended for the engine, AGI training, and GPU-heavy apps. ## Platform downloads and the optional network service - **Platform downloads:** [BTSpaniel/particlerealms.engine](https://github.com/BTSpaniel/particlerealms.engine) publishes browser-ready distribution artifacts, including the compressed `.gz` bundles. It is the public download repository, not the source tree used to generate this API reference. - **Optional master server source:** [BTSpaniel/particlerealms.engine-master-server](https://github.com/BTSpaniel/particlerealms.engine-master-server) is a separate discovery, admission, encrypted-signaling, TURN, and trusted-node service. It is never gameplay authority and is not required to run the engine or Playground locally. ## Serve the project The repository ships a static HTTP server. From the repository root (`C:\Coding\game`): ```bash python start_server.py ``` Then open the relevant entry point in a WebGPU browser: - **WebGPU OS** — `http://127.0.0.1:9001/webgpu-os/` - **Editor** — `http://127.0.0.1:9001/editor/` - **AGI Studio** — `http://127.0.0.1:9001/agi/studio/` - **These docs (zero-build viewer)** — `http://127.0.0.1:9001/MD/viewer/` > **Why a server?** The viewers and the OS load Markdown, JSON, and ES modules with `fetch()`/`import`, which browsers block from `file://` URLs. Always serve over HTTP. ## WebGPU compatibility and the Companion are different WebGPU **compatibility mode** is a browser/adapter capability intended for systems backed by older native graphics APIs. When available, it still appears through the browser's WebGPU interfaces. It does not come from an extension and may expose lower limits or fewer optional features, so rely on adapter, feature, and limit checks instead of a browser-name test. The [WebGPU OS Companion Chrome extension](https://chromewebstore.google.com/detail/webgpu-os-companion/pbibggeclfjpmmbfmjagmngefonepbjj) is an optional bridge for approved browser controls, provider connectivity, and other OS integrations. It cannot add WebGPU to an unsupported browser, GPU, or driver. The engine and Playground use browser WebGPU directly; install the Companion only for the OS features that explicitly request it. ## Set up the documentation tooling The docs are plain Markdown, but a few Python helpers build derived artifacts. From `C:\Coding\game\MD`: ```bash # 1. Vendor the viewer's front-end libs locally (offline, no CDN) python tools/fetch_vendor.py # 2. Generate the per-symbol API reference from source python tools/extract_api.py # 3. Build the search index and validate navigation python tools/build_docs.py ``` After step 1, open `http://127.0.0.1:9001/MD/viewer/` to browse. ## Optional: MkDocs Material site For the polished static-site experience: ```bash pip install -r _config/requirements.txt mkdocs serve -f _config/mkdocs.yml ``` See [Contribution Workflow](../contributing/doc-contribution-workflow.md) for the full build/lint pipeline. ## Troubleshooting - **Blank page / CORS errors** — you opened a `file://` URL. Serve over HTTP instead. - **"WebGPU not available"** — update your browser or enable WebGPU; verify with `navigator.gpu` in the console. - **Viewer renders unstyled code / no diagrams** — run `python tools/fetch_vendor.py`. The viewer still works via its built-in fallback, but without syntax highlighting or Mermaid. More in [FAQ & Troubleshooting](faq.md). --- # Quickstart This guide boots the WebGPU OS and opens an app. It assumes you have completed [Install & Run](install.md). ## 1. Boot the OS Serve the repo and open the OS: ```bash python start_server.py # then browse to: # http://127.0.0.1:9001/webgpu-os/ ``` The boot loader shows progress (`Initializing kernel… → Discovering apps… → Loading mods… → Mounting desktop shell…`). When it finishes, `window.OS` is ready and the desktop appears. ## 2. Boot programmatically (embedding) `webgpu-os/index.js` exports a side-effect-free boot function you can call yourself: ```javascript import { bootWebGpuOS } from './webgpu-os/index.js'; const os = await bootWebGpuOS({ canvasSelector: '#os-gpu-canvas', desktopSelector: '#os-desktop', taskbarSelector: '#os-taskbar', }); console.log(os.version); // e.g. "0.1.0-phase1" console.log(os.kernel); // kernel services console.log(os.desktop); // shell / window manager ``` The thin `webgpu-os/boot.js` simply calls this on `DOMContentLoaded` for plain ES-module usage. ## 3. Open an app Apps are discovered at runtime from `webgpu-os/apps/` (see `apps/index.json`). From the desktop, open the **Start Menu** and launch any app — for example **Terminal**, **Files**, or **Settings**. The full list is in the [App Catalog](../webgpu-os/app-catalog.md). ## 4. Run a security self-audit (optional) Append `?securityAudit` to the URL (or set `window.__DEV__ = true`) to run the syscall-guard audit, capability-map drift check, and Security Doctor on boot. Results are logged to the console. See the [Security & Trust Model](../concepts/security-model.md). ```text http://127.0.0.1:9001/webgpu-os/?securityAudit ``` ## Where to go next - Build an app/package: [WebGPU OS Architecture](../webgpu-os/architecture.md). - Understand boot internals: [Boot Sequence](../concepts/boot-sequence.md). - Understand GPU sharing across apps: [GPU Device Sharing](../concepts/gpu-device-sharing.md). --- # Glossary Terms used throughout this documentation. Each term is defined once here and linked from the pages that use it. ## Stack & runtime - **Engine** — the WebGPU runtime in `engine/`: GPU device, frame graph, ECS, rendering, simulation, networking, audio. - **Plauna** — the hybrid DOM/GPU UI framework in `plauna/` (panels, widgets, surfaces, theming). - **AGI** — the reinforcement-learning rigging system in `agi/` ("parasite rig"), plus a WebGPU tensor library and AGI Studio. - **WebGPU OS** — the composition layer in `webgpu-os/`: compositor, shell, kernel, package system, app runtime. - **Kernel** — the OS's privileged core (`webgpu-os/kernel/`): syscalls, scheduling, GPU mediation, trust, permissions. - **Shell** — the desktop UI (`webgpu-os/shell/`): `Desktop`, `Taskbar`, `StartMenu`, windows, notifications. ## GPU - **WebGPU** — the browser GPU API the whole stack targets. - **WGSL** — WebGPU Shading Language; the portable shader format used across tiers. - **VGPU (Virtual GPU)** — the engine's abstraction over the raw WebGPU device (`engine/core/gpu/VirtualGPU.js`) that adds multi-queue, bind-group management, streaming, and resource tracking. - **GPU device broker** — the kernel service (`kernel/GpuDeviceBroker.js`) that shares the single WebGPU device across all apps. - **device-lost** — a WebGPU event raised when the GPU context is lost; the kernel fans this out to apps for recovery. ## MorphField - **MorphField** — the Engine's additive semantic-field renderer and compiler under `engine/render/morphfield/`. - **Nexel** — a public semantic scene element that describes source geometry or media, material, motion, collision, simulation, and quality intent without selecting a GPU backend. - **Fieldlet** — MorphField's private compiled execution record. A Fieldlet belongs to one of four stable execution families and exposes a mask of supported typed queries. - **Certified query** — a query backed by compiler-derived conservative bounds or error records. Authored data cannot declare itself certified. ## OS concepts - **App** — a plug-in module discovered at runtime from `apps/`, described by a manifest. - **Manifest** — the JSON describing an app: id, entry, permissions, capabilities (see App Manifest Spec). - **Package (`.prpkg`)** — an installable, signed, encrypted container (v2 = encrypted ZIP + public envelope). - **Mod** — a runtime extension discovered from `mods/` via `ModRegistry`. - **Syscall** — a kernel-mediated operation exposed to apps (`kernel/Syscalls.js`). - **Capability** — a permission token gating a syscall or resource (see `packages/CapabilityMap.js`). - **Trust ring / ring-0 roots** — the trust hierarchy; ring-0 roots live in `kernel/trust/roots.json`. - **Provenance** — verifiable origin/lineage of a package (`kernel/ProvenanceChecker.js`, `SigningLineage.js`). - **Surface** — a renderable region (DOM, DOM+GPU, or pure GPU) managed by `SurfaceManager`/Plauna. - **Workspace / Panel** — Plauna's dockable window units; every OS window is a Plauna panel. ## ECS - **ECS** — Entity-Component-System; the engine's state model. - **Entity** — an id; **Component** — data attached to an entity; **System** — logic over components. - **World** — a container of entities/components/systems (the engine and Plauna each have worlds). ## AGI / ML - **PPO** — Proximal Policy Optimization, the RL algorithm used to train the rig. - **Tensor library** — the custom WebGPU tensor implementation in `agi/tensor/`. - **Curriculum** — the staged training progression (`agi/core/CurriculumManager.js`). - **Ragdoll** — the physics body the rig learns to control (`agi/core/RagdollController.js`). - **Observation / Action space** — the RL input (12D) and output (17D) vectors. ## Navi - **Navi** — a persistent OS principal whose identity, authority, memory, and lineage remain independent from any model, provider, session, device, or body. - **Continuity Kernel** — the kernel-owned Navi service that protects persistent identity and operational signing authority. - **Covenant** — the signed operator-Navi contract that bounds observation, memory, autonomy, disclosure, approvals, transfer, recovery, and separation. - **Cognition Fabric** — the model-neutral router that selects replaceable remote or local cognition engines while preserving task continuity. - **Faculty** — a signed, versioned, inspectable ability module with typed inputs and outputs, declared permissions, tools, models, costs, tests, and failure behavior. - **Causal Memory Weave** — append-only evidence-bearing Navi memory and its derived human-readable views. - **Authority Membrane** — the kernel boundary that intersects applicable policies and issues narrow, temporary capabilities for actions. - **Manifestation** — one body or interface through which a Navi is present, such as AI Echo, voice, a Construct body, a vehicle, or a remote projection. - **Hand** — a temporary specialist worker with a narrow task, minimal context, temporary authority, a resource lease, expiry, traceable parentage, and a required report. - **Navi Branch** — an explicitly approved persistent divergent Navi timeline with a distinct operational key; it is not a Realm branch or an independent identity. ## Realm Network - **Realm Network** — the WebGPU OS network layer for portable identity, immutable Realm content, resumable peer links, semantic replication, offline branches, governance, bounded task exchange, discovery, and entry policy. - **Passport** — the user-facing Realm identity rooted in `ProfileDriver`, with signed key lineage, device authorization, recovery, rotation, and revocation. - **Chronicle** — an append-only signed SHA-256 event history used to establish parentage and integrity. - **Realm Capsule** — an immutable semantic content package backed by existing package, Merkle, chunk, and shared content-addressed storage systems. - **Realm Link** — a logical authenticated peer session that survives transport replacement and reconnects. - **Atlas** — provider-based Realm discovery using signed, visibility-scoped, bounded records. - **Gate** — the entry verifier that derives deny, quarantine, safe, read-only, or full-entry outcomes. - **Shield** — the isolation and moderation boundary for quotas, blocking, reporting, audit, and restoration. - **State Channel** — an authoritative intent-and-projection path. Clients send typed intents; an authority emits revisioned projections and receipts. SSE is the standard downstream transport for browser views. - **Intent** — a typed request to a State Channel authority. An intent does not become shared truth until the authority accepts it. - **Projection** — confirmed state derived for a State Channel consumer as a snapshot, merge patch, or event. --- # FAQ & Troubleshooting Common questions and fixes. If something here is wrong or missing, follow the [Contribution Workflow](../contributing/doc-contribution-workflow.md) to update it. ## General **Do I need Node.js or npm?** No. The entire stack and the documentation tooling are pure browser + Python. There is no build step required to run anything. **Why does everything need an HTTP server?** Browsers block `fetch()` and ES-module `import` from `file://` URLs. Serve over HTTP with `python start_server.py` and use `http://127.0.0.1:9001/...`. **Which browser do I need?** Use a current browser release that exposes WebGPU on your operating system and GPU. Browser version alone is not proof of capability. Verify that `navigator.gpu` exists and that `await navigator.gpu.requestAdapter()` returns an adapter. Update the browser and GPU driver if either check fails. **Does the WebGPU OS Companion enable WebGPU or compatibility mode?** No. Compatibility mode belongs to the browser's WebGPU implementation. The optional Companion extension supplies approved browser and provider integrations for WebGPU OS; it cannot make an unsupported GPU/browser combination support WebGPU. The engine and Playground run without the Companion when browser WebGPU is available. ## WebGPU OS **The boot loader is stuck or shows "Boot failed".** Open the console. The boot sequence logs each phase. Common causes: WebGPU unavailable, shell root elements missing from the DOM, or an app/mod discovery error (these are logged as warnings and do not block boot). **How do I see security posture?** Boot with `?securityAudit` or set `window.__DEV__ = true`. This runs the syscall-guard audit, capability-map drift check, and Security Doctor, logging results. See [Security & Trust Model](../concepts/security-model.md). **Where do apps live, and why aren't they bundled?** Apps are discovered and fetched at runtime from `webgpu-os/apps/` (and mods from `mods/`). They are intentionally **not** bundled so they can be added/updated without rebuilding the OS. ## Documentation viewers **The viewer shows "Could not load navigation".** You opened the viewer from `file://`. Serve `MD/` over HTTP. **Code blocks are unstyled and Mermaid diagrams don't render.** The vendored libraries are missing. Run `python tools/fetch_vendor.py`. The viewer falls back to a built-in Markdown renderer so pages still load. **A reference page says "(run extract_api.py)" in the sidebar.** The API reference hasn't been generated yet. Run `python tools/extract_api.py` then `python tools/build_docs.py`. **Search returns nothing / only titles.** The search index isn't built. Run `python tools/build_docs.py` to create `_config/search-index.json`. Without it, the viewer falls back to title-only search. ## Engine / AGI **AGI training won't progress.** Confirm WebGPU support, verify 60 FPS physics, and review reward weights. See the [Training Guide](../agi/training-guide.md). **Performance is poor.** Close other tabs, reduce buffer sizes, disable debug visualizations, and check GPU utilization. --- # Capabilities — What You Can Build What the stack can actually build: browser-native WebGPU games, simulation sandboxes, tools, editors, UI systems, AI training experiments, and deployable single-file runtimes. Use this page to pick the right subsystem before writing code. ## Decision map | Goal | Use | Primary files | Docs | | --- | --- | --- | --- | | WebGPU buffer/pipeline/compute work | vGPU | `engine/core/gpu/VirtualGPU.js` | [vGPU](../engine/vgpu.md) | | Game state, entities, components | ECS | `engine/EcsImports.js`, `engine/ecs/` | [ECS v2](../engine/ecs.md) | | Visual frame, render passes, debug views | Rendering | `engine/render/` | [Rendering](../engine/rendering.md) | | Particles, fire, fluid, matter demos | Particle System | `engine/sim/particles/`, `engine/render/particles/` | [Particles](../engine/particles.md) | | Menus, HUDs, app panels | Plauna | `plauna/index.js` | [Plauna](../plauna/overview.md) | | Training, observations, rewards, neural agents | AGI Core | `agi/index.js` | [AGI](../agi/overview.md) | | Scene authoring and inspection | Editor | `editor/js/EditorApp.js`, `editor/js/ProjectManager.js` | [Editor](../editor/overview.md) | | New app / prototype | Template | `Template/index.html`, `Template/main.js` | [Template starter](#template-starter) | Primary entry points: engine → `engine/EngineBootstrap.js` · compiled global → `window.PE` · Plauna → `plauna/index.js` · AGI → `agi/index.js` · editor → `editor/js/EditorApp.js` · template → `Template/`. ## What you can build - **GPU simulation demos** — particles, fluids, boids, wave optics, ray/path tracing, reaction diffusion, sand, thermal systems, terrain, state-first rasterization, diagnostic scenes. - **Living worlds** — ECS-driven worlds with items, rules, events, saves, AI state, perception, laws, factions, social graphs, and procedural simulation layers. - **Physics sandboxes** — rigid bodies, GPU physics, PBD ragdolls, active rig controllers, cloth, rope, fluids, soft-body hooks, constraints, collision debug, PhysX-backed editor workflows. - **Visual tools** — browser editor workflows with viewport, inspector, hierarchy, world settings, gizmos, particles, audio patches, materials, project saves, runtime debug modes. ## Core engine runtime The engine exports a single public API through `engine/EngineBootstrap.js` (source mode) or `window.PE` (compiled bundle mode). ```javascript import { ENGINE_FULL, createWorld, createEntity, setEntityComponent, createTransform, stepWorld, getVGPU, } from '../../engine/EngineBootstrap.js'; const world = createWorld({ name: 'GameWorld' }); const player = createEntity(world); setEntityComponent(world, player, 'Transform', createTransform({ position: [0, 1, 0], rotation: [0, 0, 0, 1], scale: [1, 1, 1], })); stepWorld(world, 1 / 60); console.log(ENGINE_FULL); ``` ### Public engine API map | Category | Common exports | Use for | | --- | --- | --- | | Version | `ENGINE_FULL`, `VERSION_BANNER`, `PLAUNA_FULL`, `AGI_CORE_FULL` | Runtime identity, diagnostics, release banners | | Math | `vec3`, `quatIdentity`, `mat4PerspectiveRadWebGPU`, `clamp`, `lerp` | Transforms, camera math, simulation utilities | | ECS | `createWorld`, `createEntity`, `setEntityComponent`, `stepWorld` | Entity state and system stepping | | Gameplay | `EventGraph`, `RuleGraph`, `NPCBrain`, `SimulationManager` | World rules, events, perception, AI state | | Saves | `SaveSystem`, `createLocalStorageAdapter`, `SAVE_SCHEMA_VERSION` | Local persistence and schema-aware saves | | Animation | `MotionClip`, `MotionDataset`, `MotionMatcher`, `SkeletonHierarchy` | Motion matching, animation datasets, rig features | | GPU | `VirtualGPU`, `getVGPU`, `vgpu`, `initVGPU` | WebGPU device, buffers, shaders, pipelines, compute | Compiled runtime pattern: ```javascript const PE = window.PE || window.ParticleEngine; const { VERSION_BANNER, createWorld, createEntity, createPlaunaApp, AGI_CORE_FULL } = PE; console.log(VERSION_BANNER, AGI_CORE_FULL); ``` ## Rendering Classic scene rendering plus experimental research paths (see [Rendering](../engine/rendering.md)): - **Scene rendering** — entities, instancing, mesh segments, materials, lighting, shadows, debug visualizations. - **Post-processing** — tonemapping, bloom, temporal reconstruction, FSR/TSR-style upscaling, depth/normal debug passes. - **Path tracing** — engine-native path tracing foundation, ReSTIR GI experiments, guide buffers, temporal accumulation. - **Spectral rendering** — coherent wave optics pass (double-slit demo). - **State-first rendering** — CPU/GPU visibility, representation selection, temporal visibility, cluster expansion, GPU culling. - **Proxy geometry** — ray portal proxy with TLAS/BLAS, SDF, billboard, impostor, octahedral cache tiers. | Need | Start with | Notes | | --- | --- | --- | | Normal 3D scene | `engine/render/` + ECS transforms | Use existing passes before adding a new renderer | | Experimental GI/path tracing | `ReSTIRGIPass` (via EngineBootstrap) | Playground demos consume it through compiled `PE` | | Many simple visible objects | State-first rasterizer/culler APIs | Use representation selection + GPU culling | | Debug visual output | Scene debug visualizer + editor view modes | Prefer debug modes over console-only diagnosis | ## Particles, matter, and fluids Built for large GPU workloads and material behavior, not just sprites (see [Particles](../engine/particles.md)): high-count GPU particles (compaction, sorting, billboards, trails, decals, bonds, adaptive quality); matter states (solid/liquid/gas/plasma); thermal behavior (temperature, heat transfer, phase transitions); SPH fluids + volume fields; interaction (SDF collision, flocking/boids, terrain/sandbox demos). ```javascript const emitter = { id: 'campfire', position: [0, 0.3, 0], rate: 700, phase: 'plasma', temperature: 1500, color: [1, 0.45, 0.08, 1], }; ``` ## Physics and active bodies Engine physics modules + PhysX integration + active-ragdoll architecture (see [Physics](../engine/physics.md) and [GPU Physics](../engine/gpu-physics.md)). | Module | Use | Typical consumer | | --- | --- | --- | | `ActiveRigSchema.js` | Rig config, pose buffers, drive profiles | Physics controllers, animation bridges | | `ActiveRigController.js` | Init/update active ragdoll (articulation/D6 fallback) | Gameplay characters, test harnesses | | `BalanceController.js` | COM/support analysis, fallen/recovery states | Humanoid locomotion, debug readback | | `MuscleLayer.js` | Intent-modulated drive stiffness/damping/max force | AI or player control authority | | `RetargetGraph.js` | Animation → physics → render mapping | Animation import, rig display | ## Plauna UI runtime The UI layer for game menus, HUDs, tools, dashboards, context menus, and editor-like panels (see [Plauna](../plauna/overview.md)). ```javascript import { PLAUNA_FULL, createPlaunaApp, Panel, Text, Button } from '../../plauna/index.js'; const ui = createPlaunaApp({ root: document.getElementById('ui') }); const menu = new Panel('main-menu', { title: PLAUNA_FULL }); menu.add(new Text('title', 'Particle Realms')); menu.add(new Button('play', 'Play')); ui.mount(menu); ``` | Category | Exports | Use for | | --- | --- | --- | | App/Core | `createPlaunaApp`, `UINode`, `VisualTree`, `PlaunaModuleTester` | App shell, retained UI tree, diagnostics | | Widgets | `Button`, `Panel`, `Text`, `Modal`, `Tooltip`, `Badge`, `Avatar`, `Progress` | HUDs, menus, settings, overlays | | Forms | `Input`, `Checkbox`, `Radio`, `Switch`, `Select`, `Textarea`, `Slider`, `Rating` | Settings panels, inspectors, tools | | Navigation/Data | `Tabs`, `Dropdown`, `Breadcrumb`, `Pagination`, `ListView`, `Card` | Multi-screen tools and dashboards | | Utilities | `Notify`, `ToastManager`, `PlaunaConsole`, `WidgetShowcase`, `ParticleController` | Feedback, debug consoles, demos | ## AGI Core The AI/training side: observation builders, rewards, curriculum, motion matching, neural/ragdoll experiments, and agent adapters (see [AGI](../agi/overview.md)). ```javascript import { AGI_CORE_FULL, ObservationBuilder, RewardFunction, CurriculumManager, MotionMatchingTeacher } from '../../agi/index.js'; const observations = new ObservationBuilder({ includeContacts: true }); const rewards = new RewardFunction({ upright: 1.0, energyPenalty: 0.02 }); const curriculum = new CurriculumManager({ stages: ['stand', 'walk'] }); ``` | Category | Exports | Use for | | --- | --- | --- | | Agent adapters | `PBDRagdollAgentAdapter` | Bridge ragdoll/body state to agent control | | Brains | `PolicyNetwork`, `ValueNetwork`, `NetworkArchitecture`, `ExperienceBuffer`, `PPOTrainer` | Policy/value training loops, rollout storage | | Training logic | `ObservationBuilder`, `RewardFunction`, `CurriculumManager`, `MotorController` | Observations, rewards, staged training, motor output | | Motion | `MotionMatchingTeacher`, `RagdollController` | Teacher signals and body control | | Studio/Scene | `StudioApp`, `TrainingScene`, `SceneRenderer`, `TrackingCamera`, `DebugVisualizer` | Interactive AGI Studio and visualization | | Tensor | `ComputeGraph`, `GradientTape`, `TensorCache` | Compute graph and gradient utilities | ## Editor A browser-native authoring tool for scenes, entities, materials, particles, audio, physics, settings, and project persistence (see [Editor](../editor/overview.md)). | File | Role | Edit when | | --- | --- | --- | | `editor/js/EditorApp.js` | Main app orchestrator | Adding global lifecycle, systems, or panel coordination | | `editor/js/ProjectManager.js` | Save/load/autosave | Changing project serialization or restore behavior | | `editor/js/modules/EditorScene.js` | Scene/entity operations | Adding spawn, clone, delete, hierarchy behavior | | `editor/js/modules/EditorParticles.js` | Particle integration | Adding particle authoring or per-frame updates | | `editor/js/modules/EditorPhysics.js` | Physics tooling | Adding runtime physics controls or debug hooks | | `editor/js/modules/EditorAudio.js` | Audio workflow | Adding audio preview, patches, or material sound rules | ## Bundled runtime The Python bundler can generate an engine-only public runtime or a full platform runtime (see [Engine Stack Usage](engine-stack-usage.md)). ```bash # Engine / public playground bundle python bundle_engine.py --target engine --no-cache # Full platform: Engine + Editor + Plauna + AGI Core python bundle_engine.py --target platform --no-cache ``` | Target | Entries | Exposes | Use for | | --- | --- | --- | --- | | `engine` | `engine/EngineBootstrap.js` | `window.PE` engine APIs | Public site, playground, SDK, engine-only demos | | `platform` | `engine/EngineEditorBootstrap.js`, `agi/index.js`, `plauna/index.js` | Engine + Editor + AGI + Plauna APIs | Internal tools, full platform previews | ## Template starter Use `Template/` as the starter folder for new apps. Copy it, keep game-specific code local, and only promote reusable systems back into `engine/` after multiple projects need them. ```text Template/ ├── index.html ├── style.css ├── main.js └── README.md ``` ## AI editing rules for this stack - Search for existing exports before adding new helpers. - Use `engine/EngineBootstrap.js`, `plauna/index.js`, and `agi/index.js` as public entry points. - Do **not** use `agi/studio/main.js` as a bundle entry — it auto-boots a DOM app. - Use compiled `window.PE` APIs in playground/release pages, not direct source imports. - Keep app-specific code in `Template/` copies or project folders until it is reusable. - Add debug overlays/readbacks before changing complex physics, rendering, or AGI behavior. --- # Engine Stack Usage Guide Version targets: Engine `0.8.1-alpha`, Editor `0.6.0-alpha`, Plauna `0.2.0-alpha`, AGI Core `0.1.0-alpha`. This guide is the practical "how do I build with this?" document for the full stack: - **Particle Engine**: WebGPU, ECS, rendering, particles, physics, audio, saves, gameplay systems. - **Plauna**: retained-mode UI runtime for menus, HUDs, tools, dashboards, and editor-like panels. - **AGI Core**: training/control utilities for neural, ragdoll, motion, and simulation agents. - **Editor**: visual scene/project tool for authoring, inspecting, testing, and exporting. - **Template**: a copyable starter app at `Template/`. Use this guide when starting a new game, demo, tool, or prototype. --- ## 1. Which build should you use? ### Engine-only bundle Use this for public demos, playground content, engine examples, and small games that do not need AGI/Plauna/editor APIs. ```powershell python bundle_engine.py --target engine --no-cache ``` Output identity: ```js window.PE.ENGINE_VERSION window.PE.VERSION_BANNER ``` ### Full platform bundle Use this when you want Engine + Editor + Plauna + AGI Core in one runtime. ```powershell python bundle_engine.py --target platform --no-cache ``` This adds: ```js window.PE.AGI_CORE_VERSION window.PE.PLAUNA_VERSION window.PE.createPlaunaApp window.PE.StudioApp ``` ### Ad-hoc bundle Use this for local experiments where you want Engine plus one optional layer. ```powershell python bundle_engine.py --include-plauna --no-cache python bundle_engine.py --include-agi --no-cache python bundle_engine.py --include-agi --include-plauna --no-cache ``` --- ## 2. Runtime loading pattern For source-mode development, import from `engine/EngineBootstrap.js`. ```js import { ENGINE_FULL, createWorld, createEntity, setEntityComponent, stepWorld, } from '../engine/EngineBootstrap.js'; console.log(`Running ${ENGINE_FULL}`); ``` For generated release, Playground, Editor, and WebGPU OS pages, await the shared compressed-runtime contract and use `window.PE`. ```js const PE = await globalThis.__PE_RUNTIME_READY; console.log(PE.VERSION_BANNER); ``` `bundle_engine.py` writes the external `release-runtime-loader.js` tag with the exact gzip URL, decoded byte count, SHA-384 identity, asset base, and subsystem base. The loader expands `*.min.js.gz`, rejects size or integrity mismatches, executes the verified bytes from a CSP-approved Blob URL, and resolves `__PE_RUNTIME_READY`. Do not replace it with inline source execution or publish the oversized raw `*.min.js` file. Rule: **playground/release pages should use compiled `PE` APIs, not direct `../../engine/...` source imports.** --- ## 3. Minimal Engine app This is the smallest pattern for a browser app using EngineBootstrap. ```js import { createWorld, createEntity, setEntityComponent, getEntityComponent, stepWorld, createTransform, createPhysicsBody, } from '../engine/EngineBootstrap.js'; const world = createWorld({ name: 'ExampleWorld' }); const player = createEntity(world); setEntityComponent(world, player, 'Transform', createTransform({ position: [0, 1, 0], rotation: [0, 0, 0, 1], scale: [1, 1, 1], })); setEntityComponent(world, player, 'PhysicsBody', createPhysicsBody({ mass: 1, velocity: [0, 0, 0], })); let last = performance.now(); function frame(now) { const dt = Math.min((now - last) / 1000, 1 / 30); last = now; stepWorld(world, dt); const transform = getEntityComponent(world, player, 'Transform'); console.log(transform.position); requestAnimationFrame(frame); } requestAnimationFrame(frame); ``` Recommended app layout: ```text MyGame/ ├── index.html ├── style.css ├── src/ │ ├── main.js │ ├── Game.js │ ├── Renderer.js │ ├── ui.js │ └── systems/ └── data/ ``` --- ## 4. WebGPU initialization pattern Use raw WebGPU only when a high-level helper does not exist yet. ```js async function initGpu(canvas) { if (!navigator.gpu) throw new Error('WebGPU is required'); const adapter = await navigator.gpu.requestAdapter({ powerPreference: 'high-performance', }); if (!adapter) throw new Error('No WebGPU adapter'); const device = await adapter.requestDevice(); const context = canvas.getContext('webgpu'); const format = navigator.gpu.getPreferredCanvasFormat(); context.configure({ device, format, alphaMode: 'premultiplied', }); return { adapter, device, context, format }; } ``` Use a single long-lived `GPUDevice`. Recreate size-dependent textures on resize. Do not create pipelines every frame. --- ## 5. ECS conventions Use components as plain serializable data. ```js const Vehicle = { speed: 0, maxSpeed: 22, steering: 0, occupiedBy: null, }; setEntityComponent(world, carId, 'Vehicle', Vehicle); ``` System pattern: ```js function updateVehicles(world, dt) { for (const entity of world.entities || []) { const vehicle = getEntityComponent(world, entity, 'Vehicle'); const transform = getEntityComponent(world, entity, 'Transform'); if (!vehicle || !transform) continue; transform.position[0] += vehicle.speed * dt; } } ``` Recommended phases: ```text input -> ai -> physics -> simulation -> render -> ui -> late ``` Keep simulation state deterministic where possible. Keep DOM/UI state outside physics-critical loops. --- ## 6. Rendering conventions For simple demos, render from compact state snapshots: ```js const renderState = { camera: { position: [0, 8, 12], target: [0, 0, 0] }, entities: [], }; renderState.entities.push({ id: player, kind: 'sphere', position: [0, 1, 0], radius: 0.5, color: [0.2, 0.7, 1.0, 1.0], }); ``` For large worlds: - Use dirty flags for transforms/materials/bounds. - Use culling before upload. - Prefer packed typed arrays over per-entity object uploads. - Use state-first representation selection for many simple entities. - Avoid GPU readback in the frame loop unless it is delayed/asynchronous. --- ## 7. Particle system usage Basic emitter data should be content-driven. ```js const fireEmitter = { id: 'campfire', position: [0, 0.3, 0], rate: 700, lifetime: [0.7, 1.6], velocity: [0, 2.2, 0], spread: 0.55, phase: 'plasma', temperature: 1500, color: [1.0, 0.45, 0.08, 1.0], }; ``` Good particle app structure: ```text src/particles/ ├── emitters.js # content presets ├── ParticleScene.js # owns GPU state and update order └── ParticleDebug.js # overlays and counters ``` Rules: - Keep presets in data modules. - Keep GPU buffers owned by one system. - Separate emitter authoring from simulation stepping. - Add debug counters early: alive count, spawn count, upload bytes, frame ms. --- ## 8. Plauna UI usage Use Plauna when you need retained UI, themed panels, menus, HUDs, inspectors, or app shells. Source-mode import: ```js import { PLAUNA_FULL, createPlaunaApp, Button, Panel, Text, Notify, } from '../plauna/index.js'; console.log(`Plauna ${PLAUNA_FULL}`); ``` Bundle-mode usage: ```js const { PLAUNA_FULL, createPlaunaApp, Button, Panel, Text, Notify, } = window.PE; ``` Minimal Plauna mount: ```js const app = createPlaunaApp({ root: document.getElementById('ui'), theme: 'dark', }); const panel = new Panel('main-menu', { title: 'Main Menu', layout: 'vertical', }); panel.add(new Text('title', 'Particle Realms')); panel.add(new Button('play', 'Play', { variant: 'primary', onClick: () => Notify.info('Starting game...'), })); app.mount(panel); ``` Recommended Plauna file layout: ```text src/ui/ ├── app-ui.js # createPlaunaApp + root mount ├── screens/ │ ├── MainMenu.js │ ├── Settings.js │ └── PauseMenu.js ├── hud/ │ ├── StatusHud.js │ └── DebugHud.js └── theme.js ``` Plauna rules: - Use Plauna for UI state, not physics state. - Pass simulation snapshots into UI; do not let UI own simulation truth. - Keep UI events as intents: `play`, `pause`, `openSettings`, `setQuality`. - Avoid creating/destroying large UI trees every frame. --- ## 9. AGI Core usage Use AGI Core for training agents, observation builders, rewards, motion teachers, and neural control experiments. Source-mode import: ```js import { AGI_CORE_FULL, ObservationBuilder, RewardFunction, CurriculumManager, MotionMatchingTeacher, PBDRagdollAgentAdapter, } from '../agi/index.js'; console.log(`AGI Core ${AGI_CORE_FULL}`); ``` Bundle-mode usage: ```js const { AGI_CORE_FULL, ObservationBuilder, RewardFunction, CurriculumManager, MotionMatchingTeacher, } = window.PE; ``` Minimal training loop shape: ```js const curriculum = new CurriculumManager({ stages: ['stand', 'walk', 'recover'], }); const observations = new ObservationBuilder({ includeContacts: true, includeVelocities: true, includeIntent: true, }); const rewards = new RewardFunction({ alive: 0.1, upright: 1.0, targetVelocity: 0.8, energyPenalty: 0.02, }); function trainStep(agent, world, dt) { const obs = observations.build(agent, world); const action = agent.policy.predict(obs); agent.applyAction(action, dt); world.step(dt); const reward = rewards.evaluate(agent, world); agent.learn({ obs, action, reward }); curriculum.update(agent, reward); } ``` AGI rules: - Keep `agi/index.js` side-effect free. - Do not use `agi/studio/main.js` as a bundle entry; it auto-boots a DOM app. - Keep observations explicit and versioned. - Keep rewards readable and decomposed. - Log training metrics every episode, not every frame. - Avoid blocking GPU readback in training loops. --- ## 10. Editor workflow Use the editor for authoring, inspection, debugging, and visual iteration. Recommended workflow: 1. Open `editor/index.html` locally or from the release site. 2. Create or load a project. 3. Place entities, colliders, lights, particle emitters, and audio nodes. 4. Use viewport debug modes to inspect depth, normals, albedo, velocity, thermal state, and bounds. 5. Save/export the scene. 6. Load the exported data in your game runtime. Editor-side concepts: ```text EditorApp -> owns app lifecycle, ECS world, panels ProjectManager -> save/load/autosave Viewport -> camera, render passes, debug views Inspector -> selected entity component editor WorldPanel -> global lighting/physics/render settings EditorParticles -> particle system integration EditorAudio -> procedural audio preview/authoring ``` When extending the editor: - Register new component schemas first. - Add inspector UI only after the data shape is stable. - Keep editor-only convenience data separate from runtime data. - Make exports deterministic and schema-versioned. --- ## 11. Template folder usage The `Template/` folder is a starter app. Copy it for a new project: ```powershell Copy-Item -Recurse C:\Coding\game\Template C:\Coding\game\MyPrototype ``` Then edit: ```text MyPrototype/ ├── index.html # page shell ├── style.css # app styling └── main.js # app loop and engine imports ``` If using source-mode imports, paths are relative to the new folder. If the copy lives beside `engine/`, use: ```js import { createWorld } from '../engine/EngineBootstrap.js'; ``` If the copy is deployed with a compiled bundle, use: ```js const PE = window.PE || window.ParticleEngine; const { createWorld } = PE; ``` --- ## 12. Project starter template Use this as the recommended new app shape: ```js import { ENGINE_FULL, createWorld, createEntity, setEntityComponent, createTransform, stepWorld, } from '../engine/EngineBootstrap.js'; class GameApp { constructor({ canvas }) { this.canvas = canvas; this.world = createWorld({ name: 'GameApp' }); this.running = false; this.lastTime = 0; } async init() { console.log(`Booting ${ENGINE_FULL}`); this.player = createEntity(this.world); setEntityComponent(this.world, this.player, 'Transform', createTransform({ position: [0, 0, 0], rotation: [0, 0, 0, 1], scale: [1, 1, 1], })); } start() { if (this.running) return; this.running = true; this.lastTime = performance.now(); requestAnimationFrame(this.frame); } frame = (now) => { if (!this.running) return; const dt = Math.min((now - this.lastTime) / 1000, 1 / 30); this.lastTime = now; this.update(dt); this.render(); requestAnimationFrame(this.frame); }; update(dt) { stepWorld(this.world, dt); } render() { const ctx = this.canvas.getContext('2d'); ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); ctx.fillStyle = '#38bdf8'; ctx.beginPath(); ctx.arc(this.canvas.width / 2, this.canvas.height / 2, 16, 0, Math.PI * 2); ctx.fill(); } } const canvas = document.querySelector('canvas'); const app = new GameApp({ canvas }); await app.init(); app.start(); ``` --- ## 13. What to build first For a new game: 1. Start with `Template/`. 2. Add ECS data for player/world/items. 3. Add a simple renderer before complex effects. 4. Add Plauna UI screens after the game loop exists. 5. Add saves once data shapes stabilize. 6. Add AGI Core only when you have an agent, observations, rewards, and a repeatable scenario. 7. Move reusable systems back into `engine/` only after two projects need them. For a new engine demo: 1. Start in `tests/playground/index.html` only if it belongs in the public demo suite. 2. Use compiled `PE` APIs for playground runtime paths. 3. Keep new engine modules under `engine/` and export them from `EngineBootstrap.js`. 4. Rebundle with `python bundle_engine.py --target engine --no-cache`. For a new UI/tool: 1. Start with Plauna screen components. 2. Keep commands/events separate from visual widgets. 3. Use the editor only for workflows that need scene or asset authoring. --- ## 14. Release checklist Before publishing: ```powershell python bundle_engine.py --target engine --no-cache python bundle_engine.py --target platform --no-cache ``` Then check: - `release/site/index.html` loads. - `release/site/playground/` loads the compressed bundle. - `release/site/assets/` contains the selected compressed runtime. - Version banner reports the expected Engine, Editor, Plauna, and AGI Core versions. - No playground code imports directly from `../../engine`. - Editor remains accessible from utility links, but Playground is the primary public CTA. --- ## 15. Design rules for this repository - Prefer existing engine exports before adding new duplicate helpers. - Keep app-specific content outside `engine/` until it is reusable. - Keep public bundle entrypoints side-effect free. - Prefer data-driven configuration for entities, UI screens, emitters, and training scenarios. - Avoid frame-loop allocations in rendering and simulation. - Add debug readbacks and overlays before changing complex physics or neural logic. - Use the main play/runtime path for active-body validation, not old preview-only paths. --- # Architecture Overview This page is the big picture: how the engine, editor, Plauna, AGI, and the WebGPU OS compose into one system. Read it before diving into any single subsystem. ## Layered composition The stack is built in reusable layers. Lower layers know nothing about higher ones; higher layers consume lower ones as libraries. ```mermaid flowchart TD subgraph Foundation engine["Engine — engine/\nGPU device, frame graph, ECS,\nrender, sim, net, audio"] end subgraph Tools_and_UI editor["Editor — editor/\nscene & asset IDE"] plauna["Plauna — plauna/\nhybrid DOM/GPU UI framework"] agi["AGI — agi/\nRL rig + WebGPU tensors"] end subgraph Platform os["WebGPU OS — webgpu-os/\nkernel + shell + packages + apps"] end engine --> editor engine --> plauna engine --> agi editor --> os plauna --> os agi --> os engine --> os ``` ## The composition rule `webgpu-os/` is **composition glue only**. It consumes `engine/`, `plauna/`, `agi/`, and `editor/` as libraries and must not fork them. If something needs fixing, it is fixed upstream in the owning subsystem, not patched inside the OS layer. (Source: `webgpu-os/AUDIT.md` §4.) ## How the OS maps onto the subsystems The WebGPU OS does not reimplement runtime services — it *reuses* the engine and Plauna: | OS concern | Provided by | | --- | --- | | Kernel / scheduler / GPU device | Engine `core/gpu/`, `core/framepipeline/`, `core/scheduler/`, `core/memory/`, plus `webgpu-os/kernel/` glue | | Compositor / window manager / shell | Plauna `workspace/`, `surface/`, `widgets/`, `themes/` + `webgpu-os/shell/` | | Filesystem / project / packages | Engine `core/ResourceManager.js`, `core/save/` + `webgpu-os/storage/` + `webgpu-os/packages/` | | IPC / events / "syscalls" | Engine `core/events/`, Plauna `core/events.js` + `webgpu-os/kernel/Syscalls.js` | | Intelligence layer | AGI `tensor/`, `brain/`, `core/` | (Source: `webgpu-os/AUDIT.md` §3, "Asset inventory → OS subsystems".) ## Tier framing The OS is delivered in tiers; **Tier 1 (browser-resident)** is the current implementation target: | Tier | What it is | Status | | --- | --- | --- | | **1 — Browser-resident OS** | Desktop-like environment in a browser tab, built from the existing stack | **Implementation target** | | **2 — WASM + native host** | Rust + Wasmtime/WASI host wrapping Dawn/wgpu, exposing capability-mediated APIs | Documented migration path | | **3 — Native microkernel** | Kernel + user-space services around WebGPU/WGSL | Research-only | A core decision (adopted from the research): **do not put WebGPU "in the kernel."** In every tier the GPU service is a user-space process owning validation, shader compilation, and pipeline creation; the kernel handles scheduling, memory protection, and device mediation only. This mirrors the browser GPU-process model. ### Tier 2 migration contract (stable surfaces) These must survive a future Tier 2 swap, so treat them as the stable contract: - **App manifest** — same JSON boots a Plauna panel today and a WASI sandbox tomorrow. - **Syscall surface** (`kernel/Syscalls.js`) — JS shape today, WASI capability table tomorrow. - **WGSL shaders** — already portable. - **Capability gates** — the rule graph is the Tier 1 stand-in for the Tier 2 capability broker. ## Cross-cutting concerns These topics span every subsystem and have dedicated pages: - [Boot Sequence](boot-sequence.md) — how the OS comes up. - [GPU Device Sharing](gpu-device-sharing.md) — one device, many apps. - [Security & Trust Model](security-model.md) — capabilities, trust rings, package verification. - [Data Flow](data-flow.md) — how state moves (ECS, save, collab). - [History & Evolution](history-evolution.md) — why the layering looks the way it does. --- # History & Evolution This is the canonical story of how the stack grew. Understanding the order in which the layers appeared explains why the boundaries sit where they do — and why `webgpu-os/` is glue rather than a rewrite. ## The order of creation ```mermaid timeline title Stack evolution Engine : WebGPU runtime, ECS, render/sim/net Editor : scene & asset authoring on top of the engine Plauna : hybrid DOM/GPU UI framework + workbench AGI : RL "parasite rig" + WebGPU tensor library + Studio WebGPU OS : compositor + shell + kernel + packages composing all of the above ``` ### 1. Engine The foundation. A **pure-browser, GPU-first** runtime: a shared WebGPU device, frame graph, ECS, rendering pipeline, simulation systems, networking, and audio. Everything else consumes it. Its development principles — no Node.js, GPU-first, ECS-driven, modular — propagate to every later layer. (Source: `engine/README.md`.) ### 2. Editor The first major application built on the engine: a scene and asset authoring IDE (`editor/`). It established the panel/workbench patterns and the project/filesystem abstraction (`editor/js/ProjectManager.js`) that Plauna and the OS later generalize. ### 3. Plauna A UI runtime extracted to serve UI needs the editor exposed. Plauna adds **hybrid DOM/GPU rendering**, DOM-free text measurement, a GPU **surface graph**, and a **dockable workbench** (workspaces, panels, tabs). It integrates with the engine using the same bootstrap and VGPU patterns as the editor, and is explicitly **zero-dependency, no build step**. (Source: `plauna/README.md`.) ### 4. AGI An intelligence layer: a "Doc Octavius"-style **parasite rig** that injects into a humanoid ragdoll and learns to control it via reinforcement learning (PPO). It ships its own **WebGPU tensor library** (`agi/tensor/`), neural networks (`agi/brain/`), a curriculum system, and **AGI Studio** — a full training workspace application. (Source: `agi/README.md`.) ### 5. WebGPU OS The unifying layer. Rather than rebuild runtime services, it **composes** the engine, Plauna, AGI, and editor into a desktop-like, GPU-first **OS in a browser tab**: a kernel (syscalls, scheduling, GPU mediation, trust/permissions), a shell (desktop, taskbar, windows), a signed package system, and a runtime app catalog. (Source: `webgpu-os/AUDIT.md`.) ## Why documentation stopped — and why it's being redone Documentation was written per-layer as each was built, then drifted as the OS absorbed everything. The result was scattered across `docs/`, `webgpu-os/docs/`, `engine/docs/`, and many per-component `.md` files, with overlapping and stale content. This `MD/` set restructures all of it into one audience-segmented source of truth, leaving the original files in place as read-only references. See the [Contribution Workflow](../contributing/doc-contribution-workflow.md) for how to keep it from drifting again. ## Naming note Older docs and source headers may refer to the project as **"Particle Engine" / "Particle Engine v2"** and to game content as **"Particle Realms Online."** These are the historical names of the engine and a game built on it; the current umbrella is the **WebGPU OS** stack described here. --- # Boot Sequence How the WebGPU OS comes up, from the HTML page to a mounted desktop. This reflects `webgpu-os/boot.js` and the `bootWebGpuOS()` function in `webgpu-os/index.js`. ## Entry points - **`webgpu-os/index.js`** — a side-effect-free barrel exporting `bootWebGpuOS(options)`. Importing it does **not** auto-boot, which makes it the clean entry point for the static bundler (`bundle_engine.py --target webgpu-os`). - **`webgpu-os/boot.js`** — a thin wrapper that calls `bootWebGpuOS()` on `DOMContentLoaded` for plain ES-module/dev usage. ```javascript // boot.js (essence) import { bootWebGpuOS } from './index.js'; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => bootWebGpuOS(), { once: true }); } else { bootWebGpuOS(); } ``` ## The boot phases `bootWebGpuOS()` runs these phases, updating the on-screen boot status as it goes: ```mermaid sequenceDiagram participant HTML as index.html participant Boot as bootWebGpuOS() participant Kernel as KernelBootstrap participant Apps as appRegistry participant Mods as modRegistry participant Desktop as Desktop (shell) HTML->>Boot: DOMContentLoaded Boot->>Kernel: KernelBootstrap.init({ canvasSelector, logger }) Kernel-->>Boot: kernel services Boot->>Apps: appRegistry.discover() Apps-->>Boot: discovered apps Boot->>Kernel: packageManager.syncBuiltins(appRegistry) Boot->>Mods: modRegistry.discover() Mods-->>Boot: loaded mods Boot->>Desktop: new Desktop(root, taskbar, kernel).mount() Desktop-->>Boot: desktop mounted Boot->>HTML: hide boot loader, set window.OS ``` 1. **Initializing kernel** — `KernelBootstrap.init({ canvasSelector, logger })` brings up kernel services against the WebGPU canvas. 2. **Discovering apps** — `appRegistry.discover()` finds apps from `apps/` (errors are logged as warnings, not fatal). Discovered built-ins are synced into the package registry via `kernel.packageManager.syncBuiltins(appRegistry)` (idempotent). 3. **Loading mods** — `modRegistry.discover()` loads runtime mods from `mods/`. 4. **Mounting desktop shell** — `new Desktop(desktopRoot, taskbarRoot, kernel)` then `await desktop.mount()`. Missing shell root elements throw. 5. **Optional security self-tests** — when `window.__DEV__` is true or the URL contains `?securityAudit`: `auditSyscallGuards(kernel)`, `auditCapabilityMap()`, and `runSecurityDoctor(kernel)` run and log findings. `kernel.securityDoctor()` is also exposed for on-demand use. 6. **Ready** — the boot loader is hidden and `window.OS = { version, ready: true }` (frozen). `bootWebGpuOS()` resolves to `{ kernel, desktop, version }`. ## Kernel init order Inside `KernelBootstrap`, the package/trust subsystem initializes in this order (Source: `webgpu-os/docs/ARCHITECTURE.md`): ```text TrustStore.init() → PackageManager.init() (re-registers installed packages/mods) → PatchManager → UpdateManager ``` Because installed packages are re-registered on init, **installed apps survive a reload.** ## Boot options `bootWebGpuOS(options)` accepts selector overrides (defaults shown): | Option | Default | | --- | --- | | `canvasSelector` | `#os-gpu-canvas` | | `desktopSelector` | `#os-desktop` | | `taskbarSelector` | `#os-taskbar` | | `statusSelector` | `#os-boot-status` | | `loaderSelector` | `#os-boot-loader` | | `logger` | `console` | ## Failure handling If any phase throws, the boot status is set to `Boot failed: `, the error is logged via `logger.error`, and the promise rejects. App/mod discovery errors are non-fatal and surface as console warnings. ## See also - [GPU Device Sharing](gpu-device-sharing.md) — what the kernel sets up on the canvas. - [Security & Trust Model](security-model.md) — what the boot-time audits check. - WebGPU OS **API Reference** — `KernelBootstrap`, `AppRegistry`, `Desktop`. --- # GPU Device Sharing The whole OS runs against a **single** WebGPU device shared by the shell and every app. This page explains the model and where it lives. It expands the notes in `webgpu-os/docs/ARCHITECTURE.md`. ## Why one device WebGPU devices are expensive and the browser already runs GPU work in a dedicated process. The OS follows the same principle: one device, brokered by the kernel, with per-app budgets and barriers — rather than each app creating its own device. > **Design rule:** the GPU service is user-space, not "in the kernel." The kernel mediates the device (scheduling, memory protection, fan-out); validation, shader compilation, and pipeline creation happen above it. See [Architecture Overview](architecture-overview.md). ## Key components | Concern | Component | | --- | --- | | Device acquisition + sharing | `kernel/GpuDeviceBroker.js` | | Adapter/device info | `kernel/GpuInfo.js` | | VRAM accounting | `kernel/VRAMTracker.js` | | Virtual GPU abstraction | `engine/core/gpu/VirtualGPU.js` (VGPU) | | Multi-queue submission | `engine/core/gpu/VGPUMultiQueue.js` | | Resource barriers | engine VGPU resource-barrier enforcement | | Device recovery | `engine/core/gpu/GpuRecovery.js` | | Canvas bootstrap | `engine/core/gpu/WebGpuCanvasBootstrap.js` | ## The model ```mermaid flowchart TD canvas[WebGPU canvas] --> broker[GpuDeviceBroker\nsingle device] broker --> vgpu[VirtualGPU / VGPU] vgpu --> mq[VGPUMultiQueue\nper-app tick budgets] vgpu --> barriers[Resource barriers] broker --> vram[VRAMTracker] broker -. device-lost .-> appA[App A] broker -. device-lost .-> appB[App B] broker -. device-lost .-> shell[Shell] ``` - **Single device** — acquired once by the broker and handed to the VGPU abstraction. - **Frame-loop ownership** — the kernel owns the `requestAnimationFrame` loop and allocates **per-app tick budgets**; apps do not each spin their own loop. - **Multi-queue + barriers** — concurrent GPU work is ordered through `VGPUMultiQueue` and resource-barrier enforcement so apps don't corrupt each other's state. - **VRAM tracking** — `VRAMTracker` accounts for allocations so the OS can show usage (e.g. the **GPU Manager** app) and enforce limits. ## device-lost fan-out When the browser raises WebGPU's `device-lost`, the broker **fans the event out** to every app and the shell so each can release and rebuild GPU resources. Recovery logic lives in `engine/core/gpu/GpuRecovery.js`. Apps should treat their GPU resources as reconstructable and listen for the fan-out rather than assuming the device is permanent. ## What an app should assume - It shares the device; it must respect its tick budget and not block the frame loop. - GPU resources can be lost at any time; handle the `device-lost` fan-out. - Heavy compute belongs in WebGPU compute passes, scheduled through the VGPU layer. ## See also - [Boot Sequence](boot-sequence.md) — when the device is acquired. - Engine **API Reference** — `core/gpu/*`. - WebGPU OS **API Reference** — `kernel/GpuDeviceBroker`, `kernel/VRAMTracker`, `kernel/GpuInfo`. --- # Security & Trust Model How the OS contains code it runs. Apps and mods are **capability-gated** and packages carry a **trust verdict**; the two combine so that untrusted code is contained even if it declares broad permissions. This page consolidates `webgpu-os/docs/PERMISSIONS_MODEL.md` and `PACKAGING.md`. ## Two enforcement layers 1. **Capabilities** — a package may only call a syscall if it *declared* the matching permission **and** the user/policy *granted* it. 2. **Trust verdict** — the result of verifying the package's integrity, signature, provenance, and scan risk. The verdict can override grants (e.g. block network egress regardless of declared permissions). ## Capability enforcement ```mermaid flowchart LR launch[Desktop._launchPanel] --> guard[guardSyscalls\nkernel/Syscalls.js] guard --> req[kernel.permissions.require appId, cap] req -->|granted| run[run syscall] req -->|missing/denied| deny[throw or prompt] req --- store[(PermissionStore\npersisted grants)] ``` - A package declares `permissions` in its manifest. - At launch, `Desktop._launchPanel` wraps the panel's syscalls with `guardSyscalls(kernel, appId, syscalls)`. - Each guarded method calls `kernel.permissions.require(appId, cap)` before running; missing/denied capabilities throw or prompt per policy. - `kernel/Permissions.js` resolves decisions; `PermissionStore` persists grants. ### Permission vocabulary Capabilities are dotted strings. Declare only what you use — the consent prompt lists requested permissions. | Namespace | Examples | Gated action | | --- | --- | --- | | `fs.*` | `fs.read`, `fs.write`, `fs.delete`, `fs.list` | virtual filesystem | | `storage.*` | `storage.read`, `storage.write`, `cache.get`, `mount-pick` | OPFS / cache / mounts | | `ipc.*` | `ipc.emit`, `ipc.on` | inter-app messaging | | `gpu.*` | `gpu.getDevice` | raw GPU device | | `ai.*` | `ai.infer` | model inference | | `net.*` | `net.send`, `net.on` | network egress | | `ui.*` | `ui.notify`, `ui.modal` | shell UI | | `package-install`, `package-remove`, `patch-apply` | — | package/patch management | ## Trust verdicts → capability defaults Installed packages carry a verdict (`PackageManager.getTrustProfile(appId)`): | Verdict | Network egress | Notes | | --- | --- | --- | | `trusted` (root-chained) | as granted | full capability set available to grant | | `pinned` (TOFU) | as granted | accepted by the user on first install | | `untrusted` (self-signed, unpinned) | **no auto-grant** | restricted; must be explicitly granted | | `quarantined` (integrity fail / high scan risk / key change) | **hard-blocked** | `guardSyscalls` throws on any `net.*` regardless of grants | This is **default-deny egress**: it blunts credential exfiltration and worm C2 even if a malicious package declares `net.send`. ## The verification choke point All installs route through `PackageManager.verifyAndAuthorize()` (Source: `webgpu-os/docs/ARCHITECTURE.md`): ```mermaid flowchart LR integrity[Integrity\nhash check] --> trust[Trust\nroots + pinning] trust --> provenance[Provenance\nsigning lineage] provenance --> scan[Scan\nPackageScanner] scan --> policy[Policy] policy --> verdict[Verdict] ``` - **Ring-0 roots** live in `kernel/trust/roots.json`; `kernel/TrustStore.js` handles roots + publisher pinning. - **Provenance** is checked by `kernel/ProvenanceChecker.js` and `kernel/SigningLineage.js`. - **Scanning** is performed by `packages/PackageScanner.js`. ## Consent & trust-on-first-use (TOFU) - First install of a self-signed package prompts with: **publisher fingerprint**, **trust verdict**, **scan risk**, and **requested permissions**. - Accepting **pins** the publisher fingerprint (`TrustStore.pin`). - **Anti-takeover:** if the same publisher later presents a *different* fingerprint, the install is flagged (`publisherChanged`) and requires explicit re-consent — defending against `event-stream`-style account takeover. - The shell can register a rich modal via `packageManager.setConsentHandler(fn)`; otherwise a `confirm()` fallback is used. ## Install-time execution policy Packages run **no install scripts**. Code executes only when the app is opened (its `mount()`), inside the per-app sandbox (`storage/AppSandbox.js`) with guarded syscalls. There is no `postinstall`/`.pth`-style hook — the top real-world infection vector is removed by design. ## Boot-time self-audit Boot with `?securityAudit` (or `window.__DEV__ = true`) to run: - `auditSyscallGuards(kernel)` — reports guarded / open / unguarded syscalls. - `auditCapabilityMap()` — detects capability-map drift (unclassified or stale entries). - `runSecurityDoctor(kernel)` — full posture report; also exposed as `window.securityDoctor()`. ## Audit logs - Package lifecycle → `/os/logs/packages.log`; updates → `/os/logs/updates.log`. - Per-package trust metadata (`trustVerdict`, `scanRisk`, `provenanceLevel`, `publisherFingerprint`) is stored in the package registry. ## See also - WebGPU OS **API Reference** — `kernel/Permissions`, `kernel/TrustStore`, `kernel/Syscalls`, `packages/PackageManager`, `packages/PackageVerifier`. - App manifest fields — [WebGPU OS Architecture](../webgpu-os/architecture.md). --- # Data Flow How state moves through the stack: ECS state, persistence, the virtual filesystem, inter-app messaging, and optional multi-user sync. This page orients you before the per-subsystem references. ## State lives in ECS The engine is **ECS-driven**: runtime state lives in components, owned by a world, and mutated by systems. Plauna defines its own UI components in a dedicated UI world (e.g. `UIRoot`, `UIWorkspace`, `UIZone`, `UIView`, `UILayout`, `UISurface`, `UIText`). See: - Engine ECS: `engine/ecs/` (`EntityManager`, `EntitySchema`, components, systems, world). - Plauna UI ECS: `plauna/ecs/` and `plauna/core/StateStore.js` + `DirtyGraph.js`. ```mermaid flowchart LR systems[Systems] -->|mutate| components[(Components)] components -->|read| systems components --> save[Save / serialization\nengine/core/save/] components --> collab[Collab mesh\nengine/collab/] ``` ## Persistence and the filesystem The OS exposes a virtual filesystem and storage layer over browser primitives: | Layer | Component | Backed by | | --- | --- | --- | | Virtual FS (syscall-facing) | `kernel/VirtualFS.js`, `storage/SystemFS.js` | OPFS / IndexedDB | | Origin-private files | `storage/OPFSDriver.js` | OPFS | | Key-value / structured | `storage/IndexedDBDriver.js` | IndexedDB | | External mounts | `storage/MountDriver.js` | user-picked dirs | | Caching | `storage/CacheDriver.js` | Cache API | | Per-app isolation | `storage/AppSandbox.js` | scoped paths | | Orchestration | `storage/StorageManager.js` | — | Engine-side asset/resource loading and save go through `engine/core/ResourceManager.js`, `engine/core/compression/`, and `engine/core/save/`. ## Inter-app messaging (IPC) Apps communicate through kernel-mediated IPC syscalls (`ipc.emit` / `ipc.on`), gated by capabilities. Lower-level event buses exist in the engine (`engine/core/events/`) and Plauna (`plauna/core/events.js`), and the kernel adds buses such as `CommandBus`, `FxBus`, and `PatchBus`. ```mermaid flowchart LR appA[App A] -->|ipc.emit| bus[kernel IPC / CommandBus] bus -->|ipc.on| appB[App B] bus --- guard[capability guard\nipc.*] ``` ## Optional multi-user sync For collaborative or multi-user scenarios, the engine's collab mesh (`engine/collab/`) provides identity, integrity, presence, signaling, host migration, and scene/transform sync. State that needs to be shared is replicated over this mesh; identity and integrity are enforced by `CollabIdentity`, `CollabCrypto`, and `CollabIntegrityVerifier`. ## Authoritative UI state [Particle State Channels](state-channels.md) connect Plauna views to ECS, CSE, or another authority. UI events become typed intents. Confirmed snapshots or merge patches return as projections. SSE is the standard downstream browser transport, paired with HTTP `POST` for upstream intents. Particle signaling and BroadcastChannel remain available for peer-oriented routes. (Source: `engine/network/stateChannels/`, `plauna/core/BindingEngine.js`) ## End-to-end example A note created in the **Notepad** app: 1. The app calls `fs.write` (a guarded syscall) → `kernel/VirtualFS.js` → `storage/OPFSDriver.js`. 2. The capability guard checks `fs.write` against the app's grants. 3. On reload, `PackageManager` re-registers the app and its sandboxed storage path persists, so the note is still there. ## See also - [GPU Device Sharing](gpu-device-sharing.md) — GPU resource flow. - [Security & Trust Model](security-model.md) — how the syscalls above are gated. - [Particle State Channels](state-channels.md) — authoritative intent and projection flow. - Engine, Plauna, and WebGPU OS **API References**. --- # Schema Evolution and Expand-Contract Particle Realms treats every durable or independently deployed data boundary as a versioned contract. This includes SQLite tables, JSON files, browser storage, OPFS trees, binary saves, network messages, checkpoints, and signed packages. The expand-contract pattern applies directly to the active SQLite service and to any storage layout shared by old and new application instances. The same safety goal applies elsewhere, but the mechanism changes with the medium: JSON uses explicit readers and pure upcasters, live protocols negotiate overlapping versions, signed artifacts use immutable generations, and disposable caches are namespaced and invalidated. The machine-readable source of truth is `schema-contracts/catalog.json`. Its meta-schema is `schema-contracts/catalog.schema.json`, and `tools/validate_schema_contracts.py` checks the catalog, every first-party JSON document, every formal JSON Schema, and every direct production use of browser persistence APIs. A browser-storage call must be owned by a declared contract or carry one exact, reviewed classification such as primitive preference, ephemeral session state, disposable cache, storage infrastructure, or compatibility shim. Structured durable state cannot be hidden behind an exclusion. Expand-contract is not a blanket rewrite rule. It is the correct mechanism for relational columns, shared browser keys, and rolling network deployments. Immutable hashed events, signed packages, procedural voxel snapshots, and disposable caches need different strategies because dual-writing them would weaken integrity or manufacture a lossy conversion. ## Non-negotiable invariants 1. Every authoritative value has a format discriminator and an explicit version. 2. Writers emit one declared current version. Readers may accept an ordered compatibility window. 3. Reading never silently relabels old data. A pure migration must produce the new shape and pass the new validator. 4. Unknown and future durable versions fail closed without overwriting the source. 5. Durable commits are transactional, copy-on-write, manifest-last, or generation-swapped. A partially written value is never promoted as current. 6. Rollback data remains readable until the catalog's retirement gates pass. 7. Cache records are never treated as authoritative. They may be invalidated and rebuilt. 8. Signed packages are immutable. A schema change creates a new signed generation; it never mutates an installed generation in place. ## One policy, five mechanisms | Contract class | Evolution strategy | Commit boundary | Unknown version | | --- | --- | --- | --- | | SQLite authoritative data | Expand, backfill, switch reads, contract | One database transaction per migration or backfill batch | Reject startup/readiness | | JSON, IndexedDB, OPFS, binary saves | Read old, pure upcast in memory, validate, copy-on-write | Verified backup, manifest-last, or generation swap | Reject or quarantine | | WebSocket, SSE, HTTP envelopes | Advertise capabilities and negotiate current plus previous | Acknowledged message or request transaction | Protocol error; never reinterpret | | Signed package/export | Side-by-side immutable generation | Verify hashes/signature, then publish manifest | Reject | | UI and derived cache | Namespace by version and rebuild | Replace disposable entry | Invalidate | ## Repository coverage The catalog currently records 125 independently evolving contract families. The implementation wave covers the following high-risk boundaries: - The Python service uses ordered, checksummed SQLite migrations and transactional cursor-based backfills. Physical drift checks include columns, defaults, nullability, checks, unique keys, indexes, and foreign keys. (Source: `server/database/migrations.py`, `server/database/db.py`.) - Engine and Life saves use exact format readers. World WAL recovery validates the entire sequence, CRCs, entry types, coordinates, lengths, and LSN order before replay. Flush and checkpoint share one operation queue, and a failed region save cannot truncate the log. ANI motion NPZ files use bounded arrays, `allow_pickle=False`, an explicit v2 manifest, and a legacy v1 reader. (Source: `engine/world/storage/WorldStorage.js`, `Life/tools/ani_motion_contract.py`.) - State channels, chunk networking, LLLM, and master-server routes keep an explicit overlapping protocol window. Request and receipt identities remain bound to the originating client and authority epoch. MATS currently uses an additive, fire-and-forget WebSocket envelope with a bounded legacy reader; it does not claim capability negotiation or acknowledgements that the transport does not implement. (Source: `engine/network/stateChannels/StateChannelContract.js`, `engine/world/storage/ChunkNetworking.js`, `lllm/proto/lllm_protocol.py`, `editor/mats/js/workflow-contracts.js`.) - Editor projects, scenes, assets, material graphs, audio graphs, and MATS workflows validate staged documents before replacing live state. MATS writes the canonical v1 record last and retains its legacy bare-array shadow during the expand phase. (Source: `editor/js/storage/GameEditorDatabase.js`, `editor/js/components/GraphPersistenceContracts.js`, `editor/mats/js/workflow-contracts.js`.) - AGI checkpoints, conversations, tensor indexes, model registries, and model packages use validated envelopes and manifest-last or verified copy-on-write publication. One filesystem-safe model ID validator prevents path collisions. (Source: `agi/persistence/CheckpointContracts.js`, `agi/llm/formats/LLMPersistenceContracts.js`, `agi/llm/storage/AtomicJSON.js`.) - Plauna themes, page transitions, design tokens, and widget imports have explicit readers. Theme ownership has one legacy writer, and widget collections reject prototype-polluting identifiers. (Source: `plauna/themes/ThemePreference.js`, `plauna/motion/PageTransitionContracts.js`, `plauna/style/DesignTokenContracts.js`, `plauna/widgets/WidgetConfig.js`.) - WebGPU OS profiles, app settings, VFS metadata, app manifests, causal events, AI Echo state, sandbox records, backup manifests, credential vaults, shell preferences, built-in app state, shortcut overrides, and extension credentials fail closed on future versions. VFS writes and subtree deletes are hierarchically serialized. AI Echo commits versioned, hashed shard generations through one global manifest; credential envelopes authenticate provider and generation in their AAD. (Source: `webgpu-os/drivers/ProfileDriver.js`, `webgpu-os/kernel/VirtualFS.js`, `webgpu-os/apps/ai-echo/AgentStateStore.js`, `webgpu-os/kernel/schema/ShellPreferenceRecords.js`.) - RealmForge `.proasset` documents, migration evidence, persistent history, drafts, recovery evidence, and content-addressed binary descriptors publish manifests last and retain exact legacy readers. Engine sound palettes, spells, materials, particle effects, collaboration identities, realm branches, and legacy chunk persistence now use bounded records instead of shape inference. (Source: `webgpu-os/apps/realmforge/document/`, `engine/core/schema/BrowserRecordContract.js`, `engine/world/storage/ChunkPersistence.js`.) - AGI Studio directory handles remain native structured-cloned handles inside a versioned transactional envelope. Editor and MATS settings, hotkeys, recent projects, environment state, collaboration rooms, audio state, and camera state share one owner per key and retain rollback-readable legacy shadows. (Source: `agi/studio/core/StudioDirectoryHandleStore.js`, `editor/js/storage/EditorPreferenceContracts.js`, `editor/mats/js/settings-contract.js`.) - Matrix, Cardbattles, Game2, the Python client, JHC, and bundler artifacts now have explicit durable or immutable boundaries instead of shape inference. (Source: `Matrix/src/settings-store.js`, `cardbattles/src/core/SessionContract.js`, `game2/client/src/core/SchemaContracts.js`, `client/src/particle_client/json_contracts.py`, `jhc/implementations/python/jhc/package.py`, `bundler/config.py`.) `engine/core/schema/SchemaEvolutionRegistry.js` is the shared browser-side primitive for JSON-like values. It records exact readable and writable versions, rejects ambiguous or cyclic migration graphs, fingerprints inputs, requires synchronous side-effect-free adapters, and validates every intermediate value. Persistence remains outside the registry so a caller can choose the correct atomic commit strategy. ## Relational expand-contract The active Python service owns an ordered, checksummed SQLite migration ledger. Startup uses `BEGIN IMMEDIATE`, verifies migration history and physical schema drift, and refuses databases created by a newer server. Backfills persist their cursor and data in the same transaction, so a batch can be retried without skipping rows. ```mermaid flowchart LR expand["Expand: add nullable structures"] --> dual["Deploy: dual-write, read old"] dual --> fill["Migrate: idempotent bounded backfill"] fill --> readnew["Deploy: read new, dual-write"] readnew --> audit["Verify: parity, dependencies, telemetry"] audit --> appcontract["Contract app: new only"] appcontract --> dbcontract["Contract DB after rollback window"] ``` For a column rename, do not rename or drop the old column in the first deployment. Add the new column nullable, deploy dual writes, backfill in bounded batches, switch reads while retaining dual writes, and only then stop old writes. `NOT NULL`, uniqueness, and removal belong in the final contract migration after all gates pass. Each migration has a stable identifier and checksum. Editing a migration that has already shipped is schema drift; add a new migration instead. Readiness exposes the migration status so an incompatible instance is removed from service instead of returning corrupt or misleading results. ## Document and browser-storage evolution For JSON, IndexedDB, local storage, and OPFS: 1. Decode with strict JSON rules and resource bounds. 2. Inspect the format and version before applying defaults. 3. Validate the source version. 4. Plan an explicit path to the write version. 5. Run pure, deterministic adapters without mutating the source. 6. Validate each intermediate version and the final value. 7. Write a pending copy or new generation. 8. Read it back and verify it before changing the current pointer or manifest. 9. Retain the previous generation for rollback. Import paths are staged before they can replace editor projects, scenes, AGI checkpoints, models, profiles, or OS state. A malformed import or future version leaves the active value untouched. Large directory exports publish their manifest last, which makes an incomplete directory visibly incomplete instead of deceptively current. An adapter may deliberately use `read-old-write-current` when a legacy value cannot be rewritten without external procedural context. For example, a full voxel snapshot cannot be converted into a current diff without its baseline world. In that case the version-specific reader validates and applies the legacy semantics, the writer still emits only the current format, and the source is not deceptively relabelled. IndexedDB database versions and record schema versions solve different problems. The IndexedDB version upgrades object stores and indexes. Each durable record still needs its own format/version envelope and reader policy. Multiple features must not open the same database name with unrelated upgrade callbacks; the editor now has one owner for its shared database upgrade path. `webgpu-os/storage/IndexedDBDriver.js` exposes an opt-in synchronous record migration hook, but it does not pretend that one schema covers a heterogeneous object store. Production stores mix packages, registry families, trust records, pointers, and encrypted profiles. Store owners must first add key-family matching and, where required, staged asynchronous verification before registering those records. The world WAL keeps one additional deliberate compatibility boundary. WAL v1 can replay writes, but its historical wire format has no delete tombstone. Region deletion is generation-safe and atomically persisted today, but crash replay of an uncheckpointed delete requires a phased WAL v2 rollout: deploy the v2 reader first, then the v2 writer, retain v1 reads through the rollback window, and only retire v1 after dependency and telemetry gates pass. The implementation does not silently reinterpret a v1 record as a deletion. ## Protocol evolution State channels, chunk networking, and LLLM transports advertise supported versions and select an overlap. During a rolling deployment the compatibility window is current plus previous. New senders continue to understand the previous reader until compatibility telemetry shows no old peers. A message version is not inferred from its shape. Oversized messages, unsafe object keys, non-finite numbers, malformed fields, duplicate or stale response identifiers, and unsupported future versions are rejected at the boundary. A legacy unversioned reader exists only where the catalog explicitly records it; writers never emit the legacy shape. ## Retirement gates An old field, key, reader, table, object store, protocol, or generation may be removed only after every applicable catalog gate is evidenced: - `backfill-complete`: no rows or records remain unmigrated. - `zero-discrepancy`: old and new representations agree. - `dependency-audit`: application code, services, analytics, jobs, tests, and tools no longer depend on the old contract. - `compatibility-telemetry-zero`: no old-version reads, writes, peers, or fallbacks were observed for the agreed window. - `rollback-window-expired`: the rollback deployment and data-retention window has elapsed. - `verified-backup`: a tested recovery copy exists before destructive contraction. The catalog phase stays `expand`, `migrate`, or `read-new` until the evidence exists. A code merge alone is not evidence that contract is safe. ## Deployment and rollback runbook Before deployment: 1. Add or update the catalog entry and compatibility fixtures. 2. Add the old-reader/new-writer and new-reader/old-writer tests appropriate to the contract. 3. Run `python tools/validate_schema_contracts.py`. 4. Run `python tools/run_schema_compatibility.py` for the release gate. Use `--static-only` for a fast non-browser pass and `--full` for extended validation. 5. Capture a verified backup for destructive or authoritative changes. During deployment, expose migration/backfill state through readiness or diagnostics and watch rejection, fallback, quarantine, discrepancy, and backfill counters. Stop the rollout if instances disagree on the compatibility window, a checksum changes, drift appears, or any future version is encountered. Rollback application code before contracting storage. Because the expand and migrate phases retain the previous representation, the previous application version can continue reading it. If a newly written generation is bad, restore the verified backup or previous manifest/generation; do not attempt to relabel it. After the observation window, record gate evidence, switch the catalog phase, and perform contraction as a separate release. Re-run the same compatibility gate after removal. ## Adding a contract Add a catalog entry with an owner, classification, medium, strategy, phase, owned paths, version field, one write version, all readable versions, unknown-version behavior, commit and rollback strategies, implementation components, and retirement gates. The validator rejects duplicate identities, missing paths, nonexistent declared symbols, missing enforcement components, incoherent policies, unversioned live protocols, destructive cache rules applied to durable data, and invalid JSON Schemas. Prefer a small fixture matrix over only a same-version round trip: | Writer | Reader | Required result | | --- | --- | --- | | Previous | Current | Accepted and upcast without source mutation | | Current | Previous | Accepted only during an intentional dual-write/protocol window | | Current | Current | Exact validated round trip | | Future | Current | Explicit rejection; durable source preserved | | Corrupt/partial | Current | Rejection, quarantine, rollback, or cache invalidation per policy | ## Audit baseline The 2026-08-08 repository scan indexed 10,675 first-party files. The current release gate parses 385 JSON documents, validates 26 formal JSON Schemas, and inspects 111 production files that directly call browser-persistence APIs. Of those files, 71 are contract-owned, 46 have exact reviewed classifications, six are intentionally mixed, and zero are uncovered. The scan records 80 local-storage, 12 session-storage, 21 IndexedDB, and six OPFS API occurrences. That breadth is why schema evolution is enforced as a cross-stack contract rather than a database-only convention. See also [Data Flow](data-flow.md), [Security & Trust Model](security-model.md), and [Particle State Channels](state-channels.md). --- # Particle State Channels Particle State Channels define where shared state lives and how views receive it. This guide is for app, game, and UI authors who need one authoritative state path across Plauna, ECS, WebGPU OS state, and Particle Network. ## Standard flow A State Channel accepts typed **intents** and emits revisioned **projections** plus receipts. An intent asks an authority to perform an action. A projection contains confirmed state for a consumer to render. Plauna never treats an input event as shared truth. (Source: `engine/network/stateChannels/StateChannelContract.js`, `plauna/core/BindingEngine.js`) ```mermaid flowchart LR ui["Plauna UI"] -->|"intent via HTTP POST"| authority["StateChannelAuthority"] authority -->|"validated mutation"| state["ECS or CSE state"] state -->|"snapshot or merge patch"| authority authority -->|"SSE projection + receipt"| ui authority -->|"mesh projection + receipt"| peers["WebRTC peers"] authority -->|"same-origin projection"| tabs["BroadcastChannel tabs"] ``` The standard browser client transport uses Server-Sent Events (SSE) downstream and HTTP `POST` upstream. `EventSource` reconnects the projection stream. Event IDs and synthesized snapshots recover missed revisions. The local development server and V3 Masterserver enable this route by default. The production route requires a short-lived signed lease bound to a proven V3 key, route, channel, and role. Set `PARTICLE_STATE_SSE=false` on the Masterserver only when an operator intentionally disables this V3 capability. (Source: `engine/network/stateChannels/SseStateChannelTransport.js`, `Masterserver/app/state_channels.py`, `Masterserver/app/trust.py`) `resolveStateChannelTransport()` keeps that default while removing per-app setup. A server authority resolves to SSE and can acquire its production lease from `NetworkDriver`. A same-origin authority resolves to `BroadcastChannel`. A peer authority opens the existing Particle WebRTC route and resolves to mesh. An in-process authority stays local. (Source: `engine/network/stateChannels/StateChannelTransportResolver.js`, `engine/network/stateChannels/MeshStateChannelTransport.js`, `webgpu-os/drivers/NetworkDriver.js`) ## Place state by owner | State | Owner | Example | Delivery | | --- | --- | --- | --- | | Local presentation | Plauna `StateStore` | open menu, hover, draft input | in-process | | Authoritative simulation | ECS world | transform, particle emitter, combat state | mesh or State Channel projection | | App-owned durable state | WebGPU OS CSE | preferences, document state, workflow state | `AppStateChannelAdapter` | | Shared mergeable state | CRDT or semantic replication | workstation layout, offline edits | Particle Network | | Remote view | State Channel client | dashboard value, inspector state | SSE by default | Do not mirror the same authoritative value into independent UI, ECS, and network stores. Keep one owner. Derive projections for every other consumer. ## Define a channel ```javascript import { defineStateChannelContract, StateChannelAuthority, StateChannelClient, SseStateChannelTransport, } from '../../engine/network/index.js'; const contract = defineStateChannelContract({ id: 'realm.emitter', initialState: { emitter: { rate: 100 } }, intents: { 'emitter.adjust': { validate: payload => Number.isFinite(payload?.delta) || 'invalid-delta', reduce: (state, payload) => ({ ...state, emitter: { ...state.emitter, rate: state.emitter.rate + payload.delta }, }), }, }, }); const client = new StateChannelClient(contract, { clientId: 'editor-ui' }); await client.connect(new SseStateChannelTransport({ channelId: contract.id })); await client.submit('emitter.adjust', { delta: 25 }); ``` The authority serializes submissions. It validates the channel, action, payload, expected revision, authority epoch, and optional fencing token. Duplicate intent IDs receive duplicate receipts without reapplying the mutation. (Source: `engine/network/stateChannels/StateChannelAuthority.js`) ## Connect Plauna `StateStore` holds the latest projection for rendering. `BindingEngine.bindOneWay()` updates retained nodes. `bindTwoWay()` and `bindIntent()` dispatch actions; they do not write an authoritative projection before a receipt arrives. A `PlaunaApp` state-channel descriptor creates the client and resolves its transport, then owns cleanup. Callers may still provide an existing client. (Source: `plauna/core/StateStore.js`, `plauna/core/BindingEngine.js`, `plauna/core/app.js`) ```javascript app.bindOneWay(rateLabel, 'textContent', 'emitter.rate', { transform: rate => `${rate} particles/s`, }); app.bindIntent(increaseButton, 'click', { action: 'emitter.adjust', payload: { delta: 25 }, }); ``` ## Connect ECS replication `NetReplicated` version 2 selects a named profile. Profiles set authority, cadence, projection strategy, component interest, and transport. Use `ui-state-channel` for state exposed to browser views over SSE. Use `interpolated-transform` or `gpu-semantic` for peer simulation traffic over mesh. (Source: `engine/ecs/components/NetReplicated.js`, `engine/ecs/replication/ReplicationProfiles.js`) SSE is the State Channel standard, not a replacement for every network lane. WebRTC mesh carries peer gameplay and semantic replication. BroadcastChannel remains useful for same-origin peer tabs. In-process transport remains useful for tests and local authorities. ## Connect CSE app state `AppStateChannelAdapter` commits each accepted intent through `AppStateEngine.put()` with `expectedVersion`. The compare-and-swap result becomes the new authority state. External CSE writes produce a replacement snapshot. (Source: `webgpu-os/kernel/state/AppStateChannelAdapter.js`, `webgpu-os/kernel/state/AppStateEngine.js`) The OS persists bounded authority checkpoints and offline intent outboxes through `NetworkPersistence`. A standby restores only valid, non-regressing checkpoints. `StateChannelAuthorityCoordinator` uses signed, replay-rejected heartbeats, deterministic takeover, and strictly increasing fencing tokens before a promoted peer accepts writes. This is browser availability and stale-writer fencing, not Byzantine consensus across a physical network partition. (Source: `webgpu-os/drivers/NetworkPersistence.js`, `engine/network/stateChannels/StateChannelAuthority.js`, `engine/network/stateChannels/StateChannelAuthorityCoordinator.js`) An authority is eligible only while its scoped mesh route is active. Suspending that route removes local authority immediately. On resume, the coordinator waits for a current authority heartbeat before deterministic failover, preventing a restored background tab from immediately reclaiming a stale host role. (Source: `engine/network/stateChannels/StateChannelAuthorityCoordinator.js`) ## Embedded network runtime `NetworkDriver` starts one `EmbeddedParticleNode` per browser profile unless the user explicitly opts out. A browser lock, with a renewable local-storage lease fallback, makes one tab the external-backbone owner. Other tabs stay followers and can take over after lease expiry. The node is always a resident while enabled. Supernode, witness, and authority are temporary roles on that same node, announced with signed, expiring role envelopes. Supernode selection is deterministic, bounded to two through five candidates, and based on locally observed connection quality. (Source: `webgpu-os/drivers/NetworkDriver.js`, `webgpu-os/drivers/EmbeddedParticleNode.js`, `engine/network/routes/NodeRoleProtocol.js`, `engine/collab/CollabMeshTopology.js`) The resident backbone does not join an app, room, game, document, or voice route. Opening a peer-backed State Channel acquires a reference-counted route lease. Multiple local consumers share one WebRTC session. Closing one consumer cannot disconnect the others. The final release closes the route after a three-second idle grace; reopening during that grace cancels teardown. Hidden, frozen, or page-hidden contexts release immediately and reacquire only after becoming active again. (Source: `engine/network/routes/RouteSessionManager.js`, `engine/network/stateChannels/StateChannelTransportResolver.js`, `engine/network/stateChannels/MeshStateChannelTransport.js`) `ParticleEndpointRuntime` makes the resident node and temporary supernode roles one endpoint rather than separate networks. The endpoint runtime is enabled by default, but app route membership is still lazy. Only a fully open, active app acquires its room route and becomes eligible to host compatible route traffic. (Source: `engine/network/endpoint/ParticleEndpointRuntime.js`, `webgpu-os/drivers/NetworkDriver.js`.) The production Masterserver broker holds only bounded in-memory event history and the latest projection. It enforces channel, connection, message, replay, rate, role, and idle limits. It is a transport fallback, not durable app state; an ECS, CSE adapter, or elected peer remains the authority. A static site alone cannot provide this authenticated SSE route. (Source: `Masterserver/app/state_channels.py`, `Masterserver/app/config.py`.) This lifecycle follows the platform boundary: `RTCPeerConnection` is exposed to `Window`, not a permanently running service worker; Web Locks last only while their callback remains unsettled; and frozen pages should close WebRTC, BroadcastChannel, and held locks. See the [W3C WebRTC specification](https://www.w3.org/TR/webrtc/), [W3C Web Locks specification](https://www.w3.org/TR/web-locks/), and [Chrome Page Lifecycle guidance](https://developer.chrome.com/docs/web-platform/page-lifecycle-api). A closed or discarded browser therefore cannot promise continuous hosting. Another active browser node or an operator-owned server must take over. AGI Studio publishes run state and training metrics through the same contract and transport resolver. It uses same-origin delivery when standalone and accepts the OS `NetworkDriver` for mesh delivery. (Source: `agi/network/TrainingStateChannel.js`, `agi/studio/core/StudioApp.js`) ## Run the proof Start the development server, then open one authority tab and one client tab with the same channel name: ```bash python start_server.py ``` ```text http://127.0.0.1:9001/tests/state-channel-lab.html?role=authority&channel=my-emitter http://127.0.0.1:9001/tests/state-channel-lab.html?role=client&channel=my-emitter ``` The client sends an emitter intent. The authority applies it to an ECS `ParticleEmitter` with a `NetReplicated` profile. Both tabs render the confirmed Plauna projection. (Source: `tests/state-channel-lab.js`) ## See also - [Data Flow](data-flow.md) - [ECS v2](../engine/ecs.md) - [Plauna Architecture](../plauna/architecture.md) - [Security & Trust Model](security-model.md) --- # Engine Overview The engine (`engine/`) is the foundation of the whole stack: a **pure-browser, GPU-first** runtime providing the WebGPU device, frame graph, ECS, rendering, simulation, networking, and audio that every other subsystem builds on. ## What it provides - A shared **WebGPU device** and frame pipeline (the OS's GPU service runs on this). - An **ECS** for all runtime state. - A **rendering** pipeline (passes, materials, shaders, lighting, post-processing, volumes). - **Simulation** systems (physics, particles, fluids, cloth, AI, world). - **Networking** (protocol, replication, client/server) and a **collab** mesh. - **Audio**, **resources/assets**, a **modding** layer, runtime **UI**, and dev **tools**. ## Audience Engine, graphics, and simulation developers. App developers usually consume the engine indirectly through the OS and Plauna; read this when you work on rendering, simulation, or low-level GPU code. ## Development principles From `engine/README.md`: - **Pure browser runtime** — no Node.js dependencies. - **GPU-first** — prefer compute shaders for heavy simulation. - **ECS-driven** — all state lives in components. - **Modular** — each subsystem is independent and testable. ## Top-level modules | Module | Path | Purpose | | --- | --- | --- | | Core | `engine/core/` | WebGPU device, frame graph/pipeline, math, memory, scheduler, platform, workers, save, profiling, `ResourceManager` | | ECS | `engine/ecs/` | entities, components, systems, queries, storage, prefabs, world | | Render | `engine/render/` | renderers, materials, passes, lighting, culling, post-process, SDF, volumes, particles | | Sim | `engine/sim/` | physics, particles, fluids, cloth, AI, world simulation | | Net | `engine/net/` | protocol, replication, client, server | | Collab | `engine/collab/` | multi-user mesh: identity, integrity, presence, sync | | Audio | `engine/audio/` | audio core, synth, spatial audio | | Animation | `engine/animation/` | animation systems | | Gameplay | `engine/gameplay/` | rules, events, AI, narrative, perception | | Voxel / World | `engine/voxel/`, `engine/world/` | voxel and world systems | | Resources | `engine/resources/` | resource/package system | | Mod | `engine/mod/` | scripting API + sandbox | | UI / Tools | `engine/ui/`, `engine/tools/` | runtime UI, inspector/profiler | | Compat | `engine/compat/` | asset importers / compatibility | ## Entry points - `engine/EngineBootstrap.js` — full engine bootstrap. - `engine/EngineEditorBootstrap.js` — bootstrap that also wires the editor and Plauna (`PE.Plauna`). - `engine/core/AppBootstrap.js` — app-level bootstrap. - `engine/*Imports.js` — import maps (`EngineImports`, `EcsImports`, `RenderImports`, `MathImports`, `ToolsImports`). - `engine/version.js` — version info. ## Next steps - [Engine Architecture](architecture.md) — how the modules fit together. - [Engine Getting Started](getting-started.md) — boot and render something. - Engine **API Reference** — per-module symbol reference (run `tools/extract_api.py`). --- # Engine Architecture How the engine's modules compose. The engine is organized as independent subsystems that communicate through the ECS and an event bus, all running on a single shared WebGPU device. ## High-level structure ```mermaid flowchart TD bootstrap[EngineBootstrap] --> core[core/\nGPU device, frame graph,\nscheduler, memory] core --> ecs[ecs/\nworld, entities, components, systems] ecs --> render[render/\npasses, materials, lighting] ecs --> sim[sim/\nphysics, particles, fluids, cloth, ai] ecs --> net[net/\nprotocol, replication, client/server] core --> audio[audio/] core --> resources[resources/ + core/ResourceManager] ecs --> gameplay[gameplay/\nrules, events, ai, narrative] core --> tools[tools/ + ui/] ``` ## Core (`engine/core/`) The lowest layer. Notable sub-areas: - **`gpu/`** — the WebGPU device and the VGPU abstraction (`VirtualGPU.js`), multi-queue, bind groups, streaming, memory tracking, recovery, canvas bootstrap. This is what the OS's GPU device broker builds on. - **`framegraph/` + `framepipeline/`** — declarative render/compute pass graph and the per-frame pipeline. - **`scheduler/`** — task scheduling ("processes"), including async compute. - **`memory/`** — GPU and host memory managers, object pools, mapped buffer rings, vertex pools. - **`math/`, `timing/`, `events/`, `workers/`, `compression/`, `save/`, `profiler|profiling/`, `platform/`, `schema/`, `shaders/`** — supporting services. - **`ResourceManager.js`** — asset/resource loading and lifetime. ## ECS (`engine/ecs/`) State model for the whole engine. - `EntityManager.js` — entity lifecycle. - `EntitySchema.js` — component schema definitions (large; the canonical component catalog). - `ComponentHealer.js` — schema migration / repair of component data. - `components/`, `systems/`, `query/`, `storage/`, `prefabs/`, `world/` — the moving parts. Systems read and mutate components; rendering and simulation are driven from ECS state. ## Render (`engine/render/`) Turns ECS state into frames. - Renderers: `DualModeRenderer.js`, `SceneRenderer.js`, world/preview/minimap renderers. - `LightManager.js`, culling (`IndexedClusterCuller.js`), `Mesh.js`, `RenderBundleManager.js`. - Sub-areas: `materials/`, `passes/`, `postprocess/`, `lighting/`, `geometry/`, `mesh/`, `particles/`, `sdf/`, `spectral/`, `atmosphere/`, `volumes/`, `streaming/`, `shaders/`, `state/`. ## Sim (`engine/sim/`) GPU-first simulation, driven each tick by `SimulationUpdate.js`: `physics/`, `particles/`, `fluids/`, `cloth/`, `ai/`, `world/`. ## Net & Collab (`engine/net/`, `engine/collab/`) - `net/` — `protocol/`, `replication/`, `client/`, `server/`. - `collab/` — the multi-user mesh: identity, crypto, integrity, presence, signaling, host migration, fast channel, scene/transform sync. The OS uses this for cross-tab/peer IPC and multi-user scenarios. ## Gameplay (`engine/gameplay/`) `rules/` (including `RuleGraph.js`, the Tier 1 capability-gate stand-in), `events/` (`EventGraph.js`), `ai/`, `narrative/`, `perception/`. ## How the OS reuses the engine The OS does not reimplement these — see [Architecture Overview](../concepts/architecture-overview.md) for the mapping of OS concerns onto engine modules (GPU, scheduler, memory, events, resources). ## See also - [GPU Device Sharing](../concepts/gpu-device-sharing.md). - Engine **API Reference** — generated per-file from source. --- # Engine Getting Started Bring the engine up in a browser and understand the bootstrap entry points. Assumes [Install & Run](../getting-started/install.md) is done. ## Prerequisites - A current browser that exposes WebGPU on the machine. Verify both `navigator.gpu` and a successful `navigator.gpu.requestAdapter()` call. - The repo served over HTTP (`python start_server.py`). ## Bootstrap entry points Pick the bootstrap that matches your use case: | Entry | Use when | | --- | --- | | `engine/EngineBootstrap.js` | You want the full engine runtime. | | `engine/EngineEditorBootstrap.js` | You also want the editor + Plauna wired (`PE.Plauna`, `initializePlauna`). | | `engine/core/AppBootstrap.js` | You're building an app-level entry. | ## Import maps The engine groups imports into barrels so you can pull in a coherent set without long relative paths: - `EngineImports.js` — engine-wide. - `EcsImports.js` — ECS. - `RenderImports.js` — rendering. - `MathImports.js` — math. - `ToolsImports.js` — dev tools. ## Minimal flow The engine is GPU-first and ECS-driven, so a typical session: 1. Bootstrap the engine against a WebGPU canvas (acquires the device + frame pipeline). 2. Create or load an ECS **world**. 3. Spawn entities and attach components (see `engine/ecs/EntitySchema.js` for the component catalog). 4. Register systems (render, sim) that run each frame. 5. Start the frame loop — `render/` draws from ECS state; `sim/SimulationUpdate.js` advances simulation. > **Note:** Exact function signatures are generated into the Engine **API Reference** by `tools/extract_api.py`. Run it, then browse `engine/reference/` for `EngineBootstrap`, `ecs/EntityManager`, `render/SceneRenderer`, and `sim/SimulationUpdate`. ## Where to look next - Rendering: `engine/render/` — start with `SceneRenderer.js` and `DualModeRenderer.js`. - Simulation: `engine/sim/SimulationUpdate.js`. - ECS components: `engine/ecs/EntitySchema.js`. - GPU layer: `engine/core/gpu/VirtualGPU.js`. ## See also - [Engine Architecture](architecture.md). - [Boot Sequence](../concepts/boot-sequence.md) (OS-level). --- # Virtual GPU (vGPU) `VirtualGPU` is the unified GPU abstraction layer that powers every system in the engine. It wraps raw WebGPU with automatic caching, pooling, and resource management — turning ~20 lines of boilerplate into one. > **This is the most important concept in the engine's GPU layer.** Every renderer, simulation system, and compute shader goes through vGPU. It is the user-space GPU service the OS mediates (see [GPU Device Sharing](../concepts/gpu-device-sharing.md)). Source: `engine/core/gpu/VirtualGPU.js`. ## Quick start ```javascript import { getVGPU } from './engine/core/gpu/VirtualGPU.js'; // Initialize (once per app — returns singleton) const vgpu = await getVGPU(); // Create a vertex buffer const { buffer, id } = vgpu.buffer.create({ size: 1024, usage: 'vertex', label: 'myVertices' }); // Compile a WGSL shader (cached automatically) const module = vgpu.shader.compile('triangle', ` @vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f { var pos = array(vec2f(0, 0.5), vec2f(-0.5, -0.5), vec2f(0.5, -0.5)); return vec4f(pos[i], 0, 1); } @fragment fn fs() -> @location(0) vec4f { return vec4f(0.23, 0.74, 0.97, 1); } `); // Create a render pipeline — blend mode as a simple string const pipeline = vgpu.pipeline.render({ vertex: { module }, fragment: { module, targets: [{ format: 'bgra8unorm' }] }, label: 'trianglePipeline' }); ``` No `GPUBufferUsage.VERTEX | COPY_DST` flags, no bind group layout descriptors, no pipeline layout boilerplate — vGPU handles it. ## Initialization Three ways to get a vGPU instance: ```javascript // 1. Singleton (recommended) — first call creates, later calls reuse import { getVGPU, vgpu } from './engine/core/gpu/VirtualGPU.js'; const gpu = await getVGPU(); const same = vgpu(); // synchronous access; throws if not initialized // 2. Direct creation (not singleton) const inst = await VirtualGPU.create({ powerPreference: 'high-performance', requiredFeatures: ['timestamp-query'] }); // 3. From an existing GPUDevice const wrapped = VirtualGPU.fromDevice(myGpuDevice); ``` ## The 6 core managers Every vGPU instance exposes six manager objects — the primary API you'll use daily. ### `vgpu.buffer` — buffer management Create, write, and manage GPU buffers with automatic usage-flag resolution and optional pooling. ```javascript const { buffer, id } = vgpu.buffer.create({ size: 4096, usage: 'storage', // or 'vertex', 'index', 'uniform', 'storage|vertex', etc. label: 'particleData', pooled: true, // optional: reuse from buffer pool }); vgpu.buffer.write(buffer, new Float32Array([1, 2, 3, 4])); vgpu.buffer.release(id); // returns to pool if pooled ``` Usage strings map to WebGPU flags: | String | WebGPU flags | | --- | --- | | `'vertex'` | `VERTEX \| COPY_DST` | | `'index'` | `INDEX \| COPY_DST` | | `'uniform'` | `UNIFORM \| COPY_DST` | | `'storage'` | `STORAGE \| COPY_DST \| COPY_SRC` | | `'indirect'` | `INDIRECT \| COPY_DST \| STORAGE` | | `'map-read'` | `MAP_READ \| COPY_DST` | | `'map-write'` | `MAP_WRITE \| COPY_SRC` | | `'storage\|vertex'` | Combined flags (pipe-separated) | ### `vgpu.bindings` — layouts & bind groups Define named layouts and create bind groups with caching and deduplication. ```javascript const layout = vgpu.bindings.defineLayout('material', [ { binding: 0, type: 'uniform', visibility: 'vertex|fragment' }, { binding: 1, type: 'texture', visibility: 'fragment' }, { binding: 2, type: 'sampler', visibility: 'fragment' }, ]); const group = vgpu.bindings.createGroup('material', [ { binding: 0, resource: { buffer: uniformBuffer } }, { binding: 1, resource: textureView }, { binding: 2, resource: sampler }, ], 'materialGroup'); ``` Binding type strings: `'uniform'`, `'storage'`, `'read-only-storage'`, `'texture'`, `'sampler'`, `'storage-texture'`. Visibility strings are pipe-separated stage names: `'vertex'`, `'fragment'`, `'compute'`, `'vertex|fragment'`. ### `vgpu.shader` — shader compilation Compile WGSL with automatic caching, preprocessor defines, and hot-reload support. ```javascript const module = vgpu.shader.compile('myShader', wgslSource); // cached by name const hq = vgpu.shader.compile('myShader_hq', wgslSource, { // with defines MAX_LIGHTS: 16, ENABLE_SHADOWS: 1 }); vgpu.shader.recompile('myShader', updatedSource); // hot reload (dev) const info = await module.getCompilationInfo(); info.messages.forEach(m => console.warn(m.message)); ``` ### `vgpu.pipeline` — render & compute pipelines Create and cache pipelines with simplified blend-state resolution. ```javascript const pipeline = vgpu.pipeline.render({ vertex: { module: vsModule, entryPoint: 'vs_main', buffers: [/* ... */] }, fragment: { module: fsModule, entryPoint: 'fs_main', targets: [{ format: 'bgra8unorm' }] }, blend: 'alpha', // or 'additive', 'premultiplied', 'none' depthStencil: true, // shorthand for depth24plus with less/write topology: 'triangle-list', // optional, default label: 'myPipeline' }); const compute = vgpu.pipeline.compute({ module: csModule, entryPoint: 'main', label: 'physicsUpdate' }); const async = await vgpu.pipeline.renderAsync({ /* same options */ }); // non-blocking ``` Blend strings: `'none'` (opaque), `'alpha'` (srcAlpha, oneMinusSrcAlpha), `'additive'` (one, one), `'premultiplied'` (one, oneMinusSrcAlpha). > **Automatic caching:** pipelines are keyed by their full configuration. Calling `vgpu.pipeline.render()` twice with identical options returns the cached pipeline instantly — zero GPU work. ### `vgpu.texture` — textures & samplers ```javascript const { texture, view, id } = vgpu.texture.create({ width: 512, height: 512, format: 'rgba8unorm', usage: 'render|texture', // render target + sampleable label: 'colorTarget' }); const sampler = vgpu.texture.sampler({ filter: 'linear', wrap: 'repeat' }); vgpu.texture.release(id); ``` ### `vgpu.command` — command encoding ```javascript const encoder = vgpu.command.encoder('myPass'); // ... set up passes ... vgpu.command.submit(encoder.finish()); // One-shot compute dispatch (encode, dispatch, submit) vgpu.command.dispatchCompute({ pipeline: computePipeline, bindGroups: [group0, group1], workgroups: [64, 1, 1], label: 'physicsStep' }); vgpu.command.copyBuffer(srcBuffer, dstBuffer, 0, 0, 4096); const data = await vgpu.command.readBuffer(gpuBuffer); // GPU → CPU ``` ## Advanced subsystems Beyond the six core managers, vGPU includes 20+ specialized modules as properties on the instance. **Enhancement modules:** `vgpu.debug` (labels/markers), `vgpu.ring` (streaming uploads), `vgpu.profiler` (GPU timing), `vgpu.scheduler` (work scheduling), `vgpu.bundles` (render bundles), `vgpu.mipmap` (mipmap gen), `vgpu.queries` (occlusion/stats), `vgpu.warmup` (async pre-compile). **Resource management:** `vgpu.readback` (non-blocking GPU→CPU), `vgpu.memory` (usage tracking/budgets), `vgpu.materials` (material bind groups), `vgpu.barriers` (resource transitions), `vgpu.quality` (dynamic resolution), `vgpu.renderStats` (draw calls, triangles). **Advanced rendering (lazy-initialized via factory methods):** `vgpu.getRenderGraph()` (pass scheduling + resource aliasing), `vgpu.getIndirectRenderer()` (GPU-driven indirect draws), `vgpu.getHiZCulling()` (hierarchical-Z occlusion), `vgpu.getStreaming()` (texture/mesh streaming), `vgpu.getDebugDraw()` (immediate-mode debug shapes). **Compute & shader utilities:** `vgpu.computeUtils` (reduction/scan/fill/copy), `vgpu.preprocessor` (WGSL macros/includes), `vgpu.reflection` (shader introspection), `vgpu.bindless`, `vgpu.multiQueue`, `vgpu.semaphores` (timeline sync). ## Common patterns ### Simple compute shader ```javascript const { buffer: input } = vgpu.buffer.create({ size: 4096, usage: 'storage', data: inputData }); const { buffer: output } = vgpu.buffer.create({ size: 4096, usage: 'storage' }); const module = vgpu.shader.compile('transform', ` @group(0) @binding(0) var input: array; @group(0) @binding(1) var output: array; @compute @workgroup_size(64) fn main(@builtin(global_invocation_id) gid: vec3u) { output[gid.x] = input[gid.x] * 2.0; } `); const pipeline = vgpu.pipeline.compute({ module, entryPoint: 'main' }); vgpu.bindings.defineLayout('transform', [ { binding: 0, type: 'read-only-storage', visibility: 'compute' }, { binding: 1, type: 'storage', visibility: 'compute' }, ]); const group = vgpu.bindings.createGroup('transform', [ { binding: 0, resource: { buffer: input } }, { binding: 1, resource: { buffer: output } }, ]); vgpu.command.dispatchCompute({ pipeline, bindGroups: group, workgroups: [16] }); const result = new Float32Array(await vgpu.command.readBuffer(output)); ``` ### Frame lifecycle & stats ```javascript vgpu.beginFrame(); // ... all rendering and compute work ... vgpu.endFrame(); const stats = vgpu.getStats(); // → { buffers: { managed, pooled, totalSize }, shaders: { compiled, cached }, // pipelines: { render, compute }, textures: { count }, ... } ``` ## Before & after Creating a particle compute pipeline takes ~68 lines of raw WebGPU vs ~12 with vGPU — about **82% less code**, plus automatic caching, pooling, memory tracking, and debug labels for free. ## Device properties & cleanup ```javascript vgpu.device // GPUDevice vgpu.queue // GPUQueue vgpu.adapter // GPUAdapter vgpu.limits // maxBufferSize, maxComputeWorkgroupSizeX, etc. vgpu.features // supported features set vgpu.capabilities // full capability info vgpu.destroy(); // release all buffers, textures, pipelines, and the device ``` --- # ECS v2 Entity-Component-System architecture: **entities are IDs, components are data, systems are functions.** No inheritance and no scene graph — just fast, flat, data-oriented design. ## Quick example ```javascript import { createWorld, createEntity, stepWorld } from './engine/ecs/world/World.js'; import { registerSystem } from './engine/ecs/systems/SystemRegistry.js'; import { setComponent, getComponent } from './engine/ecs/storage/ArchetypeStorage.js'; // 1. Create a world const world = createWorld({ name: 'MyGame' }); // 2. Create entities (just numeric IDs) const player = createEntity(world); const enemy = createEntity(world); // 3. Attach components (plain data) setComponent(world, player, 'Transform', { position: [0, 1, 0], rotation: [0, 0, 0, 1], scale: [1, 1, 1] }); // 4. Register systems (functions that run each tick) registerSystem(world, { name: 'GravitySystem', phase: 'physics', update(world, dt) { // Query and update entities with PhysicsBody components } }); // 5. Step the simulation stepWorld(world, 1 / 60); ``` ## Core concepts ### Worlds A **world** is a container for entities, components, and systems. Most apps use a single world, but you can create multiple for isolation (e.g. a UI world separate from gameplay). ```javascript const world = createWorld({ name: 'GameWorld', fixedDelta: 1 / 60, phases: ['prePhysics', 'physics', 'postPhysics', 'render', 'lateUpdate'] }); ``` The world tracks: - **`world.time`** — current tick count, elapsed time, fixed delta. - **`world.systems`** — registered system list. - **`world.metrics`** — per-system timing for profiling. - **`world.config.phases`** — ordered execution phases. ### Entities An entity is a **generational ID** — a 32-bit integer encoding an index and a generation counter. This prevents dangling references: if entity slot 5 is destroyed and reused, the old ID (generation 1) won't match the new occupant (generation 2). ```javascript const id = createEntity(world); // → 1048577 (index=1, gen=1) destroyEntity(world, id); // frees the slot isEntityAlive(world, id); // → false const newId = createEntity(world); // reuses slot 1, but gen=2 isEntityAlive(world, id); // → false (old gen doesn't match) isEntityAlive(world, newId); // → true ``` > **ID encoding:** the lower 20 bits are the entity index (max ~1M entities); the upper bits are the generation counter. Decode via `decodeEntityId(id)` → `{ index, generation }`. ### Components Components are plain data objects attached to entities by name. The engine defines a standard schema in `EntitySchema.js` with normalization and validation: | Component | Key fields | Purpose | | --- | --- | --- | | `Transform` | position, rotation, scale | Spatial placement | | `PhysicsBody` | velocity, mass, type | Rigid body dynamics | | `Collider` | shape, size, offset | Collision shapes | | `Renderable` | meshId, materialId, visible | Visual representation | | `Light` | type, color, intensity, range | Light sources | | `Camera` | fov, near, far, projection | View configuration | | `ParticleEmitter` | preset, rate, lifetime | Particle spawning | | `NavAgent` | speed, radius, destination | AI pathfinding | | `NetReplicated` | ownerId, priority | Network sync | ```javascript // Set a component setComponent(world, entityId, 'Light', { type: 'point', color: [1, 0.9, 0.7], intensity: 2.5, range: 15 }); // Get a component const transform = getComponent(world, entityId, 'Transform'); console.log(transform.position); // → [0, 1, 0] // Remove a component removeComponent(world, entityId, 'Light'); ``` ### Systems Systems are registered functions that execute each frame in a defined phase order. They process entities by querying for required components. ```javascript registerSystem(world, { name: 'MovementSystem', phase: 'physics', // which phase to run in order: 10, // priority within phase (lower = earlier) updateKind: 'tick', // 'tick' (fixed), 'frame' (variable), or 'both' after: ['InputSystem'], // dependency ordering before: ['CollisionSystem'], // must run before these init(world, system) { // called once when registered system.state = { moveSpeed: 5.0 }; }, update(world, dt, system) { // called every tick — do your work here }, teardown(world, system) { // called when the system is unregistered } }); ``` ## Execution phases Systems are grouped into phases that execute in order. The default phases are: | Phase | Purpose | Typical systems | | --- | --- | --- | | `prePhysics` | Input processing, AI decisions | InputSystem, AISystem | | `physics` | Physics simulation, movement | PhysicsSystem, MovementSystem | | `postPhysics` | Collision response, constraints | CollisionSystem, ConstraintSystem | | `render` | Prepare render data | CameraSystem, LightSystem | | `lateUpdate` | Cleanup, UI sync | AnimationSystem, UISync | Two step functions exist: - **`stepWorld(world, dt)`** — runs all `tick`-kind systems (fixed timestep). - **`stepWorldFrame(world, dt)`** — runs all `frame`-kind systems (variable timestep). ## Archetype storage Components are stored in **archetype-based storage** (`ArchetypeStorage.js`). Entities with the same set of components are grouped together for cache-friendly iteration. The storage handles: - **Component add/remove** — moves entities between archetypes. - **Query matching** — finds all entities with a given component set. - **Sparse-set indexing** — O(1) component access by entity ID. ## Component healing `ComponentHealer.js` validates and repairs component data using the schemas in `EntitySchema.js`. It normalizes vectors, clamps values, and fills missing fields with defaults. This makes save/load robust — corrupted or outdated save data is automatically healed. ## Entity lifecycle ```javascript // 1. Create const id = createEntity(world); // 2. Add components setComponent(world, id, 'Transform', { position: [0, 0, 0] }); setComponent(world, id, 'Renderable', { meshId: 'cube' }); // 3. Systems process it each frame automatically // 4. Delete with full cleanup (GPU buffers, selections, etc.) deleteEntity({ ecsWorld: world, entityId: id, spawnedEntities, uniformBuffers, bindGroups }); ``` ## Prefabs `PrefabRegistry.js` defines reusable entity templates (spawnables) with pre-configured components and SDF collision shapes: ```javascript const entity = spawnPrefab(world, 'torch', { position: [5, 0, 3], scale: [0.5, 0.5, 0.5] }); // Automatically gets: Transform, Renderable, Light, ParticleEmitter, Collider // Plus an SDF collision shape (sphere/box/cylinder) for particle interaction ``` ## World snapshots Capture and restore world state for save/load, rewind, or debugging: ```javascript const snapshot = captureWorldSnapshot(world, { maxEntities: 1000 }); restoreWorldFromSnapshot(world, snapshot); ``` ## Key files | File | Purpose | | --- | --- | | `ecs/world/World.js` | `createWorld`, `createEntity`, `stepWorld`, `stepWorldFrame` | | `ecs/systems/SystemRegistry.js` | `registerSystem`, phase scheduling, dependency ordering | | `ecs/storage/ArchetypeStorage.js` | Component storage, queries, sparse-set indexing | | `ecs/EntitySchema.js` | Component schemas with types and normalization | | `ecs/ComponentHealer.js` | Auto-repair invalid component data | | `ecs/EntityManager.js` | High-level entity deletion with GPU cleanup | | `ecs/prefabs/PrefabRegistry.js` | Spawnable entity templates with SDF shapes | --- # Rendering Pipeline GPU-driven rendering with meshes, lights, materials, shader modes, and multi-pass compositing. All rendering is built on the [Virtual GPU (vGPU)](vgpu.md) abstraction. ## Frame structure A typical frame (from `Viewport.js`) follows this pass order: ```text 1. Update camera matrices (view, proj, viewProj, invViewProj) 2. Upload frame uniforms (camera, time, lighting) 3. [Debug] Particle debug pre-pass (if a particle-specific mode is active) 4. [Debug] Particle depth pre-pass (if scene debug mode: depth/normals) 5. Hybrid volume compute pass (density grid splatting) 6. Main render pass: a. Entity mesh rendering (GPU instanced, dynamic lighting) b. Grid rendering (ground plane with sun + ambient) c. SDF collider visualization d. Cloth / Rope rendering e. Particle rendering (full-res or deferred half-res) f. Volumetric smoke rendering g. Gizmos, wireframes, debug overlays 7. Depth buffer copy (for soft particles + debug viz) 8. [Debug] Scene Debug Visualizer post-pass (depth/normals from the depth buffer) 9. Shadow Atlas (unified depth → per-category composite) 10. Half-res particle composite (if deferred) 11. Distortion pass (heat haze) 12. SPH fluid surface pass (screen-space fluid rendering) 13. Bloom pass (emissive glow) 14. Tonemap pass (ACES + vignette) 15. Reconstruction (TSR/FSR/SVGF upscaling) + GPU submit ``` > Scene debug modes (steps 4, 8) skip all post-processing (steps 9–14) so the debug output is clean and unmodified. ## Lighting system `LightManager` handles all lighting via a single GPU uniform buffer (832 bytes). It supports sun (directional), ambient, and dynamic point lights. | Property | Default | Description | | --- | --- | --- | | `sunDirection` | `[0.2, -1.0, 0.1]` | FROM-light direction (steep overhead) | | `sunColor` | `[1.0, 0.95, 0.85]` | Warm white sun | | `sunIntensity` | `1.0` | Sun brightness multiplier | | `ambientColor` | `[0.15, 0.15, 0.2]` | Cool ambient fill | | `ambientIntensity` | `0.3` | Ambient brightness | | `globalBrightness` | `1.85` | Final multiplier on all lighting | > **Direction convention:** `sunDirection` is the FROM-light direction. The `EntityMeshRenderer` shader negates it internally (`normalize(-lighting.sunDirection)`). SDF/Cloth/Rope renderers receive the already-negated TO-light direction from the Viewport. ### Shader modes Four debug modes controlled by `lightingMode` and `debugMode`: | Mode | lightingMode | debugMode | Output | | --- | --- | --- | --- | | Standard | `dynamic` | `0` | Full sun + ambient + dynamic lights | | Unlit | `unlit` | `0` | Albedo color only, no lighting | | Normals | `dynamic` | `1` | World-space normals (`normal*0.5+0.5`) | | Depth | `dynamic` | `2` | Distance-based depth gradient | ### Particle lighting integration Particles interact with lighting three ways: - **Receive** — particles sample sun + ambient from frame uniforms. - **Emit** — hot particles (fire/plasma) become dynamic point lights via `ParticleLightEmission.js`. - **Shadow/tint** — smoke dims sunlight (`particleSunShadow`); fire tints it warm (`particleSunTint`). ## Mesh rendering Entity meshes are rendered by `EntityMeshRenderer`, which reads from ECS `Renderable` and `Transform` components. Each entity gets a per-object uniform buffer (its model matrix) and a bind group linking the uniform to the shader. ```javascript const pipeline = vgpu.pipeline.render({ vertex: { module: meshShader, entryPoint: 'vs_main', buffers: vertexLayouts }, fragment: { module: meshShader, entryPoint: 'fs_main', targets: [{ format }] }, depthStencil: true, label: 'EntityMesh' }); ``` ### State-First representation capability floors State-First semantic sources may set `minimumVisibleRepresentation` on an entity when their renderer does not implement every generic representation. The planner still returns `NONE` for a hidden or out-of-frustum entity, but a visible entity cannot fall below its declared floor. This prevents a quality profile from asking an integration to draw a `POINT`, `SPLAT`, or `LINE` when only a faithful mesh renderer exists. Actuated City Drive declares `FULL_MESH` for its 13 rigged vehicles. State-First continues to cull hidden cars, while every visible car uses the same body, glass, lights, wheels, steering, and suspension renderer as Native mode. It does not substitute chassis-sized boxes. (Sources: `engine/render/state/StateFirstRasterizer.js`, `tests/playground/src/demos/carDrive/index.js`.) ## Half-resolution particle compositing Particles render at half resolution for performance, then composite onto the main scene: 1. The SDF shader outputs `vec4(litColor, alpha)` — non-premultiplied. 2. The SDF pipeline renders into a half-res `bgra8unorm` texture with alpha blend. 3. The half-res texture starts cleared to `(0,0,0,0)`; after alpha blend, RGB = lit × alpha (premultiplied). 4. The composite pass uses fully additive blend (`one + one`) onto the scene. > **Implication:** with additive composite, particles can only *brighten* the scene, never darken it. Fire needs very low alpha (0.03–0.08) plus bright emission (2–5×) to avoid saturating the half-res buffer into a solid red wall. ## Grid renderer & shadow atlas `GridRenderer.js` draws the ground plane as a solid fill (alpha 0.85) with sun + ambient lighting, receiving lighting from `LightManager` via `setLighting()` each frame. `ShadowAtlas` provides unified shadow rendering: all casters (entities, ropes, particles) render into a shared 4096² depth texture, then shadows are composited per category with independent PCF, bias, and strength. Caster categories: `'entity'` (`EntityMeshRenderer.flushShadowDepth()`), `'rope'` (`RopeMeshRenderer` shadow pass), `'particle'` (`ParticleShadowCaster`, round billboard shadows). ## Debug visualization A two-tier debug system, accessible via the editor's view-mode dropdown. **Scene-wide modes (post-process)** read the actual hardware depth buffer (meshes + ropes) and composite with a particle depth color texture, via `SceneDebugVisualizerPass`: | Mode | Technique | Output | | --- | --- | --- | | Depth Buffer | Linearize `texture_depth_2d` + particle depth composite | Grayscale: near=white, far=black | | Normal Maps | Finite-difference world normals from composite depth | RGB = XYZ world-space normals | > **Why two sources?** Particles use `depthWrite: false` (transparent billboards), so they never appear in the hardware depth buffer. The visualizer composites hardware depth (meshes/ropes) with a separate particle depth color texture, picking whichever is closer per pixel. **Particle-specific modes (pre-pass)** render particles to a separate `rgba16float` texture using specialized renderers, displayed as a fullscreen overlay (all use circular billboard clipping, `dist > 1.0` discard): Albedo (`ParticleAlbedoRenderer`), Lighting Only (`ParticleLightingRenderer`), Velocity (`ParticleVelocityRenderer`), Age/Lifetime (`ParticleAgeRenderer`), Emissive (`ParticleEmissiveRenderer`), Size (`ParticleSizeRenderer`), Thermal (`ParticleThermalRenderer`, blackbody from temperature). Other debug systems: `VGPUDebugDraw` (immediate-mode lines/boxes/spheres/frustums), gizmo renderers (editor), and wireframe collision debug. ## Key files | File | Purpose | | --- | --- | | `render/LightManager.js` | Lighting uniforms, sun/ambient/dynamic lights | | `render/mesh/EntityMeshRenderer.js` | GPU-instanced entity mesh rendering | | `render/passes/ShadowAtlas.js` | Unified 4096² shadow depth atlas | | `render/passes/SceneDebugVisualizerPass.js` | Scene depth + particle depth → debug viz | | `render/passes/BloomPass.js` | Multi-pass bloom for emissive particles | | `render/passes/TonemapPass.js` | ACES tonemapping + vignette | | `render/passes/RenderPassManager.js` | Render target allocation, view-mode management | | `render/particles/ParticleSdfRenderer.js` | SDF billboard particle rendering | | `render/particles/ParticleHalfResComposite.js` | Half-res → full-res particle composite | | `render/shaders/ShaderComposer.js` | Modular WGSL shader composition | | `render/CameraMath.js` | View/projection matrix computation | --- # MorphField R2 Renderer MorphField is an additive, opt-in Engine renderer for semantic fields, sparse residuals, oriented kernels, and validated surface caches. A public **Nexel** describes scene intent. The compiler produces private **Fieldlets** and keeps the source scene authoritative. This page is the persistent R2 delivery record. An individual checklist box changes to `[x]` only after its implementation, focused tests, and item-specific evidence pass. A phase gate remains open until every required item and the integrated phase-level evidence pass. ## Current release status | Phase | Gate | Status on 2026-07-27 | | --- | --- | --- | | 0. Contracts, safety, research | Passed | Twelve public Draft 2020-12 schema resources (eleven source resources plus the generated offline compound bundle), the checked mode-specific capability profile, strict compiled-ABI/query ingress, ownership, diagnostics, fixtures, provenance, and the frozen core-profile baseline pass this gate. Release builders copy the schemas to their exact public routes. The current installed-Chrome revision passes all 62 browser gates, including the 12-gate real-device block. | | 1. Certified analytic slice | Open | Analytic compilation, CPU/GPU queries, conservative f32 certificates, direct tracing, a packed CPU-built threaded GPU BVH, guarded stable-analytic incremental projection and changed-range GPU publication, close-CSG/inside/seam/lifecycle coverage, and Playground scenes exist. A real compiler-worker path, general incremental compilation, and the complete reference-image gate remain open. | | 2. Assets and sparse residuals | Open | `.morph`, certified CPU residual hierarchy, and representation planning exist. GPU residency, radix/LBVH benchmarking, and fuzz evidence remain open. | | 3. Unified surface cache | Open | Regular extraction, rank-aware QEF work, atomic publication, and clean-room 2:1 transitions exist. Full Marching Cubes, Transvoxel compatibility, and manifold dual-contouring gates remain open. | | 4. Kernels, media, transparency | Open | Bounded CPU kernel bins, certified medium integration, and layered OIT reference logic exist. Integrated GPU composition and stress gates remain open. | | 5. Lighting and quality | Open | Tail-sensitive adaptive quality, native-resolution automatic tiers, certified-bound pruning, tier shadow policy, resolved/pending GPU admission guards, lighting-selective lazy wavefront construction, hybrid shading, host-safe composition, explicit-scale depth-aware reconstruction, and the renderer-integrated bounded-queue wavefront path pass the current portable and 12-gate real-device suites. ReSTIR/SVGF/IBL and the complete reference-image/energy gate remain open. | | 6. Simulation and queries | Open | Six external-encoder GPU queries, fixed-step scheduling, and compatible adapters exist. Full simulation parity and replay gates remain open. | | 7. Playground and release | Open | One public-API demo exposes nine focused Nexel specimens, lighting and simulation scenarios, the independent Structural Scale Lab, validation controls, separated timing channels, and copyable receipts. Every specimen distinguishes semantic source, compiled family, active evaluator, query/collision availability, SDF/reference-field classification, simulation ownership, and any diagnostic presentation glyph. The current source suite contains 62 gates: 50 device-independent gates and 12 real-device gates; all 62 pass on the current installed-Chrome run with zero failures or skips. Adapter absence remains one explicit device-required block. Long-run benchmarks for every preset, release hardening, and the Full R2 gate remain open. | The current code is a verified foundation and analytic vertical slice. It is not yet the Full R2 release. ## Architecture ```mermaid flowchart LR N["Nexel scene or .morph asset"] --> C["Device-independent MorphField compiler"] C --> A["Analytic field Fieldlets"] C --> R["Sparse residual Fieldlets"] C --> K["Oriented kernel Fieldlets"] C --> S["Cached surface Fieldlets"] A --> Q["Six typed queries"] R --> Q K --> Q S --> Q Q --> P["Eight ordered external-encoder phases"] P --> G["HDR and G-buffer outputs"] G --> H["Hybrid or progressive lighting"] H --> O["Host-owned color and optional depth targets"] ``` Source ownership is split by subsystem: | Path | Responsibility | | --- | --- | | `engine/render/morphfield/core/` | Nexel scene, validation, compiler, ABI, CPU BVH, and reference queries. | | `engine/render/morphfield/assets/` | Versioned `.morph` encoding, decoding, compression, limits, CRC32, and provenance. | | `engine/render/morphfield/runtime/` | Borrowed-device resources, external-encoder renderer, GPU queries, capabilities, shaders, outputs, and statistics. | | `engine/render/morphfield/schemas/` | Draft 2020-12 canonical JSON schemas, stable IDs, the public catalog, and the checked Nexel capability profile. | | `engine/render/morphfield/systems/` | Representation planning, residuals, surface extraction, transitions, kernels/media, simulation scheduling, and adapters. | | `tests/morphfield/` | Browser-native CPU, schema, ownership, shader, and real-device WebGPU acceptance harness. | | `tests/playground/src/demos/morphField.js` | Public-API interactive demo. | `editor/`, `webgpu-os/`, and `agi/` were read as integration references and remain unchanged. Vendored code, `engine/kaolin/`, and `engine/sim/physics/` remain hard boundaries. ## Public API `engine/render/morphfield/index.js` exports the namespace through `engine/render/index.js`, `engine/EngineBootstrap.js`, and bundled `window.PE` builds. ```javascript const scene = Engine.MorphField.createScene({ id: 'example', units: 'meters' }); scene.upsert({ id: 'ball', source: { kind: 'sphere', radius: 1 }, material: { type: 'pbr', baseColorFactor: [0.8, 0.2, 0.1, 1] }, }); const compiler = Engine.MorphField.createCompiler({ worker: 'auto' }); const compiled = await compiler.compile(scene); const capability = Engine.MorphField.Schemas.inspectNexelCapabilities(scene.get('ball')); console.log(capability.renderer, capability.gpuQueries, capability.limitations); const renderer = await Engine.MorphField.createRenderer({ device, colorFormat, depthFormat: 'depth32float', outputTransfer: 'auto', quality: { mode: 'auto', targetFPS: 'display' }, logger, }); renderer.setScene(compiled); renderer.resize(width, height); renderer.encode({ encoder, target: { colorView, depthView, composition: 'replace' }, camera, lights, time, deltaTime, frameIndex, performanceSample: { frameMs: rafIntervalMs, cpuMs: lastHostCpuMs, gpuMs: freshGpuTimestampMs, gpuTimingAvailable, gpuSamplePending, queueDepth, queueCapacity, queueThrottled, queueCompletionWallMs, }, }); ``` `performanceSample` is optional. `frameMs` is host cadence (the Playground supplies the rAF callback interval and reports admitted presentation separately), `cpuMs` is synchronous host work, and `gpuMs` is a fresh timestamp-query result. A host must omit `gpuMs` when no new timestamp has resolved instead of repeating a stale sample. `gpuSamplePending` is the number of outstanding timestamp samples. `queueDepth`, `queueCapacity`, and `queueThrottled` describe host submission pressure. Optional `displayIntervalMs` feeds the robust display-refresh estimator; missed callbacks are filtered and a new refresh target is accepted only after hysteresis. Optional `presentationMs` is the most recent admitted-frame interval; it qualifies queue-pressure fallback but is never folded into CPU/GPU work percentiles. `queueCompletionWallMs` is diagnostic completion latency, not shader execution time. Callers that do not provide measured channels retain the compatibility path derived from `deltaTime`; callers using the older explicit `totalMs` governor input retain that override. `renderer.setLightingMode('progressive')` makes the bounded wavefront tracer the renderer's progressive image source for supported analytic-family scenes. Each sample records Generate, Intersect, Shade, Shadow, and Finalize compute stages before resolving its `rgba32float` radiance sum and sample count into the renderer's HDR history. Unsupported representation families fall back to hybrid with an explicit reason in `getStats().lighting.fallbackReason`; the mode never silently substitutes a second fragment-shader path tracer. Advanced callers can also create the buffer-only tracer directly through `Engine.MorphField.createPathTracer()`. Wavefront initialization is lighting-selective. `hybrid` does not instantiate the `MorphFieldWavefrontPathTracer` or its tracer-specific compute pipelines and queues. `auto` task-defers that construction, returns from `createRenderer()` first, and continues encoding Hybrid with `wavefront-initializing` until readiness. Explicit `progressive` waits for initialization before creation resolves. `setLightingMode('auto')` and `setLightingMode('progressive')` return the preparation promise; callers may await it when readiness is required. `getStats().lighting.wavefront.initialization` exposes state, reason, generation, attempts, timestamps, and contained errors. Explicit Hybrid selection, device replacement, and destruction invalidate the generation, release stale resources, and prevent a late asynchronous result from publishing against the wrong lighting policy or borrowed device. `target.composition` is either `replace` (the default) or `over`. Replace clears and owns the target pixel for the encoded viewport. Over preserves the host color/depth attachments by default, depth-tests the MorphField result, and uses field transmittance as straight-alpha coverage. Internal HDR remains linear. `outputTransfer: 'auto'` applies the display transfer for plain eight-bit unorm host targets, preserves linear float targets, and does not double-encode `*-srgb` targets. A 64-slot, 256-byte-aligned frame-uniform ring keeps multiple `encode()` calls recorded into one unsubmitted command encoder isolated from later uniform writes. The host contract does not yet expose encode-to-submit `commit()`/`cancel()` acknowledgements, so robust slot reclamation across abandoned or exceptionally delayed command encoders remains an explicit lifecycle gap. The host owns the device, queue submission, command encoder, canvas, animation loop, presentation pacing, and target views. MorphField does not configure a canvas, finish or submit a command buffer, destroy the device, or destroy host-owned views. The host must keep submissions bounded. The Playground has no fixed render deadline: it attempts one submission for every host `requestAnimationFrame` callback and rejects work only while its two-submission completion-debt bound is full. The governor's frame target is a quality budget and never schedules or rejects a frame. `targetFPS: 'display'` follows a filtered measured refresh interval; a numeric target remains available for deterministic tests and fixed-budget hosts. `queue.onSubmittedWorkDone()` is used only as a coarse completion checkpoint; its wall duration is not reported as shader time. This allows 75/120/144 Hz displays to present at their native callback cadence when the device keeps up while retaining bounded latency under saturation. `replaceDevice()` reconstructs MorphField-owned resources from authoritative CPU state. `destroy()` is idempotent. (Sources: [MDN `requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame), [WebGPU `GPUQueue`](https://gpuweb.github.io/gpuweb/#gpuqueue).) ### Renderer and PhysX clocks MorphField is clock-neutral. Its phase named `Simulate` is an ordering/telemetry marker and does not step PhysX. The Engine host owns the authoritative simulation clock: `PhysicsSystem` runs as an ECS tick system, PhysX advances at a stable fixed step, and the frame path renders independently on every admitted rAF. The render side consumes previous/current pose snapshots plus an interpolation alpha; it must not write interpolated poses back into authoritative ECS or PhysX state. Ordinary rigid-body motion should update a transient transform/motion stream and spatial refit, not compile a semantic Nexel patch. Topology, material, certificate, and source edits continue through `compilePatch()`. This separation is deliberate: fixed PhysX timesteps preserve solver stability, while rendering remains native-refresh-driven. The current browser PhysX wrapper still performs a synchronous `simulate()`/`fetchResults(true)` pair, so the clocks are decoupled by ownership and time domain, not yet by a worker thread. Moving PhysX off-thread requires an explicit cross-origin-isolation/WASM threading gate and caller-owned buffering; it is not assumed by MorphField. (Sources: [PhysX simulation](https://nvidia-omniverse.github.io/PhysX/physx/5.4.1/docs/Simulation.html), [PhysX threading](https://nvidia-omniverse.github.io/PhysX/physx/5.1.3/docs/Threading.html), `engine/core/platform/MainLoop.js`, `engine/ecs/systems/PhysicsSystem.js`.) ### Sparse residency shared by fields, voxels, and virtual textures The 2026-07-26 implementation turns the useful part of the dynamic-SDF research into a shared Engine primitive rather than three incompatible caches. `SparsePageRuntime` provides fixed page and byte budgets, LRU eviction, pinned fallback pages, revisioned staging, and atomic publication. `ResidualHierarchy` uses it to guarantee that a missing fine residual resolves to a certified coarser level. `VoxelSdfBrickBridge` converts a voxel occupancy callback into a neighbor-apron sampled-field page plus a conservatively expanded coarse fallback and publishes the pair atomically as Nexels. `VirtualTexturingSystem` uses the same residency semantics for mip-aware physical slots and now supports external-encoder feedback readback without a per-frame blocking submit. A rejected or missing page resolves to a pinned neutral fallback instead of magenta or absent geometry. The live direct-field GPU evaluator now executes bounded sampled fields and analytic-plus-residual Fieldlets from their compiler-packed grids using trilinear sampling, compiler-derived error/Lipschitz certificates, generic normals, and certified surface/collision queries. This is deliberately not called a complete clipmap engine: current compiled grids are resident `f32` data, while byte quantization, nested camera-centered geometry clipmaps, fine-page GPU atlas bindings, and measured open-world residency remain open work. The screen-tile path is likewise a representation-work accelerator, not an “infinite-resolution codec”: it bins conservative projected BVH leaves per `16×16` primary tile. Interactive Scale Lab loads stay at the host extent. Source/depth-qualified reconstruction is used only when the host explicitly requests a smaller scale or the developer runs the clearly labelled bounded benchmark ladder. ([AMD Brixelizer](https://gpuopen.com/manuals/fidelityfx_sdk/techniques/brixelizer/), [Geometry Clipmaps](https://hhoppe.com/geomclipmap.pdf), [NVIDIA sparse SDF grids](https://jcgt.org/published/0011/03/06/), and [Mike Turitzin's dynamic-SDF engine presentation](https://www.youtube.com/watch?v=il-TXbn5iMA).) Optional refinement is budgeted rather than clocked. `ProgressiveWorkBudget` admits path-tracing or refinement units only from measured CPU/GPU headroom, rejects them while timestamp evidence is pending or the queue is saturated, and reduces admission for dynamic scenes. This preserves an uncapped host render loop while preventing background refinement from consuming the foreground frame budget. ## Semantic and binary contracts ### Nexel and Fieldlet A Nexel has a stable string ID, a semantic source, a normalized Engine material, optional motion/collision/simulation descriptors, and intent metadata. Backend selection is compiler-owned. Diagnostic backend forcing stays Playground-only and never enters `.morph` assets. #### Canonical JSON schemas and capability envelope MorphField's device-independent interchange surface is described by twelve public [JSON Schema Draft 2020-12](https://json-schema.org/specification) resources in `engine/render/morphfield/schemas/`: eleven independently addressable source schemas plus one generated offline compound bundle. They cover shared canonical definitions, all nine source kinds, a normalized Nexel, a scene, a patch, the production particle-chain adapter payload, the implementation capability profile, a per-Nexel capability report, benchmark receipts, validation reports, and provenance. Every resource declares the Draft 2020-12 dialect and an absolute `$id` rooted at `https://particlerealms.online/schemas/morphfield/v2/`. Platform and WebGPU OS release builders copy those exact source bytes to matching routes and reject a filename/`$id` mismatch. The compound bundle embeds each unchanged source resource under `$defs`, preserving its absolute `$id`, as required by Draft 2020-12's [bundling model](https://json-schema.org/draft/2020-12/json-schema-core#section-9.3.1). `NexelScene.toJSON()` emits `$schema`; the same scene document is the authoritative `MANF` payload in `.morph`. Normalized patches likewise emit `$schema`, `schema: "morphfield-nexel-patch"`, version `2.0`, and monotonic revision data; shorthand input remains an authoring convenience, not persisted ambiguity. Canonical schemas are strict and reject unknown core keys, authoring aliases, authored certificates, future unimplemented minor versions, duplicate object names, and non-JSON numeric tokens. Every authored numeric value that enters an f32 CPU/GPU ABI is schema-bounded and runtime-checked to the finite f32 domain. Material base-color channels are in `[0, 1]`; emissive channels may be HDR but must be finite, non-negative f32 values. Runtime authoring can still use documented conveniences, such as `collision: true` or a scalar oriented-sample radius, because normalization happens before serialization. Runtime compilation remains authoritative for certificate derivation and checked CSG evaluation, while the offline validator mirrors semantic admission checks for quaternion magnitude, rigid/uniform-scale transforms, bounds ordering, exact grid products, indexed-mesh topology, collision-offset relationships, scene/patch ID uniqueness, and receipt consistency. This is an explicit layered contract rather than a claim that JSON Schema alone can express every semantic invariant. `python tools/validate_morphfield_json.py ` validates a scene, patch, capability document, receipt, or validation report using only the local registry. It applies byte, aggregate-string-byte, depth, node, and string-work budgets; rejects BOMs, duplicate names, and NaN/Infinity before Draft validation; and refuses resource-only `common` or `bundle` schemas as instance targets. It then applies the semantic checks described above instead of allowing a schema-valid but runtime-invalid document through the offline gate. `python tests/morphfield/run_python_tests.py` checks bundle freshness, 29 JSON schema/semantic fixtures and mutation cases, offline reference resolution, the validator CLI, eight shader-contract tests, and all twelve public schema HTTP routes. These guards follow [RFC 8259's interoperable JSON rules](https://www.rfc-editor.org/rfc/rfc8259) and JSON Schema's resource-safety requirements. The public API exposes `Engine.MorphField.Schemas.MORPHFIELD_SCHEMA_CATALOG`, `NEXEL_CAPABILITY_PROFILE`, and `inspectNexelCapabilities(descriptor)`. The report distinguishes semantic admission, CPU reference support, compilation, live renderer execution, and GPU-query coverage. `compilerMode` separates certified analytic execution, certified sampled-field execution, certificate-record output, packed markers, and unavailable input; `gpuQueryModes` contains one explicit mode for each of the six typed queries. `fullyCurrentRendererExecutable` states the current renderer truth, while `fullyGpuExecutable` remains an exact compatibility alias. Unknown simulation adapters are retained as semantic data but explicitly marked unqualified. A capability report is never inferred merely because a compiler emitted a Fieldlet. | Semantic source | Fieldlet family | Compiler/CPU reference | Live R2 renderer | Current GPU-query envelope | | --- | --- | --- | --- | --- | | Sphere | Analytic | Yes | Direct field | Bound, surface, material, optional motion/collision. | | Box | Analytic | Yes | Direct field | Bound, surface, material, optional motion/collision. | | Capsule | Analytic | Yes | Direct field | Bound, surface, material, optional motion/collision. | | Hard analytic CSG | Analytic | Yes | Direct field | Bound, surface, material, optional motion/collision. | | Sampled field | Sparse residual | Yes | Certified direct field | Bound, surface, material, and optional motion/collision. Progressive wavefront remains analytic-family-only. | | Analytic plus sparse residual | Sparse residual | Yes | Certified direct field | Bound, surface, material, and optional motion/collision. Fine streaming requires the pinned certified coarse fallback. | | Oriented samples | Oriented kernel | Partial orientation semantics | Marker-only | Bound, material, and optional motion; surface/collision remain CPU-only. The current CPU reference applies anisotropic radii in source axes and retains, but does not rotate by, the sample normal. | | Indexed surface | Cached surface | Yes | Marker-only | Bound, material, and optional motion; surface remains CPU-only and collision metadata is rejected. | | Bounded medium | Analytic-medium subtype | Yes | Marker-only | Bound, medium majorant, and optional motion; surface/collision metadata is rejected. | A moving Nexel defaults to dynamic intent; explicitly combining motion with `updateClass: "static"` is rejected. Simulation records require an adapter ID, and a declared `authoritative` or `visual` simulation authority must agree with `intent.authoritative`. `qualityImportance` is normalized to the closed interval `[0, 1]`. These gates prevent descriptors that serialize successfully but fail later in Fieldlet upload or GPU query setup. JSON Schema is intentionally not applied to non-JSON contracts. The `.morph` header/directory/chunks, Fieldlet headers, certificate pools, spatial records, and query buffers are fixed little-endian/WGSL ABIs. Compiled scenes and patches contain typed arrays. Renderer creation, `encode()` targets, outputs, and device replacement contain borrowed WebGPU objects. Their layout constants, ownership checks, and ABI tests remain the source of truth; inventing JSON projections for them would hide the real contract. Renderer activation now validates every compiled array type and stride, ID/index bijection, reference, family/subtype/query combination, material/certificate record, postfix opcode/stack range, and finite value. Same-realm output must carry private compiler provenance. A structured-cloned worker result is accepted only after deterministic recompilation of its authoritative semantic snapshot produces byte-identical executable ABI arrays. Authored or modified Fieldlets cannot self-certify traversal. #### Fieldlet ABI Each Fieldlet begins with the fixed 16-byte header: ```text FieldletHeader { boundsRef: u32 payloadRef: u32 meta: u32 certificateRef: u32 } ``` `meta` packs a 12-bit subtype, four-bit family, six-bit query mask, and ten flags. The stable family IDs are analytic field, sparse residual, oriented kernel, and cached surface. A certificate bundle stores `surfaceRef`, `mediumRef`, `motionRef`, and `collisionRef`; `0xFFFFFFFF` means absent. Material queries use the normalized material table. The certified surface step is: ```text safeStep = max(fieldEstimate - fieldValueErrorMax, 0) / lipschitzMax ``` For signed fields, traversal applies the formula to `abs(fieldEstimate)`. The runtime clamps the step to the active spatial exit. Compiler-derived error expands the published trace bounds, and every bound is rounded outward when stored as `f32`; neither certificate nor AABB quantization may shrink the certified domain. Invalid certificates fail compilation. The bounded postfix interpreter accepts at most 64 instructions and a checked 32-value stack. ### Typed queries | Query | Purpose | Certificate or source | | --- | --- | --- | | Bound | Conservative world-space extent | Compiled bounds pool. | | Surface | Signed field estimate and conservative stepping data | Surface certificate. | | Medium | Density, extinction, and emission bounds | Medium majorant record. | | Material | Normalized PBR properties | Material table. | | Motion | Conservative displacement and speed | Motion certificate. | | Collision | Surface distance and contact metadata | Collision certificate. | The CPU reference evaluator uses JavaScript number arithmetic for deterministic double-precision fixtures. Collision participation is opt-in: omitting `collision` emits neither a collision query-mask bit nor a collision certificate, and untrusted packed input cannot enable collision metadata without a valid compiler-derived certificate. Collision distance is the signed surface separation after subtracting the caller's non-negative query radius. `contactOffset` is the predictive candidate shell; `restOffset` is the requested final signed separation, with `restOffset <= contactOffset`. `contactSlop` remains a compatibility alias for `contactOffset`. Contact means `distance <= contactOffset`, while penetration is `max(restOffset - distance, 0)`. The GPU query interface writes fixed 64-byte results into caller-selected external-encoder batches with explicit capacity checks. A complete CPU query batch is validated before buffer allocation, queue writes, pass recording, bind-group changes, or statistics mutation. Descriptors reject unknown properties, numeric-string coercion, alias conflicts, non-finite or out-of-f32-range numbers, malformed vectors, wrapped integers, and Fieldlet indices outside the active scene. Collision input offsets are point.xyz at byte 0, query kind at 12, preferred Fieldlet at 32, flags at 36, and radius at 40. Collision output offsets are distance at 0, normal.xyz at 4, contact at 16, supported at 20, `restOffset` at 24, field-value error at 32, Lipschitz maximum at 36, `contactOffset` at 40, penetration at 44, material index at 48, Fieldlet index at 52, layer at 56, and mask at 60. Identifier and filter lanes are `u32` bit patterns. `getQueryInterface().getStats()` exposes the bounded batch/traversal counters without weakening renderer lifetime guards. (Sources: `engine/render/morphfield/core/ReferenceQueries.js`, `engine/render/morphfield/runtime/QueryEncoder.js`, and `engine/render/morphfield/runtime/RuntimeShaders.js`.) Particle-chain producers use the public snapshot adapter rather than giving MorphField ownership of a solver: ```javascript const descriptors = Engine.MorphField.Systems.createParticleChainNexelDescriptors({ id: 'bridge-cable', positions: currentPositions, previousPositions, velocities, revision, }, { nodeRadius: 0.14, linkRadius: 0.085, collision: { contactOffset: 0.002, restOffset: 0, layer: 3, mask: 0xffffffff }, }); ``` The adapter accepts ordinary arrays, flat typed arrays, and normalized `PhysicsChain`-style `links` or `particles` collections, preserves stable node/link IDs, derives link orientation and angular motion, and builds incremental removal patches. It never steps a solver, reads back a GPU, submits a queue, or takes device ownership. Node spheres can mirror authoritative solver contact shapes. Link capsules are currently queryable connective skins; the Playground's PBD response remains node-driven and does not claim that capsule links generated contacts. (Source: `engine/render/morphfield/systems/ParticleChainNexelAdapter.js`.) Static solver colliders opt in explicitly with `simulation.pbdCollider: "ground-plane" | "sphere"`. `compileNexelPbdColliderSet()` composes Nexel and source transforms, accepts an axis-aligned box ground and sphere sources, requires one shared positive `contactOffset` per `PBDSolver`, and rejects `restOffset` above `contactOffset`. It insets the solver plane or radius by `contactOffset - restOffset`, so `PBDSolver` retains its predictive contact shell while rendered surfaces settle at the requested `restOffset`. Applying the set rebuilds compatible solver colliders without transferring solver ownership or stepping it. (Source: `engine/render/morphfield/systems/NexelPbdCollisionAdapter.js`.) ### `.morph` assets The browser format is a little-endian `MOR2` container with a fixed 32-byte header and fixed 32-byte directory entries. It rejects assets at or above 4 GiB. Chunks carry CRC32, declared raw/stored sizes, dependencies, and required/optional flags. Compression is `none`, `gzip`, or `deflate` through browser-native streams with an uncompressed fallback. Header, directory, alignment, and trailing padding bytes must be zero. Unknown optional chunks are decompressed within declared expansion limits and CRC-checked before they are skipped; optional does not mean untrusted bytes bypass integrity validation. Focused tests include targeted unknown-optional corruption and 32 deterministic whole-container bit mutations. The semantic manifest remains authoritative. Compiled data, certificates, residual pages, kernels, and surface caches are disposable derivatives keyed by schema and revision. ## Frame contract Every `encode()` call records these labeled logical phases in order: 1. Patch and stream. 2. Simulate. 3. Maintain spatial structures. 4. Cull and bin. 5. Render validated opaque surface caches. 6. Trace direct fields. 7. Integrate media and oriented kernels. 8. Shade, temporally reconstruct, and compose. The portable path does not require hardware ray tracing, mesh shaders, work graphs, bindless resources, sparse textures, or multi-draw-count. Optional WebGPU features are capability-selected from the borrowed device and must retain a core fallback. ## Adaptive quality contract MorphField uses one `AdaptiveQualityGovernor`. Its default target is 16.667 ms, with a 45-sample window, two-second cooldown, `1.18×` p95 downgrade threshold, `1.35×` p97 tail downgrade threshold, `0.78×` p95 upgrade threshold, and `0.90×` p97 upgrade guard. A p97 spike can therefore downgrade a tier even when p95 still looks healthy. When measured channels are supplied, the work budget is the greater of CPU and GPU time; rAF or presentation cadence is retained separately and is not treated as shader time. Sparse timestamp samples are accumulated in a per-tier GPU history so three timestamp results spread across many cadence frames still form valid GPU evidence. Pending GPU samples, GPU warm-up, or actionable queue pressure prevent tier upgrades. Sustained near-capacity pressure remains an immediate fallback signal when no delivery interval is supplied. Hosts that report `presentationMs` qualify that downgrade with consecutive over-budget delivered frames, so one scheduling spike or a 120/144 Hz producer filling a two-submission queue cannot force quality down while presentation is still inside the configured target. Raw queue pressure still blocks Auto-progressive lighting, but healthy delivered throughput does not prevent the quality tier itself from upgrading after measured headroom. Queue-completion wall time remains telemetry and never becomes a GPU-work sample. The direct-field pass keeps primary visibility and render extent independent of the selected automatic quality tier. Every `MORPHFIELD_QUALITY_TIERS` preset has `renderScale: 1`; Auto changes trace, shadow, residual, medium, kernel, cache, and progressive-work budgets but never silently shrinks the host pixel grid. MorphField accepts a smaller active extent only when the host supplies both `qualityDecision.renderScale < 1` and `resolutionPolicy: "host-explicit"`, or when the developer starts the explicitly labelled bounded benchmark ladder. A generic Engine governor object containing a scaled tier is normalized back to native resolution. The explicit path keeps frame textures allocated at host capacity and uses source/depth-qualified 2×2 reconstruction without sampling inactive pixels. A future automatic dynamic-resolution policy must first prove a same-workload timestamp-query GPU improvement, apply hysteresis, and stay within a declared reconstruction range. CPU time, rAF cadence, presentation cadence, queue-completion wall time, and a static worst-case work estimate cannot authorize a resolution drop. This follows the measured-GPU-history and threshold model used by [Unreal Engine Dynamic Resolution](https://dev.epicgames.com/documentation/en-us/unreal-engine/dynamic-resolution-in-unreal-engine) and the GPU-bound/reconstruction constraints in [AMD FidelityFX Super Resolution 2](https://gpuopen.com/download/GDC_FidelityFX_Super_Resolution_2_0.pdf). Primary tracing clips rays to compiler-derived analytic bounds and skips an exact Fieldlet program only when its certificate-adjusted AABB lower bound proves it cannot affect a non-negative current minimum. Inside samples never use the unsigned AABB distance to prune another overlapping Fieldlet. Equal lower bounds are still evaluated so BVH order cannot override the stable lower-source-index material/ID tie-break. The runtime starts primary rays beyond the camera near plane, refines signed crossings with a validity-checked bracket, treats the wider certificate band as a request for sign-bracket isolation rather than unconditional geometry, and advances only by `max(abs(field) - error, 0) / lipschitz`. Tier trace-step budgets apply to shadow and secondary-ray work, but MorphField normalizes the generic governor's `shadowLevel: 0` to a scoped level-1 hard-shadow baseline. Direct-field traversal records `CLEAR`, `HIT`, `EXHAUSTED`, and `INVALID`; a shadow is illuminated only after certified `CLEAR`, while every other outcome fails closed. The governor starts a new timing window after each tier transition and backs off a failed upgrade before trying it again. (Sources: `engine/render/morphfield/runtime/AdaptiveQualityGovernor.js`, `engine/render/morphfield/runtime/RuntimeShaders.js`, and `engine/render/morphfield/runtime/MorphFieldRenderer.js`.) `auto` lighting admits progressive wavefront work only on high or ultra after at least 45 stable hybrid samples whose p95 is at or below `0.72×` target and whose p97 is at or below `0.90×` target. When timestamp queries are available, admission additionally requires enough resolved GPU evidence and `gpuSamplePending === 0`. Current host timing and queue signals remain authoritative even when the host supplies an external quality-tier decision. A pending timestamp is checked before admission even when another valid GPU sample exists; the renderer remains Hybrid with `auto-progressive-gpu-sample-pending`. In the timestamp-capable path, browser rAF cadence never satisfies the GPU-work requirement. Queue pressure blocks admission and aborts active Auto-progressive work. A progressive frame above `1.75×` target aborts immediately; two consecutive frames above `1.18×` also abort. Failed admissions use an exponential 10–60 second cooldown. Scene, patch, camera, light, or quality changes reset stability and history. The focused regression supplied `45 ms` rAF cadence, `5 ms` timestamp GPU work, and one pending timestamp for 45 frames. Auto remained Hybrid and GPU p95 remained `5 ms`; clearing the pending count admitted Progressive, and subsequent queue saturation returned to Hybrid. ### Performance timing and spike triage The Playground reports five different signals rather than calling every delay “GPU time”: 1. Browser rAF interval p50/p95/p97/p99/max and one-percent-low callback pacing. 2. Admitted presentation interval, submitted/rAF counts, queue-only throttles, and current/maximum bounded submission debt. 3. Synchronous host CPU stages, including camera, swap-chain acquisition, simulation/patch publication, `renderer.encode()`, submission, HUD, and unattributed work. 4. Optional `timestamp-query` measurements for phase 1 begin through final composite end and for the direct-field trace pass. The developer host requests only this optional feature when advertised and retains a core-profile fallback. 5. Sampled submit-to-`queue.onSubmittedWorkDone()` wall time, explicitly labeled queue-fence/backlog latency rather than shader execution time. ### Publication benchmark evidence contract The representative benchmark exposes a target before it exposes evidence. Its publication target is 10,000 measured frames per tier across five independent runs. The live status reports completed runs plus GPU, CPU-encode, and queue-batch sample counts against their exact denominators. A publication-profile selection or a partially collected cohort is never labelled **Publication evidence**. Each 25-frame measurement batch records two separate wall-clock channels. `batchWallSpan` starts before batch setup and command recording and ends when the submitted work completion notification arrives. `queueDrainNotification` starts immediately after the batch's final host `queue.submit()` returns and ends asynchronously when `queue.onSubmittedWorkDone()` notifies. The drain therefore includes all GPU work still queued at that boundary plus driver, browser, and notification scheduling. Neither channel is divided by 25 or presented as individual-frame latency. Timestamp queries remain the only GPU execution-time channel, and their resolve/readback uses a later submission so transfer work does not contaminate the render-batch drain boundary. (Sources: `tests/playground/src/demos/morphfield/performanceEvidence.js` and `tests/morphfield/morphfield.test.js`.) For each tier, timestamp samples report exact 60 Hz work-budget misses: frames above `16.667 ms`, the percentage of the cohort, the longest consecutive miss streak, the greatest count in a contiguous one-second window, and the largest overshoot above budget. These are GPU-work budget statistics, not inferred presentation failures. Each non-Ultra tier also reports a paired per-run GPU-p50 delta versus the same run's Ultra result with a Student-t 95% confidence interval. An interval containing zero is labelled **No measurable difference** instead of claiming a speedup or regression. The publication gate opens only after all five tiers complete all five runs with exactly 50,000 timestamp samples, 50,000 encode samples, and 2,000 post-submit drain and batch-wall samples per tier. It also requires supported p99 values, non-limited timestamp resolution, exact frame/submission metadata, successful validation quality, and measured zero renderer-owned resource creation, release, or byte growth across tier transitions. Missing resource counters or any incomplete cohort keeps the result diagnostic. The combined channel heading is **GPU timestamp + CPU encode + queue drain**; batch wall remains a separately displayed fourth channel. Publication collection is visibility-isolated. When the document becomes hidden, the active-time clock pauses and no new warm-up or measurement batch starts. A batch that crosses a visibility epoch is discarded in full and repeated after the document is visible; none of its timestamps, CPU samples, queue-drain spans, frame counts, or submissions enter the accepted cohort. The exported run-quality record reports the pause count, paused duration, and discarded-batch count. Fast diagnostic validation intentionally remains fail-closed on any visibility change because it does not use the long-run isolation contract. Timestamp resolution is judged against the claim being made, not against repetition alone. A single resolved bucket remains unusable. Otherwise the smallest positive timestamp step must be no greater than one percent of the observed p99 scale. Repeated fine-grained buckets therefore remain valid when their step is small relative to the measured tail, while a coarse quantization step still blocks publication. This avoids rejecting a 50,000-sample cohort merely because a stable GPU workload naturally repeats many values. Timestamp readback uses a fixed three-slot asynchronous ring sampled every eight submitted frames. That cadence provides at least five opportunities inside the governor's 45-frame window while remaining asynchronous and allocation-free. It performs no blocking readback and publishes each resolved GPU result exactly once. The Playground keys a workload cohort by published scene generation, Fieldlet count, active traversal, render extent, lighting path, debug path, and the quality decision's work knobs. A cohort transition invalidates pending timestamp and queue-checkpoint epochs and starts fresh timing windows, so an equal-resolution work change cannot label an old tail as the current tier. rAF spike counts are still shown both for the current 240-frame window and since the developer's last reset. Timestamp tails inform adaptive semantic-work quality only; they never create a render deadline or authorize an extent change. The validation lab separately runs a 320×180, 8-Fieldlet/27-primitive tier matrix after warm-up. On the current AMD RDNA 3 run, every tier remained at 320×180; timestamp-query GPU p97 was `1.97 ms` ultra, `1.84 ms` high, `1.57 ms` balanced, `1.38 ms` performance, and `1.44 ms` emergency. CPU encode p97 stayed at or below `0.625 ms`, and tier changes created and released zero renderer resources. These are diagnostic measurements, not cross-device performance promises. The Playground reports a sustained bottleneck separately from individual rAF spikes. An asynchronous timestamp can attribute a rolling interval to `TraceDirectFields`, but it cannot prove that one exact callback was delayed by the GPU, GC, the browser scheduler, or presentation. A controlled installed-Chrome probe held Performance, Hybrid, Direct, and the exact 1008×509 active extent for 24 seconds per condition. The moving 8-Fieldlet stress scene produced 214 trace samples at p50/p95/p97/max `12.96/16.28/16.64/16.91 ms`; the same scene paused produced 182 samples at `15.95/16.40/16.43/16.63 ms`. No trace sample exceeded 20 ms. Patch CPU p95 fell from `1.54 ms` to `0.01 ms` when paused, but trace p95 did not improve, so semantic patch publication is not the deterministic GPU bottleneck. The 3-Fieldlet analytic scene produced 240 samples at `2.82/3.55/3.59/3.76 ms`, localizing the persistent cost to stress-scene field evaluation. A presentation outlier still reached `34.74 ms` while the corresponding trace maximum was `16.91 ms`; that remaining tail belongs to queue, vsync, browser scheduling, or external contention rather than a measured 34 ms shader pass. The compiler now leaves top-level sphere, box, and capsule Fieldlets at `programLength = 0`, activating the shader's direct primitive evaluator instead of interpreting a one-instruction postfix program. Layout-stable primitive patches retain that path, preserve buffer/bind-group generations, and still match a canonical full compile. The direct shader avoids rotational work for invariant spheres, resolves a primary normal from the selected contributing Fieldlet instead of four complete scene scans, and reuses an accepted unbracketed sample. The runtime packs Fieldlet bounds, compiler `bvhBounds`/`bvhMetadata`, one collision-metadata record per Fieldlet, and a validated scene trailer into one mixed 48-byte `SpatialRecord` storage buffer. Collision metadata stores enabled, layer, mask, and the `f32` `restOffset` bits; `contactOffset` remains in the collision certificate. The query compute stage therefore stays at WebGPU's portable eight-storage-buffer baseline: six read-only scene buffers, one caller result buffer, and `spatialRecords`, with no ninth binding. CPU validation rejects invalid roots, topology, leaves, bounds, incomplete trees, or broken containment and selects the certified linear fallback. Each valid node receives an escape link in the record's typed padding lane. The shader follows those links with a dynamic `nodeCount` visit ceiling, validates child-thread invariants, and falls back to a fresh certified linear evaluation on any malformed link or cycle. It has no private BVH stack and makes equal-distance source selection index-stable. The renderer eagerly compiles a lean linear trace/query variant and uses it for every scene by default. The stackless-BVH trace variant is quarantined behind the non-serialized diagnostic option `experimental: { pointBvh: true }`; a validated scene then needs at least 64 Fieldlets before generation-safe background preparation begins. The complete linear pipeline remains correct and active while preparation is pending or failed. Cancellation releases the unpublished shader and pipeline, a permanent failure is not retried on later patches, and device replacement is the only lifecycle event that clears that failure. This source-level specialization matters because a WGSL runtime branch did not prevent Dawn from optimizing unreachable traversal code. The removed 64-entry per-ray candidate experiment took `146.4 s` to cold-start and drove the representative tier matrix to roughly `86–312 ms` GPU frames. Removing repeated linear-fallback call sites reduced the full stackless pipeline from more than `300 s` to `95.102 s` on the measured AMD/Dawn path, which still fails the cold-start gate and is why automatic activation is disabled. An explicit 64-sphere probe kept linear active, published BVH atomically after `90.870 s`, encoded without WebGPU errors, and then ended with output parity inconclusive because its synthetic comparison camera produced empty masks; the accelerated pixel-parity gate therefore remains open. A corrected lean control produced 220 covered pixels spanning all 64 source IDs. The current exact cold test 39 uses the lean path and completed in `20.475 s` (`20.432 s` pipeline preparation), then produced `2,077` primary hits, `1,948` certified floor pixels, zero tier differences, zero false sky misses, and zero resource churn. Its UI emits truthful five-second stage heartbeats instead of appearing frozen. The final integrated installed-Chrome run completed all `48/48` checks with zero failed or skipped gates; the validation UI receipt recorded `26,992.5 ms`. (Sources: `engine/render/morphfield/runtime/SceneBufferUploader.js`, `engine/render/morphfield/runtime/RuntimeShaders.js`, `engine/render/morphfield/runtime/MorphFieldRenderer.js`, `engine/render/morphfield/runtime/QueryEncoder.js`, and `tests/morphfield/morphfield.test.js`.) ### Nexel representation lab and truth chain The Playground now uses focused specimens rather than the removed all-at-once Living Watershed animation. Its nine cards are: | Specimen | Semantic Nexel | Compiled family | Live presentation | SDF/reference-field meaning | | --- | --- | --- | --- | --- | | Analytic | Hard CSG of box/capsules | 0 analytic | Native certified direct field | Certified signed distance. | | Particle | One stable sphere Nexel per PBD particle | 0 analytic | Native direct field with real PBD ground, self, and sphere-obstacle contact | Per-particle sphere SDF. | | Particle chain | Stable node spheres plus link capsules from one snapshot adapter | 0 analytic | Native direct field; nodes drive PBD contact and capsules remain queryable skins | Sphere/capsule SDFs. | | Oriented sample cloud | One `oriented-samples` Nexel | 2 kernel | Explicit family-0 support glyph until the kernel pass is integrated | Anisotropic iso-field, not Euclidean distance. | | Indexed mesh | One closed indexed-surface Nexel | 3 cached surface | Explicit edge-cage glyph until family-3 rasterization is integrated | Derived closed-mesh signed-distance reference. | | Voxel | One bounded sampled scalar grid | 1 sparse residual | Explicit occupancy-shell glyph | Trilinear sampled scalar-distance field. | | Residual | Analytic base plus sparse sampled correction | 1 sparse residual | Explicit analytic base glyph | Composed field estimate. | | Medium | One bounded density/extinction/emission Nexel | 0 analytic records | Certified bounds cage until media integration is active | Bounds SDF only; not a material surface. | | Mixed | Independent Nexels from all four families | 0, 1, 2, and 3 | Native analytic plus explicit constant-complexity overview markers; focused cards retain their detailed glyphs | Classification follows the selected Fieldlet. | “Particle Nexel” is deliberately split three ways: individual physical particles are native sphere Nexels, a constrained chain is a stable collection of sphere/capsule Nexels, and a whole splat cloud is one `oriented-samples` Nexel. The public API terms remain **Nexel** and **Fieldlet**; “Noxel” is not a source kind. Mesh data uses `indexed-surface`, and voxel data uses `sampled-field` or `sparse-residual`. (Source: `tests/playground/src/demos/morphfield/nexelDemos.js`.) The particle and chain cards reuse the same generic CPU `PBDSolver` used by the Editor's `EditorPhysicsSim` chain path. Physics advances at a fixed 60 Hz while native-refresh rendering interpolates snapshots, so the renderer is not capped at 60 FPS. The visual floor and obstacle come from the same semantic collider Nexels used to compile the solver set. The focused high-speed fixture uses a predictive `contactOffset` of `0.020 m` and a zero `restOffset`. The larger shell covers the measured per-substep motion that previously crossed a 2 mm shell before contact response. The adapter lowers the solver ground and reduces the solver obstacle radius by `0.020 m`, so the predictive range does not introduce a visible rest gap. Published transforms, radii, offsets, collider source IDs, and maximum-over-time obstacle clearance remain parity-checked. The chain approaches the obstacle from outside its surface so the solver's shallow-contact path is exercised rather than reporting a deeply embedded false contact. The simulation owns contact response. MorphField owns only the current semantic/query snapshot, and those dynamic snapshots remain labeled visual until a separate conservative swept-motion bound can prove arbitrary solver impulses and constraint projections. This design follows PBD distance/contact constraints, XPBD's time-step-independent compliance direction, and PhysX guidance to keep fixed simulation time independent from rendering. ([PBD survey](https://matthias-research.github.io/pages/publications/PBDTutorial2017-CourseNotes.pdf), [XPBD](https://matthias-research.github.io/pages/publications/XPBD.pdf), [PhysX best practices](https://nvidia-omniverse.github.io/PhysX/physx/5.4.1/docs/BestPractices.html).) The anatomy panel can execute all six double-precision CPU reference queries for the selected stable Nexel and displays declared-mask participation, explicit unsupported results, material data, exact Fieldlet header words, flags, bounds, and the actual query-specific certificate records. A separate status line describes the real 64-byte external-encoder GPU query ABI but says `NO INSPECTOR READBACK`; merely exposing that interface is never reported as GPU execution. The one-click `SDF inspect` control switches the live renderer to trace-step visualization and draws a CPU semantic section for the selected Fieldlet. The label changes between exact/derived SDF, sampled or composed field, anisotropic iso-field, and medium-bounds field so every source can be inspected without falsely calling every scalar function a signed-distance function. ### Playground and Editor precedent audit The repository's other Playground demos were scanned before shaping the focused lab. Their reusable design lessons and boundaries are: | Existing demo/system | Reused lesson | MorphField boundary | | --- | --- | --- | | `assetImporter.js` | Present one real indexed asset with clear source metadata and inspection controls. | An imported mesh remains `indexed-surface`; its family-0 cage is explicitly diagnostic. | | `stateRaster.js` and `urcState.js` | Put representation state, cache policy, and current execution mode in developer-visible telemetry. | CSE/state labels do not replace Nexel source, Fieldlet ABI, query certificates, or scene revisions. MorphField has no required CSE dependency. | | `glassBoids.js` and `pbr.js` | Reuse Engine camera/light conventions and reset temporal state on material/camera changes. | Their hard-coded PBR geometry is not the MorphField intersection engine. | | `sdf.js` | Make field stepping, normals, and shading visually inspectable. | Its standalone shader is not reused as a certified multi-family evaluator; the lab samples MorphField's own CPU reference and live trace view. | | `particleStorm.js`, `sphFluid.js`, and the sandbox demos | Show particle density, motion, and stress clearly. | They are visual precedents, not proof of MorphField collision, stable IDs, or query parity. The focused particle card uses actual CPU PBD snapshots. | | `mandelbrot.js` | Progressive refinement can make resolution demand-driven without changing semantic coordinates. | MorphField's current Scale Lab measures scene-representation scaling; it does not claim the Mandelbrot codec or infinite detail for uncertified sources. | | Editor `PhysicsChain` + `EditorPhysicsSim` | Stable chain component data and the shared CPU PBD solver are suitable snapshot producers. | The Editor viewport has no stable borrowed-device renderer-extension stage yet, so this change adds no Editor dependency or viewport edit. | The audit also found incompatible particle-shape numeric enums between the general particle schema, the current particle SDF renderer, and collision code. The focused particle/chain presets therefore certify only the sphere and capsule semantics implemented by MorphField. The field-inspection toggle works for every specimen, but arbitrary legacy particle-shape conversion is intentionally blocked until one shared shape ABI and parity suite exists. Every card keeps the researched truth chain visible: **semantic source → compiled family → active evaluator → presentation**. Analytic sphere, box, capsule, hard CSG, bounded sampled fields, and analytic-plus-residual sources are native certified GPU surfaces in Hybrid mode. Oriented samples and indexed surfaces have real validation, deterministic Fieldlet compilation, certificates, bounds, CPU reference queries, and BVH participation, but their dedicated GPU integration/raster passes are not connected. A medium has real bounds and a compiler-derived majorant, but phase 7 integration remains marker-only. Those still-unintegrated specimens therefore use unmistakably labelled family-0 support, wireframe, anisotropic, or bounds glyphs; a glyph is a developer visualization and is never reported as the semantic backend. Progressive wavefront traversal remains analytic-family-only and falls back to Hybrid explicitly for residual families. This follows the separation used by [sphere tracing](https://doi.org/10.1007/s003710050084), [adaptively sampled distance fields](https://www.ronaldperry.org/sig2000_ADFs_Paper.pdf), the [glTF indexed-mesh contract](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html), [oriented-particle surface modeling](https://www.microsoft.com/en-us/research/publication/surface-modeling-with-oriented-particle-systems/), and [direct volume rendering](https://graphics.stanford.edu/papers/volume-dissertation/). (Sources: `engine/render/morphfield/core/validation.js`, `engine/render/morphfield/core/MorphFieldCompiler.js`, `engine/render/morphfield/core/ReferenceQueries.js`, `engine/render/morphfield/runtime/RuntimeShaders.js`, `engine/render/morphfield/runtime/SceneBufferUploader.js`, and `tests/playground/src/demos/morphfield/telemetryView.js`.) `compilePatch()` now has a guarded `stable-analytic` path for existing-ID analytic upserts whose material ownership, query mask, certificate presence, program length, parameter count, and buffer layout remain unchanged. It compiles touched descriptors, clones the authoritative ABI and BVH to preserve snapshot immutability, splices fixed records, refits each touched leaf ancestry, and emits an immutable revision/CRC/layout-keyed runtime delta. The uploader independently validates that delta and proves all differences remain inside the declared records before issuing changed-range `queue.writeBuffer()` calls. The three-Fieldlet moving-sphere fixture published eight subranges totaling `400 bytes`, retained every GPU scene buffer and bind group, created and released zero resources, matched a canonical full compile, and reset Progressive history. An invalid delta falls back to full in-place publication; an incompatible layout uses failure-atomic full replacement. This is not yet O(changes) CPU compilation: the current path clones complete ABI arrays and the complete BVH, supports only layout-stable analytic upserts, and `worker: "auto"` still runs on the main thread. (Sources: `engine/render/morphfield/core/MorphFieldCompiler.js`, `engine/render/morphfield/runtime/SceneBufferUploader.js`, and `tests/morphfield/morphfield.test.js`.) ### Structural Scale Lab and benchmark receipts The Structural Scale Lab is a deterministic scaling workload, not a single authored showcase scene. It provides `3`, `30`, `300`, `3,000`, and `30,000` total-Fieldlet rungs. The count includes one dark analytic ground receiver, so the three-Fieldlet rung intentionally contains two test primitives plus the floor. **Lattice** separates primitives to expose framing and scene-count scaling; **clustered** creates bounded local overlap to stress candidate density; **coincident** puts every non-ground Fieldlet at one origin and should look like one merged union silhouette. The generator recenters the actual occupied bounds, and each load computes a compiler-bounds frame and applies its target and distance to the inspection camera. A visible **Fit scene** control repeats that operation after manual camera movement. The helper also returns conservative near/far recommendations; the Playground currently retains the shared `0.01 m` near plane and `500 m` far plane instead of applying those recommendations. Interactive Scale Lab loads use a fixed native comparison profile: `renderScale: 1.0`, `192` primary trace steps, one bounded shadow ray, and Hybrid lighting. Its general Quality selector is disabled because the lab owns that fixed comparison profile. `3` and `30` Fieldlets render at the current host extent; `300` and larger remain compile/upload-only until same-resolution timestamp evidence proves a complete primary-and-secondary traversal benefit. A traversal pipeline becoming ready cannot silently activate a larger rung, and a host resize recomputes native admission against the new host extent. The separate **Bounded 3→30k** action is an explicit benchmark mode. It may select a smaller diagnostic extent from the conservative work estimate and reconstruct it to the host target, but its HUD and receipt include `bounded-benchmark` and label that output timing evidence rather than interactive quality or full-resolution geometry, shadow, and depth evidence. The host supplies `depth32float`; reconstructed explicit probes use one source-ID, normal, and linear-depth-qualified footprint for both display color and projected depth. The dashboard reports requested, active, and capacity extents independently from compiler BVH and active traversal. Before recording work, the estimator checks semantic counts, analytic program work, storage-binding limits, combined CPU/GPU scene bytes, render extent, and the bounded work budget. The ladder reports descriptor construction, compilation, upload/publication, timestamped trace/full-frame work when available, queue-completion wall time, memory, and a log-log p95 exponent normalized to GPU trace nanoseconds per active pixel. It stops on configured tail limits instead of continuing an unsafe case. Portable validation proves deterministic occupied-bound centering, exact counts with the receiver, ground contact, directional-shadow footprint coverage for all three overlap modes, packed-bounds framing, probe-aspect preservation, fixed-profile/depth contracts, honest traversal labels, and normalized complexity analysis. The Playground explicitly enables a bounded screen-tile experiment for eligible scenes with at least 64 Fieldlets and a validated compiler BVH. One phase-4 invocation owns each `16×16` tile, scans compiler-validated BVH leaf records, conservatively projects their bounds, and publishes at most 64 Fieldlet indices. The lean phase-6 fragment specialization evaluates those primary candidates without a fragment-local BVH stack or candidate array. The bin and trace stages share one revision/frame/extent tag; a missing, stale, malformed, or overflowed tile record selects complete certified-linear evaluation. Secondary shadows also remain certified linear. A July 27 audit briefly reintroduced point-BVH secondary traversal, then rejected it when real-device cold compilation exceeded 50 seconds, reproducing the already documented Dawn backend-cost failure. That variant is not shipped. Scale admission uses candidate estimates only after renderer statistics report the matching generation ready, and the estimates cannot change interactive resolution. The diagnostic estimator still shows `173×87` linear versus `232×117` tiled probes for the `300`-Fieldlet `1680×847` benchmark input; those numbers are explicit benchmark planning evidence, not a measured speedup or an automatic quality decision. A separate secondary accelerator needs a same-device cold-start, output-parity, and GPU-time win before activation. (Sources: `engine/render/morphfield/runtime/RuntimeShaders.js`, `engine/render/morphfield/runtime/MorphFieldRenderer.js`, `tests/playground/src/demos/morphfield/scaleLab.js`, `tests/playground/src/demos/morphField.js`, `tests/playground/src/demos/morphfield/telemetryView.js`, and `tests/morphfield/morphfield.test.js`.) Structure Lab continuation checklist, updated 2026-07-27: - [x] Generate the exact `3/30/300/3,000/30,000` total-Fieldlet ladder deterministically. - [x] Keep lattice primitives separated, clustered envelopes bounded, and coincident overlap explicitly intentional. - [x] Include one touching ground receiver without changing the requested total Fieldlet count. - [x] Expand the receiver for the demo light's complete conservative projected-shadow footprint in lattice, clustered, and coincident modes. - [x] Recenter actual occupied bounds and fit the camera from packed compiler bounds on load, resize, and developer request. - [x] Provide a host-owned `depth32float` target and one fixed `renderScale: 1.0` / 192-step / one-shadow Hybrid comparison profile. - [x] Reconstruct display color and host depth from the same edge-aware, source-qualified footprint. - [x] Keep interactive Scale Lab loads at host resolution; unsafe large native rungs become compile/upload-only instead of silently downscaling. - [x] Make reduced-resolution execution an explicit **Bounded 3→30k** benchmark action and label it as timing evidence rather than interactive quality. - [x] Report compiler BVH availability separately from the active GPU traversal and normalize timing to active pixels. - [x] Pass the device-independent generation, framing, admission, depth-ownership, telemetry, and complexity gates. - [x] Implement the explicit-opt-in `16×16`/64-candidate screen-tile experiment with tagged records, exact primary fallback, complete linear shadows, failure-atomic publication, lifecycle coverage, and truthful telemetry. - [x] Keep admission linear until the matching accelerator generation is ready, and retain exact full-scene planning for shadows plus clustered/coincident overflow cases. - [x] Reject automatic resolution changes driven by static estimates, rAF cadence, presentation cadence, or queue-wall time; MorphField presets remain `renderScale: 1`. - [ ] Prove that the screen-tile evaluator meets the cold-pipeline budget and improves same-device GPU trace time without output drift; the Engine default remains certified linear. - [ ] Pass the complete same-device five-rung timestamp cohort with no cross-cohort timing contamination. - [ ] Pass the installed-Chrome full-resolution silhouette, depth, ground-contact-shadow, and reconstruction-parity sweep. The 2026-07-19 traversal continuation audit rejected another point-local fragment-BVH variant. Measured cold pipeline time fell from `146.4 s` for the removed candidate/local-stack graph to `95.102 s` for the current stackless point traversal, but remained far beyond the roughly `20.0-20.5 s` certified-linear baseline. Removing the postfix interpreter from the same fragment graph would not establish a compiler boundary or resolve the underlying backend cost. The implemented replacement moves candidate construction into the separate phase-4 compute cull/bin pass described in this section. It is active only behind `experimental.screenTileBvh: true`; MorphField's public safe default remains the complete certified-linear shader. Portable contracts now pass for tagged-record validation, conservative fallback selection, ordered phase work, asynchronous pipeline readiness, resize and scene-generation retirement, partial failure, device replacement, idempotent destruction, Scale Lab admission, and telemetry. Real-device tile-shader compilation, primary color/source/depth parity, overflow fallback readback, cold compilation, and measured speedup remain required before automatic activation or any claim of a cold-budget-safe spatial evaluator. The dashboard can copy an immediate snapshot or run a three-second quick benchmark and then copy a portable `morphfield-benchmark-receipt/v2` receipt. The receipt includes environment, the published scene, compiler spatial state, active trace traversal, analytic instruction count, workload-cohort identity/duration, lifecycle, timing, pacing, resources, the latest 64 diagnostic events, and sample counts beside percentile tails. Runtime and offline validators require GPU frame/trace/timestamp counts to agree, cohort counts not to exceed their timing/run windows, `queueDepth <= maximumQueueDepth <= queueCapacity`, and long-frame counts to remain a subset of the wider spike count. Its human header says `warming/insufficient` below five GPU samples and distinguishes compiler BVH availability from the renderer's active linear or BVH path. Timing windows and delayed queue checkpoints cannot cross a workload-cohort transition. A quick receipt is a diagnostic snapshot, not the publication benchmark or ten-minute release benchmark. The left live-HUD panel separately exposes a sticky **Copy all metrics** control. It copies the complete current human-readable HUD text byte-for-byte, including timing tails, pacing, simulation, representation, memory, error, and ownership lines, and reports the copied line and character counts in an ARIA live region. This convenience copy is intentionally not presented as a schema-validated benchmark receipt; the receipt controls on the right remain the portable evidence path. Both actions share the native Clipboard API with the existing hidden-textarea fallback. (Sources: `tests/playground/src/demos/morphfield/benchmarkReceipt.js`, `tests/playground/src/demos/morphfield/telemetryView.js`, and `tests/playground/src/demos/morphField.js`.) The two supplied `2026-07-18T21:27:48.248Z` mixed-scene receipts were byte-for-byte duplicates, so they represent one run. Their three fresh timestamp samples consistently measured `178.26–178.91 ms` in `TraceDirectFields`, but three samples are a warming cohort rather than a sustained p95/p97 tail. The root cause was representation work hidden by the ten-Fieldlet count: four overview glyphs expanded the mixed scene to `134` interpreted analytic instructions and `70` primitive SDF evaluations per scene sample, while the active renderer was linear despite the compiler owning a 19-node BVH. The mixed overview now keeps every semantic family Fieldlet but uses four direct-primitive markers, reducing its compiled analytic-program total to `5`; focused voxel, kernel, mesh, and medium cards retain their richer developer glyphs. A fresh same-device timestamp receipt is required before recording the resulting GPU speedup. The representative command-recording gate now runs four warm-up frames and 48 measured frames per quality tier. It removes test-wrapper and frame-descriptor allocation from the timed interval, enforces an absolute 12 ms median ceiling, and uses nearest-rank p95 so the third-worst observation detects three or more repeatable stalls. At most two more-extreme observations remain labeled isolated host-pause candidates; p97 and max stay visible diagnostics instead of being misrepresented as a sustained tail from a 12-sample cohort. The current hardware matrix passes across every quality tier with the CPU/GPU/queue channels reported separately. (Source: `tests/morphfield/morphfield.test.js`.) ### Ray-candidate regression resolution checkpoint The ray-coherent candidate experiment is no longer an active renderer path. Besides its original reserved-identifier shader failure, real hardware isolation showed a deeper structural problem: a 64-entry ray candidate array and the private point-BVH stack were lowered inside the fragment trace graph. Cold pipeline creation reached `146.4 s`, and the eight-Fieldlet matrix regressed by about two orders of magnitude. Removing only candidates reduced cold creation to `116.875 s`; bounding the old stack by `nodeCount` still took `107.483 s`; a physically linear shader took `20.018 s`. The correction removes candidate pointer plumbing, threads the validated BVH without a shader-local stack, and compiles the lean linear source independently. The full threaded source remains experimental because its current `95.102 s` cold pipeline has zero WGSL diagnostics but not an acceptable runtime startup cost; its GPU output-parity gate remains open. `GPUShaderModule.getCompilationInfo()` reports named line/column diagnostics before an invalid pipeline cascade. Static contracts reject reintroduction of `RayCandidates`, `evalRayScene`, a private `array` traversal stack, or duplicated certified-linear fallback exits. The final installed-Chrome suite passes `48/48` through the safe default path. (Sources: `engine/render/morphfield/runtime/RuntimeShaders.js`, `engine/render/morphfield/runtime/SceneBufferUploader.js`, `engine/render/morphfield/runtime/MorphFieldRenderer.js`, and `tests/morphfield/morphfield.test.js`.) ### Open gap register The audit leaves these explicit blockers. None is implied complete by a portable pass or historical hardware receipt: 1. Add an explicit encode-to-submit `commit()`/`cancel()` lifecycle so abandoned, delayed, or multiply recorded host command encoders cannot retain or prematurely recycle renderer-owned ring slots. 2. Make frame-resource and bind-group growth transactional: prepare and validate a complete replacement generation, publish it atomically, then retire the prior generation only after success. 3. Exercise real `device.lost`, asynchronous out-of-memory, error-scope ordering, and device replacement on supported adapters, including work already recorded but not submitted. 4. Replace fixed-capacity direct wavefront dispatch with measured indirect queue compaction while retaining bounded overflow, deterministic seeds, and a portable fallback. 5. Replace the remaining marker-only logical phases (1-3, 5, and 7) with substantive external-encoder work, or remove any phase that is not part of the final execution contract. Phase 4 is substantive only while the opt-in screen-tile accelerator is active. 6. Integrate and qualify the non-analytic GPU families: resident sparse residual evaluation, cached-surface publication/rasterization, oriented kernels, media, and bounded OIT composition. 7. Complete deterministic reference-image, G-buffer, depth/motion, shadow, camera-cut, energy, disocclusion, and hybrid/progressive agreement sweeps across supported adapters. 8. Move `worker: "auto"` compilation off the main thread, avoid whole-scene ABI/BVH cloning for stable patches, and run the guarded `3`/`30`/`300`/`3,000`/`30,000` same-device Scale Lab ladder, including linear/threaded-BVH parity where eligible. 9. Pin and run a documented compatibility subset of the official WebGPU CTS and the official JSON Schema Test Suite in the release matrix instead of treating local tests as substitutes for either conformance suite. 10. Complete the ten-minute stability run plus 120-frame warm-up and 600-frame benchmark for every preset, with resource, quality-settling, oscillation, cancellation, and leak gates. Wavefront statistics now distinguish the latest frame from lifetime counters. A Hybrid frame reports wavefront work as inactive even when an earlier Progressive run contributed to lifetime `encodedPasses`. Resolution-dependent queues and accumulation above the 64 MiB retention threshold are released when the renderer enters explicit Hybrid or Auto falls from Progressive to Hybrid; pipelines, scene bindings, source state, and lifetime counters remain available, and a later Progressive frame rebuilds a fresh bounded extent. On the recorded 1680×847 hardware run, this transition reclaimed `213.713 MiB` and reduced combined renderer/wavefront ownership from `295.158 MiB` to `81.444 MiB`; Progressive rebuilt the queue without errors. This prevents an inactive 1,048,576-record queue from presenting as current work or retaining hundreds of MiB indefinitely. (Sources: `engine/render/morphfield/runtime/MorphFieldRenderer.js` and `engine/render/morphfield/runtime/wavefront/MorphFieldWavefrontPathTracer.js`.) ### Close-surface and mesh-repair boundary The Analytic CSG Playground preset contains only family-0 Fieldlets. It does not contain triangles, boundary edges, or a mesh that a welding or hole-filling pass could repair. The box-minus-capsules source also contains two intentional bores. A close camera can see certified cavity walls through those openings. The Playground sweeps a conservative spherical camera envelope over the complete previous-eye-to-current-eye segment. The envelope covers the `0.18 m` inspection body and every near-plane corner, then adds `0.005 m` clearance. An analytic endpoint test proves the complete segment against the infinite ground plane; a swept-envelope BVH query prunes the remaining semantic collision Fieldlets before CPU reference sampling. Contact, non-finite data, or sweep exhaustion restores the complete last verified pose. The `0.01 m` near plane remains inside the collision envelope, so an accepted camera outside a surface cannot begin its primary ray behind that surface. (Sources: `tests/playground/src/demos/morphField.js`, `tests/playground/src/core/context.js`, `engine/render/morphfield/core/ReferenceQueries.js`, and `engine/render/morphfield/runtime/RuntimeShaders.js`.) Mesh sanitation and repair belong at two explicit boundaries: 1. Sanitize an imported indexed surface before compilation. Any repair creates a new authoritative source revision and requires new bounds and certificates. 2. Validate a generated family-3 surface-cache domain before atomic publication. A failed cache remains quarantined while direct-field rendering stays active. Any optional repair must be deterministic and must pass winding, incidence, manifold-link, boundary-signature, provenance, and direct-field error checks again. Indexed-surface normalization and surface-cache publication now share one generic indexed-triangle topology qualifier. It rejects malformed or non-finite arrays, invalid indices, geometric and topological degenerates, duplicate triangles, non-manifold edges, and inconsistent edge winding. When `closed: true` is authored, the qualifier proves that every edge has the required paired incidence and rejects boundary edges; the flag is no longer accepted as an unproved assertion. This gate does not weld nearby vertices, detect arbitrary triangle-triangle self-intersections, or prove manifold vertex links, so those stronger import/cache qualifications remain open. MorphField does not use mesh repair to hide extraction cracks, close intentional CSG openings, or change an analytic source after certification. `MeshTopologyValidation.js` supplies the shared compiler/cache gate described above. `QefSolver.js` is suitable for rank-aware dual-contouring vertex placement, including an in-cell fallback for unstable solutions. `TransitionBoundary.js` and `TransitionValidation.js` contain reusable audit primitives, but neither repairs topology nor proves a complete cache domain. `SurfaceCacheManager` provides the useful quarantine, atomic-publication, and direct-field-fallback boundary. The AGI mesh sanitizer, legacy MC33 tables, and abbreviated voxel transition tables do not prove arbitrary watertight manifold output and remain unsuitable as the Phase 3 foundation. The Playground's extractor selector is therefore labeled as a planning preview; the current active renderer remains direct-field. (Sources: `engine/render/morphfield/core/MeshTopologyValidation.js`, `engine/render/morphfield/core/validation.js`, `engine/render/morphfield/core/ReferenceQueries.js`, `engine/render/morphfield/systems/QefSolver.js`, `engine/render/morphfield/systems/SurfaceCacheExtractor.js`, `engine/render/morphfield/systems/transitions/TransitionValidation.js`, `engine/render/morphfield/systems/transitions/TransitionBoundary.js`, `agi/loader/ModelLoader.js`, and `engine/voxel/MC33Tables.js`.) Hybrid lighting follows the Engine directional-light convention: `direction` is the direction light travels, while the explicit `directionToLight` field points from the surface toward the light. Renderer inputs also accept the Engine `LightManager` sun, ambient, global-brightness, and particle-light compatibility fields. Its bounded sky contribution keeps unlit surfaces legible. Hybrid and progressive work use explicit WGSL control flow so the inactive lighting path and unnecessary shadow traces are not evaluated. Certificate uncertainty expands secondary-ray surface offsets to avoid immediate self-intersection. Materials retain RGB emission in the 12-float CPU/GPU ABI. | Tier | Scale | Trace steps | Candidates | Residual bias | Medium | Kernels | Surface cache | Shadows | Stride | Bounces | | --- | ---: | ---: | ---: | ---: | ---: | ---: | --- | ---: | ---: | ---: | | ultra | 1.00 | 192 | 96 | 0 | 1.00 | 1.00 | full | 2 | 1 | 8 | | high | 0.90 | 144 | 64 | 0 | 0.75 | 0.75 | full | 1 | 1 | 6 | | balanced | 0.75 | 96 | 48 | 1 | 0.50 | 0.50 | medium | 1 | 2 | 4 | | performance | 0.60 | 64 | 32 | 2 | 0.35 | 0.35 | coarse | 1 | 3 | 2 | | emergency | 0.50 | 40 | 16 | 3 | 0.25 | 0.25 | proxy | 1 | 5 | 1 | Quality may reduce optional work. It may not weaken bounds, certificate validation, authoritative collision, required coarse residuals, or safe overflow behavior. ## Gate-controlled implementation checklist ### Phase 0: contracts, safety, and research baseline - [x] Add the persistent roadmap and freeze Nexel, Fieldlet, four-family, and six-query terminology. - [x] Establish the additive Engine subsystem, exports, logger injection, labels, error scopes, and structured diagnostics. - [x] Select variants from actual device features and limits. - [x] Freeze host ownership, frame, patch, certificate, and `.morph` schemas. - [x] Add the double-precision CPU reference evaluator and deterministic fixtures. - [x] Record research and clean-room provenance dated 2026-07-17. - [x] Establish performance-stat runtime contracts and resource ownership tracking. Exit gate: **passed for the frozen Phase 0 baseline**. Schema/asset fixtures round-trip; raw-device and forwarding-facade tests pass; the core-profile WGSL probes and current installed-Chrome suite pass on a real WebGPU device; the renderer does not configure a canvas, submit/finish host commands, destroy a device, or destroy host views. ### Phase 1: certified analytic vertical slice - [ ] Implement semantic validation and deterministic full/incremental compilation. - [x] Implement Fieldlet buffers, bounds, certificate pools, material tables, and checked postfix interpretation. - [x] Support sphere, box, capsule, rigid/uniform transforms, and hard union/intersection/difference. - [ ] Build a deterministic CPU/worker binary AABB BVH with rigid-transform refit. - [x] Implement certified tracing, inside starts, bounded fallback, normals, depth, IDs, and opaque material output. - [ ] Produce the standard HDR/G-buffer outputs. - [x] Add the analytic/CSG Playground scene through the public API. Exit gate: **open**. Thin-feature, CSG-seam, inside/grazing-ray, close-camera, false-positive, outward-bound, GPU exit-depth/normal, resize, and repeated-entry checks pass on the current AMD WebGPU path. Layout-stable analytic patches pass canonical-parity, immutable-baseline, BVH-refit, bounded-subrange-publication, invalid-delta fallback, and failure-atomic replacement tests. Packed threaded-BVH and lean-linear contracts, opt-in preparation lifecycle, and all safe-default direct-renderer hardware gates pass. The threaded GPU runtime still fails its cold-pipeline budget and is not automatically activated. General incremental compilation, real worker execution, topology/material/layout-changing fast paths, and the complete reference-image evidence set remain open. (Sources: `engine/render/morphfield/core/validation.js`, `engine/render/morphfield/core/MorphFieldCompiler.js`, `engine/render/morphfield/core/ReferenceQueries.js`, `engine/render/morphfield/runtime/SceneBufferUploader.js`, `tests/playground/src/demos/morphfield/nexelDemos.js`, `tests/playground/src/demos/morphField.js`, and `tests/morphfield/morphfield.test.js`.) ### Phase 2: assets, spatial execution, and sparse residuals - [x] Implement `.morph` encoding/decoding, patches, checksums, compression, provenance, and source recovery. - [x] Add bounded sampled fields with compiler-generated certificates and live direct-field execution. - [x] Implement analytic plus sparse residual certificate composition. - [x] Keep a certified coarse residual level pinned for fine-page fallback. - [x] Add the shared fixed-budget software page table, atomic revision publication, LRU residency, and corruption-safe staging contract. - [ ] Bind streamed residual fine pages through a measured GPU atlas/clipmap path. - [ ] Benchmark GPU Morton/radix/LBVH construction against the deterministic CPU fallback. - [x] Record analytic/residual planning decisions in compiler and renderer telemetry. Exit gate: **open**. The codec, sampled/residual compiler, direct GPU evaluator, real-device typed-query parity, shared sparse residency controller, pinned coarse fallback, voxel bridge, and virtual-texture external-encoder feedback gates pass. Residual fine-page GPU atlas/clipmap binding, GPU construction benchmarks, byte-quantized storage, and broad corrupt/bomb fuzz campaigns remain incomplete. (Sources: `engine/core/gpu/SparsePageRuntime.js`, `engine/render/morphfield/core/MorphFieldCompiler.js`, `engine/render/morphfield/systems/ResidualHierarchy.js`, `engine/render/streaming/VirtualTexturingSystem.js`, `engine/voxel/VoxelSdfBrickBridge.js`, and `tests/morphfield/morphfield.test.js`.) ### Phase 3: unified surface cache - [x] Implement the unified `SurfaceCacheExtractor` request/entry contract and six boundary signatures. - [ ] Build Marching Cubes plus exact 2:1 Transvoxel for dynamic, streamed, smooth, or noisy domains. - [ ] Generate and validate extraction tables from documented topology rules. - [ ] Add manifold adaptive dual contouring for certified, stable hard-surface domains. - [ ] Use local coordinates and rank-aware QR/SVD-style pseudoinverse with mass-point fallback. - [x] Implement deterministic domain-level extractor selection. - [ ] Prevent mixed extractors across a seam domain and publish validated domains atomically. - [ ] Promote eligible stable expensive domains using the R2 thresholds. Exit gate: **open**. The unified request/entry ABI, six boundary signatures, atomic entry validation, and deterministic extractor policy pass their portable gates. The repository contains a clean-room conforming 2:1 piecewise-linear transition slab, not a Transvoxel-compatible implementation. It also lacks arbitrary octree face/corner closure and the full manifold topology gate. (Sources: `engine/render/morphfield/systems/SurfaceCacheExtractor.js`, `engine/render/morphfield/systems/RepresentationPlanner.js`, and `tests/morphfield/morphfield.test.js`.) ### Phase 4: oriented kernels, media, and bounded transparency - [ ] Compile oriented samples into anisotropic kernel Fieldlets with culling, bins, IDs, and motion. - [ ] Implement certified medium density/extinction/emission majorants. - [ ] Add deterministic real-time integration and path-tracer majorant tracking. - [ ] Add portable weighted blended OIT. - [ ] Add the measured four-layer exact head plus weighted tail. - [ ] Compose surfaces, fields, kernels, and media under consistent ownership rules. - [ ] Add bin-overflow counters and deterministic fallbacks. Exit gate: **open**. Bounded CPU reference systems pass; integrated GPU composition and stress evidence do not. ### Phase 5: advanced lighting, path tracing, and adaptive quality - [x] Refactor generic GPU quality scaling into the compatibility-preserving `AdaptiveQualityGovernor`. - [x] Map one immutable per-frame decision across MorphField work. - [x] Add borrowed-encoder operation to all nine legacy FrameGraph passes while preserving their standalone submit wrappers. - [ ] Implement the complete hybrid lighting path, including ReSTIR and compatible reconstruction passes. - [x] Implement the bounded-queue MorphField wavefront path tracer. - [x] Pass the corrected real-device 47-step grazing-primary readback gate on the current supported hardware adapter. - [ ] Reuse suitable accumulation, reservoir, denoising, and reconstruction components. - [x] Implement `hybrid`, `progressive`, and stability-driven `auto` modes. - [x] Keep rendering host-clock-neutral and derive Auto quality budget from a filtered display refresh estimate. - [x] Admit optional progressive work only from measured CPU/GPU/queue headroom. - [x] Keep every automatic quality tier at native resolution; require an explicit host policy marker for reconstruction scaling. - [ ] Invalidate temporal data only for affected source/version regions. Exit gate: **open**. Portable contracts separate certified-clear, hit, exhausted, and invalid wavefront outcomes; primary visibility uses the full certified ceiling and uncertain shadows fail closed. Lifecycle coverage proves Hybrid avoids tracer construction, Auto yields before deferred wavefront pipelines, pre-readiness frames stay Hybrid, late readiness synchronizes the authoritative scene, asynchronous failures remain contained, and lighting changes, device replacement, or destruction cannot publish stale generations. Pending-timestamp and unmarked-generic-governor regressions pass. The current 12-gate real-device block passes, including grazing-primary status, the 48-byte shadow-record ABI, native tier extents, explicit host reconstruction, and allocation stability. Broader adapter coverage plus ReSTIR, denoising, IBL/probes, energy, reference images, and the persistent-firefly gate remain open. ### Phase 6: simulation and query integration - [x] Expose all six GPU typed queries with layouts, capacity checks, and external-encoder operation. - [x] Keep fixed 60 Hz simulation independent from uncapped host-rAF rendering, with bounded catch-up and render interpolation. - [ ] Adapt compatible kinematic, particle/XPBD, fluid, and volume-grid systems. - [ ] Add external-encoder variants to allowed generic simulation modules while preserving wrappers. - [x] Keep all `engine/sim/physics/` bindings untouched. - [ ] Add only genuinely missing generic algorithms. - [x] Separate authoritative and visual quality behavior. - [ ] Propagate simulation changes into bounds, spatial maintenance, history, and certificate revisions. Exit gate: **open**. Query readback and scheduling tests pass. The focused CPU PBD particle/chain gate now proves deterministic replay, stable node/link IDs, typed-array and `PhysicsChain` snapshots, pinned endpoints, actual obstacle contact, matching rendered/contact radii, a `0.020 m` predictive `contactOffset`, zero-rest-offset visual floor and obstacle contact, semantic-to-solver collider parity, and visual-versus-authoritative labels. Full PhysX, GPU-particle, fluid, volume-grid, energy, swept-motion-certificate, and high-velocity parity gates remain open. (Sources: `engine/render/morphfield/systems/ParticleChainNexelAdapter.js`, `engine/render/morphfield/systems/NexelPbdCollisionAdapter.js`, `engine/render/morphfield/runtime/SceneBufferUploader.js`, `engine/render/morphfield/runtime/QueryEncoder.js`, `tests/playground/src/demos/morphField.js`, and `tests/morphfield/morphfield.test.js`.) ### Phase 7: final Playground, hardening, and release gate - [x] Finish one public-API Playground with nine focused Nexel specimens plus lighting, simulation/stress, and the Structural Scale Lab. - [x] Add editing, asset, quality, lighting, extraction, simulation, cache, and resource-rebuild controls. - [ ] Add all requested debug views. - [ ] Add the complete telemetry HUD. - [ ] Test raw/facade hosts and the full lifecycle/cancellation matrix. - [ ] Run ten-minute stability plus 120-frame warm-up and 600-frame benchmarks per preset. - [ ] Verify quality settling, oscillation, and memory targets. - [x] Complete SPDX, public API, research, architecture, and checklist documentation for the implemented R2 surface. - [x] Rebuild docs, discovery files, and bundles with Python tooling. Final gate: **open**. The integrated Full R2 acceptance matrix has not passed. ## Engine pass audit on 2026-07-18 The Engine pass library was read end to end before changing MorphField integration. Twenty-eight passes already record into a supplied encoder or caller-open render pass. Nine older FrameGraph passes created and submitted private command buffers; they now reuse `context.encoder` when supplied and retain the old create/finish/submit wrapper otherwise. The shared ownership test verifies their order and proves that the borrowed path performs zero encoder creation, finish, or queue submission. (Sources: `engine/render/passes/*.js`, `tests/render-pass-encoder-ownership.test.js`.) The audit also found eleven classes that are not ready for MorphField integration. Ten expose pipeline/configuration state without an encode operation, while `TAAPass` has an invalid texture-copy source. `PathTracingPass` is a G-buffer/environment accumulator rather than a geometry intersection engine. MorphField therefore keeps its certified wavefront intersection path and will reuse `SVGFDenoise`, `TemporalSuperResolution`, `ReSTIRGIPass`, bloom, and tone mapping only after explicit format, history, and image-readback gates pass. (Sources: `engine/render/passes/PathTracingPass.js`, `engine/render/passes/SVGFDenoise.js`, `engine/render/passes/TemporalSuperResolution.js`, `engine/render/passes/ReSTIRGIPass.js`, `engine/render/passes/TAAPass.js`.) The renderer's eight named phases are an ordering contract, not eight completed GPU systems. Phases 1-3, 5, and 7 currently encode telemetry markers only. Phase 4 records a substantive screen-tile BVH cull/bin compute pass only while that opt-in accelerator generation is active; otherwise it remains marker-only. Phase 6 performs direct Fieldlet tracing, and phase 8 performs composition plus optional progressive wavefront work. `getStats().phaseExecution` describes implementation state; `getStats().encodedWork` reports the exact ordered work recorded in the latest frame. The Playground does not display `8/8` for marker dispatches. (Source: `engine/render/morphfield/runtime/MorphFieldRenderer.js`.) ## Verification evidence | Evidence | Result | Scope | | --- | --- | --- | | Publication interruption hardening | Implemented; fresh publication rerun required | The supplied five-run, 93-minute report remains invalid because it recorded seven visibility changes. Publication collection now pauses while hidden and discards/retries any in-flight batch that crosses a visibility epoch. Timer-resolution qualification now compares observed step size with one percent of the p99 claim scale instead of rejecting a cohort from repeated values alone. Completion clears the active-run label. The post-change diagnostic suite passed 63/63 in `23,469.0 ms` with zero browser-console errors; it validates the contracts but does not replace the required five-run publication cohort. | | Current installed-Chrome baseline | 63/63 passed, zero failed, zero skipped in `78,040.6 ms` | Chrome 150 on the default WebGPU adapter passed all 51 portable and 12 real-device gates after the publication-timing correction. The run includes sampled/residual query parity, screen-tile color/source/depth parity plus overflow fallback, wavefront traversal, lifecycle, exact 60 Hz work-budget pacing, unmarked generic-governor rejection, explicit host reconstruction, and the five-tier native-extent matrix. The 64-frame timestamp probe reported GPU p50 `0.066 ms` and maximum `0.131 ms`; p90, p95, and p99 remained suppressed because their declared sample minima were not met. The diagnostic matrix separately reported post-submit drain and whole-batch wall spans without per-frame division, plus zero created/released/owned-byte resource deltas. | | Immediately preceding current-source failure provenance | 51/55 then 55/56 passed before correction | Four failures were test-contract defects rather than renderer failures: a flat union did not reach the claimed 32-value stack, one WebGPU adapter was incorrectly reused after device creation, the wavefront expected count was stale at 9 instead of 10, and a semantic bound was compared to its outward-rounded packed f32 form at an invalid tolerance. The final remaining self-test expected an invalid `1e100` radius to become a capability report even though semantic validation correctly rejected it. Each fixture was corrected and the current 56/56 run supersedes these reports. | | Prior installed-Chrome integrated suite | Historical 48/48 passed, zero failed, zero skipped | Chrome 150 on the AMD RDNA 3 WebGPU adapter passed all 38 then-current portable and ten real-device gates together. The validation UI run recorded `26,992.5 ms`; a separate exact cold test 39 recorded `20,474.985 ms`, including `20,431.850 ms` lean pipeline preparation, and zero tier differences, false sky misses, or resource churn. | | Historical supplied report before the final fixes | 37/47 passed, 10 failed, zero skipped | This preserved regression fixture exposed the reserved WGSL identifier and downstream invalid-pipeline cascade in the removed ray-candidate experiment. It is retained as failure provenance; the current row above supersedes it. | | Last pre-regression installed-Chrome baseline | Historical 47/47 passed, zero failed, zero skipped | Chrome 150 on the same adapter passed the ten then-current hardware gates before the candidate experiment. It remains regression history rather than current evidence. | | Prior `tests/morphfield/` hardware-Chromium baseline | 45/45 passed, zero failed, zero skipped | AMD RDNA 3 WebGPU adapter before the 2026-07-18 grazing-primary regression was added. It remains historical evidence, not proof of the current shader revision. | | GPU-disabled embedded-browser behavior | Portable gates execute; the required WebGPU block remains actionable | Adapter absence is reported as one actionable `Required real-device WebGPU suite` block rather than many misleading skips. Default and fallback adapter acquisition share one device broker when either is available. | | Draft 2020-12 schema and semantic suite | 29/29 passed | Python `Draft202012Validator` metaschema checks, unique IDs, full `$ref` resolution, all nine canonical sources, canonical scene/patch fixtures, finite-f32 and material-domain parity, topology and revision semantics, receipt consistency, exact capability coverage, validator resource budgets, and negative contract cases pass. The browser suite independently rejects drift between the static JSON capability artifact and the public ES-module profile. | | Shader contract suite | 8/8 passed | The Python shader checks cover required declarations, portable layouts, the shared `16×16`/64-candidate generation tag, exact-linear invalid/overflow fallback, complete-linear shadows, conservative BVH-leaf projection, non-negative-only AABB pruning, and the absence of a fragment-local BVH/candidate array. The browser suite separately checks real shader-module, pipeline, parity, and overflow validation. | | Public schema HTTP routes | 4/4 tests passed across all twelve routes | The HTTP suite serves every one of the eleven source schema resources plus the generated bundle at its exact public `$id` route and verifies platform/release routing behavior. | | `.morph` canonical-integrity hardening | Passed | Asset tests reject non-zero directory/alignment/trailing padding, validate size/decompression/CRC before skipping unknown optional chunks, target an unknown-optional CRC failure, and catch 32 deterministic whole-container bit mutations. This is focused mutation coverage, not the still-open broad corrupt/bomb fuzz campaign. | | Per-test validation watchdog | Passed for asynchronous gates | The browser harness applies a 60-second portable and 180-second real-device default timeout, configurable only inside the bounded 1-600 second range. A timeout always closes the suite and destroys a harness-owned device. Like any main-thread Promise watchdog, it cannot preempt JavaScript that synchronously monopolizes the browser thread. | | Current representative real-device tier matrix | Passed at native extent | 8 Fieldlets/27 primitives at 320×180 with four warm-ups plus 48 measured frames per tier. Every output remained 320×180. GPU p97 was `1.97/1.84/1.57/1.38/1.44 ms` from ultra through emergency; CPU encode p97 was at or below `0.625 ms`; zero renderer resource churn. The result does not justify automatic resolution scaling because no reduced-resolution cohort was requested or measured. | | Focused Nexel representation lab | Implemented; current hardware suite passed | Nine specimens cover analytic CSG, real PBD particle spheres, an Editor-compatible PBD particle chain, oriented samples, sampled voxels, sparse residuals, indexed meshes, bounded media, and a mixed four-family scene. Validation compiles every declared semantic kind/family, runs all six CPU reference queries, executes sampled/residual surface queries on the real GPU, samples a finite SDF/reference section for every specimen, and verifies that diagnostics distinguish native execution from derived glyphs. The mixed overview retains ten Fieldlets/four families while its diagnostic program work is bounded to five analytic instructions. | | Structural Scale Lab portable gate | Passed; accelerator hardware ladder open | The exact rung set is `3/30/300/3,000/30,000`. Portable coverage proves deterministic occupied-bound centering, exact total counts with one touching ground receiver, conservative directional-shadow receiver coverage, packed compiler-bounds camera fitting, native interactive admission, resize-aware admission, compile/upload-only safety, explicit aspect-preserving bounded probes, shared edge-aware color/depth reconstruction into host-owned `depth32float`, one fixed 192-step/one-shadow Hybrid profile, compiler-BVH versus active-traversal disclosure, and a per-active-pixel trace exponent. Live verification rendered the 30 rung at the full `1040×536` host extent; the 300 rung remained compile/upload-only. Only **Bounded 3→30k** may use smaller diagnostic estimates. No complete same-device five-rung timestamp cohort or native shadow/depth sweep has passed yet. | | Benchmark receipt contract | Passed | `morphfield-benchmark-receipt/v2` serializes the published scene, compiler BVH and active traversal separately, Scale Lab execution mode, analytic instruction count, exact workload cohort, lifecycle, separate timing channels, pacing, resources, validation state, and a bounded 64-event tail. Its human form distinguishes `native-inspection` from `bounded-benchmark`, labels queue-completion wall time separately from timestamp-query GPU work, and marks GPU cohorts below five samples insufficient. Legacy v1 receipts remain readable. | | Playground presentation, timestamp, and stress probe | Passed for the exercised presets | The max-two-in-flight pacer kept submission debt bounded. At fixed 1008×509 Performance/Hybrid/Direct, the moving 8-Fieldlet scene measured trace p50/p95/p97/max `12.96/16.28/16.64/16.91 ms` across 214 same-cohort samples; paused it measured `15.95/16.40/16.43/16.63 ms` across 182 samples. Neither condition produced a sample above 20 ms. The static 3-Fieldlet scene measured `2.82/3.55/3.59/3.76 ms` across 240 samples. A `34.74 ms` presentation maximum occurred while trace max remained `16.91 ms`, proving that callback/presentation outliers cannot be labeled as equal-duration shader work. At 1680×847, Hybrid reclaimed `213.713 MiB` of inactive wavefront frame resources and Progressive rebuilt cleanly. The required ten-minute and every-preset release benchmark remains open. | | Adapter-unavailable validation behavior | Passed | A browser exposing `navigator.gpu` but no adapter reports one actionable `WEBGPU_DEVICE_UNAVAILABLE` blocked suite with all twelve GPU gates named and zero misleading skips. Default and fallback adapter acquisition share one device broker when either is available. | | Adversarial analytic certificate/bounds fixtures | Passed | A semantic radius of `16,777,217` stores as `16,777,216`, derives a conservative `129.00001525878906` error, and publishes outward trace bounds of `±130.00001525878906`; negative, nonrepresentable, and subnormal bound probes also round outward, while a composed `1e-4 × 1e-4` scale is rejected. | | Direct-shader and screen-tile traversal | Safe default plus current real-device accelerator parity passed | Candidate pointer plumbing and the shader-local BVH stack are absent; the eager source is lean-linear. Top-level analytic and certified sampled/residual Fieldlets execute through the direct evaluator. Renderer initialization reports `getCompilationInfo()` errors before awaiting pipeline creation. The screen-tile experiment builds a separate compute/fragment pipeline pair, publishes one tagged candidate generation atomically, and falls back to complete linear evaluation for invalid or overflowing primary records and every shadow ray. AABB pruning applies only to non-negative current unions and uses strict-greater bounds so equal-distance source/material ties remain deterministic. Static ABI, lifecycle, ordered-work, color/source/depth parity, and overflow gates pass. A complete Scale Lab speedup cohort remains open. | | `runtime/wavefront/selfTest.html` | Portable 9/9 and real WebGPU 10/10 passed | The deterministic fixture proves a grazing sphere needs 47 steps and is exhausted by the emergency 40-step budget. Its real-device half uses a finite invertible camera matrix, reads `HitRecord` status before shading, validates emissive accumulation separately, and asserts the 48-byte shadow-record ABI. | | `tests/render-pass-encoder-ownership.html` | 9/9 passes; 19 ownership/order checks | The shared host encoder records all nine legacy FrameGraph passes in order with zero private encoder creation, finish, or submission; every compatibility wrapper still creates, ends, finishes, and submits once. | | `tools/generate_morphfield_transition_tables.py --check --self-test` | Passed | 14 samples, 22 boundary triangles, 22 tetrahedra, normalized volume `0.9999999999999999`, SHA-256 `97c1129c30bb1a202b04fac804a3a24c1016307d46df5750f3b13b16cd9fbe85`. | | Historical Playground manual scene sweep | Superseded by focused specimen gallery | The earlier analytic, residual, surface, kernels/media, lighting, and simulation scenes rendered with zero reported errors. The replacement nine-specimen gallery has portable compilation/UI evidence; its fresh same-device visual sweep, the Scale Lab five-rung cohort, and every-preset long-run sweep remain open. | | Engine, Platform, and WebGPU OS Python runtime bundles | Passed | Actual `--no-cache --no-site` builds scanned 1,089 Engine modules, 2,744 Platform modules, and 2,022 WebGPU OS modules with zero skipped. The generated runtimes include native-resolution MorphField quality normalization, display-aware quality budgeting, shared sparse pages, certified sampled/residual execution, the voxel bridge, virtual-texture feedback, and the public capability schema. Site copying was deliberately excluded from this runtime-only gate. | | Documentation toolchain | Passed | Engine API extraction previously produced 1,706 reference pages; the current documentation build indexed 2,578 documents with valid navigation and rebuilt `llms.txt` and `llms-full.txt`. | | Scoped SPDX audit | Passed | Every new MorphField, validation-console, and transition-generator source carries the project SPDX header; the repository-wide dry run still reports one unrelated pre-existing Editor source file. | The validation page exports a machine-readable JSON report. Browser timing is diagnostic rather than a release benchmark. ## Research and provenance Research was rechecked against primary sources on 2026-07-17 through 2026-07-18 and again for sparse residency and display-aware pacing on 2026-07-26: - [WebGPU specification](https://gpuweb.github.io/gpuweb/) and the [`GPUAdapter` contract](https://gpuweb.github.io/types/interfaces/GPUAdapter.html) for immutable requested device capabilities, one device creation per adapter object, device loss, validation, and resource ownership. The core-only hardware probe requests a fresh adapter instead of attempting to create a second device from the validation suite's consumed adapter. - The official [WebGPU Conformance Test Suite](https://gpuweb.github.io/cts/) for future pinned browser/device conformance coverage. MorphField's focused tests are implementation qualification, not a substitute for the CTS. - [WGSL specification](https://gpuweb.github.io/gpuweb/wgsl/) for host-shareable layouts, reserved words, pointer parameters, shader validation, and portable core behavior. The 2026-07-18 audit removed the invalid candidate experiment, retained pre-pipeline module diagnostics, and changed the private mixed spatial record to an explicitly typed stackless layout. - [JSON Schema Draft 2020-12](https://json-schema.org/draft/2020-12), its [bundling guidance](https://json-schema.org/draft/2020-12/release-notes), and the official [JSON Schema Test Suite](https://github.com/json-schema-org/JSON-Schema-Test-Suite) for canonical resource behavior and the future pinned validator-conformance matrix. The repository's 29 focused schema/semantic cases validate MorphField contracts but do not claim full JSON Schema implementation conformance. - [Performance Timeline](https://www.w3.org/TR/performance-timeline/) and [Long Tasks](https://www.w3.org/TR/longtasks-1/) for browser-side timing provenance. MorphField receipts keep performance entries, long-task observation, rAF/presentation cadence, WebGPU timestamps, whole-batch wall span, and post-submit queue-drain notification as distinct evidence channels. - [MDN `requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame), [Unity target frame rate](https://docs.unity3d.com/2023.2/Documentation/ScriptReference/Application-targetFrameRate.html), [Unreal display-rate guidance](https://dev.epicgames.com/documentation/en-us/unreal-engine/setting-your-display-rate), and [Godot's engine clock contract](https://docs.godotengine.org/en/stable/classes/class_engine.html) for the separation between display cadence, optional frame caps, and fixed physics ticks. MorphField stays host-clock-neutral and uses measured refresh only as an Auto-quality budget. - Hart's [sphere tracing paper](https://experts.illinois.edu/en/publications/sphere-tracing-a-geometric-method-for-the-antialiased-ray-tracing/) and Keinert et al.'s [enhanced sphere tracing](https://diglib.eg.org/items/8ea5fa60-fe2f-4fef-8fd0-3783cb3200f0) for conservative implicit-surface traversal. - Mitchell's [robust interval ray intersection](https://graphicsinterface.org/wp-content/uploads/gi1990-8.pdf), Kalra and Barr's [guaranteed ray intersections](https://authors.library.caltech.edu/records/1qdsf-e4t24), and Galin et al.'s [segment tracing](https://diglib.eg.org/handle/10.1111/cgf13951) for bounded root isolation, tangent/multiple-root cautions, and local Lipschitz reasoning. The current analytic slice uses conservative stepping and validity-checked signed brackets; complete interval isolation and analytic tangent fallback remain Phase 1 gate items rather than implied completed features. - [Lipschitz-pruning research](https://diglib.eg.org/server/api/core/bitstreams/d7139fe4-fb28-4a06-8011-c813fa4d59b5/content) for conservative lower-bound pruning of implicit fields. MorphField's current implementation applies compiler-derived certificate error to its AABB lower bound and retains certified fallback when the spatial traversal cannot be trusted. - Karras's [parallel BVH construction](https://research.nvidia.com/publication/2012-06_maximizing-parallelism-construction-bvhs-octrees-and-k-d-trees) for hierarchy layout direction and future measured GPU LBVH work. The current packed hierarchy is still constructed deterministically on the CPU; it does not claim a GPU radix/LBVH implementation. - [Dual Contouring of Hermite Data](https://www.cs.rice.edu/~jwarren/papers/dualcontour.pdf) and [Manifold Dual Contouring](https://people.engr.tamu.edu/schaefer/research/dualsimp_tvcg.pdf) for Hermite placement, stable QEF treatment, and topology requirements. - The [Transvoxel reference](https://transvoxel.org/) for the target transition-cell behavior. MorphField does not copy its published lookup tables and does not claim equivalence for the current clean-room tetrahedral transition slab. - [CGAL Polygon Mesh Processing repair documentation](https://doc.cgal.org/4.13/Polygon_mesh_processing/group__PMP__repairing__grp.html) for the scope and preconditions of triangle-mesh sanitation operations. MorphField treats repair as a source-revision-producing import step followed by a new topology audit, never as proof that analytic fields or extracted caches are automatically watertight. - [Weighted Blended OIT](https://jcgt.org/published/0002/02/09/) for bounded-memory approximate transparency. - The original [ReSTIR research](https://research.nvidia.com/publication/2020-07_spatiotemporal-reservoir-resampling-real-time-ray-tracing-dynamic-direct) for future spatiotemporal reservoir validation. - The [XPBD paper](https://matthias-research.github.io/pages/publications/XPBD.pdf) for compliance and time-step/iteration-independent stiffness semantics. - The [Position-Based Dynamics survey](https://matthias-research.github.io/pages/publications/PBDTutorial2017-CourseNotes.pdf) and [Unified Particle Physics](https://matthias-research.github.io/pages/publications/flex.pdf) for particle state, distance/contact constraints, and representation-independent solver snapshots. The focused particle/chain demo reuses the repository CPU PBD implementation and does not claim that the currently unverified GPU rope constraint path is production-ready. - The official [PhysX best-practices guide](https://nvidia-omniverse.github.io/PhysX/physx/5.4.1/docs/BestPractices.html) for fixed-frequency simulation independent of rendering, bounded catch-up, and sphere-based chain stability guidance. - The [glTF 2.0 specification](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html) for indexed mesh primitives and material/topology separation, and the [OpenVDB overview](https://www.openvdb.org/documentation/doxygen/overview.html) for the distinction between sparse narrow-band level sets and fog volumes. - The original [3D Gaussian Splatting project](https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/) for anisotropic Gaussian representation direction. MorphField's oriented-kernel Nexel remains a compiled CPU-reference/diagnostic specimen and does not claim the complete rasterization method from that work. - [NanoVDB research](https://research.nvidia.com/labs/prl/publication/nanovdb/) only for sparse GPU-friendly data-structure direction. It is not evidence for MorphField residual certification. - [Geometry Clipmaps](https://hhoppe.com/geomclipmap.pdf), [AMD Brixelizer](https://gpuopen.com/manuals/fidelityfx_sdk/techniques/brixelizer/), and NVIDIA's [compact signed-distance grids](https://jcgt.org/published/0011/03/06/) for bounded sparse residency, nested refinement, and conservative distance-grid direction. MorphField currently implements the shared page lifecycle, coarse fallback, voxel bridge, and resident sampled/residual evaluator; it does not yet claim a complete camera-centered clipmap or byte-quantized GPU atlas. The transition topology generator is an independent rules-based implementation. Its generated module records the generator version, topology hash, no external table dependency, and no unverified equivalence claim. ## Reproduce the current checks Serve the repository over HTTP: ```bash python start_server.py ``` Open `http://127.0.0.1:9001/tests/morphfield/` in a WebGPU-capable browser, then run: ```bash python tests/morphfield/run_python_tests.py python -m unittest discover -s tests/morphfield -p "test_*.py" -v python tools/generate_morphfield_transition_tables.py --check --self-test python MD/tools/extract_api.py python MD/tools/build_docs.py python MD/tools/build_llms.py python bundle_engine.py --target engine --no-site ``` ## See also - [Rendering Pipeline](rendering.md) - [Virtual GPU](vgpu.md) - [GPU Device Sharing](../concepts/gpu-device-sharing.md) - [Physics and Simulation](physics.md) --- # Shaders & WGSL A modular WGSL shader system with composition, preprocessing, a shared library of reusable modules, and the `ShaderComposer` for assembling complex shaders from parts. ## Shader organization ```text engine/render/shaders/ ├── ShaderComposer.js ← assembles shaders from modules ├── ShaderLoader.js ← file-based shader loading ├── ShaderSchema.js ← shader metadata and validation ├── ShaderSources.js ← inline shader source strings ├── WgslPreprocessor.js ← #define, #if, #include preprocessing ├── core/ ← core shader modules (lighting, transforms) ├── modules/ │ ├── core/ ← e.g. particles_sdf_billboard.js, phase_vfx.js │ ├── passes/ ← fullscreen post-process & debug pass shaders │ └── lib/ ← reusable WGSL function libraries (density, depth) ├── materials/ ← material shaders (PBR, unlit, etc.) ├── effects/ ← post-process effect shaders └── debug/ ← debug visualization shaders ``` ## ShaderComposer `ShaderComposer` assembles complex shaders from a library of reusable WGSL modules. Modules are registered by name and injected at compile time, avoiding duplicate functions (e.g. lighting) across shaders. ```javascript import { ShaderComposer } from './engine/render/shaders/ShaderComposer.js'; const source = ShaderComposer.compose({ libs: ['particles/phase_vfx', 'lighting/pbr'], main: myShaderCode }); ``` The composer resolves the `LIBRARY_MAP` to inject WGSL function definitions before your main code. ## WGSL preprocessor `WGSLPreprocessor` supports C-style directives before compilation: ```wgsl #define MAX_LIGHTS 16 #define ENABLE_SHADOWS #if ENABLE_SHADOWS // shadow mapping code included #endif ``` ```javascript vgpu.shader.compile('lit', source, { MAX_LIGHTS: 8, ENABLE_SHADOWS: 1 }); ``` ## Shader reflection `VGPUShaderReflection` parses WGSL source to extract bind group layouts, struct definitions, and entry points, enabling automatic pipeline-layout generation from shader source. ## Compilation via vGPU All shader compilation goes through `vgpu.shader` (see [Virtual GPU](vgpu.md)): ```javascript const module = vgpu.shader.compile('name', wgslCode); // compile + cache vgpu.shader.recompile('name', updatedCode); // hot reload (dev) const info = await module.getCompilationInfo(); // check errors ``` > **Important:** use `textureSampleLevel(..., 0.0)` instead of `textureSample()` in compute shaders and non-uniform control flow — WebGPU validation rejects `textureSample` outside uniform control flow. ## Common pattern: billboard circle clipping Particle debug shaders render billboard quads with vertices `(-1,-1)`..`(1,1)`. The fragment shader must discard corners to produce circular particles: ```wgsl let dist = length(input.localPos); if (dist > 1.0) { discard; } // hard circle clip let falloff = falloffGaussian(dist, 0.8); if (falloff < 0.01) { discard; } // soft edge ``` > Without the hard clip, `falloffGaussian(1.414, 0.8) ≈ 0.21` still passes the 0.01 threshold, making particles appear as squares. --- # Particle System The engine's flagship subsystem: large-scale GPU particles with physics, thermal simulation, chemistry, SPH fluids, SDF collision, flocking, and volumetric rendering. Everything runs on compute shaders via [vGPU](vgpu.md). > **Scale:** the particle system spans 60+ simulation files and 30+ rendering files — the largest subsystem in the engine. This page covers the architecture and key concepts. ## Architecture Three distinct layers: ```text ┌─────────────────────────────────────────────┐ │ Editor / Game API │ │ EditorParticles.js — orchestrates per-frame │ ├─────────────────────────────────────────────┤ │ Rendering Layer (engine/render/particles/) │ │ SDF Billboard · Half-Res Composite · Beams │ │ Bonds · Decals · Distortion · Mesh · Trail │ ├─────────────────────────────────────────────┤ │ Simulation Layer (engine/sim/particles/) │ │ ParticleSimWorld — main compute shader │ │ + 30 advanced subsystems (GPU compute) │ ├─────────────────────────────────────────────┤ │ Emitter System (ParticleEmitterSystem.js) │ │ Presets, spawn shapes, rate control │ └─────────────────────────────────────────────┘ ``` ## Per-frame pipeline Each frame in `EditorParticles.js`: 1. **Emit** — spawn new particles from active emitters into GPU buffers. 2. **Alive-list compaction** — a GPU scan writes alive particle indices (skip dead slots). 3. **Main sim** — GPU compute: gravity, curl noise, forces, integration, lifetime. 4. **Advanced systems** — thermal, SPH, flocking, bonds, chemistry, constraints. 5. **Sort** — radix sort by camera distance for correct alpha blending. 6. **Collisions** — SDF collision against entity meshes + ground plane. 7. **Light extraction** — GPU compute finds the hottest particles → async readback → `LightManager`. 8. **Render** — SDF billboard at half-res → additive composite onto the scene. ## Emitter system `ParticleEmitterSystem.js` manages emitter presets and spawning. ### Matter states | State | Phase value | Render mode | Examples | | --- | --- | --- | --- | | Solid | `0` | Matte diffuse + specular | Sparks, debris, snow | | Liquid | `1` | Fresnel + refraction | Water, blood, rain | | Gas | `2` | Volumetric (Beer-Lambert) | Smoke, steam, fog | | Plasma | `3` | Emissive glow | Fire core, lightning, magic | ### Spawn shapes `ParticleSpawnShapes.js` provides configurable emission geometries: **point**, **sphere** (surface or volume), **box**, **cone**, **ring** (torus), and **mesh surface** (emit from mesh triangles via `MeshToParticlesCompute.js`). ## GPU simulation The core sim runs in `ParticleSimWorld.js` — a large compute shader processing all particles each frame. Buffer layout: | Buffer | Per-particle data | Stride | | --- | --- | --- | | Position | `vec4(x, y, z, lifetime)` | 16 bytes | | Velocity | `vec4(vx, vy, vz, age)` | 16 bytes | | Thermal | `vec4(temperature, heat, packedMaterial, latentEnergy)` | 16 bytes | | Color | `vec4(r, g, b, size)` | 16 bytes | > **`thermalData.z` packing:** lower 8 bits = material index (0–15), upper bits = collision group ID. Encode: `(groupId << 8) | materialIdx`. Decode in WGSL: `materialIdx = u32(thermal.z) & 0xFFu`. ### Advanced subsystems Initialized via `initAllAdvancedSystems()`: - **Thermal & chemistry** — temperature with material-specific melt/boil points, latent heat, and phase transitions (16 material presets: water, metal, wax, lava, etc.). - **SPH fluids** — smoothed-particle hydrodynamics (pressure, viscosity, surface tension). - **SDF collision** — particles collide with entity meshes via signed distance fields (sphere/box/cylinder), per-entity SDF from `PrefabRegistry`. - **Flocking** — boids (separation, alignment, cohesion) using a neighbor grid. - **Bonds** — spring connections for soft-body/cloth-like behavior (async CPU readback for bond evaluation). - **Electromagnetic** — electric/magnetic field forces, charged interactions. - **Constraints** — distance/position/velocity constraints (rope, chains, attached particles). - **Event system** — particle events (collision, death, threshold) that trigger sub-emissions or gameplay actions. ## Performance optimizations - **Alive-list compaction** — a GPU scan builds an alive list of active indices; the main sim dispatches only `aliveCount` threads via indirect dispatch. - **Radix sort** — 4-bit radix sort replaces bitonic. For 100M particles: 24 dispatches (8 passes × 3) vs ~289 for bitonic (`ParticleRadixSort.js`). - **FBM noise pre-bake** — `ParticleNoiseTexture.js` first bakes three decorrelated vector-potential channels, then takes one periodic centered-difference curl on the volume lattice. The octave count follows grid resolution and tiling period to avoid undersampling; at period 16, 64³ uses two, 128³ uses three, and 256³ uses four. Configurations with fewer than two lattice samples per base-noise cell are rejected. Creation resolves WebGPU validation and out-of-memory scopes before exposing the resources. Runtime tracers use one filtered `textureSampleLevel` instead of evaluating procedural curl per particle. (Source: `engine/sim/particles/ParticleNoiseTexture.js`.) - **Neighbor grid** — spatial-hash grid for O(1) neighbor queries (SPH, flocking, bonds), rebuilt each frame on GPU. - **Selectable long-range solver** — direct, open-boundary FMM, periodic PME, or experimental periodic ESP. See [Particle Long-Range Solvers](particle-long-range.md) for the boundary and accuracy tradeoffs. - **Particle Storm saturation benchmark** — the Playground's first and default demo grows against a measured 60 FPS budget. Fifty million particles is a calibration waypoint, not a population ceiling; growth continues until measured frame pressure, WebGPU's 32-bit identity space, or an adapter allocation failure stops it. The baseline uses a 16-byte binary16-packed record while retaining `f32` arithmetic. Optional experiments compose in a fixed pipeline order independent of activation order: state storage, pressure handling, learned control, then HDR resolve. Experiment 2 selects the proven 12-byte fully dynamic record (three `u32` words containing three half-float positions, three signed 11-bit velocities, and a 15-bit normalized lifetime). Experiment 5 requests maximum state capacity, but currently resolves to that same 12-byte inertial record because an all-in-one 8-byte trial introduced visible quantization seams and changed the vortex dynamics. A separate one-way 8-byte retained tier remains available to the pressure stage; it is counted separately because it preserves analytic motion and colour variation but no longer runs the full vortex/noise integration. WGSL storage layout gives a structure of three 4-byte-aligned `u32` members a 12-byte size and array stride; the live shader compile verifies support, while hardware transaction cost remains an adapter benchmark question. The fused simulation/density pass feeds a recursive least-squares model of `GPU ms = fixed + simulation cost × simulated millions + raster cost × rendered millions`. The model remains advisory until samples vary independently in simulated count and render fraction, preventing a false split while both columns are identical at 100% rendering. Under pressure, the governor changes by no more than one 1/256 cohort per adjustment and never drops below 160/256, or 62.5%, rendered. Every complete 256-particle block contributes an exact quota selected by a hashed bit-reversal permutation; each particle receives equal participation across the 256-frame cycle. Partial blocks use an exact rotating tail quota. This point-wise transition follows the continuous-LOD finding that gradual density changes are less irritating than chunk popping. An optional two-frame density-history blend suppresses residual cohort noise and rejects history after sharp camera or mouse-force changes, following the temporal-stability motivation of spatiotemporal blue-noise work without introducing long TAA ghost trails. A single fullscreen pass resolves the density buffer to HDR, replacing tens of millions of point draws. The HDR path operates at 75% internal resolution, uses renderable `rg11b10ufloat` when available, and falls back to `rgba16float`. The density implementation supports one, two, four, or eight privatized banks, but defaults to the empirically faster single bank on the tested adapter; `stormBanks` remains a direct benchmark override. Backing storage grows only when active particles nearly fill existing primary capacity. Sustained pressure first lowers render quota, can transition a full-dynamics chunk to the retained tier, then retires particles gradually. (Sources: `tests/playground/src/demos/particleStorm.js`, `tests/playground/src/demos/particleStormTuning.js`, `tests/playground/src/core/experiments.js`, [WGSL structure and array layout](https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size), [WGSL data packing built-ins](https://gpuweb.github.io/gpuweb/wgsl/#pack-builtin-functions), [WebGPU supported limits](https://gpuweb.github.io/types/interfaces/GPUSupportedLimits.html), [MDN `GPUOutOfMemoryError`](https://developer.mozilla.org/en-US/docs/Web/API/GPUOutOfMemoryError), [TU Wien continuous point-cloud LOD](https://www.cg.tuwien.ac.at/research/publications/2019/schuetz-2019-CLOD/), [NVIDIA scalar spatiotemporal blue-noise masks](https://research.nvidia.com/publication/2021-12_scalar-spatiotemporal-blue-noise-masks), [Rendering Point Clouds with Compute Shaders](https://arxiv.org/abs/1908.02681), [Software Rasterization of 2 Billion Points in Real Time](https://arxiv.org/abs/2204.01287).) - **Curl Noise Flow Atlas** — the Playground Curl demo reuses Storm's chunked allocation, two-dimensional dispatch, exact-quota point selection, timing governor, fused compute-density raster, short HDR history, glow, and tone mapping. It stores bounded position plus lifetime in two packed `u32` words, or 8 bytes per tracer, and derives velocity from the shared field. Four aggregate State-First emitter cohorts select point, splat, line, field, or low-mesh deposition without per-particle CPU objects or state removal. Five authored emitter and analytic-vortex studies provide composition without changing the uncapped measured-growth policy. See [Curl Noise Flow Atlas](curl-noise-flow-atlas.md) for measurement semantics and controls. (Sources: `tests/playground/src/demos/curlNoise.js`, `tests/playground/src/demos/curl/shaders.js`, `tests/playground/src/demos/curl/model.js`.) - **Galaxy Mythic Spiral Atlas** — the Playground Galaxy demo stores one 4-byte orbital state per active tracer, advances every active orbit, and reuses Storm's exact-quota density selection and learned governor. Eight atomic planes separate old stars, young stars, H-II emission, and dust. Four aggregate population proxies plus the resolved field feed State-First buckets without reading orbital state back to the CPU; bucket quality modulates continuous deposition energy and never deletes a family. The HDR resolve applies exponential dust extinction before fantasy color grading. Five authored studies add bars, rings, a tidal wake, outer spurs, and a sparse polar veil without presenting the result as an N-body simulation. See [Galaxy Mythic Spiral Atlas](galaxy-mythic-spiral-atlas.md) for its art direction, measurement semantics, and scientific boundary. (Sources: `tests/playground/src/demos/galaxy.js`, `tests/playground/src/demos/galaxy/model.js`, `tests/playground/src/demos/galaxy/shaders.js`.) ## Rendering The primary renderer (`ParticleSdfRenderer.js`) draws each particle as a camera-facing quad and raymarches a signed distance field in the fragment shader for volumetric shapes. The fragment shader branches by matter phase: - **Solid (0)** — matte diffuse + subtle specular, opaque sphere. - **Liquid (1)** — broad specular, Fresnel reflection, transparent center. - **Gas (2)** — volumetric raymarch with Beer-Lambert transmittance, Henyey-Greenstein phase function, depth-based self-shadowing. - **Plasma (3)** — pure emissive glow. Lifetime effects modulate color/size/alpha via GPU textures: a `rgba8unorm` 1D color gradient (`textureSampleLevel`) and a `rgba32float` lifetime-curves texture (`textureLoad`, unfilterable). Hot particles use the Tanner Helland blackbody approximation (CIE 1931); very hot particles (`thermalGlow > 0.5`) get an emissive bloom boost. Additional renderers: `ParticleBeamRenderer` (lasers/lightning), `ParticleBondRenderer` (springs), `ParticleDecalRenderer` (impact decals), `ParticleDistortionRenderer` (heat haze), `ParticleMeshRenderer` (mesh-shaped debris), `ParticleTrailHistory` (ribbons/trails), `ParticleSPHSurfaceRenderer` (screen-space fluid), `RopeGPURenderer` (rope/chain). ## Audio integration `ParticleAudioBridge.js` maps particle substance properties (temperature, density, velocity) to procedural audio parameters — fire crackles, water splashes, and wind howls are generated from particle state, with no pre-recorded samples. ## Key files | File | Purpose | | --- | --- | | `sim/particles/ParticleSimWorld.js` | Core GPU compute sim | | `sim/particles/ParticleEmitterSystem.js` | Emitter presets and spawning | | `sim/particles/ParticleAdvanced.js` | Advanced subsystem orchestration | | `sim/particles/ParticleFMM.js` | Open-boundary uniform-octree FMM | | `sim/particles/ParticleMeshEwald.js` | Periodic PME and experimental ESP | | `sim/particles/ParticleConstraints.js` | Distance/position constraints | | `render/particles/ParticleSdfRenderer.js` | SDF billboard rendering | | `render/particles/ParticleHalfResComposite.js` | Half-res compositing | | `render/shaders/modules/core/particles_sdf_billboard.js` | Main SDF particle shader | | `editor/js/modules/EditorParticles.js` | Per-frame orchestration | ## See also - [Kuramoto Resonance Field](kuramoto-resonance-field.md) — a phase-oscillator lab that reuses compute-density and HDR rendering principles while keeping its real oscillator count separate from stateless visual samples. - [Curl Noise Flow Atlas](curl-noise-flow-atlas.md) — adaptive procedural-flow art with packed tracers and compute-density rendering. - [Galaxy Mythic Spiral Atlas](galaxy-mythic-spiral-atlas.md) — adaptive orbital-tracer art with physical dust attenuation and five fantasy studies. - [Particle Long-Range Solvers](particle-long-range.md) - [Physics and Simulation](physics.md) --- # Galaxy Mythic Spiral Atlas Galaxy Mythic Spiral Atlas is an adaptive GPU orbital-tracer demo in the Playground. It combines observed spiral-galaxy structure with five deliberately enhanced fantasy studies. This page is for developers who tune its morphology, rendering, or performance governor. An orbital tracer is a procedural sample that follows an analytic galactic orbit. The demo is not a self-gravitating N-body simulation, and it does not use FMM to approximate pairwise gravity. Its scientific content is limited to population distributions, differential rotation, a separate spiral-pattern speed, dust offsets, and transparent measurement semantics. ## Rendering pipeline ```text packed 4-byte orbital state -> differential orbital update -> logarithmic arm and population classification -> semantic State-First population buckets -> exact-quota eight-plane density accumulation -> stellar emission - dust optical depth + nebular emission -> short motion-aware HDR history -> thresholded glow + hue-preserving ACES ``` Every active tracer stores two 16-bit angular values in one `u32`: orbital phase and epicyclic phase. One initialization bit distinguishes untouched allocation from live state. The compute shader advances this state before density selection, so the HUD's **simulated** count means actively updated orbital states. (Sources: `tests/playground/src/demos/galaxy.js`, `tests/playground/src/demos/galaxy/shaders.js`.) The position model derives disk radius, vertical thickness, stellar family, luminosity, and structural variation from a stable integer identity. Disk stars follow a cored-to-flat rotation curve. Spiral arms use a logarithmic phase field whose pattern speed remains distinct from each star's orbital speed. Arm width increases outward, while segment masks and feathers prevent perfectly continuous ribbons. Selected studies add a bar, tidal wake, resonant ring, outer arc, or sparse polar veil. (Sources: `tests/playground/src/demos/galaxy/model.js`, `tests/playground/src/demos/galaxy/shaders.js`.) ## Light, dust, and color The eight-plane atlas stores old stars, young stars, H-II emission, and dust in two atomic shards per family. Shards reduce avoidable contention without changing the resolved image. The resolve applies wavelength-dependent transmission: ```text transmission = exp(-opticalDepth * extinctionColor) ``` Optical depth measures how strongly material attenuates light along a sampled path. This lets dust lanes darken stars instead of adding nearly black light to an additive target. A separate rim term adds faint scattered color. Young blue populations and coral or magenta H-II regions sit at different arm-phase offsets from dust. (Source: `tests/playground/src/demos/galaxy/shaders.js`.) The palette is an enhanced visualization, not unaided human vision. It retains a warm old population, cooler young clusters, emission regions, and dark dust, then grades those components into each study's fantasy palette. The final pass blooms only energy above a threshold, adds rare background stars and core diffraction, and applies a hue-preserving ACES curve once at presentation. (Source: `tests/playground/src/demos/galaxy/shaders.js`.) ## Adaptive scale The demo begins with one million active tracers and grows in allocation chunks. It has no configured particle-count ceiling. Growth ends only when measured pressure, the 32-bit identity range, or a recoverable WebGPU allocation failure requires it. Shaders compile before large buffers allocate, and size-dependent targets replace the previous target only after validation and out-of-memory scopes succeed. (Source: `tests/playground/src/demos/galaxy.js`.) The fused pass simulates every active tracer and selects a spatially distributed subset for density work. Selection never falls below `160 / 256`, or 62.5%, and changes by at most one cohort per governor adjustment. A low-discrepancy permutation spreads a quota change across each 256-tracer block. It does not remove one visible contiguous population. The HUD says **selected**, because projection and frustum rejection occur after quota selection. (Sources: `tests/playground/src/demos/particleDensitySelection.js`, `tests/playground/src/demos/particleStormTuning.js`, `tests/playground/src/demos/galaxy.js`.) GPU timestamps separate recurring clear, fused simulation-density work, resolve, history, and presentation. A recursive model estimates fixed, simulated-million, and selected-million costs. The governor waits for fresh samples, excludes reset and target-rebuild transients, and changes one quota slot per frame under pressure. Camera, study, and pointer discontinuities reject short-term history to prevent ghost trails. (Source: `tests/playground/src/demos/galaxy.js`.) State-First planning uses four aggregate stellar-family proxies plus one resolved field proxy. These bounded CPU descriptors represent old stars, young stars, H-II regions, dust, and the composed density field; individual orbital tracers remain authoritative packed GPU state and are never read back for bucket classification. The active profile supplies a quota ceiling of `256`, `224`, `192`, or `160` slots, while the existing one-slot governor smoothing and `160 / 256` floor remain in force. Bucket representations modulate continuous deposition energy rather than removing a stellar family, so a policy change cannot erase or recreate simulation state. Native policy preserves the original density response. (Sources: `tests/playground/src/demos/galaxy.js`, `tests/playground/src/demos/galaxy/model.js`, `tests/playground/src/demos/galaxy/shaders.js`.) Memory telemetry includes live state, allocated-but-inactive state capacity, eight density planes, HDR targets, and timestamp resources. It is an estimate of resources owned by the demo, not whole-process GPU memory. ## Studies | Key | Study | Composition | | --- | --- | --- | | `1` | Astral Crown | Four feathered sapphire arms cross an ivory-gold disk with coral nurseries and deep dust. | | `2` | Void Cathedral | A cold barred spiral carries dark arches and a sparse bipolar ionization veil. | | `3` | Dragonwake | Three loose ember arms shear into an asymmetric blue-violet tidal feather. | | `4` | Seraphim Ring | Five pale-gold resonant feathers carry rose H-II knots into a turquoise halo. | | `5` | Arcane Meridian | Two broad cyan-violet arms cross a molten core and dissolve into broken outer spurs. | Study data lives in `GALAXY_STUDIES`. `validateGalaxyStudies()` rejects invalid arm count, pitch, radius, exposure, or camera values before the demo allocates GPU resources. (Source: `tests/playground/src/demos/galaxy/model.js`.) ## Controls | Input | Action | | --- | --- | | `1`-`5` | Select and deterministically reset an authored study. | | Left drag | Bend projected light around a local interactive gravity-lens effect. This is an art control, not a gravity solve. | | Right drag | Orbit the camera and reject stale HDR history. | | `Space` | Pause or resume orbital evolution while presentation remains live. | | `R` | Reset the current study from its stable identity seed. | ## Research basis - [NASA's NGC 3982 image and description](https://science.nasa.gov/missions/hubble/pinwheel-of-star-birth/) grounds the warm central population, blue young clusters, reddish star-forming regions, and obscuring dust lanes. - [NASA's galaxy morphology guide](https://science.nasa.gov/universe/galaxies/types/) describes spiral disks, bulges, halos, bars, gas, dust, and population differences. - [Dobbs and Baba's spiral-structure review](https://arxiv.org/abs/1407.5062) motivates treating arms as patterns that stars move through instead of rigid material ribbons. - [Draine's interstellar-dust review](https://arxiv.org/abs/astro-ph/0312592) motivates absorption, scattering, and wavelength-dependent extinction. - [Rendering Point Clouds with Compute Shaders](https://www.cg.tuwien.ac.at/research/publications/2021/SCHUETZ-2021-PCC/) motivates compute-density point rasterization at high sample counts. - [Continuous Level of Detail for Point Clouds](https://www.cg.tuwien.ac.at/research/publications/2019/schuetz-2019-CLOD/) motivates distributed point-wise transitions rather than visible chunk removal. - [Scalar Spatiotemporal Blue Noise Masks](https://research.nvidia.com/publication/2021-12_scalar-spatiotemporal-blue-noise-masks) motivates temporally stable changing sample sets. - [ACES output-transform guidance](https://docs.acescentral.com/system-components/output-transforms/) motivates a scene-linear HDR pipeline followed by one display transform. - [WGSL](https://gpuweb.github.io/gpuweb/wgsl/) defines the storage layout, integer atomics, and packing operations used by the implementation. ## See also - [Particle System](particles.md) - [Curl Noise Flow Atlas](curl-noise-flow-atlas.md) - [Kuramoto Resonance Field](kuramoto-resonance-field.md) - [Particle Long-Range Solvers](particle-long-range.md) --- # Curl Noise Flow Atlas Curl Noise Flow Atlas is an adaptive GPU tracer demo in the Playground. It combines a shared periodic curl field with Particle Storm's high-count compute-density architecture and five authored flow studies. The demo visualizes procedural incompressible-style flow. It is not a Navier-Stokes solver, fluid-pressure simulation, or claim of physically exact continuous incompressibility after texture filtering. ## Pipeline ```text three-channel vector potential -> periodic discrete curl volume -> packed 8-byte tracer advection -> four semantic State-First cohort buckets -> exact-quota atomic density -> chromatic HDR resolve -> clamped 2-3 frame history -> thresholded glow + hue-preserving ACES ``` `ParticleNoiseTexture.js` bakes three decorrelated potential channels into an `rgba16float` 3D texture. A second compute pass reads periodic neighbors and writes the centered-difference curl into a separate volume. The shared stencil makes discrete divergence cancel on the bake lattice before half-float quantization. Trilinear interpolation can introduce residual divergence between texels, so the demo describes the result as procedural curl flow rather than exact computational fluid dynamics. (Source: `engine/sim/particles/ParticleNoiseTexture.js`.) The bake limits unfiltered octaves to the volume's sample density and rejects configurations with fewer than two lattice samples per base-noise cell. At the default period of 16, a 64³ field uses two octaves, 128³ uses three, and 256³ uses four. Runtime work then becomes one filtered field lookup per tracer instead of repeated scalar-noise evaluations. The direct fallback in `ParticleSimWorld.js` uses the same three-component potential construction. (Sources: `engine/sim/particles/ParticleNoiseTexture.js`, `engine/sim/particles/ParticleSimWorld.js`.) ## Scaling model Each tracer stores three bounded positions and normalized lifetime in two packed `u32` values. `pack2x16unorm` gives uniform precision across the fixed `[-16, 16]` domain. Velocity remains derived from the flow field, which keeps live state at 8 bytes without counting a retained or non-simulated tier as full dynamics. (Source: `tests/playground/src/demos/curl/shaders.js`.) One compute invocation unpacks a tracer, samples and applies the field, advances lifetime, repacks state, projects the result, and optionally adds one integer contribution to one of eight density planes. Two-dimensional dispatch avoids the one-dimensional workgroup-count ceiling. State grows in adapter-probed chunks, shaders compile before large state allocation, and size-dependent targets commit only after asynchronous WebGPU validation and out-of-memory scopes succeed. A failed resize retains the last valid image. (Sources: `tests/playground/src/demos/curlNoise.js`, `tests/playground/src/demos/curl/shaders.js`.) The governor has no configured particle-count ceiling. It grows until measured frame pressure, WebGPU's 32-bit identity space, or allocation failure stops it. Per-pass GPU timestamps separate fused simulation from resolve and presentation cost. Two timestamped empty markers distinguish the recurring density clear from transient state resets before the compute pass without replacing optimized `clearBuffer` commands with a slower compute clear. Reset and reactivation samples remain visible in telemetry but are excluded from governor learning. The governor also requires two fresh timestamp intervals before acting, so one cold sample cannot force a quality step. A frame-cadence fallback still calibrates on adapters without timestamp queries. The HUD reports estimated GPU memory because it includes state, density, HDR history, and both field volumes. (Source: `tests/playground/src/demos/curlNoise.js`.) Under the State-First rasterizer policy, four authored emitter cohorts act as bounded semantic proxies for the packed GPU population. The demo submits one aggregate bucket plan per sampled frame; it never reads individual tracer state back to JavaScript or creates one CPU object per tracer. The selected `POINT`, `SPLAT`, `LINE`, `FIELD`, or `LOW_MESH` representation is packed into the existing uniform block and changes the density-deposition footprint and weight. It does not delete, freeze, or change the 8-byte simulation state. Native policy retains the original field-style deposition. (Sources: `tests/playground/src/demos/curlNoise.js`, `tests/playground/src/demos/curl/model.js`, `tests/playground/src/demos/curl/shaders.js`.) ## Selection and rendering semantics The demo always keeps at least `160 / 256`, or 62.5%, of active tracers eligible for density rasterization. It changes the quota by at most one cohort per adjustment. A low-discrepancy permutation distributes changes within each 256-tracer block, and stochastic integer weighting makes lifecycle fades gradual without fractional atomics. (Sources: `tests/playground/src/demos/particleStorm.js`, `tests/playground/src/demos/particleStormTuning.js`, `tests/playground/src/demos/curl/shaders.js`.) The HUD calls this number **selected**, not rendered. Frustum rejection, camera direction, and lifecycle fading happen after selection, so no honest fixed percentage can guarantee that the same fraction contributes to visible pixels every frame. The resolve normalizes material chromaticity separately from density. Hue-preserving ACES avoids turning dense complementary colors white. Thresholded glow blooms bright filaments without lifting the whole occupied region, while a short clamped history rejects camera, study, and pointer-force discontinuities. (Sources: `tests/playground/src/demos/curl/shaders.js`, `tests/playground/src/demos/curlNoise.js`.) ## Studies | Key | Study | Composition | | --- | --- | --- | | `1` | Aurora Loom | Four narrow polar emitters rise through a translating field. | | `2` | Vortex Cathedral | Two counter-rotating columns use nested, color-separated shells. | | `3` | Braided Wake | Four narrow jets cross a moving analytic vortex pair. | | `4` | Solar Bloom | A toroidal emitter unfolds around an orbital core. | | `5` | Helicity Garden | Four shells expose coarse and fine rotational structure. | The authored vortex primitives are divergence-free cross-product fields. Pointer interaction injects another localized vortex instead of a radial sink. (Sources: `tests/playground/src/demos/curl/model.js`, `tests/playground/src/demos/curl/shaders.js`.) ## Controls | Input | Action | | --- | --- | | `1`-`5` | Select an authored study and reset its tracer field. | | Left drag | Move a local vortex through the projected flow. | | Right drag | Orbit the camera. | | `Space` | Pause or resume simulation. Presentation remains live and the HUD says `SIM PAUSED`. | | `R` | Reset the current study. | Reset clears active and inactive allocated state. Reactivated ranges also clear before compute, so stale particles cannot reappear after pressure-driven retirement. Lifecycle fades and a visible paused spawn age avoid bulk disappearance. (Sources: `tests/playground/src/demos/curlNoise.js`, `tests/playground/src/demos/curl/shaders.js`.) ## Research basis - [Curl-Noise for Procedural Fluid Flow](https://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph2007-curlnoise.pdf) defines curl of a vector potential, potential-space modulation, boundary treatment, and analytic vortex primitives. - [Rendering Point Clouds with Compute Shaders](https://www.cg.tuwien.ac.at/research/publications/2021/SCHUETZ-2021-PCC/SCHUETZ-2021-PCC-paper.pdf) motivates compute-density point rasterization. - [Continuous Level of Detail for Point Clouds](https://www.cg.tuwien.ac.at/research/publications/2019/schuetz-2019-CLOD/) motivates point-wise transitions instead of visible chunk changes. - [Scalar Spatiotemporal Blue Noise Masks](https://research.nvidia.com/publication/2021-12_scalar-spatiotemporal-blue-noise-masks) motivates temporally stable changing sample sets. - [High-Speed, Off-Screen Particles](https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-23-high-speed-screen-particles) describes reduced-resolution off-screen particle accumulation. - [WGSL](https://gpuweb.github.io/gpuweb/wgsl/) defines the packing, texture, storage-buffer, and atomic operations used by the implementation. ## See also - [Particle System](particles.md) - [Kuramoto Resonance Field](kuramoto-resonance-field.md) - [Particle Long-Range Solvers](particle-long-range.md) --- # Kuramoto Resonance Field The Kuramoto Resonance Field demos turn collective phase synchronization into a large, interactive HDR sculpture. The CPU and GPU versions share the same five studies and renderer, but they integrate different numbers of real oscillators. Both report the integrated oscillator count separately from the stateless field-sample count. - [Run the CPU demo](/tests/playground/?demo=kuramoto-cpu) - [Run the GPU demo](/tests/playground/?demo=kuramoto-gpu) ## Mathematical model For oscillator phase $\theta_i$, natural frequency $f_i$ in cycles per second, coupling $K$, and optional external drive $\lambda$, the demos integrate $$ \frac{d\theta_i}{dt} = 2\pi f_i + \frac{K}{N}\sum_j \sin(\theta_j-\theta_i) + \lambda\sin(2\pi f_d t-\theta_i). $$ The complex order parameter $$ Z_1 = \frac{1}{N}\sum_j e^{i\theta_j}=R_1e^{i\psi} $$ measures first-harmonic synchronization. $R_1$ approaches zero for a distributed population and one for phase lock. The demos also report $R_2=|N^{-1}\sum_j e^{2i\theta_j}|$, which exposes two-cluster and standing-wave structure that can be hidden by $R_1$ alone. Uniform global coupling has an exact linear-time reduction: $$ \frac{K}{N}\sum_j\sin(\theta_j-\theta_i) =K\left(\operatorname{Im}(Z_1)\cos\theta_i-\operatorname{Re}(Z_1)\sin\theta_i\right). $$ This identity replaces an $O(N^2)$ pair loop with one $O(N)$ order-parameter reduction and one $O(N)$ integration pass. It is exact for the all-to-all, equal-weight model; it is not an approximation and does not apply unchanged to an arbitrary weighted network. The background and canonical model are covered by the [Kuramoto review by Acebrón et al.](https://doi.org/10.1103/RevModPhys.77.137). ## CPU path The CPU demo uses `stepKuramotoMeanFieldDriven()` at a fixed 120 Hz simulation step. It computes $Z_1$, advances every active phase from the same immutable state, and swaps two typed-array views without copying the completed population. An adaptive governor changes the number of real CPU oscillators only after sustained timing evidence; it does not slow simulation time to hide load. The original pairwise engine functions remain available for weighted or small networks. Their in-place output path snapshots its source, so reusing the input array cannot turn a simultaneous Euler step into an order-dependent update. ## GPU path The GPU demo stores one `f32` phase per oscillator and starts with 1,048,576 active phases on a desktop adapter. Each fixed 120 Hz substep performs this sequence: 1. Integrate phases using the current reduced order parameter. 2. Accumulate partial $Z_1$ and $Z_2$ sums from the newly written phase buffer. 3. Complete the reduction before the next substep reads it. Separate uniform buffers preserve the time and parameters for every encoded substep. A near-square two-dimensional dispatch avoids the 65,535-workgroup limit on one dispatch dimension without dispatching a mostly empty 4,096-wide row. A persistent readback ring samples only the small order-parameter result and rejects results from an earlier study generation. GPU timestamp queries, when supported, guide population growth using measured work instead of frame-rate guesses alone. Study resets initialize and copy only the active range; newly exposed ranges are initialized as the population grows. The current desktop safety guard reserves at most $2^{24}$ real phases, subject to the adapter's storage-buffer limit. This is an implementation allocation guard, not a theoretical Kuramoto limit. GPU implementations at the same $2^{24}$ scale have been reported in the literature; see [Januszewski and Kostur's GPU Kuramoto implementation](https://arxiv.org/abs/0903.3852). ## High-density field renderer The luminous field deliberately separates simulation state from display density. When field samples outnumber oscillators, repeated layers choose real oscillators by stable modulo identity; when oscillators outnumber samples, a rotating stratified mapping covers the complete population over time instead of permanently showing a low-index prefix. Each sample then derives an outer halo, interference membrane, inner resonator, or order core without storing another particle record. Increasing field samples therefore improves density and grain without falsely increasing the reported oscillator population. The shared renderer uses the following pipeline: 1. A stateless compute pass projects samples into eight atomic-density planes: four visual materials with two contention shards each. 2. A fullscreen resolve reads each plane once into a compact HDR target, preserving cool, warm, violet, and gold structures. Texture-space glow in the presentation pass avoids another 32 density-buffer reads per HDR pixel. 3. A short, clamped history blend suppresses single-frame density noise while rejecting history after a phase kick or study reset. 4. A final pass applies bloom-like neighborhood energy, ACES tone mapping, and display conversion. This follows the compute-density principle used by Particle Storm, but it does not copy Particle Storm's packed dynamic-state codecs, retained tiers, or cohort culling. Kuramoto phases remain `f32`, and field samples are regenerated every frame. A timestamp-driven field governor assigns the remaining frame budget after measured simulation work, while the simulation governors primarily react to their own measured costs. This prevents one slow visual pass from unnecessarily shrinking the real oscillator population. Reported field GPU time covers the timestamped compute, resolve, history, and presentation passes; WebGPU's native density-buffer clear is outside that query scope. ## Studies and controls | Key | Study | What it demonstrates | | --- | --- | --- | | `1` | Freqora WaveVM | Frequency spread, phase coupling, and interference inspired by Freqora's public oscillator proof of concept. | | `2` | Critical Synchronization | The transition from distributed phases to collective lock as $K$ crosses the population's effective threshold. | | `3` | Forced Entrainment | Competition between natural-frequency spread and an external periodic drive. | | `4` | Standing Wave | Two counter-rotating frequency populations, tracked with both $R_1$ and $R_2$. | | `5` | Phase-Kick Recovery | Dephasing and recovery after an interactive impulse. | Additional controls are shared by both versions: - Mouse wheel adjusts coupling $K$. - Shift + mouse wheel adjusts drive strength. - Left click applies the same deterministic all-population phase-field force in both backends and rejects visual history. - Space pauses or resumes integration. - `R` resets the current study. ## Freqora attribution and scientific boundary Study 1 credits [Freqora](https://github.com/colector1337-hub/Freqora) by Colector1337 (Michał Stankiewicz) and Grok (xAI). Its public `WaveVM` stores frequency, phase, amplitude, and waveform shape; `WaveVM::step` advances the globally coupled phases with explicit Euler and a direct nested pair loop, giving $O(N^2)$ work per step in that reference implementation. See the [source at the audited revision](https://github.com/colector1337-hub/Freqora/blob/a546789b13a9b944ac2dc0c4eb20cbdbb6a325ad/src/wave_vm.rs#L85-L112) and its [MIT software license](https://github.com/colector1337-hub/Freqora/blob/a546789b13a9b944ac2dc0c4eb20cbdbb6a325ad/LICENSE). The demos simulate a classical phase-oscillator model. Their shells, colours, terms such as “resonance field,” and the central sculpture are an artistic mapping of phase, detuning, $R_1$, and $R_2$. They do not simulate matter-antimatter annihilation, quantum wave functions, gravity, vacuum energy, or a “Void” substrate, and they do not present those ideas as established physics. No mathematical matter-antimatter annihilation or “Void substrate” convergence model was found in the [public Freqora tree at the audited revision](https://github.com/colector1337-hub/Freqora/tree/a546789b13a9b944ac2dc0c4eb20cbdbb6a325ad). ## Key files | File | Purpose | | --- | --- | | `engine/core/math/MathOscillator.js` | Pairwise and exact global mean-field CPU integrators. | | `tests/playground/src/demos/kuramoto/model.js` | Shared studies, deterministic frequency distributions, metrics HUD, and attribution. | | `tests/playground/src/demos/kuramoto/renderer.js` | Stateless atomic-density, HDR history, and ACES rendering pipeline. | | `tests/playground/src/demos/kuramotoCpu.js` | Fixed-step adaptive CPU laboratory. | | `tests/playground/src/demos/kuramotoGpu.js` | Multi-million-phase GPU integration and reduction pipeline. | ## See also - [Particle System](particles.md) - [Math Library](math.md) - [Shaders and WGSL](shaders.md) --- # Particle Long-Range Solvers The particle simulation has four mutually exclusive long-range force backends. Use FMM for a large open domain, PME for a periodic domain, direct summation as the small-system accuracy oracle, and ESP only as an experimental periodic alternative. These systems accelerate the same content-dependent pair force as the existing N-body solver; they are unrelated to Pai, BLT, HIER, or Ouroboros model training. (Sources: `engine/sim/particles/ParticleNBody.js`, `engine/sim/particles/ParticleFMM.js`, `engine/sim/particles/ParticleMeshEwald.js`.) ## Choose a backend | Backend | Boundary | Best fit | Main tradeoff | | --- | --- | --- | --- | | `direct` | Open | Small particle counts and reference validation | Exact softened pair sum, but quadratic work | | `fmm` | Open | Large or spatially clustered particle sets | Approximate; current tree is uniform and capped at depth 5 | | `pme` | Periodic | Uniform periodic particle sets | FFT/grid cost and periodic-image physics | | `esp` | Periodic | Experiments with a smaller prolate-window grid | Wider grid assignment and real-space work can erase the FFT saving | Do not switch between open and periodic backends merely for speed. They solve different boundary-value problems. FMM is the primary upgrade path for Particle Realms scenes because those scenes normally use an open world. Published comparisons likewise show that workload distribution matters: FMM can benefit strongly inhomogeneous systems while mesh methods can remain better for uniform periodic systems. GPU crossover points depend on hardware, particle distribution, requested accuracy, and expansion order. (Sources: [Treecode and fast multipole method for N-body simulation with CUDA](https://arxiv.org/abs/1010.1482), [Adaptive fast multipole methods on the GPU](https://arxiv.org/abs/1205.4611), [FMM and PME comparison](https://pmc.ncbi.nlm.nih.gov/articles/PMC7660746/).) ## N-body encounter Playground The [N-Body Encounters demo](../../tests/playground/?demo=nbody) separates gravitational accuracy from visual sampling. Full-precision macro bodies source and receive softened gravity through the open FMM backend. The 4,096-body Direct Reference uses a separate race-free tiled direct kick. A packed 12-byte tracer population responds to at most three moving cluster cores, but never contributes mass to either force solve. The HUD reports mutual bodies, active tracers, quota-selected tracers, allocated state, memory, solver timing, and FMM leaf diagnostics as separate quantities. (Sources: `tests/playground/src/demos/nBody.js`, `tests/playground/src/demos/nbody/shaders.js`.) The tracer renderer reuses the Particle Storm exact-quota permutation. Every block of 256 active tracers contributes exactly `renderSlots` candidates, the quality floor remains 160 of 256 candidates, and the governor changes no more than one cohort per adjustment. Tracer state has no preset count ceiling. Allocation stops at available GPU memory, storage-binding limits, or the 32-bit identity limit. A learned cost model and separate GPU timestamps prevent expensive body solves from automatically thinning a cheap visual population. (Sources: `tests/playground/src/demos/particleDensitySelection.js`, `tests/playground/src/demos/particleStormTuning.js`, `tests/playground/src/demos/nBody.js`.) The State-First adapter submits one aggregate proxy for each active authored gravitating system plus one restricted-tracer field proxy. This keeps bucket planning proportional to the number of semantic systems rather than the number of particles and avoids GPU readback. Raster profiles map to quota targets of `256`, `240`, `208`, `176`, or `160` slots; the target is still approached by at most one slot per governor adjustment and can never cross the 62.5% floor. Bucket representation changes presentation policy only. It cannot alter macro-body integration, tracer motion, allocation, or lifetime. (Sources: `tests/playground/src/demos/nBody.js`, `tests/playground/src/demos/nbody/model.js`.) The authored encounter studies use deterministic truncated disk, Plummer, or cored Dehnen-like seeds. Restricted outer-disk tracers add low-mass visual resolution to bridges and counter-tails, following the restricted-particle approach used in foundational galaxy-encounter work. These tracers are an artistic collisionless approximation. Color families, dust, starburst light, and sparkle are rendering proxies rather than gas dynamics, radiative transfer, or star formation. (Sources: [Toomre and Toomre encounter models](https://www.giss.nasa.gov/pubs/abs/to03000u.html), `tests/playground/src/demos/nbody/model.js`, `tests/playground/src/demos/nbody/shaders.js`.) The 65,536-body Apex study is an explicit stress mode. It uses a depth-5 uniform tree, a cored profile that reduces central leaf overload, and a 20 Hz force cadence while rendering between solves. The default study uses 8,192 mutual bodies at 60 Hz so hardware headroom can grow the visual tracer population into the millions. No cadence or count converts the current uniform tree into an adaptive FMM; inspect maximum leaf occupancy and clamped-body diagnostics when tuning clustered scenes. (Sources: `tests/playground/src/demos/nbody/model.js`, `engine/sim/particles/ParticleFMM.js`.) ## Configure a world Select a backend when creating the world: ```js const world = await createParticleSimWorld(gpuDevice, { maxParticles: 65_536, longRangeConfig: { backend: 'fmm', domainHalfExtent: 32, targetLeafOccupancy: 32, softening: 0.05, coupling: 1, }, }); ``` Change it later through the public Engine API: ```js configureParticleLongRange(world, { backend: 'pme', gridSize: 32, domainHalfExtent: 32, ewaldAlpha: 1.25, realCutoff: 2, }); const state = getParticleLongRangeState(world); ``` `stepParticleSimWorld()` records exactly one selected long-range solver. Existing callers that use `enableNBody` continue to select the direct backend. Changing an immutable topology parameter such as FMM depth, mesh size, mesh window radius, or prolate bandwidth safely recreates only the long-range solver resources. ESP also recreates its precomputed split spectrum when the domain extent or real-space cutoff changes. (Source: `engine/sim/particles/ParticleSimWorld.js`.) ## FMM pipeline The WebGPU FMM implementation performs the complete uniform-octree sequence: 1. Count and scatter particles into Morton-ordered leaves. 2. P2M: accumulate source strength and center information in each leaf. 3. M2M: translate child moments up the tree. 4. M2L: translate the 189-cell interaction list into first-order local fields. 5. L2L: propagate local fields to children. 6. L2P plus P2P: evaluate the local field and exact neighboring-leaf interactions. The current clean implementation stores monopole source moments and first-order Cartesian local fields. It uses a uniform tree with depths 2 through 5, clamps particles to the configured open domain for tree assignment, preserves inactive-target/source semantics from the direct solver, supports caller-owned command encoders, and exposes pass, memory, scatter, and readback diagnostics. This is a working GPU baseline, not an adaptive or high-order production FMM. (Sources: `engine/sim/particles/ParticleFMM.js`, `engine/sim/particles/ParticleLongRangeMath.js`.) ## PME and experimental ESP Both particle-mesh paths use an Ewald split: short-range complementary interactions under periodic minimum-image boundaries plus a reciprocal solve on a three-dimensional complex FFT grid. PME uses the conventional Gaussian split with cubic B-spline assignment. ESP numerically solves the even prolate-spheroidal Sturm-Liouville eigenproblem in an orthonormal Legendre basis, normalizes the resulting compact radial density, integrates its real-space complement, and precomputes its cosine-transform response for the spectral influence function. It also uses the prolate window for particle-grid assignment and deconvolves that window's measured response. (Sources: `engine/sim/particles/ParticleMeshEwald.js`, `engine/sim/particles/ParticleLongRangeMath.js`.) The Phys.org result concerns **Ewald Summation with Prolates**, not FMM. The underlying paper reports lower grid, communication, and particle-grid costs at matched high accuracy in large MPI molecular-dynamics runs. This browser implementation tests the algorithmic idea on one WebGPU device; it does not reproduce the paper's distributed LAMMPS/GROMACS implementation or its performance claim. Current local evidence shows that ESP compiles and produces finite output, but the wider assignment window can make it slower than PME at small browser workloads. Keep `esp` labelled experimental until matched-error GPU timestamp benchmarks demonstrate a repeatable win. (Sources: [Accelerating Molecular Dynamics Simulations using Fast Ewald Summation with Prolates](https://arxiv.org/abs/2505.09727), [Phys.org summary](https://phys.org/news/2026-06-mathematicians-unleash-multifold-boost-supercomputer.html), `tests/playground/src/demos/prolateParticles.js`.) WGSL core atomics support only `i32` and `u32`, so the particle-mesh deposition pass assigns one invocation to each grid cell and gathers nearby sorted particles instead of using unsupported floating-point atomic additions. The sort/scatter stages use integer atomics. (Sources: [WGSL atomic types](https://www.w3.org/TR/WGSL/#atomic-types), `engine/sim/particles/ParticleMeshEwald.js`.) ## Validate and benchmark The Prolate Particle Lab is hidden from the normal menu by default while ESP remains research-grade, but its [direct Playground link](../../tests/playground/?demo=prolate-particles) remains available. It runs the real Engine exports and lets you compare direct, FMM, PME, and ESP backends, particle count, and FFT grid size. The HUD separates host command-recording duration from asynchronous queue-drain notification; neither value is shader-only GPU time. Use the direct-vs-FMM relative L2 comparison as a correctness signal, not a visual approximation. (Source: `tests/playground/src/demos/prolateParticles.js`.) Open the [long-range invariant suite](../../tests/particle-long-range.html) for CPU layout and Morton tests, an analytic two-body direct test, numerical prolate-window checks, randomized GPU FMM comparison against a float64 direct oracle, and live PME/ESP finite-output and scatter checks. Always compare methods at equivalent error before making a performance decision. (Sources: `tests/particle-long-range.html`, `engine/sim/particles/ParticleLongRangeMath.js`.) ## Current limits - FMM uses a uniform rather than adaptive octree and low-order expansions. - FMM depth is capped at 5 to bound GPU memory and dispatch count. - PME and ESP require a power-of-two grid from 8 through 64. - PME and ESP model periodic images; FMM and direct do not. - ESP's numerical PSWF split and assignment window are clean-room implementations of the published mathematical operators, not copied LAMMPS or GROMACS code. - Reported browser queue-drain durations include previously queued work, driver scheduling, and notification delay. - No backend is selected automatically from particle count because boundary semantics and the hardware-dependent crossover must remain explicit. ## See also - [Particle System](particles.md) - [Physics and Simulation](physics.md) - [Virtual GPU](vgpu.md) --- # Physics & Simulation GPU-accelerated cloth, rope, fluid volumes, and rigid-body physics. All solvers run on compute shaders via [vGPU](vgpu.md). > For the full WebGPU compute physics engine with PhysX 5 parity (rigid bodies, solver, CCD, vehicles, CCT, FEM soft bodies, mesh/heightfield queries), see [GPU Physics Engine](gpu-physics.md). ## Cloth simulation A mass-spring cloth solver in `engine/sim/cloth/`. Each cloth is a grid of particles connected by structural, shear, and bending springs, solved on GPU compute. Configurable: stiffness (spring force coefficient), damping (velocity damping), per-cloth gravity override, wind (directional force with turbulence noise), pin constraints (fixed vertices), and sphere/plane collision response. ## Rope physics A Position-Based Dynamics (PBD) rope solver in `engine/sim/particles/RopePhysics.js`. Ropes are chains of particles with distance constraints solved iteratively: - **PBD constraints** — distance constraints with configurable compliance. - **Material properties** — stiffness, damping, mass per unit length (`RopeMaterial.js`). - **Particle interaction** — ropes interact with the particle system (`RopeParticleInteraction.js`). - **GPU rendering** — smooth tube rendering with normals and lighting (`RopeGPURenderer.js`). ## Fluid simulation Two approaches: - **Lagrangian (SPH)** — smoothed-particle hydrodynamics via the [particle system](particles.md). Each fluid particle carries density, pressure, and viscosity; the solver computes inter-particle forces using a neighbor grid (`ParticleSPH.js`). - **Eulerian (grid-based)** — `ParticleEulerianFluid.js` solves the Navier-Stokes equations on a 3D grid using pressure projection and velocity advection, suitable for contained volumes (pools, rivers). ## Rigid body physics The ECS `PhysicsBody` component drives rigid-body simulation: body types (dynamic, kinematic, static), collider shapes (sphere, box, capsule, mesh via the `Collider` component), forces (gravity, impulses, torques), and constraints (distance, hinge, ball-socket). ## PBD ragdoll A Position-Based Dynamics ragdoll solver for character physics — joint limits, bone chains, and muscle constraints. It integrates with the [AGI](../agi/overview.md) system for learning-based locomotion. ## Simulation update `SimulationUpdate.js` orchestrates all simulation systems each frame, in order: 1. ECS physics system tick (rigid bodies, colliders). 2. Cloth solver step (GPU compute). 3. Rope constraint solving (PBD iterations). 4. Particle simulation (main compute + advanced subsystems). 5. Fluid pressure solve (if active). ## Key files | File | Purpose | | --- | --- | | `sim/SimulationUpdate.js` | Master simulation orchestrator | | `sim/cloth/` | Mass-spring cloth solver | | `sim/fluids/` | Eulerian fluid volumes | | `sim/physics/` | Rigid body physics system | | `sim/particles/RopePhysics.js` | PBD rope solver | | `sim/particles/RopeMaterial.js` | Rope material properties | | `sim/particles/ParticleSPH.js` | SPH fluid solver | | `sim/particles/ParticleEulerianFluid.js` | Grid-based fluid | | `sim/particles/ParticleConstraints.js` | Distance/position constraints | --- # GPU Physics Engine A WebGPU compute-based physics engine with full PhysX 5.4.1 feature parity: 15 modules in `engine/sim/physics/gpu/` (~400 KB total), all shaders in WGSL. It is a parallel implementation — no PhysX code is modified — designed for a future native migration. > Every GPU-accelerated feature in PhysX 5.4.1 (rigid bodies, broadphase, contact gen, solver, CCD, vehicles, CCT, soft bodies, triggers, scene queries, heightfield, triangle mesh) has a dedicated module. See the [parity table](#physx-5-feature-parity). ## Architecture ```text GPU Physics Pipeline CCD Expand → Broadphase (hash) → Narrowphase (PCM) → Solver (TGS_Soft) Heightfield contacts · TriMesh contacts · Triggers/events · Integration + sleep Vehicles (GPU) · Soft body (FEM) · CCT (CPU) · Readback (async) CPU-side synchronous: Raycast (CPU/GPU) · Scene query ``` Key principles: - **WebGPU compute shaders** (WGSL) for all parallel workloads. - **CPU orchestration** for serial logic (islands, CCT, scene queries). - **Fixed pre-allocated GPU buffers** (PhysX 5 pattern) — overflow warns, never crashes. - **SoA (structure of arrays)** layout for GPU cache efficiency. - **No PhysX code modified** — parallel implementation for future migration. ## PhysX 5 feature parity Audited against PhysX 5.4.1. ### GPU physics modules (15 files) | PhysX 5 feature | Module | Status | | --- | --- | --- | | GPU Rigid Bodies | `GPURigidBodyWorld.js` | Built | | GPU Broadphase | `GPUBroadphase.js` | Built | | GPU Contact Gen (PCM) | `GPUNarrowphase.js` | Built | | GPU Constraint Solver (TGS) | `GPUConstraintSolver.js` | Built | | Convex Hull Cooking | `GPUConvexHull.js` | Built | | Raycasting | `GPURaycast.js` | Built | | Speculative CCD | `GPUContinuousCollision.js` | Built | | Vehicle SDK | `GPUVehicle.js` | Built | | Character Controller | `GPUCharacterController.js` | Built | | FEM Soft Bodies | `GPUSoftBody.js` | Built | | Trigger Events | `GPUTriggerSystem.js` | Built | | Scene Queries | `GPUSceneQuery.js` | Built | | Heightfield Terrain | `GPUHeightfield.js` | Built | | Triangle Mesh Collider | `GPUTriangleMesh.js` | Built | ### Existing engine systems Modules in the parent `engine/sim/physics/` directory cover additional PhysX features, referenced from the GPU barrel export: PBD cloth (`GPUClothSolver.js`), articulations (`GPUArticulationSolver.js`), SDF mesh geometry (`SDFCollision.js`), XPBD solver (`PBDSolver.js`), MLS-MPM soft body (`MLSMPMSolver.js`), OGC contact (`OGCContact.js`), CPU CCD (`SpeculativeContacts.js`), shock propagation (`ShockPropagation.js`), destruction (`VoronoiFracture.js` + `FragmentPhysics.js`), convex decomposition (`ConvexDecomposition.js`), voxel mesh collider (`VoxelMeshCollision.js`), and GPU spatial hash (`GPUSpatialHash.js`). ### Features that exceed PhysX 5 - **OGC contact model** (`OGCContact.js`) — SIGGRAPH 2025 penetration-free barrier energy. - **MLS-MPM** (`MLSMPMSolver.js`) — handles topology changes (melting, fracture). - **LBM wind** (`WindSimulation.js`) — Lattice-Boltzmann GPU wind field. - **Thermal particles** (`ParticleSimWorld.js`) — phase transitions, buoyancy, chemistry. - **Rope interaction** (`RopeParticleInteraction.js`) — per-fiber thermal (burn, wet, corrode). ## Core rigid body pipeline - **`GPURigidBodyWorld.js`** — central world manager owning all GPU buffers, body descriptions, and the island manager. 5 WGSL shaders (integrate, applyDeltas, deriveVelocity, sleepDetect, clearForces); CPU union-find island manager (sleeping islands skip GPU dispatch); SoA layout; body types Dynamic (0), Kinematic (1), Static (2); shapes Sphere (0), Box (1), Capsule (2). - **`GPUBroadphase.js`** — spatial-hash broadphase. 4 WGSL shaders (computeAABB, clearHash, insertHash, findPairs); 27-neighbor cell query with layer/mask filtering. - **`GPUNarrowphase.js`** — analytic shape-shape contact generation with persistent contact manifold (PCM). Pairs: sphere-sphere, sphere-box, box-box (SAT 15 axes), sphere-capsule, capsule-capsule, ground plane. Contact data: normal, penetration, point, accumulated impulse, local anchors (A+B), featureId. - **`GPUConstraintSolver.js`** — TGS_Soft iterative solver (Box2D v3 / Catto 2023). Contact solve (bias velocity, Coulomb friction cone, restitution, impulse clamping, warm starting); D6 joint (ball, hinge, fixed, distance, cone limits); post-solve relaxation pass. - **`GPUConvexHull.js`** — CPU Quickhull 3D + GPU upload (PhysX 64-vertex GPU limit). - **`GPURaycast.js`** — GPU parallel raycasting (ray-sphere/box/capsule) with workgroup reduction; CPU fallback for synchronous queries. - **`GPUContinuousCollision.js`** — speculative CCD: AABB expansion by velocity × dt for CCD-flagged bodies (bit 25), then TOI via conservative advancement. ## Extended simulation - **`GPUVehicle.js`** — per-wheel suspension (spring-damper) + tire force (simplified Pacejka); CPU manager for input and gear shifting; presets sedan/sports/truck/offroad; `MAX_VEHICLES=64`, `MAX_WHEELS_PER_VEHICLE=8`, drive types FWD/RWD/AWD. - **`GPUCharacterController.js`** — CPU-driven kinematic CCT: Quake-style recursive slide-move (max 4 bounces), downward-raycast ground detection (skin width 0.08 m, step height 0.35 m), ~45° slope limit, step climbing, capsule (default) or box shape. - **`GPUSoftBody.js`** — FEM soft body on tetrahedral meshes. 2 GPU shaders (co-rotational FEM force + integration); Müller polar decomposition; materials via Young's modulus + Poisson's ratio → Lamé parameters; presets rubber/jelly/flesh/foam/silicone/stiff. - **`GPUTriggerSystem.js`** — trigger volumes + contact events. GPU AABB overlap for trigger-flagged bodies (bit 24); CPU persistent pair state for enter/stay/exit; callbacks `onTriggerEnter/Stay/Exit` and `onContactBegin/Persist/End`. ## Geometry & queries - **`GPUSceneQuery.js`** — CPU-side synchronous queries (overlap sphere/box, sweep sphere/box, multi-hit), with layer/exclude/include filtering. CPU because 1–10 queries/frame need immediate results. - **`GPUHeightfield.js`** — heightmap terrain collider: 5-point bilinear sampling, per-cell materials, NaN-height holes, up to 1024×1024. - **`GPUTriangleMesh.js`** — static mesh collider with BVH: CPU median-split BVH cook, GPU iterative traversal (32-level stack), 8 contacts/body, up to 16 meshes, 65536 triangles/mesh. ## Constants & limits | Constant | Value | Module | | --- | --- | --- | | `MAX_BODIES` | 4096 | GPURigidBodyWorld | | `MAX_CONTACTS` | 16384 | GPUNarrowphase (shared) | | `MAX_PAIRS` | 32768 | GPUBroadphase | | `MAX_JOINTS` | 2048 | GPUConstraintSolver | | `MAX_VEHICLES` | 64 | GPUVehicle | | `MAX_WHEELS_PER_VEHICLE` | 8 | GPUVehicle | | `MAX_TRIGGER_EVENTS` | 4096 | GPUTriggerSystem | | `MAX_CCD_PAIRS` | 8192 | GPUContinuousCollision | | `MAX_SOFT_BODY_NODES` | 16384 | GPUSoftBody | | `MAX_SOFT_BODY_TETS` | 32768 | GPUSoftBody | | `MAX_TRIMESH_TRIANGLES` | 65536 | GPUTriangleMesh | | `MAX_TRIMESH_INSTANCES` | 16 | GPUTriangleMesh | | `MAX_HEIGHTFIELD_SIZE` | 1024 | GPUHeightfield | All limits are configurable via constructor options (PhysX 5 GPU pattern: fixed pre-allocated buffers with overflow warnings). ## Pipeline execution order Each physics frame dispatches in this order: (1) CCD expand AABBs, (2) broadphase, (3) narrowphase, (4) heightfield contacts, (5) triangle-mesh contacts, (6) CCD TOI contacts, (7) constraint solver, (8) integration + sleep, (9) trigger & contact events, (10) vehicle forces, (11) soft-body step, (12) character controller, (13) readback positions. Scene queries and raycasts can run at any time (CPU-side, synchronous). ## Design decisions | Decision | Rationale | Source | | --- | --- | --- | | TGS_Soft solver | Sub-stepping + warm starting + soft constraints | Box2D v3 (Catto 2023) | | Delta-position formulation | FP32 stability far from world origin | Erin Catto, GDC 2024 | | Simulation islands (CPU) | Union-find groups for per-island sleep/wake | Jolt, PhysX 5 | | D6 as sole GPU joint | All joint types decompose to D6 — one shader | PhysX 5 GPU best practice | | Spatial hash broadphase | O(1) insert/query, good GPU utilization | GPU Gems 3 Ch.32 | | Fixed buffers | Pre-allocated, overflow warnings, no runtime alloc | PhysX 5 GPU pattern | | PCM contacts | Persistent manifold + local anchors + feature IDs | PhysX 5 eENABLE_PCM | | CPU scene queries | 1–10 queries/frame need synchronous results | PhysX 5 architecture | | Co-rotational FEM | Stable under large deformation, cheaper than Neo-Hookean | Müller, Irving et al. | | BVH for triangle mesh | Median-split AABB tree, iterative GPU traversal | Embree, PhysX | --- # Math Library 350+ pure functions for vectors, matrices, quaternions, geometric primitives, GPU data packing, and interpolation. All exported via `EngineBootstrap.js` and `MathImports.js`. ## Design philosophy - **Pure functions** — no classes, no mutation of inputs; every function returns a new value. - **Array-based** — vectors are `[x, y, z]`, quaternions are `[x, y, z, w]`, matrices are `Float32Array(16)`. - **WebGPU-aligned** — projection matrices use a `[0, 1]` Z-range (not `[-1, 1]` like OpenGL). - **No dependencies** — self-contained, no external math libraries. For binding rules around matrix layout, multiplication order, quaternion order, projection depth, tolerance, and CPU/WGSL parity, see the [Math Contract](math-contract.md). ## Module map | Module | Functions | Purpose | | --- | --- | --- | | `MathVec3.js` | ~30 | 3D vectors: add, sub, scale, dot, cross, normalize, lerp, reflect, project, smoothDamp | | `MathVec2.js` | ~12 | 2D vectors: add, sub, scale, dot, length, normalize, lerp, distance | | `MathQuat.js` | ~15 | Quaternions: slerp, fromAxisAngle, fromEuler, lookAt, multiply, inverse | | `MathMat4.js` | ~15 | 4×4 matrices: perspective, orthographic, lookAt, inverse, multiply, fromRotationTranslation | | `MathScalar.js` | ~8 | Scalar: clamp, lerp, smoothstep, saturate, inverseLerp, remap | | `MathRay.js` | ~20 | Rays: create, intersect (sphere, AABB, plane, triangle, capsule, OBB), transform | | `MathPlane.js` | ~20 | Planes: create, distance, project, intersect (ray, segment, plane), transform | | `MathLine3.js` | ~15 | Line segments: create, closest point (to point, segment, ray), distance | | `MathRect2.js` | ~25 | 2D rectangles: create, contains, intersects, merge, grow, clamp | | `MathDualQuat.js` | ~20 | Dual quaternions: create, multiply, sclerp, transform point, toMat4 (DQS skinning) | | `MathPacking.js` | ~20 | GPU packing: half-float, UNORM/SNORM, RGB9E5, R11G11B10F, octahedral normals | | `MathGeometry.js` | ~20 | Geometry helpers: AABB, sphere, frustum, distance calculations | | `MathColor.js` | ~10 | Color: HSL↔RGB, temperature→RGB, sRGB↔linear | | `MathCurves.js` | ~15 | Curves: bezier, catmull-rom, hermite, arc-length parameterization | | `MathNoise.js` | ~10 | Noise: simplex2D/3D, perlin, FBM, curl noise | ## Quick examples ### Vectors ```javascript import { vec3, vec3Add, vec3Normalize, vec3Cross, vec3Dot } from './engine/MathImports.js'; const a = vec3(1, 0, 0); const b = vec3(0, 1, 0); const sum = vec3Add(a, b); // → [1, 1, 0] const up = vec3Cross(a, b); // → [0, 0, 1] const dot = vec3Dot(a, b); // → 0 const n = vec3Normalize(sum); // → [0.707, 0.707, 0] ``` ### Matrices ```javascript import { mat4PerspectiveRadWebGPU, mat4LookAt, mat4Multiply } from './engine/MathImports.js'; // WebGPU projection (Z range [0,1]) const proj = mat4PerspectiveRadWebGPU(Math.PI / 4, 16 / 9, 0.1, 1000); const view = mat4LookAt([0, 5, 10], [0, 0, 0], [0, 1, 0]); const vp = mat4Multiply(proj, view); ``` ### GPU packing ```javascript import { floatToHalf, packOctNormal, packRGB9E5 } from './engine/core/math/MathPacking.js'; const half = floatToHalf(3.14); // → uint16 const oct = packOctNormal([0, 1, 0]); // → [sn8, sn8] const hdr = packRGB9E5([5.0, 2.0, 0.1]); // → uint32 ``` ### Ray intersection ```javascript import { rayCreate, rayIntersectSphere } from './engine/core/math/MathRay.js'; const ray = rayCreate([0, 0, 5], [0, 0, -1]); const hit = rayIntersectSphere(ray, [0, 0, 0], 1.0); // → { t: 4.0, point: [0,0,1], normal: [0,0,1] } or null ``` --- # Math Contract This page defines the rules new engine, editor, Plauna, AGI, and WebGPU OS code must follow when it uses shared math. It locks the current runtime behavior before MathEngine grows beyond the existing modules. The contract is based on the current source in `engine/core/math/`, `engine/render/CameraMath.js`, and `tests/math-invariants.html`. ## Source of truth | Area | Canonical source | Notes | | --- | --- | --- | | Basic vectors, quaternions, and mat4 helpers | `engine/core/math/EngineMath.js` | Compatibility surface exported through `engine/core/math/index.js`, `engine/MathImports.js`, and `engine/EngineBootstrap.js`. | | Extended matrices | `engine/core/math/MathMat.js` | Mat2/Mat3 and extended Mat4 helpers, including TRS compose/decompose. | | Extended quaternions | `engine/core/math/MathQuat.js` | Quaternion creation, conversion, interpolation, comparison, and orientation helpers. | | Camera projection/view composition | `engine/render/CameraMath.js` | Defaults to WebGPU projection depth for camera rendering. | | Gate 0 invariant tests | `tests/math-invariants.html` | Browser ES module checks for decompose, inverse, look-at, WebGPU depth, quaternion, and camera finite output. | New code should import from the narrow module it needs when possible. Broad app or compatibility surfaces may import from `engine/MathImports.js`. ## Value representation | Value | Representation | Contract | | --- | --- | --- | | Scalar | JavaScript `number` | Use finite values unless the function explicitly documents non-finite handling. | | Vec2 | `[x, y]` | Plain array unless a specific API documents a typed array. | | Vec3 | `[x, y, z]` | Plain array. World up is `[0, 1, 0]` for camera helpers. | | Vec4 | `[x, y, z, w]` | Plain array. | | Quaternion | `[x, y, z, w]` | Identity is `[0, 0, 0, 1]`. `q` and `-q` represent the same orientation. | | Mat3 | `Float32Array(9)` | Column-major. Translation-style 2D mat3 helpers store translation in the final column. | | Mat4 | `Float32Array(16)` | Column-major. Translation lives at indices `12`, `13`, and `14`. | Functions must not mutate input arrays unless the name or signature makes mutation explicit, such as `copy(out, value)`, `set(out, ...)`, `mat4Multiply(a, b, out)`, or `mat4MultiplyInto(out, a, b)`. Mutating the explicit `out` parameter is allowed. (Source: `engine/core/math/EngineMath.js`, `engine/core/math/MathMat.js`, `engine/core/math/MathQuat.js`.) ## Matrix layout and order Mat4 values use column-major storage and column-vector transform semantics. The engine applies the rightmost matrix first. ```javascript const viewProj = mat4Multiply(proj, view); const clip = mat4TransformPoint(viewProj, worldPoint); ``` `viewProj = proj * view` is the camera contract used by `CameraMath.computeViewProjMatrix()`. The same order should be used in render tests and tools. (Source: `engine/render/CameraMath.js`.) When composing transforms, use TRS helpers instead of manual index writes unless the code is a low-level math helper. ```javascript const model = mat4FromRotationTranslationScale(rotation, translation, scale); const { translation, rotation, scale } = mat4Decompose(model); ``` `mat4Decompose()` preserves translation and scale. If any scale axis is zero, near-zero, or non-finite, rotation is not recoverable, so it returns identity rotation `[0, 0, 0, 1]` instead of `NaN`. (Source: `engine/core/math/MathMat.js`; verified by `tests/math-invariants.html`.) ## Coordinate and camera rules | Rule | Contract | | --- | --- | | World up | `[0, 1, 0]` for camera and look-at helpers. | | Camera forward in view space | Negative Z. `mat4LookAt([0,0,5], [0,0,0], [0,1,0])` maps the target to negative Z. | | Transform forward | `mat4GetForward()` treats forward as the negative local Z axis. | | View-projection order | `proj * view`. | | UI and DOM units | Keep DOM/CSS pixel math outside core engine math unless a DOM-specific adapter documents the conversion. | The source currently has both render-facing camera helpers and generic matrix helpers. New camera code should use `engine/render/CameraMath.js` or the WebGPU projection helpers from `EngineMath.js` instead of reimplementing projection math. (Source: `engine/render/CameraMath.js`, `engine/core/math/EngineMath.js`.) ## Projection depth WebGPU render paths must use the WebGPU projection helpers. These map clip-space Z into `[0, 1]`. | Use case | Helper | | --- | --- | | Perspective, radians | `mat4PerspectiveRadWebGPU()` | | Perspective, degrees | `mat4PerspectiveDegWebGPU()` | | Orthographic | `mat4OrthographicWebGPU()` | | Camera default | `computePerspectiveProjection()` with default options | The legacy helpers `mat4PerspectiveRad()`, `mat4PerspectiveDeg()`, and `mat4Orthographic()` use OpenGL-style `[-1, 1]` depth. They remain available for compatibility and explicit OpenGL-depth tests only. They must not be used in WebGPU render passes. (Source: `engine/core/math/EngineMath.js`; verified by `tests/math-invariants.html`.) ## Quaternion rules Quaternions are `[x, y, z, w]`. Rotation quaternions should be normalized before use in transforms, interpolation, and camera code. ```javascript const q = quatNormalize(quatFromAxisAngle([0, 1, 0], Math.PI / 3)); const m = mat4FromQuat(q); const restored = quatNormalize(quatFromRotationMatrix(m)); ``` `quatFromAxisAngle(axis, angle)` does not normalize `axis` for the caller. Pass a normalized axis or normalize the returned quaternion before using it as a rotation. `quatEquals()` and test assertions must treat `q` and `-q` as equivalent orientations. (Source: `engine/core/math/MathQuat.js`.) ## Units and ranges | Category | Contract | | --- | --- | | Angles | Radians by default. Degree helpers include `Deg` in the name. | | Time | Seconds for runtime simulation and animation math unless the caller documents milliseconds. | | Color channels | Normalized linear values for renderer math unless a function explicitly says sRGB or packed format. | | Depth | WebGPU render depth is `[0, 1]`. | | Scale | Zero scale is valid as data, but rotation cannot be recovered from a collapsed axis. | ## Tolerance policy Use `EPSILON` from `engine/core/math/MathConstants.js` as the default scalar tolerance. Use a wider tolerance only when the operation naturally accumulates error, such as matrix inverse, projection, or CPU/GPU parity checks. | Check type | Default tolerance | | --- | --- | | Scalar/vector equality | `EPSILON` or `1e-6` | | Matrix identity after inverse | `1e-4` unless a narrower bound is proven stable | | Projection depth | `1e-5` for CPU-side invariant tests | | Quaternion orientation | Compare absolute dot product near `1` so `q` and `-q` both pass | | GPU parity | Define a per-test tolerance and state why it is wider than CPU tolerance | Do not compare floats with exact equality except for sentinel values and intentional constants. ## Degenerate input policy Math helpers should return finite, documented fallbacks for common degenerate inputs. Current examples: | Input | Expected behavior | | --- | --- | | Zero-length quaternion normalization | Identity quaternion. | | Singular matrix inverse | Identity matrix from current `mat4Inverse()` behavior. | | Zero or near-zero TRS scale in `mat4Decompose()` | Preserve translation/scale, return identity rotation. | | Zero-length look direction | Return identity or documented fallback in the relevant helper. | If a function cannot produce a mathematically unique answer, document the fallback and add an invariant test. Do not return `NaN` for ordinary degenerate gameplay/editor data. ## Determinism and side effects Core math modules must stay browser ES modules with no Node.js, npm, DOM, GPU device, network, or filesystem dependency. They should be worker-safe unless the module name or docs say otherwise. Random and noise helpers must document their seed/source behavior. Deterministic systems should not call ambient random helpers unless they thread a seed or generator through the call. ## WGSL parity Any math helper promoted as shader-safe needs a CPU/WGSL parity test before broad use. Parity tests should cover representative values and edge cases for: - Quaternion rotate and normalize. - Ray, AABB, plane, and triangle intersection. - Packing and unpacking helpers. - SDF primitives. - Deterministic noise snapshots. The JavaScript implementation remains the authoring source until a WGSL mirror is explicitly registered and parity-tested. ## Acceptance checklist Before adding or changing shared math, verify: - The function follows the value representation table. - Matrix code uses column-major `Float32Array` storage and the established multiplication order. - WebGPU render code uses WebGPU projection helpers. - Degenerate inputs either return finite documented fallbacks or throw documented errors. - Tests cover normal and edge cases in `tests/math-invariants.html` or a more specific browser test. - Shader-safe code has or schedules a CPU/WGSL parity test. ## See also - [Math Library](math.md) - [Rendering](rendering.md) - [Shaders & WGSL](shaders.md) - [GPU Device Sharing](../concepts/gpu-device-sharing.md) --- # Audio System A fully procedural audio engine with node-graph synthesis, material-to-sound mapping, spatial audio, and real-time particle-driven sound generation — no pre-recorded samples required. ## Architecture Three execution paths converge on the same patch format: ```text ┌─────────────────────────────────────┐ │ Audio Editor (AudioEditorPanel.js) │ ← main-thread preview │ WebAudioNodeFactory → Web Audio │ ├─────────────────────────────────────┤ │ Worklet Runtime (PatchRunner) │ ← production playback │ NODE_PROCESSORS → AudioWorklet │ ├─────────────────────────────────────┤ │ Particle Bridge │ ← real-time mapping │ ParticleAudioBridge.js → patches │ └─────────────────────────────────────┘ ``` ## Patch system A **patch** is a JSON descriptor defining a node graph of audio generators and processors — the universal currency of the audio system. ```javascript // Example patch: simple sine with envelope { nodes: [ { id: 'osc', type: 'Oscillator', params: { waveform: 'sine', frequency: 440 } }, { id: 'env', type: 'ADSR', params: { attack: 0.01, decay: 0.1, sustain: 0.5, release: 0.3 } }, { id: 'out', type: 'Output' } ], connections: [ { from: 'osc', to: 'env' }, { from: 'env', to: 'out' } ] } ``` ### Node types 30+ node types organized by category: | Category | Node types | | --- | --- | | Generators | Oscillator, Noise, GrainCloud | | Processors | Filter, Delay, Reverb, Compressor, Waveshaper | | Modulators | LFO, ADSR, Envelope, RandomWalk | | Physics models | KarplusStrong, CombFilter, FMOperator, Waveguide, ModalBank | | Atoms | CrackleAtom, HissAtom, RumbleAtom, ImpactAtom | | Output | Output, SoundBlender | ## Material-to-sound mapping `ParticleAudioBridge` maps particle substance properties to audio parameters in real time, so burning, flowing, or colliding particles generate sound procedurally: - **Temperature** → pitch, brightness, crackle intensity. - **Density** → body/weight of the sound. - **Velocity** → whoosh intensity, impact force. - **Phase** → which procedural patch to use (fire, water, wind). ## Spatial audio `SpatialAudioEnvironment.js` provides 3D positional audio with distance attenuation, reverb zones, and environmental effects. Sources are positioned in world space and attenuated by listener distance. ## Synthesis modules - **Waveguide** — bidirectional delay-line physical model for string/tube sounds (damping, reflection, excitation). - **Modal bank** — resonant filter bank with material presets (metal, glass, wood) using Bessel zeros for accurate modal frequencies. - **Noise generator** — 8 noise colors via Voss-McCartney: white, pink, brown, blue, violet, velvet, grey, crackle. ## Key files | File | Purpose | | --- | --- | | `audio/synth/WebAudioNodeFactory.js` | Main-thread node creation (30+ types) | | `audio/synth/NodeRegistry.js` | Node type registry and categories | | `audio/synth/nodes/WaveguideNode.js` | Physical modeling waveguide | | `audio/synth/nodes/ModalBankNode.js` | Resonant modal bank | | `audio/bridge/SubstanceAudioResolver.js` | Material→audio parameter mapping | | `sim/particles/ParticleAudioBridge.js` | Particle→audio bridge | | `audio/SpatialAudioEnvironment.js` | 3D spatial audio | --- # Engine The WebGPU runtime foundation of the stack. Source: `engine/`. ## In this section - [Overview](overview.md) — what the engine is and its modules. - [Architecture](architecture.md) — how core, ECS, render, sim, net, and gameplay compose. - [Getting Started](getting-started.md) — bootstrap entry points and minimal flow. ### Deep dives - [Virtual GPU (vGPU)](vgpu.md) — the GPU abstraction every system builds on. - [ECS v2](ecs.md) — worlds, entities, components, systems, archetype storage. - [Rendering](rendering.md) — the multi-pass pipeline, lighting, and compositing. - [MorphField R2](morphfield.md) — semantic fields, compiled Fieldlets, certified queries, assets, renderer contracts, and the gate-controlled delivery checklist. - [Shaders & WGSL](shaders.md) — modular shaders, the composer, and the preprocessor. - [Particle System](particles.md) — GPU particles, matter states, and the sim pipeline. - [Galaxy Mythic Spiral Atlas](galaxy-mythic-spiral-atlas.md) — adaptive orbital tracers, dust extinction, and fantasy spiral studies. - [Curl Noise Flow Atlas](curl-noise-flow-atlas.md) — packed GPU tracers and compute-density flow art. - [Kuramoto Resonance Field](kuramoto-resonance-field.md) — CPU and GPU phase-oscillator labs with high-count HDR visualization. - [Physics & Simulation](physics.md) — cloth, rope, fluids, and rigid bodies. - [GPU Physics Engine](gpu-physics.md) — WebGPU compute physics with PhysX 5 parity. - [Math Library](math.md) — 350+ pure vector/matrix/quaternion/packing functions. - [Math Contract](math-contract.md) — required matrix, quaternion, projection, tolerance, and parity rules for shared math. - [Audio](audio.md) — procedural node-graph synthesis and particle-driven sound. ### Reference - **API Reference** — per-file symbol reference generated from source by `tools/extract_api.py` (browse `engine/reference/`). ## Module map ```text engine/ core/ GPU device, frame graph/pipeline, math, memory, scheduler, save, workers, ResourceManager ecs/ EntityManager, EntitySchema, ComponentHealer, components, systems, query, storage, prefabs, world render/ renderers, materials, passes, lighting, culling, post-process, sdf, volumes, particles sim/ SimulationUpdate + physics, particles, fluids, cloth, ai, world net/ protocol, replication, client, server collab/ multi-user mesh (identity, integrity, presence, sync) audio/ audio core, synth, spatial animation/ animation systems gameplay/ rules (RuleGraph), events (EventGraph), ai, narrative, perception voxel/ world/ voxel + world systems resources/ resource/package system mod/ scripting API + sandbox ui/ tools/ runtime UI, inspector/profiler compat/ asset importers / compatibility ``` ## Related concepts - [GPU Device Sharing](../concepts/gpu-device-sharing.md) - [Data Flow](../concepts/data-flow.md) --- # Editor Overview The editor (`editor/`) is the scene and asset authoring IDE built on the engine. It was the first major application on top of the runtime and established the panel/workbench and project-filesystem patterns that Plauna and the OS later generalized. ## What it provides - A viewport for editing scenes against the engine's renderer. - Dockable panels (inspector, hierarchy, asset/material tools). - A project/filesystem abstraction (`editor/js/ProjectManager.js`). - Gizmos, spawnables, and material authoring. ## Audience Content creators authoring scenes/assets, and tools developers extending the editor. ## Layout | Path | Purpose | | --- | --- | | `editor/index.html` | The editor shell page. | | `editor/js/main.js` | Entry point. | | `editor/js/EditorApp.js` | The main application class (large; orchestrates panels, viewport, project). | | `editor/js/ProjectManager.js` | Project / filesystem abstraction. | | `editor/js/components/` | UI components. | | `editor/js/panels/` | Dockable editor panels. | | `editor/js/viewport/` | The 3D viewport. | | `editor/js/gizmos/` | Transform/manipulation gizmos. | | `editor/js/spawnables/` | Spawnable entity definitions. | | `editor/js/modules/` | Feature modules. | | `editor/js/project/` | Project data/handling. | | `editor/js/themes/` | Editor theming. | | `editor/js/utils/` | Utilities. | | `editor/js/workers/` | Web workers. | | `editor/mats/` | Materials. | ## Relationship to the engine and Plauna - The editor bootstraps through `engine/EngineEditorBootstrap.js`. - Plauna can **enhance** existing editor panels without replacing them (`plauna.enhanceExistingPanels(...)`), sharing the same VGPU instance and ECS patterns. See [Plauna Overview](../plauna/overview.md). ## Next steps - [Editor Architecture](architecture.md). - [Editor Getting Started](getting-started.md). - Editor **API Reference** — generated from `editor/js/` by `tools/extract_api.py`. --- # Editor Architecture How the editor is organized. The editor is a single-page application whose `EditorApp` orchestrates the viewport, panels, and project state on top of the engine. ## Structure ```mermaid flowchart TD html[editor/index.html] --> main[js/main.js] main --> app[EditorApp.js] app --> viewport[viewport/] app --> panels[panels/] app --> project[ProjectManager + project/] app --> gizmos[gizmos/] app --> spawnables[spawnables/] app --> modules[modules/] viewport --> engine[(Engine\nVGPU + renderer)] app -. enhanced by .-> plauna[(Plauna panels)] ``` ## Key pieces - **`EditorApp.js`** — the central application object. It wires panels, the viewport, project lifecycle, and editor modules together. (It is the largest file in the editor; treat the generated API reference as the index of its surface.) - **`main.js`** — boots the editor and constructs `EditorApp`. - **`ProjectManager.js` + `project/`** — the project/filesystem abstraction the OS later generalizes into its storage layer. - **`viewport/`** — renders the editable scene using the engine's renderer and VGPU. - **`panels/`** — dockable UI panels (hierarchy, inspector, asset tools). These are the panels Plauna can enhance. - **`gizmos/`** — transform and manipulation handles in the viewport. - **`spawnables/`** — entity templates that can be placed into a scene. - **`modules/`** — discrete feature modules. - **`workers/`** — offloaded work via Web Workers. - **`themes/`** — editor visual themes. ## Integration points - **Bootstrap:** `engine/EngineEditorBootstrap.js` brings up the engine and exposes Plauna as `PE.Plauna`. - **Plauna enhancement:** existing panels are passed to `plauna.enhanceExistingPanels(panels)` for hybrid DOM/GPU upgrades, sharing the editor's VGPU. - **As an OS app:** the editor is one of the userland apps the OS re-wraps as a Plauna panel (Source: `webgpu-os/AUDIT.md`). ## See also - [Plauna Architecture](../plauna/architecture.md) — the panel/surface system the editor feeds into. - Editor **API Reference** — per-file symbols from `editor/js/`. --- # Editor Getting Started Open the editor and learn where things live. Assumes [Install & Run](../getting-started/install.md) is done. ## Launch ```bash python start_server.py # then browse to: # http://127.0.0.1:9001/editor/ ``` The page (`editor/index.html`) loads `js/main.js`, which constructs `EditorApp` and mounts the viewport and panels. ## Orientation | You want to… | Look at | | --- | --- | | Understand the app shell | `editor/js/EditorApp.js` | | Add/modify a panel | `editor/js/panels/` | | Work on the 3D viewport | `editor/js/viewport/` | | Add a placeable entity | `editor/js/spawnables/` | | Manipulate transforms | `editor/js/gizmos/` | | Handle projects/files | `editor/js/ProjectManager.js`, `editor/js/project/` | | Author materials | `editor/mats/` | ## Extending the editor - New features are typically added as **modules** (`editor/js/modules/`) or **panels** (`editor/js/panels/`). - For hybrid DOM/GPU panel upgrades, enhance panels via Plauna (`plauna.enhanceExistingPanels`). See [Plauna Getting Started](../plauna/getting-started.md). ## See also - [Editor Architecture](architecture.md). - Editor **API Reference** (run `tools/extract_api.py`). --- # Editor Scene and asset authoring IDE built on the engine. Source: `editor/`. ## In this section - [Overview](overview.md) — what the editor is and its layout. - [Architecture](architecture.md) — `EditorApp` orchestration and integration points. - [Getting Started](getting-started.md) — launch and orientation. - **API Reference** — per-file symbols from `editor/js/` (browse `editor/reference/`). ## Module map ```text editor/ index.html editor shell page js/ main.js entry point EditorApp.js main application class ProjectManager.js project/filesystem abstraction components/ UI components panels/ dockable panels viewport/ 3D viewport gizmos/ transform gizmos spawnables/ placeable entity templates modules/ feature modules project/ project data/handling themes/ editor themes utils/ utilities workers/ web workers mats/ materials ``` ## Related - [Plauna](../plauna/index.md) — the UI framework that enhances editor panels. - [Engine](../engine/index.md) — the runtime the editor renders with. --- # Plauna Overview Plauna (`plauna/`) is a browser-first **hybrid DOM/GPU UI framework** and workbench. It extends the engine with advanced UI: DOM-free text measurement, GPU surfaces, a dockable workspace, and ECS-driven UI state. It is the compositor/window-manager foundation the WebGPU OS shell is built on. ## What it provides From `plauna/README.md`: - **Hybrid rendering** — DOM, DOM+GPU, and pure-GPU modes. - **Text engine** — DOM-free text measurement/layout (Pretext-style). - **Surface graph** — GPU-accelerated surfaces with clipping, warping, composition. - **Workbench layout** — dockable panels, tabs, splitters, floating windows. - **ECS integration** — a dedicated UI world with component-driven state. - **Zero dependencies** — pure ES modules, no build step. ## Audience UI and app developers. OS shell developers depend on Plauna's workspace/surface/widget systems. ## Rendering modes | Mode | Use for | | --- | --- | | **DOM** | Standard UI (inspector, forms, menus); full CSS/accessibility/text editing. | | **DOM+GPU** | Viewports with GPU overlays; DOM structure + GPU visuals. | | **GPU** | Warped/particle-reactive UI; pure WGSL rendering for performance-critical visuals. | ## Module map | Module | Path | Purpose | | --- | --- | --- | | Core | `plauna/core/` | `app`, `UINode`, `VisualTree`, `DOMRenderer`, `BindingEngine`, `StateStore`, `DirtyGraph`, `registry`, `events`, `ModuleTester` | | Layout | `plauna/layout/` | layout engine | | Surface | `plauna/surface/` | GPU surface management | | Workspace | `plauna/workspace/` | workspaces, panels, splitters, compositor, switcher | | Widgets | `plauna/widgets/` | UI atoms (Primitive, Form, Navigation, DataViews, Layout, Feedback) | | Text | `plauna/text/` | DOM-free text measurement/layout | | Input | `plauna/input/` | input devices/handling | | Motion | `plauna/motion/` | animation/motion | | Themes / Style | `plauna/themes/`, `plauna/style/`, `plauna/styles/` | design tokens + CSS | | Particle | `plauna/particle/` | VGPU bridge for GPU UI | | Notifications | `plauna/notifications/` | notification system / toasts | | Console | `plauna/console/` | dev REPL / system console | | Showcase / Lab | `plauna/showcase/`, `plauna/lab/` | demos / experiments | | Editor / ECS | `plauna/editor/`, `plauna/ecs/` | editor integration, UI components | ## UI ECS components Plauna defines UI components that integrate with the engine's ECS: `UIRoot`, `UIWorkspace`, `UIZone`, `UIView`, `UILayout`, `UISurface`, `UIText`. ## Next steps - [Plauna Architecture](architecture.md). - [Plauna Getting Started](getting-started.md). - Plauna **API Reference** — generated from `plauna/` by `tools/extract_api.py`. --- # Plauna Architecture How Plauna renders and manages UI. State lives in a UI ECS world; a visual tree is reconciled to DOM and/or GPU surfaces through a dirty-tracking pipeline. ## Rendering pipeline ```mermaid flowchart TD state[StateStore\nUI ECS components] --> binding[BindingEngine] binding --> tree[VisualTree / UINode] tree --> dirty[DirtyGraph\nchange tracking] dirty --> dom[DOMRenderer] dirty --> surface[SurfaceManager\nGPU surfaces] surface --> bridge[particle/bridge\nVGPU] bridge --> gpu[(Shared WebGPU device)] ``` ## Core (`plauna/core/`) - **`app.js`** — `PlaunaApp`, the top-level application object (`createPlaunaApp(options)`). - **`UINode.js` / `VisualTree.js`** — the retained UI tree. - **`StateStore.js`** — UI state container. - **`BindingEngine.js`** — binds state to the visual tree. - **`DirtyGraph.js`** — tracks what changed so only dirty regions re-render. - **`DOMRenderer.js`** — renders the tree to DOM. - **`registry.js` / `events.js`** — view/surface registry and event system. - **`ModuleTester.js`** — module self-tests. ## Surfaces and the GPU bridge - `surface/` manages renderable surfaces (rect/warped, interactive, hit-testable). - `particle/bridge.js` bridges surfaces to the engine's VGPU, so GPU UI shares the single device. See [GPU Device Sharing](../concepts/gpu-device-sharing.md). ## Workspace (the window manager) `workspace/` provides `WorkspaceManager`, `Workspace`, `Panel`, `PanelLayout`, `WorkspaceCompositor`, and `WorkspaceSwitcher`. **Every OS window is a Plauna panel** — the OS shell (`webgpu-os/shell/`) builds its desktop/taskbar on top of this. (Source: `webgpu-os/AUDIT.md`.) ## Text engine `text/` measures and lays out text **without the DOM** (Pretext-style), enabling GPU-rendered text and accurate layout in non-DOM surfaces. Public API: `prepare(text, style)`, `layout(handle, width, lineHeight)`, `measureElement(el)`, `invalidateFont(key)`. ## Integration with the engine and editor - Bootstraps via `engine/EngineEditorBootstrap.js` (`initializePlauna(...)`, exposed as `PE.Plauna`). - Uses the existing VGPU instance and ECS patterns — no separate device. - Can enhance existing editor panels incrementally (`enhanceExistingPanels`). ## See also - [Plauna Overview](overview.md) — rendering modes and module map. - [WebGPU OS Architecture](../webgpu-os/architecture.md) — how the shell consumes Plauna. - Plauna **API Reference**. --- # Plauna Getting Started Initialize Plauna and create UI. This mirrors the examples in `plauna/README.md`. Assumes [Install & Run](../getting-started/install.md) is done. ## Initialize Plauna bootstraps through the engine's editor bootstrap: ```javascript import { initializePlauna } from './engine/EngineEditorBootstrap.js'; const plauna = await initializePlauna({ root: document.getElementById('plauna-root'), getVGPU: () => viewport.vgpu, // reuse the shared GPU device engine: window.ParticleEngine, editor: editorApp, // optional useCSS: true, textEngine: 'pretext', }); ``` `PlaunaApp` options: | Option | Meaning | | --- | --- | | `root` | DOM element for the Plauna root. | | `getVGPU` | Function returning the VGPU instance to share. | | `engine` | The engine instance. | | `editor` | An `EditorApp` instance (optional). | | `useCSS` | Load Plauna CSS (default `true`). | | `textEngine` | Text engine to use (default `'pretext'`). | ## Measure text without the DOM ```javascript const handle = plauna.textService.prepare('Hello, world!', { fontFamily: 'Inter', fontSize: 16, fontWeight: 400, }); const layout = plauna.textService.layout(handle, 300, 24); console.log(`Lines: ${layout.lineCount}, Height: ${layout.height}px`); ``` ## Create a GPU surface ```javascript const surface = plauna.createSurface({ id: 'viewport-surface', kind: 'viewport', shape: 'rect', interactive: true, }); ``` ## Enhance existing editor panels ```javascript await plauna.enhanceExistingPanels(editorApp.panels); ``` ## Choosing a rendering mode - **DOM** for text-heavy, accessible UI. - **DOM+GPU** for panels with GPU visuals. - **GPU** for warped/particle-reactive, performance-critical UI. ## See also - [Plauna Architecture](architecture.md). - Plauna **API Reference** — `core/app`, `surface/`, `text/`, `widgets/`. --- # Plauna Hybrid DOM/GPU UI framework and workbench. Source: `plauna/`. ## In this section - [Overview](overview.md) — features, rendering modes, module map. - [Architecture](architecture.md) — the state → visual tree → DOM/GPU pipeline. - [Getting Started](getting-started.md) — initialize, measure text, create surfaces. - **API Reference** — per-file symbols from `plauna/` (browse `plauna/reference/`). ## Module map ```text plauna/ core/ app (PlaunaApp), UINode, VisualTree, DOMRenderer, BindingEngine, StateStore, DirtyGraph, registry, events, ModuleTester layout/ layout engine surface/ GPU surface management workspace/ workspaces, panels, splitters, compositor, switcher widgets/ UI atoms (Primitive, Form, Navigation, DataViews, Layout, Feedback) text/ DOM-free text measurement/layout input/ input handling motion/ animation/motion themes/ style/ styles/ design tokens + CSS particle/ VGPU bridge for GPU UI notifications/ toasts/notifications console/ dev REPL / system console showcase/ lab/ demos + experiments editor/ ecs/ editor integration + UI components ``` ## Related - [WebGPU OS](../webgpu-os/index.md) — the shell built on Plauna workspaces. - [GPU Device Sharing](../concepts/gpu-device-sharing.md). --- # AGI Overview AGI (`agi/`) is a reinforcement-learning **animation rigging** system: a "Doc Octavius"-style mechanical **parasite rig** that injects into a humanoid ragdoll and learns to control it through RL. It ships its own WebGPU **tensor library**, neural networks, a curriculum system, and **AGI Studio** — a full training workspace application. ## What it provides From `agi/README.md`: - A custom **WebGPU tensor library** (`agi/tensor/`) with compute shaders (matmul, activation, reduction) and automatic differentiation. - **Neural networks** (`agi/brain/`): policy + value networks, PPO trainer, experience buffer, optimizers, losses. - **Core RL control** (`agi/core/`): ragdoll controller, observation builder, motor controller, reward function, curriculum manager, motion-matching teacher. - A **parasite rig** visual system (`agi/rig/`): brain sphere, 17 tentacles, neural pulses, injection animation. - **AGI Studio** (`agi/studio/`): a workspace app with panels, editors, visualizers, and tools. ## Audience ML and animation developers training or extending the rig. ## How it works (RL loop) ```mermaid flowchart LR ragdoll[Ragdoll\nPBD physics] --> obs[ObservationBuilder\n12D observation] obs --> policy[Policy network] policy --> action[MotorController\n17D action] action --> ragdoll ragdoll --> reward[RewardFunction] reward --> ppo[PPOTrainer\nclipped surrogate] ppo --> policy curriculum[CurriculumManager\n7 stages] --> reward ``` - **Observation space (12D):** pelvis height, uprightness, angular velocity (3D), linear velocity (3D), ground contact (2D), target direction (2D). - **Action space (17D):** one impulse-based action per controllable bone, range `[-1, 1]`. - **Algorithm:** PPO (clipped surrogate objective) with GAE. ## Module map | Module | Path | Purpose | | --- | --- | --- | | Core | `agi/core/` | RagdollController, ObservationBuilder, MotorController, RewardFunction, CurriculumManager, MotionMatchingTeacher | | Brain | `agi/brain/` | policy/value networks, PPO trainer, optimizers, losses, training utils | | Tensor | `agi/tensor/` | WebGPU tensor ops + compute shaders | | Rig | `agi/rig/` | parasite rig visuals (injection, tentacles, brain) | | Scene | `agi/scene/` | training scene, ground, camera, renderer, debug | | Studio | `agi/studio/` | the AGI Studio workspace app | | Runtime | `agi/runtime/` | runtime manager | | API | `agi/api/` | Gym-compatible environment API | | Adapters | `agi/adapters/` | multi-runtime adapters (WebGPU, Python, WASM, Rust, C++) | | Loader / Config / Data | `agi/loader/`, `agi/config/`, `agi/data/` | model loading, hyperparameters/curriculum/rewards, data | ## Next steps - [AGI Architecture](architecture.md). - [AGI Getting Started](getting-started.md). - [Training Guide](training-guide.md). - AGI **API Reference** — generated from `agi/`. --- # AGI Architecture How AGI is layered: a WebGPU tensor library at the bottom, neural networks above it, an RL control loop on top, and the rig visuals + Studio around it. ## Layers ```mermaid flowchart TD tensor[tensor/\nWebGPU tensors + compute shaders\n+ autodiff] --> brain[brain/\npolicy + value nets, PPO, optimizers, losses] brain --> core[core/\nRagdoll, Observation, Motor, Reward, Curriculum] core --> scene[scene/\ntraining env, camera, renderer] core --> rig[rig/\nparasite visuals] scene --> studio[studio/\nAGI Studio app] rig --> studio api[api/ Gym-compatible] --> core adapters[adapters/\nWebGPU/Python/WASM/Rust/C++] --> core ``` ## Tensor library (`agi/tensor/`) A zero-dependency tensor implementation on WebGPU: - Operations including softmax, layernorm, dropout. - A compute graph for chaining operations. - WebGPU compute shaders in `tensor/shaders/` (matmul, activation, reduction). - Automatic differentiation (gradient tape) and a tensor cache for memory management. ## Neural networks (`agi/brain/`) - **Policy network** (12→64→64→17, tanh) and **value network** (12→64→64→1, linear). - **PPO trainer** (`brain/trainers/`), **optimizers** (Adam/AdamW/SGD), **losses** (policy/value/entropy), and training **utils** (GAE, normalizer, scheduler). - Forward/backward passes and network serialization (save/load). ## RL control (`agi/core/`) - **`RagdollController.js`** — the main training loop driving episodes. - **`ObservationBuilder.js`** — builds the 12D observation each step. - **`MotorController.js`** — applies the 17D action as bone impulses. - **`RewardFunction.js`** — configurable reward weights. - **`CurriculumManager.js`** — advances through the 7 training stages. - **`MotionMatchingTeacher.js`** — motion-matching guidance. ## Scene and rig - `scene/` — training scene controller, infinite grid ground, tracking camera, WebGPU scene renderer, debug visualizer. - `rig/` — brain sphere with pulse animation, the 17-tentacle injection system, tentacle renderer (curved paths, electrical effects), and neural-activity visualization. ## Studio (`agi/studio/`) A professional workspace app: core (`StudioApp`, project/workspace managers), panels (Scene/Training/Network/Curriculum), visual editors (Reward/Network/Curriculum/Action), visualizers (Graph/Network/Activation/Gradient), and tools (Exporter/Recorder/Benchmarker/Debugger). ## Multi-runtime + API - `api/` exposes a Gym-compatible environment interface. - `adapters/` provides optional WebGPU/Python/WASM/Rust/C++ runtime adapters. ## Performance targets Physics 60 FPS (16.67 ms), neural inference < 5 ms/forward pass, rendering < 8 ms/frame, total memory < 1 GB. ## See also - [Training Guide](training-guide.md). - AGI **API Reference** — `core/`, `brain/`, `tensor/`, `rig/`. --- # AGI Getting Started Launch AGI Studio and start a training run. Based on `agi/README.md`. Assumes [Install & Run](../getting-started/install.md) is done. ## Requirements - A current browser that exposes WebGPU on the machine. Verify both `navigator.gpu` and a successful `navigator.gpu.requestAdapter()` call. - 8 GB RAM minimum (16 GB recommended); a dedicated GPU recommended. ## Launch AGI Studio ```bash python start_server.py # then browse to: # http://127.0.0.1:9001/agi/studio/ ``` ## First run 1. **Create or load a project** — click **New Project** in the header. The system initializes with default settings and configures the WebGPU device. 2. **Start training** — click **Start Training** in the viewport controls. The parasite rig injects into the ragdoll; metrics update live; training runs at 60 FPS. 3. **Save your model** — click **Save Model**; the model downloads as JSON. Load it later to continue. ## Default hyperparameters | Parameter | Value | | --- | --- | | Learning rate | 3e-4 | | Clip range | 0.2 | | Gamma | 0.99 | | Lambda (GAE) | 0.95 | | Batch size | 64 | | Buffer size | 2048 | ## Next steps - [Training Guide](training-guide.md) — stages, tuning, troubleshooting. - [AGI Architecture](architecture.md) — how the pieces connect. - AGI **API Reference** — `core/RagdollController`, `brain/`, `tensor/`. --- # AGI Training Guide How to train the parasite rig from standing to full locomotion, and how to fix common problems. Condensed from `agi/README.md` and `agi/TRAINING_GUIDE.md`. ## Curriculum stages Training uses curriculum learning with 7 progressive stages. The `CurriculumManager` advances automatically as criteria are met. | # | Stage | Approx. time | Goal | | --- | --- | --- | --- | | 1 | Standing | 1–2 h | Stand upright for 10 s | | 2 | Balance Recovery | 2–3 h | Recover from random perturbations | | 3 | Walking Forward | 4–6 h | Walk at 1 m/s sustained | | 4 | Directional Control | 6–8 h | Walk toward target positions | | 5 | Obstacle Navigation | 8–12 h | Navigate around obstacles | | 6 | Dynamic Terrain | 12–16 h | Walk on slopes up to 30° | | 7 | Full Locomotion | 16–24 h | Run, jump, turn, crouch | **Total:** ~24–72 h for complete mastery. ## The training loop Each step: 1. `ObservationBuilder` reads the ragdoll into a 12D observation. 2. The policy network outputs a 17D action. 3. `MotorController` applies the action as bone impulses. 4. PBD physics advances; `RewardFunction` scores the result. 5. Experience is buffered (with GAE); `PPOTrainer` updates the policy. ## Tuning tips - **Reward shaping** — adjust weights in `agi/config/` (or the Studio Reward editor). Increasing the uprightness weight helps early stages. - **Buffer/batch size** — larger buffers stabilize updates but use more memory. - **Curriculum pacing** — if a stage stalls, verify its advancement criteria before moving on. ## Troubleshooting **Ragdoll not learning?** - Confirm WebGPU is available in the browser. - Verify physics is running at 60 FPS. - Increase the uprightness reward weight. **Performance issues?** - Close other browser tabs. - Reduce buffer size (default 2048). - Disable debug visualizations. - Check GPU utilization. **Browser crashes?** - Reduce buffer size. - Clear the tensor cache. - Save the model frequently. ## See also - [AGI Getting Started](getting-started.md). - [AGI Architecture](architecture.md). - AGI **API Reference** — `core/RewardFunction`, `core/CurriculumManager`, `brain/trainers/`. --- # AGI Reinforcement-learning animation rigging ("parasite rig") with a WebGPU tensor library and AGI Studio. Source: `agi/`. ## In this section - [Overview](overview.md) — what AGI is and how the RL loop works. - [Architecture](architecture.md) — tensor → brain → core → scene/rig → studio. - [Getting Started](getting-started.md) — launch Studio and start training. - [Training Guide](training-guide.md) — curriculum, tuning, troubleshooting. - **API Reference** — per-file symbols from `agi/` (browse `agi/reference/`). ## Module map ```text agi/ core/ RagdollController, ObservationBuilder, MotorController, RewardFunction, CurriculumManager, MotionMatchingTeacher brain/ policy/value networks, PPO trainer, optimizers, losses, utils tensor/ WebGPU tensors + compute shaders (matmul/activation/reduction) + autodiff rig/ parasite visuals (injection, tentacles, brain) scene/ training scene, ground, tracking camera, renderer, debug studio/ AGI Studio app (core, panels, editors, visualizers, tools) runtime/ runtime manager api/ Gym-compatible environment API adapters/ WebGPU/Python/WASM/Rust/C++ loader/ config/ data/ model loading, hyperparameters/curriculum/rewards, data ``` ## Related - [GPU Device Sharing](../concepts/gpu-device-sharing.md) — the tensor library runs on the shared device. - [Engine](../engine/index.md) — AGI is built on Engine v2. --- # WebGPU OS Overview WebGPU OS (`webgpu-os/`) is the composition layer that turns the engine, Plauna, AGI, and editor into a **GPU-first, desktop-like OS that boots in a single browser tab**. It provides a kernel, a shell, a signed package system, storage, drivers, and a runtime app catalog. > **Composition, not forking:** the OS consumes `engine/`, `plauna/`, `agi/`, and `editor/` as libraries. Fixes go upstream, not into the glue layer. (Source: `webgpu-os/AUDIT.md` §4.) ## What it is (and isn't) - **Is:** a secure, GPU-accelerated **app platform** with a web-native developer experience — closer to OS.js + WebContainers + WASI than to a native game launcher. - **Isn't:** a Steam-class native-game platform. Browser sandboxing rules out native overlays/input. (Source: `AUDIT.md` §1.) ## Tier 1 today The current implementation is **Tier 1 — browser-resident**. Tier 2 (Rust + Wasmtime/WASI host wrapping Dawn/wgpu) is a documented migration path; Tier 3 (native microkernel) is research-only. See [Architecture Overview](../concepts/architecture-overview.md) for the tier framing and the stable Tier 2 migration contract. ## Subsystems | Subsystem | Path | Purpose | | --- | --- | --- | | Kernel | `webgpu-os/kernel/` | syscalls, scheduling, GPU mediation, trust, permissions, theming, surfaces, logging, FS | | Shell | `webgpu-os/shell/` | desktop, taskbar, start menu, windows, dialogs, notifications | | Packages | `webgpu-os/packages/` | `.prpkg` build/sign/verify/install/update, capability map | | Storage | `webgpu-os/storage/` | virtual FS over OPFS/IndexedDB/cache/mounts, per-app sandbox | | Drivers | `webgpu-os/drivers/` | audio, crypto, net, profile, web-surface | | Browser bridge / extension | `webgpu-os/browser-bridge/`, `browser-extension/` | native browser integration + adblock relay | | Apps | `webgpu-os/apps/` | 35 runtime-discovered apps (see [App Catalog](app-catalog.md)) | | AppForge | `webgpu-os/appforge/` | deterministic part registry, tags, services, context graph, commands, layouts, blueprints, packages, timeline, lenses, starter packs, and builder | ## Key documents (read-only sources) - `webgpu-os/AUDIT.md` — asset inventory, tiers, folder layout, security model. - `webgpu-os/ROADMAP.md` — phased delivery plan. - `webgpu-os/RESEARCH.md` — source research. - `webgpu-os/docs/` — `ARCHITECTURE`, `PACKAGING`, `PERMISSIONS_MODEL`, `APP_MANIFEST_SPEC`. - [AppForge Contracts](appforge-contracts.md) — modular public contracts layered over the current kernel, package, permission, app, and Plauna systems. ## Next steps - [Architecture](architecture.md) — kernel, shell, packages, storage. - [AppForge Contracts](appforge-contracts.md) — deterministic registry, assembly, context, layout, package export, timeline, lens, pack, and builder contracts. - [Getting Started](getting-started.md) — boot and build an app. - [App Catalog](app-catalog.md) — every shipped app. - WebGPU OS **API Reference** — generated from `kernel/`, `shell/`, `packages/`, `storage/`, `drivers/`. --- # WebGPU OS Architecture The kernel, shell, package system, storage, and drivers — and how an app moves from a folder or `.prpkg` to a running, capability-gated panel. ## Layout ```mermaid flowchart TD boot[boot.js / index.js\nbootWebGpuOS] --> kernel[kernel/] kernel --> shell[shell/\nDesktop, Taskbar, StartMenu] kernel --> packages[packages/\nPackageManager, Loader, Verifier, Update] kernel --> storage[storage/\nVirtualFS, OPFS, IndexedDB, Sandbox] kernel --> appforge[appforge/\nRegistry, Services, Context, Layout, Factory] kernel --> drivers[drivers/\nAudio, Crypto, Net, Profile, WebSurface] appforge --> apps shell --> apps[apps/\nruntime-discovered] packages --> apps ``` ## Kernel (`webgpu-os/kernel/`) The privileged core. Notable components: - **`KernelBootstrap.js`** — brings up kernel services in order: `TrustStore.init()` → `PackageManager.init()` → `PatchManager` → `UpdateManager`. - **`Syscalls.js`** — the syscall surface exposed to apps; `guardSyscalls()` wraps them with capability checks; `auditSyscallGuards()` reports coverage. This is a **stable Tier 2 contract**. - **`AppRegistry.js` / `ModRegistry.js`** — discover apps/mods at runtime. - **`Permissions.js` / `PermissionPortal.js` / `PermissionStore.js`** — capability resolution, consent UI, persisted grants. - **`TrustStore.js` / `ProvenanceChecker.js` / `SigningLineage.js`** — trust roots, pinning, provenance. - **`RuleGraph.js`** — Tier 1 capability-gate stand-in. - **`SecurityDoctor.js`** — full posture report. - **GPU mediation:** `GpuDeviceBroker.js`, `GpuInfo.js`, `VRAMTracker.js` (see [GPU Device Sharing](../concepts/gpu-device-sharing.md)). - **Buses:** `CommandBus.js`, `FxBus.js`, `PatchBus.js`. - **Surfaces/theme/sound:** `SurfaceManager.js`, `SubsurfaceManager.js`, `ThemeEngine.js`, `UiSounds.js`, `AmbientEngine.js`. - **Misc:** `VirtualFS.js`, `OsLogger.js`, `ProcessTable.js`, `SessionStore.js`, `SearchManager.js`, `RuntimeModeManager.js`, `net-safety.js`. ## AppForge (`webgpu-os/appforge/`) AppForge is a modular composition layer over the existing OS. It keeps `AppRegistry`, `CommandBus`, `Permissions`, `PackageManager`, `PackageHostRealm`, Desktop, and Plauna panels as the backing runtime, then adds folders for definitions, registry, tags, scoring, services, context graph, command objects, layout zones, blueprints, package exports, timeline, lenses, starter packs, and the visual workspace builder. See [AppForge Contracts](appforge-contracts.md) for the public API and security invariants. ## Shell (`webgpu-os/shell/`) The desktop UI, built on Plauna workspaces (every window is a Plauna panel): - **`Desktop.js`** — the compositor/window manager; `_launchPanel` wraps an app's syscalls with `guardSyscalls`, `_resolveEntryModule` routes `pkg:` entries to the package loader. - **`Taskbar.js`, `StartMenu.js`, `StatusTray.js`** — shell chrome. - **`DialogManager.js`, `NotificationCenter.js`** — dialogs + notifications. - **`PackageHostRealm.js`** — host realm for packaged apps. - **`WindowSizer.js`, `WindowStateStore.js`, `app-icon.js`** — window sizing/state/icons. ## Packages (`webgpu-os/packages/`) The `.prpkg` v2 system (encrypted ZIP container + cross-verified public envelope): ```mermaid flowchart LR build[PackageBuilder] --> sign[PackageCrypto\nsign] sign --> verify[PackageVerifier\n+ verifyAndAuthorize] verify --> install[PackageManager\ninstall] install --> load[PackageLoader\npkg: from OPFS] ``` - **`PackageManager.js`** — install/remove/verify/rollback; the `verifyAndAuthorize()` choke point chains integrity → trust → provenance → scan → policy → verdict. - **`PackageLoader.js`** — loads installed apps from OPFS as a blob-URL module graph (patch-overlay aware). - **`PackageBuilder/Crypto/Verifier/Scanner/Registry.js`** — build, sign, verify, scan, register. - **`UpdateManager.js`** — differential updates with anti-rollback + version cooldown. - **`AppCompiler.js`, `FolderIngestor.js`, `CapabilityMap.js`, `PublisherKeyManager.js`, `Zip.js`, `Gzip.js`** — supporting tools. See [Security & Trust Model](../concepts/security-model.md) for the trust pipeline. ## Storage (`webgpu-os/storage/`) Virtual filesystem over browser primitives: `VirtualFS`/`SystemFS` (syscall-facing), `OPFSDriver`, `IndexedDBDriver`, `MountDriver`, `CacheDriver`, `AppSandbox` (per-app isolation), `StorageManager` (orchestration). See [Data Flow](../concepts/data-flow.md). ## Drivers (`webgpu-os/drivers/`) `AudioDriver`, `CryptoDriver`, `NetDriver`, `ProfileDriver`, `WebSurfaceDriver`. The browser bridge (`browser-bridge/`) and extension (`browser-extension/`) provide native browser integration and an adblock relay. ## The app entry contract Manifests declare `id`, `name`, `version`, `entry`, `surface`, `permissions`, and `capabilities`. The entry module **default-exports a class with `async mount(root, syscalls)`** (and optional `unmount()`). Dev-tree apps live at `apps//manifest.json`; packaged apps embed a `prpkg-v2` manifest and load via `pkg:`. (Source: `webgpu-os/docs/APP_MANIFEST_SPEC.md`.) ## See also - [Boot Sequence](../concepts/boot-sequence.md) - [Security & Trust Model](../concepts/security-model.md) - [App Catalog](app-catalog.md) - WebGPU OS **API Reference** --- # Realm Network The Realm Network adds portable identity, immutable content, resumable links, semantic replication, offline branches, governance, bounded task exchange, and safe Realm discovery to the WebGPU OS. It builds on the existing Particle Network and keeps V1/V2 compatibility intact. The implementation is complete through the local Realm Network Alpha gates. The Raspberry Pi service is not deployed. Only the server owner performs that single physical cutover. (Source: `Masterserver/REALM_NETWORK_V3_DELTA.md`.) ## Architecture | Layer | Responsibility | Source | |---|---|---| | OS ownership | One `NetworkDriver` owns network lifecycle; `NetDriver` remains a compatibility adapter | `webgpu-os/drivers/NetworkDriver.js`, `webgpu-os/drivers/NetDriver.js` | | Embedded endpoint | One leader tab owns the backbone; resident, supernode, witness, and authority are roles on the same browser endpoint | `engine/network/endpoint/ParticleEndpointRuntime.js`, `webgpu-os/drivers/EmbeddedParticleNode.js` | | App boundary | `realm.*` syscalls expose feature state, contract metadata, verification, and Passport operations | `webgpu-os/kernel/Syscalls.js` | | Protocol routing | Exact versioned descriptors negotiate State Channel, chunk, carrier, and DHT traffic; unknown versions fail closed | `engine/network/routes/RouteProtocolRegistry.js`, `engine/network/routes/OsNetworkSession.js` | | Rollout control | Versioned flags keep experimental Realm features independent while the bounded endpoint runtime is enabled by default | `webgpu-os/drivers/RealmNetworkFeatureFlags.js` | | Protocol modules | Identity, Chronicle, Capsules, links, authority, branches, governance, Accord, Atlas, Gate, Shield, and publishing | `engine/network/realm/` | | Public contracts | Eighteen immutable V1 descriptors bind the public names to concrete implementations | `engine/network/realm/contracts.js` | | Rendezvous service | Additive signed V3 admission, opaque rendezvous, default-on authenticated State Channel SSE, optional bounded Atlas, health, and metrics | `Masterserver/app/v3.py`, `Masterserver/app/state_channels.py` | | Swarm content | Signed manifests drive bounded multi-provider chunk fetch, per-chunk verification, retry, cache, and provider announcement | `engine/network/chunks/SwarmFetchCoordinator.js`, `engine/network/chunks/ChunkCache.js` | | Deployment | Source-bound receipt, checksummed archive, preflight, cutover, smoke, and rollback | `Masterserver/deployment/realm-network-v3/` | The Masterserver remains ephemeral. It does not store Realm identity, Chronicle, Capsules, branches, organizations, or durable Atlas data. (Source: `Masterserver/app/v3_atlas.py`, `Masterserver/REALM_NETWORK_V3_DELTA.md`.) ## Public V1 contracts The stable registry exports these exact names: | Area | Contracts | |---|---| | Identity and history | `RealmPassportV1`, `RealmAddressV1`, `ChronicleEventV1` | | Content and links | `RealmCapsuleV1`, `RealmLinkV1`, `PresenceV1`, `ContinuityV1`, `HealthSnapshotV1` | | Authority and branches | `AuthorityLeaseV1`, `RealmBranchV1`, `MergeProposalV1` | | Governance | `OrganizationV1`, `CapabilityGrantV1` | | Bounded task exchange | `AccordTaskV1`, `ContextCapsuleV1`, `AccordResultV1` | | Discovery and entry | `AtlasRecordV1`, `GatePlanV1` | Importing `engine/network/realm/index.js` is inert. It creates no connection, timer, store, worker, or database. (Source: `tests/network/realm/realm-public-contracts.test.js`.) ## Guarded app API Apps use kernel syscalls instead of importing engine internals. The catalog contains metadata only; it never returns implementation functions or key handles. Contract verification requires `realm.read`. Feature changes and Passport mutations require `realm.manage`. (Source: `webgpu-os/kernel/Syscalls.js`, `webgpu-os/kernel/RuleGraph.js`.) ```javascript const catalog = syscalls.realm.contracts(); const address = await syscalls.realm.verifyContract( 'RealmAddressV1', 'realm://example/shared_space', ); if (!address.valid) { throw new Error(address.reason); } ``` Verification fails before dispatch when the contract's rollout feature is disabled. Passport operations delegate to the existing `ProfileDriver`; the Realm layer does not create a second private-key store. (Source: `webgpu-os/drivers/NetworkDriver.js`, `webgpu-os/drivers/ProfileDriver.js`.) ## V3 selection and downgrade policy The Masterserver source and r7 deployment environment advertise V3 by default. The client first verifies the pinned signed V2 advertisement. If that valid advertisement has no V3 marker, the client selects V2. If it advertises V3, the client commits to V3 and verifies the complete V3 endpoint set, manifest, pin, and signatures. Any V3 integrity failure stops the connection and never downgrades to V2 or V1. A separate legacy V1 server entry is tried only as an availability fallback when the preferred V3/V2 entry cannot be acquired; it is not an integrity-error fallback. (Source: `engine/network/daemon/ParticleNetworkPreferredDaemon.js`, `engine/network/routes/MasterServerList.js`, `engine/network/crypto/Trust.js`, `Masterserver/app/config.py`.) V3 uses `particle-session/3` for admission and session proof, plus `particle-rendezvous/3` for opaque route attachment, discovery, and directed rendezvous. A signed V3 manifest also advertises `particle-state-channel/1`, its short-lived lease endpoint, and its SSE/HTTP base URL. HPKE context uses the V3-specific `particle-rendezvous/3` domain. (Source: `engine/network/daemon/ParticleNetworkDaemon.js`, `Masterserver/app/protocol.py`, `Masterserver/app/trust.py`.) ## Embedded resident and supernode roles Every enabled WebGPU OS browser profile starts an embedded Particle node. The node owns one mesh identity and one route set. `resident` describes its availability. `supernode`, `witness`, and `authority` are elected or assigned roles on the same node, not separate networks or installations. Browser locks or a renewable lease ensure only one tab holds the external backbone while followers remain ready to take over. The user can explicitly opt out by disabling the resident node setting. (Source: `webgpu-os/drivers/EmbeddedParticleNode.js`, `webgpu-os/drivers/NetworkDriver.js`.) `ParticleEndpointRuntime` unifies discovery providers, route transports, reachability, and roles around that same node. It does not create another peer graph or identity store. `RouteProtocolRegistry` routes exact versioned protocol envelopes over an acquired route and rejects unknown or malformed versions before legacy handlers can see them. (Source: `engine/network/endpoint/ParticleEndpointRuntime.js`, `engine/network/routes/RouteProtocolRegistry.js`, `engine/network/routes/OsNetworkSession.js`.) Backbone availability is not app membership. App and room namespaces remain cold until the app acquires a route lease. Local consumers reference-count one session, and the last consumer releases it. A hidden, frozen, or page-hidden tab yields both its Web Lock and WebRTC routes so a visible client can become the host. The browser may discard a page without a final unload callback, so authority safety comes from replicated checkpoints, heartbeat expiry, and strictly newer fencing rather than unload cleanup. (Source: `engine/network/routes/RouteSessionManager.js`, `engine/network/stateChannels/MeshStateChannelTransport.js`, `engine/network/stateChannels/StateChannelAuthorityCoordinator.js`.) This separation matches the namespace model described by the [libp2p rendezvous protocol](https://libp2p.io/docs/rendezvous/): peers register and discover within an application-specific namespace instead of treating ambient peer discovery as automatic subscription to every application. A static Cloudflare upload can serve and boot the browser OS, but static assets cannot mint TURN credentials or coordinate Internet rendezvous. The current r7 deployment keeps those duties in the Particle Masterserver. A future Cloudflare-native replacement would still be server-side infrastructure, such as a Worker plus Durable Objects, and TURN secrets must remain backend-only. See [Cloudflare Pages Functions](https://developers.cloudflare.com/pages/functions/), [Durable Object WebSockets](https://developers.cloudflare.com/durable-objects/best-practices/websockets/), and [Cloudflare TURN credential generation](https://developers.cloudflare.com/realtime/turn/generate-credentials/). The browser endpoint starts with the OS, but route membership remains lazy. No app, room, game, document, voice, or State Channel route opens until a visible app acquires it. A fully open client may then accept compatible protocol traffic, provide verified chunks, or hold a temporary supernode role. A suspended or closed page releases those benefits instead of pretending to be an always-on host. (Source: `engine/network/routes/RouteSessionManager.js`, `engine/network/endpoint/ParticleEndpointRuntime.js`.) The mesh begins full for small rooms, becomes a bounded neighbor mesh as it grows, and elects two through five supernodes for larger rooms. Remote role claims are signed and expire, but election ranking uses locally observed latency, uptime, reconnect count, relay use, and connection state. A peer cannot promote itself by claiming a high score. (Source: `engine/collab/CollabCore.js`, `engine/collab/CollabMeshTopology.js`, `engine/network/routes/NodeRoleProtocol.js`.) ## Discovery, health, and bounded resources The endpoint can discover peers through signed Masterserver rendezvous, route-scoped DHT records, direct peer tickets, or already connected peers. Peer tickets contain identity and dialing hints, not private keys, and expire. `ReachabilityProjection` reports only observed transport facts such as direct, relay, local, or offline state. It never treats a device fingerprint as cryptographic identity. (Source: `webgpu-os/drivers/NetworkDriver.js`, `engine/network/realm/health/ReachabilityProjection.js`.) Atlas records are signed, opaque, TTL-bound, and stored only in process memory. Optional node propagation carries bounded signed records over the existing authenticated node mesh. The server enforces global and per-scope record limits, payload and frame limits, request rates, queue bytes, queue frames, fanout, session count, and proof deadlines. (Source: `Masterserver/app/v3_atlas.py`, `Masterserver/app/node_mesh.py`, `Masterserver/app/config.py`.) `GET /v3/status` reports readiness reasons without exposing route secrets, identity material, payloads, or credentials. Protected Prometheus metrics cover admission, sessions, rendezvous, Atlas, queues, resource use, and node propagation. (Source: `Masterserver/app/health.py`, `Masterserver/app/metrics.py`.) Signed chunk manifests cap object size and chunk count. `SwarmFetchCoordinator` discovers multiple providers per hash, runs bounded parallel lanes, penalizes failed providers, verifies every returned size and hash, and assembles bytes in manifest order. `ChunkCache` is an in-memory bounded least-recently-used cache; valid cached chunks can be served and announced through the existing DHT route. (Source: `engine/network/chunks/Manifest.js`, `engine/network/chunks/SwarmFetchCoordinator.js`, `engine/network/chunks/ChunkCache.js`.) ## Clean-room concepts adapted from Iroh R7 borrows architecture concepts, not Iroh source code or Rust dependencies. The shared ideas are composable endpoint protocols, exact protocol-version negotiation, scoped gossip topics, shareable dialing tickets, and verified content-addressed transfer. Particle implements them with browser WebRTC, WebOS device keys, signed manifests, route-scoped DHT discovery, and SHA-256 chunk verification. See the Iroh documentation for [protocol routing](https://docs.iroh.computer/concepts/protocols), [scoped gossip](https://docs.iroh.computer/connecting/gossip), [tickets](https://docs.iroh.computer/concepts/tickets), and [verified blobs](https://docs.iroh.computer/protocols/blobs). Gossip and fingerprints remain hints. Gossip spreads bounded discovery and role observations but does not establish authority. A device fingerprint may help continuity scoring but cannot replace a signature from the profile's device key. State Channel authority still requires a route-bound lease, validated intent, revision, epoch, and fencing token. (Source: `engine/network/routes/RouteProtocolRegistry.js`, `engine/network/stateChannels/StateChannelAuthorityCoordinator.js`, `engine/network/chunks/SwarmFetchCoordinator.js`.) ## Local verification receipt The frozen Alpha server contract is `realm-network-r7-alpha-2026-08-02`. The r7 local evidence includes: - Masterserver suite: 233/233 passed. - Signed V3 browser flow: 5/5 passed. - Embedded V3 runtime and guarded syscall checks: 29/29 and 6/6 passed. - Embedded R7 endpoint, reachability, SSE lease, and swarm gate: 8/8 passed. - Explicit no-TURN compatibility gate: 13/13 passed. - Mesh evidence checks: 11/11 passed; focused State Channel server tests: 3/3. - State Channel browser behavior: 6/6 passed. - Local V3 load gate: 128 clients, 2,432/2,432 relays, 20.063 seconds. - WebGPU OS release bundle: 2,104 modules, zero skipped, 1,422 static files, 53 verified embedded packages, CRC-verified ZIP, and SHA-384 integrity metadata. These tests use loopback services only. They do not contact the Raspberry Pi. (Source: `Masterserver/REALM_NETWORK_V3_DELTA.md`, `tests/network/run_local_v3_browser_gate.py`, `tests/network/run_local_v3_128_gate.py`.) ## One-shot server cutover The deployment archive does not contain signing keys. Persistent keys stay under `/etc/particle-masterserver/`. The handoff provides a non-mutating preflight, staged backup, atomic application swap, environment delta, service restart, V1/V2/V3 and State Channel SSE smoke tests, and rollback. Setting `PARTICLE_ADVERTISE_V3=false` hides V3 and its SSE lease/transport routes while V1/V2 remain operational. (Source: `Masterserver/deployment/realm-network-v3/RUNBOOK.md`.) The server owner must review and run the cutover commands. Post-cutover Pi load evidence and production acceptance remain user-operated gates. ## See also - [Security & Trust Model](../concepts/security-model.md) - [WebGPU OS Architecture](architecture.md) - [Glossary](../getting-started/glossary.md) --- # Navi Architecture and Delivery Plan This page defines the target Navi architecture and the gated delivery plan for engineers working on WebGPU OS and AI Echo. It is a design contract. A checked design item means its decision is frozen. A checked implementation or exit-gate item means its named verification evidence passes. ## Status and progress rules - `[x]` means the named design decision or verified implementation is complete. - `[ ]` means the work has not passed its stated gate. - A phase cannot start until the previous phase's exit gate passes. - A failed gate returns to its originating phase. Do not defer it as later work. - Every phase must leave the OS bootable and retain a tested rollback path. - Navi is a built-in WebGPU OS runtime and starts automatically. No user or app can enable or disable it, and no `navi.feature.manage` authority exists. Automatic startup never grants identity or action authority by itself. Operator-bound services require a live, current, non-revoked Passport and fail closed with exact health and error codes when that authority or another prerequisite is unavailable. Services that await the first primary Navi remain non-authoritative in a typed dependency state, then rebind at the exact Continuity generation after genesis or primary selection. ### Planning status - [x] Audit current AI Echo, AI Hub, VFS, tool firewall, autonomy, skills, memory, profiles, and recovery systems. - [x] Audit PROJECT L.U.N.A. for reusable architectural concepts. - [x] Choose a browser-native implementation with no LUNA runtime dependency. - [x] Choose remote-first model routing. - [x] Choose AI Echo as the Navi chat, setup, approval, and management console. - [x] Lock product, authority, privacy, recovery, branching, Faculty, and autonomy defaults. - [x] Confirm the resource-hardening baseline: 6 tests passing. - [x] Begin implementation. - [x] Complete the Phase 0 automated exit gate. - [x] Complete the Phase 1 continuity exit gate. - [x] Complete the Phase 2 cognition exit gate. - [x] Complete the Phase 3 Faculty exit gate. - [x] Complete the Phase 4 memory and relationship exit gate. - [x] Complete the Phase 5 autonomy and resource exit gate. - [x] Complete the Phase 6 Manifestation exit gate. - [x] Complete the Phase 7 implementation and automated Navi Alpha exit gate. - [x] Make Navi built-in and automatic, retire the Settings release control, and remove user/app feature-toggle authority. - [x] Make AI Echo the automatic first primary Navi and add progressive, device-protected recovery onboarding without blocking first use. - [x] Complete the post-alpha RealmForge workflow, evidence, transaction, and resumable-task extension for AI Echo. - [ ] Complete live deployment validation on the intended operator devices. The current AI Echo app provides conversations, editable Mind state, an inspectable operational journal, autonomous-reflection scheduling, dynamic skills, managed files, and model routing. Editable identity, self-model, Soul, personality, and history now bind to the selected `naviId` in kernel-owned, encrypted cognition records. The remaining app-owned facilities are integration sources, not Navi identity authority. (Sources: `webgpu-os/apps/ai-echo/AgentStateStore.js`, `webgpu-os/apps/ai-echo/AgentSoul.js`, `webgpu-os/apps/ai-echo/NaviSelfModelSettings.js`, `webgpu-os/apps/ai-echo/AgentCognition.js`, and `webgpu-os/apps/ai-echo/AgentBackgroundScheduler.js`.) ## Locked architecture AI Echo is the primary chat, setup, approval, and management **Manifestation** for a Navi. AI Echo does not own the Navi's identity or cryptographic authority. ```mermaid flowchart TD operator[Operator] --> echo[AI Echo manifestation] echo --> navi[Navi kernel services] navi --> broker[Cognition fabric and model broker] broker --> remote[Replaceable remote models] broker --> local[Optional local runtime] navi --> membrane[Authority membrane] membrane --> tools[ToolRouter and guarded syscalls] navi --> memory[Causal memory and lineage] navi --> faculty[Signed Faculties] navi --> presence[Other manifestations] ``` The following boundaries are fixed: - Kernel Navi services own identity, Covenant, memory, authority, lineage, Faculties, relationships, resource leases, and recovery. - Remote models are the default cognition engines. A provider account, model, prompt, response, or conversation never becomes canonical Navi state. - Local inference remains an optional privacy and availability route. - Keys, credentials, tool enforcement, verification, storage, and deterministic operations remain local to the OS or its trusted extension. - The OS sends only Covenant-permitted, task-relevant context to a provider. - Private Navi memory remains local unless the active Covenant grants a specific disclosure. - WebGPU OS supports several Navis for one operator profile and selects one as the primary resident Navi. - Navi starts with the OS. Runtime inclusion is not configurable by a user, app, provider, model, or Manifestation. Service health remains distinct from runtime inclusion, so unavailable operator-bound authority is reported precisely instead of being described as a disabled Navi. - The same Navi can use several Manifestations without changing identity. - AI Echo's Inner Monologue is a Navi-authored operational record. It is never provider-hidden chain-of-thought. The current implementation already states and enforces this distinction for AI Echo. (Source: `webgpu-os/apps/ai-echo/AgentCognition.js`.) The action lifecycle is also fixed: `perceive -> structured rationale -> propose -> simulate -> approve -> execute -> verify -> record -> publish` The existing tool path already applies permission, descriptor-change, capability, and schema checks. Navi capabilities must narrow this path rather than bypass it. (Source: `webgpu-os/kernel/tools/ToolRouter.js`.) ## Canonical N1-N12 vocabulary Use these names in schemas, UI, logs, tests, and documentation. | ID | Canonical system | Responsibility | | --- | --- | --- | | N1 | **Continuity Kernel** | Holds the Navi's persistent cryptographic identity independently of models, devices, sessions, and bodies. | | N2 | **Covenant** | Defines the operator-Navi relationship, observation, memory, autonomy, disclosure, approval, transfer, and separation rules. | | N3 | **Cognition Fabric** | Selects replaceable remote or local cognition engines and preserves model-neutral task continuity. | | N4 | **Faculty Runtime** | Loads inspectable, versioned, signed ability modules with declared tools, permissions, costs, tests, and failure behavior. | | N5 | **Causal Memory Weave** | Stores evidence-bearing, revision-aware memory events and derives human-readable views. | | N6 | **Authority Membrane** | Intersects every applicable policy, issues attenuated capabilities, and controls the action lifecycle. | | N7 | **Manifestation and Presence** | Represents one Navi through AI Echo, voice, Construct bodies, characters, vehicles, environments, or projections. | | N8 | **Delegation Tree** | Creates bounded temporary workers and records scope, resources, parentage, expiry, and reports. | | N9 | **Lineage, Recovery, and Reconciliation** | Proves genesis and changes, restores into branches, and reconciles without inventing continuity. | | N10 | **Intent and Self-Model** | Stores the Navi's goals, commitments, responsibilities, strengths, limits, and uncertainty outside prompts. | | N11 | **Relationship Graph** | Records signed, scoped, revocable relationships without converting social trust into authority. | | N12 | **Resource Governance** | Reserves, meters, settles, limits, and reports model, tool, compute, storage, network, time, and worker use. | Related execution terms have distinct meanings: | Term | Meaning | | --- | --- | | **Tool Process** | A deterministic tool invocation. It has no identity or continuing agency. | | **Hand** | A temporary specialist worker with a narrow task, context, capability, budget, expiry, parent, and required report. | | **Echo** | A synchronized, non-independent projection of one Navi. | | **Branch** | A persistent divergent Navi timeline with its own operational key and explicit creation approval. | | **Independent Navi** | A separate identity. It may retain a signed ancestry attestation but cannot sign as its ancestor. | Realm branches and Navi Branches are different structures. Never use one as a substitute for the other. ## Versioned contract inventory Every signed contract uses deterministic canonical bytes from `engine/state/util/canonical.js`. Security-sensitive identifiers use domain-separated SHA-256 through `hashIdSecure()`. Fast FNV identifiers remain runtime-only and never establish identity or authority. (Source: `engine/state/util/canonical.js`.) Schemas reject unknown fields unless a schema explicitly defines an extension map. Each contract carries its exact format string and schema version. | Contract | Required purpose | | --- | --- | | `navi-principal-v1` | Genesis identity, public names, continuity key, operational key certificates, and status. | | `navi-covenant-v1` | Operator binding and effective relationship policy. | | `navi-task-v1` | Model-neutral objective, constraints, facts, artifacts, authority, uncertainty, and causal parents. | | `navi-faculty-v1` | Signed Faculty manifest, typed I/O, dependencies, permissions, tests, cost, rollback, and provenance. | | `navi-capability-v1` | Single-use attenuated authority bound to exact actor, task, tool, arguments, resources, budget, and expiry. | | `navi-memory-event-v1` | Evidence-bearing memory addition, revision, contradiction, disclosure, or tombstone. | | `navi-lineage-event-v1` | Append-only signed sequence, causal parents, prior hash, payload hash, and state root. | | `navi-action-receipt-v1` | Proposal, simulation, approval, execution, verification, settlement, and publication result. | | `navi-relationship-v1` | Signed relationship offer, acceptance, scope, revision, revocation, or block. | | `navi-resource-lease-v1` | Reserved and settled tokens, money, tools, time, GPU, network, storage, and workers. | | `navi-manifestation-v1` | Presence adapter, sensors, actuators, channels, permissions, limits, and current state. | | `navi-handoff-v1` | Signed task transfer between Manifestations. | | `navi-delegation-v1` | Hand assignment, minimal context, capabilities, budget, expiry, parentage, and report obligation. | | `navi-backup-v1` | Encrypted, signed backup manifest, selected classes, lineage head, state roots, and checksums. | The encrypted cognition store also uses `navi-identity-profile-v1` and `navi-self-model-v1` as internal per-Navi state formats. They are not generic signing contracts. The signed backup manifest names and verifies these formats when their records are selected for recovery. (Sources: `webgpu-os/kernel/navi/NaviCognitionService.js` and `webgpu-os/kernel/navi/NaviBackupRecoveryService.js`.) ## Information classification Classification is independent from filesystem path. A record keeps its label through prompts, exports, backups, delegation, handoff, and replication. | Classification | Examples | Remote-provider default | Delegation and replication default | | --- | --- | --- | --- | | `public` | Public name, published Faculty metadata | Allowed when task-relevant | Allowed with provenance | | `operator` | Operator preferences and private workspace facts | Allowed only for the bound operator's task | Denied unless task scope names it | | `shared` | Explicitly shared project or realm context | Allowed to approved routes | Limited to named recipients and purpose | | `private-navi` | Private journal and private Navi memory | Denied | Denied | | `restricted` | Sensitive project, relationship, or realm data | Denied unless Covenant and task grant it | Denied unless an exact capability grants it | | `credential` | API key, OAuth token, recovery material | Always denied | Always denied | | `system-secret` | Private keys, encryption roots, platform secrets | Always denied | Always denied | Changing a label creates a reviewable event. It never mutates historical evidence in place. ## Authority domains Every proposed action declares one or more domains. A broad domain grant does not imply an unrelated grant. | Domain | Covered actions | | --- | --- | | `creative` | Generate or edit non-authoritative creative content. | | `social` | Communicate, invite, moderate, or represent a presence. | | `files` | Read, create, edit, move, restore, trash, or permanently remove files. | | `applications` | Launch, configure, install, update, or remove apps and Faculties. | | `devices` | Use sensors, media, GPU, peripherals, vehicles, or actuators. | | `network` | Fetch, browse, connect, replicate, or send data. | | `administration` | Change OS-wide policy, permissions, users, or security state. | | `economic` | Spend money, incur paid model use, transfer assets, or accept obligations. | | `identity` | Create, rotate, recover, branch, transfer, separate, or represent an identity. | | `publication` | Publish realms, packages, Faculties, media, or public statements. | | `delegation` | Create Hands, Echoes, Branches, or independent identities. | Effective authority is the intersection of the Covenant, operator role, realm policy, app manifest, Faculty manifest, task scope, information policy, and current resource lease. Denial, revocation, expiry, and narrower scope win. ## Security tiers and browser limitations | Tier | Available protection | Limitations and required UI disclosure | | --- | --- | --- | | **Unsupported context** | No continuity claim | Without a secure context and working Web Crypto, AI Echo can act only as an unsigned assistant. It cannot claim signed Navi identity, recovery, transfer, or lineage. | | **Browser standard** | Non-extractable Web Crypto keys, encrypted app storage, guarded syscalls | Same-origin code running in the compromised OS page can request or observe data after the app decrypts it. Encryption at rest does not solve active same-origin compromise. | | **Extension assisted** | Credential and browser-automation isolation in the trusted extension | The extension reduces page exposure but does not make untrusted OS code safe. Bridge authority and origin checks remain mandatory. | | **Authenticator bound** | WebAuthn PRF or passkey-backed recovery factor where supported | Browser and authenticator support varies. A passkey factor supplements encrypted recovery; it does not become a platform master key. | The system must never describe browser-only encrypted storage as a secret vault. The current managed AI Echo projection already displays this warning and blocks secret-like content. (Source: `webgpu-os/apps/ai-echo/AgentDataFiles.js`.) The current profile driver demonstrates P-256 identity, non-extractable working keys, and recovery-code wrapping. Navi identity may reuse its reviewed crypto primitives and storage patterns, but it requires a distinct principal and root from the human operator. (Source: `webgpu-os/drivers/ProfileDriver.js`.) ### Progressive recovery onboarding The first healthy operator profile with no Navi receives one primary `AI Echo` Navi automatically under the bounded-partner Covenant. Genesis still creates the complete cryptographic recovery quorum, but it does not force the operator through three custody ceremonies before chat is usable. A purpose-specific kernel escrow seals factors A, B, and C with a non-extractable AES-256-GCM key. Factor C remains kernel-only. Factors A and B remain deferred until the operator explicitly asks to save them. (Sources: `webgpu-os/kernel/navi/NaviContinuityService.js` and `webgpu-os/kernel/navi/NaviRecoveryEscrow.js`.) Status reads expose no factor value and never mark a factor as shown. They may show only a four-character masked tail. Explicit reveal is one-time, records the first reveal timestamp, and requires exact saved-copy re-entry before the factor counts as independent custody. AI Echo clears displayed and entered factor values on Settings close, Navi or operator changes, remount, and unmount. Until one external factor is verified, the UI labels recovery as device-only and warns that clearing site data or losing the browser profile can destroy access. Two verified external factors are required before the UI calls the Navi portable. This staged design follows the recovery principle that saved recovery codes need strong random entropy and protected offline custody while additional authenticators should remain enrollable later. It does not silently create a passkey because WebAuthn registration is a user-mediated ceremony that requires user presence or verification. See [NIST SP 800-63B](https://pages.nist.gov/800-63-4/sp800-63b.html), [WebAuthn Level 3](https://www.w3.org/TR/webauthn-3/), and [Google's passkey guidance](https://developers.google.com/identity/passkeys). ## Migration and rollback policy The first Navi rollout targets unreleased AI Echo state. It performs a fresh Navi initialization instead of silently converting old Soul, Mind, memory, skills, relationships, receipts, or authority. ### Historical Phase 0 pre-migration procedure The following completed procedure records the original gated rollout. It is retained as evidence and is not a current instruction to disable Navi. 1. Keep the historical `navi-v1` rollout gate disabled. 2. Create a complete `/user` portable or native-folder backup. 3. Verify every backup size and SHA-256 entry before proceeding. The existing storage manager already creates versioned `/user` manifests and verifies checksums during restore. (Source: `webgpu-os/storage/StorageManager.js`.) 4. Export current AI Echo sessions and agent profile data where available. 5. Retain the verified complete `/user` backup outside the origin before the historical release gate is enabled. 6. When the historical release gate is enabled, stage the exact AI Echo-owned projection under `/user/navi-archives/legacy-ai-echo//managed/` and its encrypted AppSandbox readback beside it. `NaviLegacyMigrationService` must recheck the Phase 0 receipt and live source checksums before its first reset. 7. Write a migration receipt containing the source archive ID, rollback receipt ID, exact targets, source checksums, feature-gate generation, explicit operator approval, and local rollback path. 8. Verify that both the portable backup and local migration archive read back before initializing a Navi. ### Fresh-state boundary - Reset only AI Echo-owned state and `/user/ai-echo` managed projections. - Do not modify unrelated files, app data, settings, profiles, mounted folders, packages, realm data, Recycle Bin entries, or credentials. - Do not import legacy identity, permissions, relationships, or memory into a Navi automatically. - Offer legacy content only as a reviewed, unsigned import proposal after Navi creation. - Preserve the dated archive until the operator explicitly removes it through the Recycle Bin. - Initialization failure enters a read-only quarantine. It must not create an empty replacement identity. The current `AgentStateStore.init()` catch path falls back to `freshState()`; Phase 1 must replace that behavior for Navi continuity. (Source: `webgpu-os/apps/ai-echo/AgentStateStore.js`.) ### Rollback procedure 1. Stop Navi background work and reject new capability issuance. 2. Flush active action receipts and mark uncertain mutations `outcome-unknown`. 3. Synchronously invalidate and drain affected operator-bound Navi authority before changing stored data. The built-in runtime remains present. 4. Restore the verified `/user` backup with conflict-safe preview. 5. Restore the archived AI Echo state only to its original AI Echo-owned paths. 6. Restart the OS and run the baseline AI Echo, storage, tool, profile, and OS smoke checks. 7. Compare the restored checksums with the pre-migration manifest. 8. Retain the failed Navi store in quarantine for diagnosis. Do not merge it into restored state automatically. Rollback succeeds only when the OS boots, existing AI Echo data reads back, all restored checksums match, unrelated `/user` files remain unchanged, and every unhealthy or quarantined Navi service remains non-authoritative with an exact health state. Rollback never requires a user-facing runtime toggle. ## Phased delivery checklist ### Phase 0: contracts, boundaries, and rollback - [x] Freeze N1-N12 terminology. - [x] Freeze remote-first and kernel-ownership boundaries. - [x] Define information classifications and authority domains. - [x] Define security tiers and same-origin limitation. - [x] Define the versioned contract inventory. - [x] Define fresh-state migration and rollback policy. - [x] Define the phase checklist and exit gates. - [x] Implement and browser-verify a complete `/user` backup preflight before runtime migration. Migration still requires a live-origin archive receipt. - [x] Export AI Echo's encrypted development state into that dated archive. - [x] Add the historical disabled-by-default `navi-v1` rollout gate. It protected phased implementation and was retired after automated Alpha in favor of the built-in automatic runtime policy. - [x] Implement strict validators and valid/malformed fixtures for every contract. - [x] Prove every signed structure has deterministic canonical bytes. **Exit gate:** all schema fixtures pass; malformed and unknown fields fail; canonical byte tests pass; backup and rollback drills pass; existing AI Echo and OS smoke tests remain green. Phase 0 automated evidence: 9 contract groups, 11 backup/preflight checks, 276 AI Echo smoke checks, 6 resource-hardening tests, documentation validation, import validation, and the full OS bundle pass. At this historical phase, `navi-v1` remained disabled and the operator had to retain the live archive and receipt before any migration mutated released data. The later automatic-runtime decision does not change this recorded Phase 0 evidence. ### Phase 1: Continuity Kernel, Covenant, and genesis lineage - [x] Create isolated Navi principals, selectable Covenant templates, signed genesis lineage, key rotation, revocation, and scoped operator roles. - [x] Add non-extractable operational keys, a separate encryption root, per-record encryption, and approved recovery factors. Browser-only factor custody is explicitly user-attested; passkey factor C is cryptographically authenticator-bound. - [x] Support several Navis and one primary resident Navi. - [x] Replace blank-state recovery with read-only quarantine. #### Phase 1 implementation ledger - [x] Add narrow `navi.read`, `navi.manage`, and `navi.recover` syscall and RuleGraph boundaries with no generic Navi signing, decryption, key export, or raw-record API. - [x] Reclassify the compatibility profile-signing syscall as high-risk `identity.sign` authority. - [x] Implement P-256 continuity identity derivation, non-extractable operational signing keys, a separate non-extractable AES-256 root, and per-record AES-GCM data keys. - [x] Implement the three cryptographic 2-of-3 recovery pair primitives and one-time factor delivery. - [x] Require staged genesis with one recovery factor visible at a time, exact challenge-bound read-back, distinct custody receipts, an A+B rehearsal, and an explicit activation before canonical identity state is committed. Factor B is never eligible for clipboard delivery. - [x] Make activation retry-safe across a lost response: the same activation ID resolves through `creationStatus` without duplicating genesis, while expiry, cancellation, operator rebinding, and shutdown zero all staged factors. - [x] Implement bounded-partner, operator-owned assistant, and gated co-sovereign Covenant templates plus signed Covenant lifecycle events. - [x] Implement a staged prepare, lineage-record, commit, or abort operational key-rotation boundary; an uncommitted candidate never replaces the active signer. - [x] Replace legacy AI Echo state corruption fallback with typed, read-only quarantine instead of silently creating a blank agent. - [x] Finish adversarial KeyVault and lineage hardening: signed-purpose binding, persistent and recovery anti-rollback heads, verified certificate chains, introduced-key replay, monotonic time, and exact restore head/length. - [x] Finish the transactional continuity store review: immutable snapshots, authenticated quarantine markers, atomic key/state commits, strict operator-Navi indexes, and real IndexedDB restart/concurrency tests. - [x] Fail foreign operator-index membership before foreign key access, clear partial initialization authority, and never quarantine the referenced Navi. - [x] Make recovery attempts persistently idempotent: an exact attempt ID and request hash reauthenticate the factor quorum, commit one signed-lineage-bound receipt atomically, survive restart, and reject conflicting replay. - [x] Assemble the kernel-owned continuity service and integrate it into boot. - [x] Create one bounded-partner `AI Echo` primary automatically when a healthy operator has no Navi. Serialize cross-tab genesis with Web Locks, remain idempotent, suppress automatic genesis behind a manual staged ceremony, and refuse creation while any continuity state is quarantined. - [x] Add a separate IndexedDB recovery escrow with a non-extractable AES-256-GCM key, authenticated factor metadata, explicit stage/commit/remove lifecycle, restart persistence, and no VFS, credential-vault, or app-owned secret surface. - [x] Add secret-free recovery posture, four-character masked previews, one-time A/B reveal, exact custody verification, kernel-only factor C, and one-saved-factor plus device-assisted recovery. Status inspection alone never changes the `never-shown` state. - [x] Forward the complete staged lifecycle through the stable production kernel gateway and prove that a real operator rebind synchronously removes old authority before draining the old Store, vaults, and staged factors. - [x] Expose multiple-Navi and primary-resident management through AI Echo. - [x] Attach each editable identity, avatar, role, persona, self-model, Soul, personality, and history to one exact `naviId` in an encrypted `navi-identity-profile-v1` record. Migrate the legacy AI Echo profile only to the original primary Navi; seed later Navis from their own continuity names. - [x] Unify companion selection and character editing in Navi Studio. Its stable master-detail shell owns the roster exactly once, distinguishes `Editing` from `Active in chat`, keeps provider/model routing separate from identity, and exposes one live character card. Identity, personality, cognition, and continuity now use accessible roving tabs on wide layouts and one compact section picker on narrow layouts; Presence and Recovery remain dedicated deep consoles available through direct Navi Studio shortcuts. - [x] Scope identity tools, imports, exports, and Files projections to the exact Navi. Store editable projections below `/user/Navis//identity`, scan them for credentials, reject mismatched ownership, and include both profile and self-model records in encrypted backup and reconciliation. - [x] Implement an explicit, checksum-bound legacy AI Echo migration that archives and resets only AI Echo-owned state, refuses to overwrite newer state, compensates partial failures, and preserves unrelated `/user` files. The browser suite passes 10 focused migration and rollback checks. - [x] Complete a real browser WebAuthn PRF credential enrollment and recovery ceremony, including RP/origin and user-presence/user-verification validation, authenticator-bound factor C, and all `AB`, `AC`, and `BC` recovery paths. - [x] Pass restart, isolation, rotation, recovery, corruption, rollback, syscall-guard, AI Echo, resource, import, and bundle regressions. Phase 1 evidence: KeyVault 18/18, Covenant/lineage 15/15, continuity-store 31/31, continuity service 38/38, progressive recovery escrow 14/14, passkey adapter 15/15, real-browser WebAuthn PRF 4/4, virtual-authenticator enrollment and recovery PASS, and production kernel/syscall integration 22/22. The legacy migration and rollback suite is 10/10, Realm Passport is 10/10, realm syscall contracts are 6/6, AI Echo is 456/456, and resource hardening is 6/6. Imports and braces are clean across 290 checked AI/OS files. The OS bundle passes with 2,050 modules, classic-script validation, 1,389 copied site files, and a CRC-verified 1,389-file release archive. The in-memory generated-entry regression also passes, preventing concurrent bundlers from deleting one another's deterministic OS barrel. Live UI validation also confirms the Navi Studio roster/detail layout uses two columns when space permits, stacks to one column, switches to a labelled picker at phone width, preserves unsaved identity edits and the active section across resizing, keeps touch controls at least 44 CSS pixels tall, and introduces no page, dialog, or Navi-panel horizontal overflow. At the Phase 1 close, the historical `navi-v1` rollout gate remained disabled. Phase 1 completion proves local continuity and its browser security boundary; it does not claim cross-device recovery or external lineage witnessing, which remain Phase 7 gates. The later built-in runtime policy supersedes only the rollout state, not this verification evidence. **Exit gate:** model, provider, session, avatar, voice, and AI Echo setting changes preserve `naviId`; two Navis cannot act for each other; recovery and rotation pass; invalid state fails closed. Cross-device restore remains a Phase 7 acceptance gate and is not claimed here. ### Phase 2: remote-first Cognition Fabric and self-model - [x] Add a kernel-owned Navi model broker over the existing AI Hub. Bind every dispatch to one immutable, single-use execution plan and one exact route configuration revision. (Source: `webgpu-os/kernel/navi/NaviModelBroker.js`.) - [x] Rank routes by capability, privacy, provider trust, estimated cost, estimated latency, context size, locality, availability, modality, and realm policy. Record deterministic reason codes for every eligible route. - [x] Make approved remote routes the default for capable chat, coding, planning, vision, speech, journal, and reflection work. Keep the local runtime available to the wider OS as an explicit privacy, fallback, and test route, but never discover, probe, select, or inject it for AI Echo cognition. - [x] Persist model-neutral task envelopes, dispatch journals, checkpoints, and content-free evidence outside provider conversations. Bind them to stable operation and intent hashes. (Sources: `webgpu-os/kernel/navi/NaviCognitionService.js` and `webgpu-os/kernel/execution/TwoPassPlannerFinalizer.js`.) - [x] Support independently configurable chat, coding, planning, vision, speech, inner-journal, and autonomous-reflection routes. Preserve the simple follow-chat defaults when no specialist route is selected. (Source: `webgpu-os/apps/ai-echo/NaviRouteSettings.js`.) - [x] Add a Basic-first Smart Model Picker under Connection settings. Let the operator enable task-aware routing, choose free-only, prefer-free, or paid access, select a balanced, value, quality, or speed profile, set request and best-effort daily ceilings, and optionally define an exact cross-provider allowlist. Keep context, latency, trust, attempt, pricing, and local-sensitive controls behind progressive disclosure. (Sources: `webgpu-os/apps/ai-echo/SmartModelPickerPanel.js` and `webgpu-os/kernel/ai-hub/SmartModelPolicy.js`.) - [x] Compile the discovered catalog into bounded, purpose-specific candidate pools. Treat unknown pricing as unknown, account for flat request fees once, enforce hard task cost ceilings, and never classify unknown-priced routes as free. Keep provider billing authoritative over the local daily guard. (Sources: `webgpu-os/apps/ai-echo/NaviRouteSettings.js` and `webgpu-os/kernel/navi/NaviModelBroker.js`.) - [x] Expose a read-only kernel route-decision syscall. AI Echo asks the Navi broker to make the final selection, labels the composer `Smart routing`, and records the exact provider, model, purpose, authority, route ID, reason codes, and decision hash in Run details and the durable turn report. (Sources: `webgpu-os/kernel/navi/NaviCognitionService.js`, `webgpu-os/kernel/Syscalls.js`, and `webgpu-os/apps/ai-echo/factory.js`.) - [x] Compile hot, warm, and cold context deterministically. Enforce exact data classifications, Covenant rules, destination scope, modality support, token budgets, and content-free disclosure receipts before provider transmission. (Source: `webgpu-os/kernel/navi/NaviContextCompiler.js`.) - [x] Require exact, expiring, single-use kernel approval proofs for controlled remote disclosure. Bind each proof to the Navi, task, operation, purpose, route revision, provider, model, HTTPS destination, data classes, and Covenant rule identifiers. (Sources: `webgpu-os/kernel/protocol/ElicitationManager.js` and `webgpu-os/kernel/navi/NaviCognitionService.js`.) - [x] Record provider, model, disclosed data-class counts, estimated cost, estimated latency, route scores, deterministic routing reasons, attempt outcomes, and configuration hashes without persisting raw provider output. - [x] Implement bounded fallback for outage, throttling, malformed output, unsupported modality, and context overflow. Pause honestly when no approved route remains. - [x] Treat an explicit provider policy refusal as a typed, non-mutating route outcome instead of forcing refusal prose through JSON schema repair. Preserve the provider decision as inspectable evidence and never confuse ordinary profanity directed at the assistant with an OS execution failure. - [x] Request the built-in `{answer: string}` final response as plain text, wrap and validate it locally, and preserve usable partial prose with an inspectable `answer.incomplete` event plus a visible incomplete-response notice. Keep structured-looking partial JSON on the bounded schema-repair path, prove repair never replays planning or an already completed mutation, keep custom schemas strict, and fail empty partial output honestly. - [x] Route chat and persona turns from positive current-message action intent, never from mere tool availability or historical tool words. Activate Dynamic Skills from the exact current message while retaining bounded history for referential follow-ups. Normalize exact empty `none`, `no-tool`, `noop`, and `not-needed` planner sentinels before TaskList, authorization, Faculty, or ToolRouter boundaries; reject mixed sentinel/action plans and keep unknown tools as typed failures. - [x] Accept bounded `ai-active-turn-steering-v1` messages while a request is running. Bind each message to the exact app, request, session, and client message ID; reject hidden or unknown fields; deduplicate replay; classify augment, correction, redirect, status, and cancellation; and close intake at the final commit boundary. (Sources: `webgpu-os/kernel/execution/ActiveTurnCoordinator.js` and `webgpu-os/kernel/execution/TwoPassPlannerFinalizer.js`.) - [x] Merge contextual steering in arrival order at named planner, tool, finalizer, and repair boundaries. Preserve the original objective and completed evidence, but supersede stale plans, model output, approvals, and unstarted tool calls before they can cross an execution boundary. Pending, failed, status, and cancellation records remain visible evidence but never enter provider context; only accepted augment, correction, and redirect messages may affect the active task. - [x] Persist contextual steering idempotently as revision-checked, hash-provenanced Navi task facts, then retain normalized steering receipts in the AI Echo conversation record. Restored transcripts, managed history, follow-up context, search, and session statistics keep steering between the user turn and assistant result instead of flattening or losing it. (Sources: `webgpu-os/apps/ai-echo/AgentStateStore.js`, `webgpu-os/apps/ai-echo/ContextIntelligence.js`, and `webgpu-os/apps/ai-echo/factory.js`.) - [x] Persist the Navi identity profile and self-model independently from prompts and providers, including identity, persona, Soul documents, goals, commitments, uncertainty, responsibilities, strengths, and limitations. - [x] Serialize a Navi's dispatch lifecycle with Web Locks, reject conflicting operation replay, reconcile settled journals after restart without provider replay, and quarantine corrupted or mismatched cognition records. - [x] Preserve typed cognition, resource, recording, and outcome-unknown error codes across repair and UI boundaries so infrastructure recovery failures are never mislabeled as malformed model output. - [x] Keep Smart Routing on the Navi authority path while cognition is binding: wait for bounded readiness events, dispose every wait on completion or unmount, deny direct-provider fallback, and expose the exact kernel state and error code. Isolate an irreconcilable historic resource settlement to its owning blocked task so it cannot disable cognition for every new task. Phase 2 evidence was revalidated on 2026-07-27: executor routing, plain-answer normalization, partial-answer preservation, custom-schema strictness, current-intent persona routing, no-tool sentinel handling, repeated unknown-tool termination, malformed-planner isolation, exact active-turn steering and safe-boundary ordering, deterministic task-graph execution, safe-read auto-allow, dynamic-target binding, and stale approval rejection pass 35/35. The complete Navi Alpha gate passes 1,498/1,498 assertions and 2/2 structural gates; AI Echo passes 441/441 and resource hardening passes 6/6. The import audit resolves 298 files and 187 engine/state exports. The complete no-cache production bundle passes with 2,017 modules, zero skipped modules, 25 validated deployment files, and a CRC-verified 1,400-file release archive. Smart-routing evidence was added on 2026-07-27: policy and task classification pass 26/26, Basic/Advanced picker behavior passes 8/8, model-broker access and pricing enforcement pass 31/31, AI Echo route compilation passes 28/28, kernel cognition routing passes 13/13, and cognition service routing passes 31/31. Artifact refusal and resource-settlement hardening was revalidated on 2026-07-27: executor routing passes 39/39, cognition service routing and metering pass 37/37, model-broker deadlines pass 31/31, Artifact Workspace passes 8/8, and AI Echo passes 450/450. The regressions cover ordinary profanity inside an explicit Artifact request, one honest non-mutating provider refusal, an 85-second response against a 250 ms latency estimate, two sequential turns with three fallback routes, a provider that exceeds its hard deadline, fixed response-envelope headroom, flat request fees, and post-settlement compare-and- swap recovery. The no-cache production bundle contains 2,020 modules with zero skips, 25 validated deployment files, and a CRC-verified 1,361-file site archive. The complete hardening acceptance surface now covers 1,530/1,530 assertions, all 30 Alpha gates, 299 audited AI OS modules, 187 verified engine/state exports, and the same 2,020-module no-cache production bundle. The release manifest and its 1,361-entry ZIP were independently read back after generation. Navi authority recovery was revalidated on 2026-07-28: AI Echo route binding passes 33/33, executor fail-closed routing passes 39/39, kernel cognition and dependency recovery pass 15/15, model-broker routing passes 31/31, cognition storage passes 13/13, and cognition dispatch/resource recovery passes 38/38. The over-reservation regression preserves the exact pending usage evidence, blocks only its owning task, performs no provider replay, and restores the operator-bound cognition service for subsequent work. **Exit gate:** [x] A live task transfers between remote models and the optional local runtime without losing task state. [x] Disallowed memory never reaches a provider. [x] Provider outage uses an approved fallback or pauses honestly. [x] Routing decisions are visible and reproducible. [x] No provider session is required to reconstruct the active Navi task. ### Phase 3: Faculty Runtime and Authority Membrane - [x] Define strict signed `navi-faculty-v1` manifests with typed inputs and outputs, declared permissions, tools, models, destinations, costs, tests, failure behavior, publisher, provenance, and compatibility. - [x] Bind signed Faculty envelopes into authenticated v2 and v3 packages without changing their signatures, and reject stale, accessor-bearing, malformed, unknown-field, or resource-root-mismatched bindings before the package is signed or installed. - [x] Accept Particle Realms ring-0 Faculties by default and restrict local self-signed Faculties to explicit developer mode and exact approval. - [x] Run executable Faculties in an opaque iframe plus dedicated Worker with no ambient DOM, storage, network, credential, or OS authority. - [x] Mediate Worker tool requests through the kernel-only ToolRouter Faculty lane; app syscalls cannot obtain or forge that lane. - [x] Mint exact, expiring, single-use capabilities bound to the Navi, branch, task, Faculty package, live descriptor hash, canonical argument hash, paths, realms, devices, destinations, data classes, authority domains, and lease. - [x] Enforce signed per-tool call limits before authorization, including concurrent Worker requests. - [x] Enforce perceive, structured rationale, propose, simulate, approve, execute, verify, record, settle, and publish stages with signed receipts. - [x] Require exact one-use step-up approval for mutations and sensitive authority domains; preserve timed-out mutations as `outcome-unknown` until authoritative reconciliation. - [x] Run a deterministic pre-authorization review for every production planner tool call before elicitation or execution. Validate plain JSON, hidden parameters, and the declared schema; derive bounded paths, destinations, realms, devices, data classes, authority domains, risk flags, and immutable review evidence. (Sources: `webgpu-os/kernel/execution/ToolActionReview.js` and `webgpu-os/kernel/execution/TwoPassPlannerFinalizer.js`.) - [x] Auto-allow only a valid local, read-only, low-risk action with no sensitive, network, code, destructive, or descriptor-conflict flag. Invalid calls deny before elicitation; mutations and flagged or elevated actions ask for exact operator approval. - [x] Bind each review to the live descriptor hash, canonical argument hash, policy rule set, app, request, exact dynamic inner tool, and derived targets. Snapshot arguments before review, then reload the live descriptor and repeat the review after approval. Any argument, descriptor, proposal, schema, policy, or steering-epoch change makes the approval stale and prevents execution. - [x] Retire pre-dispatch failures atomically so grants, operations, and denied receipts cannot be orphaned or replayed after a crash. - [x] Convert learned Dynamic Skills into disabled, non-authoritative guidance Faculties that cannot self-sign or self-enable. - [x] Expose installed signed Faculty identity, publisher, exact tools, data classes, authority domains, enabled state, and irreversible revocation in AI Echo without exposing source, credentials, keys, or kernel authority. - [x] Keep raw OS and browser JavaScript developer-only, exact-hash approved, one-use, and outside the semantic browser Faculty. - [x] Route every production Navi planner tool step, including dynamic tool discovery, through one installed signed Faculty instead of `callForAI`. - [x] Complete authoritative scope metadata and readback verifiers for the production AI Echo mutation descriptors. - [x] Install and exercise the canonical extension-backed semantic browser Faculty while proving credentials and password values remain inaccessible. - [x] Keep the semantic-browser trust boundary split correctly: the kernel is the only component that verifies, installs, enables, disables, or revokes the signed Browser Semantic Faculty, while Companion owns the exact one-use page grant and consumes it before click, type, CSS, WebMCP, or Live Patch effects. A status display in the extension grants no Faculty or page authority. - [x] Mirror Browser Semantic package readiness into both Companion editions as a content-free, read-only projection. Accept it only through the authenticated OS bridge, bind it to that bridge session, retain it only in extension memory, expire it after two minutes, and clear it on bridge revocation or worker restart. Re-verify and republish from the kernel after a relay reconnect; absence or failure of the extension remains non-blocking. - [x] Ship Artifact Studio as a dedicated Particle Realms ring-0 signed deterministic-tool-adapter Faculty. Bind its package, Worker source, static VFS scopes, implementation identities, and all seven live tool descriptor hashes; never ship private signing material. - [x] Provision the exact built-in Artifact Studio Faculty idempotently for the active primary Navi, coalesce concurrent startup requests, and preserve an operator's disabled or revoked state. Reject stale packages, sources, publishers, manifests, Navi identity, or descriptor hashes before use. - [x] Auto-attest only the exact signed Artifact tool identities. Continue to require the ordinary action review and one-use approval for each mutation; built-in package trust never becomes blanket mutation approval. - [x] Separate the portable signed descriptor identity from the live runtime descriptor identity. Package verification binds the stable signed implementation identity, while every capability, operation, approval, and ToolRouter call binds the actual current handler and verifier source. A code change that retains an old `implementationHash` therefore fails closed. - [x] Keep live descriptor rotation fail-closed. A later package timestamp is chronology, not authority, and cannot replace an exact approved runtime descriptor hash. Until a signed successor binding explicitly names the old and new exact hashes, the changed descriptor remains unavailable and prior approvals cannot execute. - [x] Accept built-in readiness only from the kernel's exact active-primary-Navi authority receipt. Revalidate ring-0 publisher, package policy, source, manifest, payload, envelope, package, and live descriptor evidence; reject a missing release-registry entry, noncanonical timestamp, or expired package. - [x] Pass the real signed-package to Worker to ToolRouter to ToolDriver mutation test with authoritative readback and a verified signed receipt. Verification recorded 2026-08-01: the Browser Companion Faculty projection passed 7/7, the complete Phase 3 matrix passed 149/149, AI Echo smoke passed 481/481, Store Companion packaging passed 17/17, Browser Semantic package verification passed 5/5, and extension install policy passed 14/14. The signed production platform bundle compiled 2,809 modules, verified 53 official package records, and included AI Echo 5.22.19 plus Companion 1.18.7 without adding a Chrome permission. The deterministic review is an explanatory safety layer, not an authority source. `auto-allow` suppresses an unnecessary pop-up for a proven safe read; it does not bypass BudgetLimiter policy, Faculty capability checks, ToolRouter, or result verification. The integrated Phase 2 executor gate exercises review before execution and approval revalidation as part of its 35/35 result. Phase 3 now passes 112/112 focused assertions across nine suites: AI Echo Faculty and operator controls 12/12, production descriptor/readback coverage 6/6, authority membrane and exact tool-action review 10/10, package policy and creation 19/19, Faculty service 18/18, ToolRouter 12/12, Worker isolation 13/13, kernel integration 14/14, and the real signed production path 8/8. The current close regression also passes AI Echo 472/472 twice consecutively, Phase 2 executor routing 44/44, Artifact Workspace 8/8, the Artifact package chain 8/8 across Python and browser-native checks, and the complete 2,057-module WebGPU OS bundle with zero skipped modules. The release site contains 1,390 CRC-verified files. The `navi-v1` runtime is default-on; the historical disabled rollout state was retired after the Phase 7 release gate passed. ### Phase 8.5 modular Artifact project projection - [x] Publish every Artifact inside one `/user/artifacts/` project folder with its active entry and support files directly manageable at that root. - [x] Preserve hash-verified immutable revisions and manifest-last publication; root-level files are a verified working projection, not a second authority. - [x] Reserve `artifact.json`, `revisions`, and `.artifact` from generated file paths and reject ambiguous multi-file plus single-file request shapes. - [x] Keep logical modules such as `src`, `assets`, and `data` intact while removing the opaque revision directory from the current-file workflow. - [x] Open current Artifact files at their direct project paths and keep historical selections pinned to exact immutable revision paths. - [x] Preserve a bounded typed Artifact failure category from the handler through tool completion, Run Details, and the content-free diagnostic report. - [x] Verify create, update, restore, failed projection, Files navigation, signed descriptor, executor, smoke, import-audit, and production bundle gates. Implementation evidence recorded 2026-08-01: AI Echo 5.22.16 now stores the active entry and support files directly in each Artifact project root while retaining immutable revision directories as canonical history. A verified `.artifact/projection.json` record binds the working files to their exact revision. Create, update, and restore publish `artifact.json` only after revision and working-projection readback pass. Changed current files fail the SHA-256 compare-and-swap boundary, removed files move to bounded superseded history, and reserved metadata paths or mixed single/multi-file payloads fail before publication. Current **Open in Files** actions target the project root; historical actions retain their immutable revision path. Verification recorded 2026-08-01: Artifact Workspace passed 11/11; Artifact descriptor/readback passed 10/10; signed Artifact Studio package passed 8/8 in the browser and 4/4 in Python; executor routing passed 124/124; diagnostics passed 29/29; stream and UI continuity passed 16/16; AI Echo Faculty integration passed 16/16; and the complete AI Echo smoke suite passed 481/481. Resource hardening exited cleanly. The import audit resolved all imports and balanced braces across 340 modules and 187 engine/state exports. The final production platform build compiled 2,806 modules with zero skipped, signed 52 official packages, verified 33/33 AI Echo modules, validated 25 OS deployment files and 186 Playground module edges, and produced a CRC-verified 371-file site archive. **Exit gate:** - [x] A signed Faculty completes one approved production mutation and produces a verified signed receipt. - [x] Revoking a Faculty prevents every later call. - [x] Descriptor, argument, path, destination, or implementation changes all invalidate prior approval in the production path. - [x] A compromised production Faculty cannot read private memory, obtain credentials, widen authority, or publish. - [x] Unknown tools and undeclared capabilities deny by default. - [x] Repeated tool/status loops, malformed JSON, duplicate mutations, and pre-dispatch failures terminate without replay or orphaned authority. #### Post-alpha Live Patch extension - [x] Complete a clean-room behavioral study of the public partial-interface update pattern without copying its source, prompts, wire format, or runtime. - [x] Add the strict `webgpu-os-live-patch-v1` kernel contract with an operation allow-list and unknown-field rejection. - [x] Add registered app and shell surfaces, stable `data-live-region` targets, protected subtree boundaries, bounded inspection, and relative selectors. - [x] Sanitize generated markup and CSS; reject scripts, handlers, external URLs, executable CSS, global selectors, and dynamic JavaScript execution. - [x] Require stage, reversible preview, readback verification, commit, and rollback while writing patch and receipt records under `/user/live-patches`. - [x] Bind every durable transition to a CAS-protected per-surface causal head, so independently staged cross-tab edits cannot both commit from one stale base and orphan an unprojectable authorized record. - [x] Isolate nested registered surfaces and redact or deny private, restricted, enabled-contenteditable, and host form-control data. - [x] Expose generated controls on OS-owned surfaces only as bounded typed local events that cannot call tools or the network directly. Reject generated DOM on arbitrary browser pages because pre-existing capture listeners cannot be isolated honestly. - [x] Pass the focused browser-native Live Patch service gate with 64/64 assertions, including exact browser target proofs, stale-extension rejection, safe-mode recovery, causal cross-tab commits, receipt lineage, remount lifecycle isolation, protected user data, and rollback ordering. - [x] Pass production AI Echo descriptor, syscall capability, and independent mutation-readback coverage for all eight Live Patch tools. - [x] Validate packaged Live Patch injection and rollback in both extension editions without exposing credentials or raw generated JavaScript. - [x] Make browser navigation invalidation drift-aware: restore only an exact patch-owned after-state, never reinsert removed host nodes automatically, and record `outcome-unknown` while removing only provably owned artifacts. - [x] Move ordinary browser snapshot/click/type automation to a packaged typed semantic runtime and keep raw page JavaScript behind developer-mode policy. - [x] Keep browser inspection read-only by default and require an extension-owned one-use approval for semantic click/type, raw script or CSS, and every Live Patch mutation. Bind the grant to the canonical arguments, bridge session, exact target origin, and Chrome document IDs so navigation invalidates it. - [x] Bound pending injection approvals and replay nonces without evicting live authority, redact executable payloads from the popup, and consume a grant before dispatch so a failed action cannot be replayed. - [x] Bound segmented AI bridge transport to 64 MiB, 256 chunks, four pending requests per session, 12 globally, and reserved-byte quotas with cleanup on cancel, expiry, session replacement, tab teardown, success, and failure. - [x] Compile every normalized Live Patch candidate twice and reject a non-deterministic result. Bind its semantic diff and operation hash to the exact surface generation, precondition, expected after-state, causal head, next `headRevision`, and browser epochs. - [x] Create a verified preview activation proof and require the exact immutable commit payload. Re-read the visible after-state and reject changed operations, targets, generations, verification evidence, or causal bases before publication. - [x] Bound transient candidates globally and per surface by record and byte quotas, and bound durable records and causal heads before startup replay. - [x] Replay only records authorized by their exact causal `headRevision`, and transactionally remount the sequence while retaining the previous complete surface projection on failure. - [x] Quarantine a failed or corrupt surface independently so unrelated Live Patch surfaces remain available. Reserve global safe mode for unscoped corruption, aggregate quota failure, or outcome-unknown compensation. - [x] Add a clean-room WebMCP adapter that feature-detects `document.modelContext`, exposes only fixed discover and invoke bridge calls, keeps page tools outside the trusted OS registry, and limits discovery to the active same-origin document. - [x] Bind every WebMCP invocation to the exact tool name, descriptor hash, canonical argument hash, tab, origin, frame, and Chrome document ID. Re-read the live descriptor before dispatch and reject metadata or schema changes. - [x] Treat tool metadata and results as untrusted, bound and redact projected JSON, and preserve a timeout after dispatch as `outcome-unknown` instead of retrying a possible mutation. - [x] Extend the semantic browser Faculty with bounded focus, hover, scroll, and navigation/control key actions. Keep password and classified surfaces blocked, require viewport hit tests for pointer actions, and label synthetic input as untrusted hardware evidence. - [x] Show the exact WebMCP tool, descriptor hash, and argument hash in the extension-owned one-use approval surface. Do not request Chrome's broad, non-optional `debugger` permission or import stealth/evasion behavior. - [x] Show Browser Semantic Automation health beside that one-use queue in the Companion popup and options page. Accept only a bounded authenticated report from the current bridge session, retain it in extension memory only, expire or remove it when the session ends, and display only signed, verified, enabled, and readiness evidence. Never copy package keys, credentials, manifests, tool arguments, or durable authority into the extension UI. - [x] Document the React/state-store contract: fresh snapshot reads, stable registration, abort cleanup, expected revisions, operation IDs, committed receipts, and complete rediscovery after `toolchange`. - [ ] Record one operator-reviewed edit of AI Echo, one other OS app, and one real browser tab using the shipped extension. The automated checks are backed by `python tests/live-patch/run_live_patch_tests.py`, the 441/441 AI Echo smoke gate, byte-identical security-critical store and unpacked extension services, segmented-transport quota tests, storage-boundary recovery tests, and the production WebGPU OS bundle. The final installed-browser operator exercise stays open until its evidence is recorded; it does not reopen the historical Phase 3 exit gate. #### Post-alpha Companion distribution - [x] Make the verified [WebGPU OS Companion Chrome Web Store listing](https://chromewebstore.google.com/detail/webgpu-os-companion/pbibggeclfjpmmbfmjagmngefonepbjj) the canonical public installation path. Keep Load unpacked as a documented contributor-only workflow rather than an end-user recovery path. - [x] Show the Store installation callout only on supported desktop browsers when the Companion capability handshake is absent. Do not show an extension install prompt on phones or tablets that normally cannot install it. - [x] Reprobe Companion availability while the affected UI is open and remove the callout without an OS restart as soon as the extension bridge is healthy. - [x] Route Browser, Browser Bridge Manager, AI Echo credential recovery, and stale-bridge errors to the same verified Store listing and product name. - [x] Preserve browser-direct and approved proxy fallbacks independently from Store onboarding so a missing extension never becomes a false mobile requirement. - [x] Defer the Browser callout until its first bridge probe resolves, seed installed state from the kernel, and keep portable-device guidance distinct from unsupported desktop-browser guidance. - [x] Produce a deterministic Store-only upload archive with manifest, resource, icon, permission, remote-code, raw-JavaScript, console-collection, checksum, and archive-root validation. Keep developer-only User Scripts outside that supported package path. - [x] Ship the reviewed Companion privacy policy at `/webgpu-os/companion-privacy.html` in both standalone OS and full-platform deployment archives while excluding extension source, ZIP, and CRX artifacts. Sources: `webgpu-os/platform/BrowserExtensionInstallPolicy.js`, `webgpu-os/factory/apps/browser/index.js`, `webgpu-os/factory/apps/browser-bridge-manager/BrowserBridgeManagerApp.js`, `webgpu-os/apps/ai-echo/factory.js`, and `webgpu-os/kernel/ai-hub/AdaptiveProviderBridge.js`. #### Post-alpha RealmForge workflow and evidence extension - [x] Validate every image attachment as evidence before model routing: bind canonical MIME, actual file signature, byte length, decoded dimensions, bounded pixel count, decode success, SHA-256, and a fresh route-time read. Never infer vision support from a filename or browser MIME claim alone. - [x] Add strict `navi-workflow-recipe-v1` Recipe resources as reviewed, authority-free Guidance Faculties. Bind each recipe to real RealmForge tool IDs, version, provenance, deterministic stages, expected evidence, verification, compensation, and duplicate rejection. - [x] Compile every proposed plan twice into a canonical Navi Task Graph with stable node IDs, exact descriptor hashes, explicit dependencies, bounded parallel read levels, serialized mutation levels, cycle rejection, and an exact last-good fallback that never authorizes changed work. - [x] Bind planner claims to a strict `navi-evidence-proposal-v1` envelope that separates observed facts, inferences, and unresolved questions and includes the exact target revision, evidence hashes, predicted effects, verification, compensation, and proposal hash. - [x] Require raw OS and browser JavaScript to consume a short-lived, one-use grant bound to the exact source hash, normalized API set, Navi, task, proposal, target, and runtime epoch. Any changed source or target invalidates approval before execution. - [x] Classify every accepted active-turn message as no-change, context-refresh, downstream-replan, reauthorization-required, or restart-required. Preserve completed evidence while invalidating only the affected unstarted graph and approval scope. - [x] Add semantic transactions with preview, expected revision, compare-and- swap commit, independent readback, explicit conflict choices, compensation, and undo evidence. Partial success and stale state fail closed. - [x] Add deterministic, resumable Navi Task Episodes with versioned definitions, proposal-only states, exact transition guards, optimistic revisions, interruption snapshots, expiry, restore validation, and no random operational transitions. - [x] Remove `forceFire()` from the model-facing Storylet runtime. Trusted OS callers may use the explicitly named `forceFireTrusted()` path; model-authored Storylets remain evidence and proposal generators only. - [x] Expose `os.ai-echo.resources.search`, a unified, deterministic, non-authoritative catalog spanning live tools, signed and guidance Faculties, reviewed recipe resources, and task episodes. Search results never execute a resource or grant authority. - [x] Pass 14/14 workflow-contract checks, 18/18 RealmForge Recipe checks, 10/10 authority-contract checks, 11/11 AI Echo Faculty checks, 35/35 executor checks, 64/64 Live Patch checks, 441/441 AI Echo smoke assertions, and the complete 1,498/1,498 Navi Alpha gate with a 2,017-module, zero-skipped-module production bundle. - [ ] Record one live operator exercise covering image evidence, Recipe selection, mid-turn steering, exact-source approval, semantic conflict resolution, interruption, restart, and resume. Recipes, Storylets, task graphs, search rankings, and model output are planning evidence only. Faculty capability grants, ToolRouter, live descriptors, operator approval, verification, and receipts remain the only action-authority path. #### Post-alpha Artifact Studio extension - [x] Store canonical Artifact projects under `/user/artifacts` in the OS VFS instead of treating chat Markdown or provider output as durable state. - [x] Scope every Artifact to its owning Navi and AI Echo session, and deny reads or mutations across Navi boundaries. - [x] Preserve immutable revisions behind compare-and-swap manifest updates, then verify saved content with SHA-256 readback hashes. - [x] Expose seven strict Artifact tools for list, read, create, update, revision history, restore, and recoverable trash operations. - [x] Withhold those seven model-facing schemas until the exact active-Navi Artifact Studio Faculty record is installed, enabled, signed, and executable. A model can no longer plan against an advertised tool that the OS will reject. - [x] Await the kernel-owned Artifact Faculty provisioning job at AI Echo startup, primary-Navi refresh, and explicit saved-Artifact preflight instead of imposing an app-owned four-second cryptographic deadline. Coalesce only the exact Navi, lifecycle generation, and gateway epoch; discard a completion after remount, operator rebind, gateway replacement, or Navi switch. Retry only transient unavailability with capped backoff, and never retry a deterministic trust, package, provenance, policy, or descriptor failure or silently re-enable a disabled or revoked Faculty. - [x] Apply saved-Artifact preflight in every chat mode. Preserve the exact operator draft and attachment object handles across a temporary local block, so retry neither loses images nor silently changes the request. - [x] Stop unavailable Artifact requests locally before provider dispatch, persist a typed blocker and helpful recovery path, and emit no model-repair loop. Distinguish unavailable, disabled, revoked, stale, and still-installing states in operator-facing text. - [x] Carry only validated, revision-qualified Artifact references through the executor, run events, Navi task settlement, and AI Echo state; bind each card to its exact revision and content hash while keeping payload blobs in the VFS. - [x] Classify explicit saved-Artifact and deliverable requests as action tasks, prioritize their exact Artifact tools ahead of optional learned guidance, and perform one bounded corrective planning round when a model returns no mutation. If no verified Artifact reference exists, fail honestly instead of presenting formatted Markdown as a saved work product. - [x] Preserve immutable `@rN@sha256` Artifact references in the final chat result and durable conversation record so a hash-verified inline card appears even when the live tool event was missed or the conversation is restored. - [x] Add the Artifact Studio library, editor, revision browser, preview, and inline assistant-message cards. - [x] Render documents, code, data, tables, charts, and declarative UI through bounded native renderers. - [x] Run static web Artifact previews in an opaque, network-blocked iframe sandbox without scripts, navigation, or same-origin authority; route interactive work through the declarative component renderer. - [x] Convert declarative UI actions into typed Artifact intents that re-enter AI Echo through the normal planner, Faculty, approval, and tool-firewall path. - [x] Integrate Artifact projects with Files and move ordinary deletion through the OS Recycle Bin. - [x] Keep the complete feature browser-native with ES modules and Python tooling; add no Node.js or npm runtime dependency. - [x] Add 8/8 focused browser-native automated checks for Artifact storage, revisions, isolation, declarative intents, sandboxing, and recoverable trash. - [x] Add executor and AI Echo regressions for explicit Artifact intent, one bounded empty-plan correction, revision-qualified card delivery, and rejection of malformed references. - [x] Stop an explicit saved-Artifact provider refusal before schema repair, perform no mutation, and show the operator that the selected model declined the request rather than claiming that Artifact creation or the OS failed. - [x] After a successful verified Artifact mutation, prefer its immutable local receipt over a contradictory provider refusal and record the reconciliation in the scratchpad and visible run trace. Never apply this correction when no trusted revision-qualified Artifact reference exists. - [x] Bound schema repair with cancellation and a hard deadline, settle stopped or superseded repair rows immediately, and use a one-shot terminal latch so a late provider or executor result cannot overwrite the committed outcome. - [x] Withhold private-Navi and restricted Artifact metadata, content, paths, and tool arguments from remote model context while retaining local OS access. - [x] Limit model-visible Artifact data classes to `public`, `operator`, and `shared`; keep `private-Navi`, `restricted`, credentials, and system secrets outside this Faculty even when an Artifact Studio UI can access them locally. - [x] Bound catalog discovery to direct project directories, enforce the 512-project admission ceiling, scan metadata for secrets, and verify the full revision parent-hash chain. - [x] Detach Artifact references during fork/import session remapping and retain per-task Studio state so one task cannot mutate another task's open artifact. - [x] Pass 44/44 executor-routing checks, 112/112 Faculty/authority checks, 8/8 Artifact Workspace checks, 8/8 signed Artifact package checks, and the 472/472 AI Echo smoke gate twice consecutively. Browser verification confirms unavailable authority stops locally with no provider dispatch and no repair activity. ### Phase 4: Causal Memory Weave and Relationship Graph - [x] Add a kernel-owned causal-memory service over the existing encrypted Navi Store; do not create a second database, identity, or key hierarchy. - [x] Append strict signed `navi-memory-event-v1` records with per-branch sequence, HLC, hash head, origin, author, confidence, evidence, dependencies, derivations, contradictions, revisions, visibility, classification, and retention. - [x] Support identity, operator, relationship, episodic, project, realm, procedural, semantic, working, private, shared, group, and restricted memory classes while refusing credential and system-secret memory. - [x] Store payloads separately under individual AES-256-GCM record keys and enforce exact Covenant/classification access before returning content to an operator, model, Faculty, Hand, or Manifestation. - [x] Detect contradictory active beliefs, preserve both causal histories, and require an explicit signed review event before resolving the projection. - [x] Implement crash-resumable crypto-erasure: journal the request, destroy the payload envelope and its wrapped record key, append a minimal signed tombstone and provenance hash, and exclude erased payloads from active storage/backups. - [x] Maintain deterministic human-readable Wiki, Soul/identity, project, and relationship projections with source hashes, confidence, revisions, contradiction state, classification redaction, and search/topic indexes. - [x] Keep authority and lineage projections read-only; convert every attempted projection edit into a reviewable unsigned proposal rather than canonical state. - [x] Add a Navi-specific signed relationship graph independent from Chatroom contacts and package trust. - [x] Support primary operators, scoped delegates, collaborators, trusted Navis, guests, organizations, realm authorities, and blocked identities with signed offer, acceptance, revision, suspension, rejection, revocation, and block evidence. - [x] Default to the Navi speaking as itself. Speaking for an operator requires an explicit signed, expiring, destination-limited representation rule and never widens file, identity, economic, administrative, or publication scope. - [x] Integrate memory, relationship, explanation, contradiction review, forgetting, proposal review, and derived views through guarded kernel syscalls and AI Echo without exposing keys, raw ciphertext, or Store access. - [x] Migrate current AI Echo memories, Wiki pages, Soul facts, and relationship references idempotently while preserving source provenance and leaving the legacy state recoverable until Phase 7. - [x] Add a Phase 4 umbrella covering unit, production-path, concurrency, restart, corruption, access-control, erasure, contradiction, projection, migration, and adversarial relationship cases. **Exit gate:** - [x] The Navi explains where a belief came from, how it changed, its current confidence, supporting evidence, and unresolved contradictions. - [x] An unauthorized operator, model, Faculty, Hand, or Manifestation cannot read private or restricted memory. - [x] Crypto-erased content cannot be recovered from active storage, derived views, or a newly produced backup. - [x] Relationship trust never automatically grants file, identity, economic, administrative, publication, or delegation authority. - [x] Equal-priority operator conflicts pause deterministically for approval. - [x] Representation fails closed unless the exact operator, destination, action, data classes, signature, status, and expiry all match. ### Phase 5: autonomy, resources, and delegation - [x] Preserve Inner Monologue as structured Navi-authored operational cognition, never provider-hidden reasoning. - [x] Support operator-readable and encrypted private journal entries. - [x] Store objectives, evidence, assumptions, uncertainty, alternatives, proposed actions, authority checks, and budget state. - [x] Run background work while any WebGPU OS tab or installed PWA process is alive. - [x] Use Web Locks and BroadcastChannel to elect exactly one cross-tab leader. - [x] Persist due work and catch up safely after reopening. - [x] Allow automatic inspection, organization, planning, and proposals while requiring existing authority or fresh approval for mutations. - [x] Distinguish Tool Processes, Hands, Echoes, Branches, and independent Navis. - [x] Give every Hand a signed narrow assignment, minimal context, expiry, temporary capabilities, resource limits, parentage, and mandatory report. - [x] Use VFS overlays or snapshots rather than Git worktrees. - [x] Require explicit approval and a new continuity key for persistent Branch creation. - [x] Meter tokens, cost, model and tool calls, wall time, GPU and VRAM, network, storage, worker count, and available power information. - [x] Reserve resources before dispatch and settle actual usage afterward. - [x] Derive model-attempt wall-time reservations from the signed task's remaining charge instead of catalog latency estimates. Enforce the same bounded deadline through an abort signal, retain per-attempt cleanup headroom, and shrink later planner or finalizer reservations without starving the task. - [x] Reserve fixed provider-envelope transport headroom, count flat request fees once for successful and failed attempts, and reconcile a successful resource settlement marker through bounded compare-and-swap conflict recovery. - [x] Keep flat request fees independent in ordinary Smart Routing and reject a flat-fee autonomous route before durable scheduling while the autonomous daily-budget contract remains token-price-only. - [x] At 90 percent utilization, reduce parallelism and switch to approved cheaper or local routes. - [x] Ask before the hard limit or stop safely. - [x] Reserve 5 percent, two tool calls, and 30 seconds for verification and compensation. - [x] Keep Inner Monologue journal authority component-local, while retaining aggregate diagnostics for background coordination, delegation, and Branch keys. Retry transient authority-chain binds in dependency order without duplicating a scheduled retry or retaining a timer after recovery. Phase 5 closes with two consecutive complete passes of 13 isolated suites and 175/175 assertions per pass: resource accounting 16/16, cognition metering 13/13, local-runtime telemetry 9/9, autonomy 12/12, AI Echo autonomy 15/15, delegation 21/21, Branch keys 10/10, VFS overlays 13/13, kernel agency 9/9, guarded syscalls 7/7, Faculty resource recovery 14/14, bounded Hand execution 19/19, and trusted storage/browser boundary receipts 17/17. The close regression also passes Phase 0 through Phase 4, the real signed Faculty production path, AI Echo smoke 354/354, and resource hardening 6/6. The WebGPU OS release bundle passes with 2,002 modules, zero skipped modules, classic-script validation, 1,387 copied site files, and a CRC-verified 1,386-file archive. At this historical Phase 5 close, the `navi-v1` rollout gate remained disabled until Phase 7. The 2026-07-28 regression pass adds kernel agency 10/10 and confirms that a degraded delegation or Branch-key component cannot falsely make the canonical Inner Monologue journal unavailable. **Exit gate:** - [x] Background work runs once across multiple open tabs. - [x] Missed work resumes safely after reopening. - [x] A Hand cannot access unrelated files, private memory, credentials, or authority. - [x] Expired Hands and capabilities cannot continue working. - [x] Concurrent reservations cannot overspend. - [x] A mutation can still be verified or compensated after its ordinary budget expires. ### Phase 6: Manifestations and Construct handoff - [x] Register AI Echo as the primary OS Manifestation. - [x] Define active, observing, available, delegated, private, offline, and embodied-elsewhere presence states. - [x] Add Manifestation adapters for: - [x] AI Echo portrait and request-scoped approval pop-up. - [x] Voice presence. - [x] Construct body. - [x] Generated character. - [x] Vehicle or drone. - [x] Environmental intelligence. - [x] Remote projection. - [x] Declare each Manifestation's sensors, actuators, channels, permissions, and limitations. - [x] Implement signed handoff envelopes containing objectives, context, authority, pending actions, commitments, Manifestation limits, and causal head. - [x] Ensure avatars, voices, bodies, and presence state never become identity authority. - [x] Reuse engine model, rigging, animation, collaboration-presence, and spatial-context systems. **Verification evidence:** The Phase 6 fail-fast umbrella passed twice with seven isolated browser suites and 71/71 assertions on both runs: continuity signing 6/6, Manifestation service 13/13, kernel lifecycle 7/7, real production handoff and return 6/6, adversarial boundaries 7/7, Construct adapter 13/13, and AI Echo Presence 19/19. The later final Alpha replay supersedes the earlier regression counts and retains Phase 6 at 71/71. **Exit gate:** - [x] One active project moves from AI Echo into a Construct body. - [x] The Construct resumes the same task and authority scope. - [x] Returning to AI Echo preserves pending work, memory, receipts, and identity. - [x] A Manifestation cannot perform actions outside its declared sensors, actuators, or permissions. ### Phase 7: recovery, reconciliation, network hooks, and alpha - [x] Produce encrypted, signed Navi backup bundles. - [x] Include identity, Covenant, key certificates, lineage, selected memory, Faculties, relationships, Manifestations, and state roots. - [x] Validate signatures, encryption, lineage links, schema versions, state roots, and file checksums before restore. - [x] Restore into a recovery branch rather than overwriting the active Navi. - [x] Show typed reconciliation differences. - [x] Require approval before merging recovered changes. - [x] Prevent non-canonical branches from publishing, widening authority, transferring identity, or rotating the continuity root. - [x] Create a new independent identity with ancestry attestation during permanent separation. - [x] Define Particle Network adapters for signed identity, lineage-head witnessing, revocation, relationship handshakes, Faculty packages, delegation requests, and receipts. - [x] Replicate approved commands, events, artifacts, and receipts only. - [x] Never replicate raw model output, credentials, private memory, or hidden reasoning. - [x] Complete the automated adversarial, crash-recovery, browser, and mobile viewport test matrix. - [x] Retire the Settings-only rollout activation control after automated Alpha and make Navi start automatically on new and existing origins. - [x] Remove the user/app on/off mutation surface and the `navi.feature.manage` authority. Retain a read-only kernel health projection. - [x] Normalize missing, malformed, and legacy disabled rollout records to the built-in enabled policy. A policy-storage failure cannot grant service authority or prevent the built-in runtime from starting. - [x] Allow a valid current Passport operator with no primary Navi to start the runtime. Keep identity-dependent services non-authoritative with typed dependency states, then rebind Manifestations, Agency, and Particle Network at the exact Continuity generation after creation, recovery, quarantine, or primary selection. Missing, stale, or revoked operators remain fatal to their bound services and expose exact health without publishing authority. - [x] Route AI Echo Wiki organization and nested protocol sampling through persisted Navi tasks. Remove their raw-provider fallback paths and fail closed when the Navi-authoritative executor is unavailable. - [x] Replace the ambient shell AI widget with a hidden-by-default approval and elicitation pop-up. It contains no general chat, provider, executor, task, protocol, or timeline surface and appears only for a pending decision. - [x] Attach bounded operator guidance to the exact request and elicitation scratchpad, preserve exact approval parameters, default focus to Deny or Dismiss, and clear expired or settled blockers authoritatively. - [x] Keep approval pop-up appearance customization cancel-safe while its Settings preview reacts live to label, dock, accent, scale, width, and opacity changes. - [x] Route reviewable user-adaptation suggestions through the same hidden-by-default request pop-up with an immutable preference snapshot, provenance, confidence, exact revision binding, and non-blocking lifecycle. - [x] Auto-apply only fresh, explicit, exact low-impact preferences for response length, emoji style, and measurement units. Restored, imported, free-form, autonomous, tool-use, sensitive, and authority-changing suggestions require review or are denied and redacted. - [x] Harden adaptation review with app-scoped request, dedupe, timeout, and cancellation metadata; bounded immutable elicitation payloads; duplicate-ID tombstones; shared secret detection; exact suggestion fingerprints; locked full-state persistence; bounded retry; and teardown cleanup. - [x] Prevent app-owned command callbacks from receiving the raw kernel or a reusable kernel session token while preserving kernel-owned command context. A live localhost UI probe submitted the review-only tool-use preference through AI Echo. The request appeared in the shell widget with the exact preference and provenance, `Reject` held default focus, no task blocker was created, and settlement removed the card while leaving behavior unchanged. **Current Phase 7 automated evidence:** `python tests/navi/run_phase7_tests.py` passes 12 isolated suites and 178/178 assertions: contracts 9/9, signed backup and recovery 17/17, recovery-branch authority 22/22, settlement checkpoints 5/5, crash/replay runtime 20/20, kernel recovery 8/8, OS authority 12/12, Particle Network adapter 22/22, kernel network boundary 10/10, always-on runtime policy 11/11, and AI Echo Recovery 21/21 at both desktop and a 390 by 844 mobile viewport. The backup suite exports and verifies selected principal identity, editable per-Navi identity profile, self-model, Covenant, certificates, lineage, memory, Faculty, relationship, Manifestation, handoff, and state-root families while excluding provider-route evidence. Post-mutation, post-signature, and post-lineage crash windows reuse the exact signed receipt and never duplicate a canonical mutation or lineage event. A real-browser bootstrap probe and the kernel-network regression prove that a valid Passport operator with zero Navis can start the built-in Navi runtime. Particle Network reports `dependency-unavailable / NAVI_NETWORK_PRIMARY_UNAVAILABLE` until genesis. The Continuity `created` event then rebinds Manifestations, Agency, and Particle Network to ready without changing Navi identity. Missing or stale operators remain fatal to operator-bound services, publish zero authority, and expose their exact unavailable state. (Source: `webgpu-os/kernel/KernelBootstrap.js` and `tests/navi/phase7-kernel-network.test.js`.) **Final alpha acceptance:** - [x] Create two isolated Navis and select a primary. - [x] Start an OS task through the production remote-model route using a controlled provider adapter. - [x] Change remote provider routes without losing task continuity. - [x] Continue the same task through the optional local-runtime route. - [x] Invoke, verify, receipt, revoke, and retest a signed Faculty. - [x] Delegate verification to a bounded Hand. - [x] Prove the Hand cannot access private memory or unrelated files. - [x] Move the Navi and task from AI Echo into the Construct. - [x] Close and reopen persistent kernel services and safely run scheduled cognition catch-up exactly once. - [x] Export and restore the Navi into an independent clean browser store that represents a second device. - [x] Rotate the operational key without changing `naviId`. - [x] Reconcile a recovery branch while preserving both histories. - [x] Reproduce the complete signed receipt and lineage chain. - [x] Pass existing AI Echo, VFS, storage, tool-loop, resource, bundler, and OS smoke tests. - [x] Pass new Navi unit, integration, adversarial, concurrency, corruption, recovery, and end-to-end tests. **Automated Alpha evidence:** the current `python tests/navi/run_navi_alpha_tests.py` acceptance surface contains 30 serial fail-fast gates with 1,530/1,530 assertions and 2/2 structural gates. The result includes Phase 0 backup and rollback preflight, legacy migration, real WebAuthn PRF, continuity, remote-to-remote-to-local cognition fallback, Faculty, memory, relationships, autonomy, resource governance, Manifestations, recovery, network authority, Artifact Workspace 8/8, AI Echo 450/450, storage atomicity 10/10, and resource hardening 6/6. The latest storage receipt is `785bc3e131d198ad442ab40b2ae98564c2bd0f13612187f776a327355693cd45`. The import audit resolves 299 files and 187 engine/state exports. The no-cache release bundle passes with 2,020 modules, zero skipped modules, 25 validated runtime-reachable deployment files, classic-script validation, and a CRC-verified 1,361-file site archive. Its copied-site and ZIP-member counts are both 1,361 by contract. ### Live deployment validation These checks require the operator's extension-owned credentials, installed local model, installed PWA lifecycle, or another physical device. They are not simulated or silently marked complete by the repository tests. - [ ] Run one real remote-provider task, switch to a second real provider, and continue it through the operator's loaded GGUF runtime. - [ ] Close and reopen the installed OS or PWA and inspect one scheduled cognition catch-up receipt. - [ ] Restore the encrypted export on a physical second device, inspect the reconciliation diff, and approve or reject it. - [ ] Start the OS on a clean origin, verify that Navi starts automatically with no on/off control, and confirm that the kernel creates exactly one bounded- partner `AI Echo` primary with device-only recovery and no factor marked as shown. Reopen the OS and confirm the same `naviId` remains primary. The code workstream is complete when the checked automated gates remain green. Live deployment validation is complete only after the four operator-owned checks above are recorded. Navi is already a built-in automatic runtime; these unchecked receipts validate real providers, installed lifecycle behavior, physical recovery, and live service health rather than activating the product. ## AI Echo Intelligence Upgrade — Post-Alpha Phase 8 Phase 8 strengthens AI Echo's task continuity, investigation discipline, context selection, output discovery, and operator-facing explanations. It is additive. It does not replace the Navi authority, Faculty, memory, routing, Artifact, Live Patch, or Recycle Bin contracts completed in Phases 0 through 7. ### Phase 8.0: Contracts and Regression Baseline - [x] Append this post-Alpha workstream to the canonical Navi delivery plan. - [x] Complete clean-room behavioral audits of Augment, FAIL, and Blackboard. Record transferable scenarios and gaps without copying their source, prompts, wire formats, or runtime dependencies. - [x] Add strict validators, canonical serialization, valid fixtures, malformed fixtures, and unknown-field rejection for all eight Phase 8 contracts. - [x] Import the audited behavioral scenarios as WebGPU OS tests rather than importing implementation source. - [x] Record 104 focused checks green at the Phase 8 planning baseline: 27 Phase 2 context-compiler checks, 12 Phase 3 AI Echo Faculty checks, 14 RealmForge workflow-contract checks, 6 Phase 3 AI Echo descriptor checks, 44 Phase 2 executor-routing checks, and 1 focused LLM-runtime context check. The Phase 8 public contracts are: | Contract | Required purpose | Status | | --- | --- | --- | | `navi-investigation-case-v1` | Bounded Investigation Episode, hypotheses, phase transitions, budgets, and deterministic stop reason. | [x] | | `navi-investigation-evidence-v1` | Source-bound observation, hash, time, confidence, contradiction, and verification evidence. | [x] | | `navi-task-state-v1` | Unified current-task objective, steering, progress, blockers, approvals, outputs, receipts, and remaining budget. | [x] | | `navi-context-manifest-v1` | Content-free context composition, classification, truncation, disclosure, and difference evidence. | [x] | | `navi-resource-selection-v1` | Candidate resource readiness and the selected or rejected reason codes for one round. | [x] | | `navi-strategy-scorecard-v1` | Per-Navi advisory strategy outcomes derived from verified evidence. | [x] | | `guidance-faculty-candidate-v2` | Reviewable learned guidance with independent success evidence and exact descriptor bindings. | [x] | | `workspace-output-index-v1` | Rebuildable references to canonical workspace outputs without moving or duplicating them. | [x] | **Exit gate:** - [x] Valid Phase 8 fixtures canonicalize deterministically. - [x] Malformed fixtures and unknown fields fail closed. - [x] The 104-check planning baseline and every existing Navi, AI Echo, VFS, storage, tool, resource, browser, and bundle gate remain green. Phase 8.0 evidence recorded 2026-07-28: Phase 8 contracts 11/11, legacy Navi contracts 9/9, the focused planning baseline 104/104, Phase 3 112/112, Phase 5 183/183, Phase 7 179/179, atomic storage 10/10, resource hardening 6/6, Artifact Workspace 8/8, AI Echo smoke 472/472, import audit 324 files and 187 exports, and a successful no-cache 2,059-module WebGPU OS bundle. The umbrella expectations were updated to the live suite totals; no product behavior was weakened to satisfy a check. ### Phase 8.1: Unified Task State, Steering, and Progress - [x] Add one `navi-task-state-v1` projection containing the objective, accepted steering, completed work, current action, blockers, approvals, evidence, Artifacts, receipts, and remaining budget. - [x] Extend active-task steering with `checkpoint-answer` while retaining correction, additive instruction, redirect, cancel, and status request. - [x] Invalidate stale plans and approvals when accepted steering changes scope. Preserve completed verified evidence and unaffected work. - [x] Advance visible progress only from verified evidence or an authoritative state change. - [x] Stop repeated fingerprints, repeated observations, repeated status calls, and alternating no-progress loops deterministically. - [x] Grant at most one bounded budget extension after measurable progress while preserving the verification and compensation reserve. - [x] Reconnect the AI Echo UI to the kernel stream registry with an exact sequence cursor. Replay unseen events only. - [x] Render checkpoint questions in the request-scoped approval pop-up with two to four bounded choices and bind the selected answer to the exact task. - [x] Keep explicit cancel, status, urgency, correction, and deferral commands deterministic and local so operator control never waits for another model. - [x] Route only ambiguous steering through an isolated, free-only Smart Routing lane while the selected main model continues its current dispatch. - [x] Keep steering-model output advisory: it cannot cancel work, approve an action, call a tool, grant authority, or select its own delivery boundary. - [x] Fall back to deterministic local additive steering when no approved free remote route is healthy or its classifier envelope is invalid. **Exit gate:** - [x] Mid-run steering merges into the active task without replacing its objective or erasing completed evidence. - [x] A stale approval cannot execute after a scope-changing steering event. - [x] Remount or reconnect replays only unseen events and preserves the current task projection. Phase 8.1 evidence recorded 2026-07-28: task-state, steering, progress, budget, and checkpoint runtime 18/18; stream replay, remount, retention-gap recovery, session switching, and checkpoint UI 12/12; executor routing and descriptor invalidation 44/44; AI Echo smoke 472/472; Phase 8 contracts 11/11; resource hardening 6/6; and the AI/OS import audit passed across 327 JavaScript modules and 187 registered engine/state exports. Adversarial cases prove that volatile freshness metadata and unverified mutations cannot manufacture progress, failed callbacks do not advance cursors, expired replay prefixes are visible, and stale task revisions, steering epochs, approvals, and descriptors fail closed. #### Bounded observation-fingerprint settlement checkpoint - [x] Keep complete read-only tool evidence in the authoritative result and receipt paths; never copy an evidence body into a progress fingerprint. - [x] Reuse the semantic tool-round fingerprint for read-only stagnation detection so volatile timestamps are ignored and large search results remain bounded. - [x] Preserve the fail-closed 16,384-character progress-guard contract rather than weakening validation around an oversized producer. Checkpoint evidence recorded 2026-07-31 for incident `AEI-ai-task-1785517831023-1`: two successful tool-search observations no longer fail settlement when their evidence bodies exceed the fingerprint limit. The oversized-result regression passed inside executor routing 111/111, the task progress runtime remained green at 21/21, AI Echo smoke passed 481/481, and the production 2,080-module bundle completed with zero skipped modules and 52 signed packages. ### Phase 8.2: Deterministic Sherlock Investigation Episode - [x] Upgrade the existing `code_investigator` Guidance Faculty into an OS-owned Investigation Episode instead of adding a second agent loop. - [x] Enforce the phases frame, generate three to five hypotheses including one non-obvious hypothesis, gather three to six read observations, name the largest evidence gap, run a discriminating test, classify each hypothesis, and stop deterministically. - [x] Enforce hard bounds of four cycles and 24 evidence records. Neither a model, Guidance Faculty, nor approval may expand the Investigation Episode. - [x] Store each observation's source, content hash, time, confidence, contradictions, and verification state under `navi-investigation-evidence-v1`. - [x] Route every investigation tool through the ordinary Faculty, capability, ToolRouter, and receipt path. Keep every mutation in a separate proposal and approval lifecycle. - [x] Show operational evidence, uncertainty, and hypothesis status. Never expose or claim provider-hidden chain-of-thought. - [x] Auto-select Sherlock only for audit, diagnose, investigate, root-cause, or materially uncertain tasks. **Exit gate:** - [x] The episode pivots when evidence contradicts its leading hypothesis. - [x] Replaying the same inputs produces the same phases and stop reason. - [x] The conclusion cites its evidence and unresolved uncertainty. - [x] Investigation cannot mutate data or widen authority. Phase 8.2 evidence recorded 2026-07-28: deterministic Investigation Episode 22/22; receipt, recovery, production Finalizer, cancellation, steering, and atomic-commit integration 27/27; kernel-owned human proof review 16/16; cross-tab task-head assertion and atomic episode/case commit 6/6; unified task runtime and commit-boundary steering 20/20; and Phase 8 contracts 11/11. These 102 focused checks prove the four-cycle/24-evidence hard bounds, contradictory evidence pivot, deterministic replay and stop reasons, exact source-projection attestation, local-only review, fail-closed cancellation and stale task heads, and observation-only authority. Cognition service 39/39, cognition Store 13/13, resource hardening 6/6, the 2,065-module WebGPU OS bundle dry run, and the AI/OS import audit across 330 JavaScript modules and 187 registered engine/state exports also passed after the atomic persistence changes. ### Phase 8.3: Context, Resource Discovery, and Dynamic Skills - [x] Let the app collect bounded context candidates. Make `NaviContextCompiler` the sole Navi component that admits, classifies, truncates, and discloses them. Keep generic non-Navi chat independent. - [x] Emit a content-free `navi-context-manifest-v1` receipt and a context difference that explains additions, removals, truncation, and denied classes. - [x] Record resource readiness, attestation, health, prerequisites, modality, cost, latency, verifier, and compatibility before selection. - [x] Emit one `navi-resource-selection-v1` receipt per planning round with selected and rejected resources plus deterministic reason codes. - [x] Bind every selected tool and resource to its current descriptor and verifier. Expose only selected schemas, then use bounded resource search when the planner needs another capability. - [x] Allow a valid declared tool to run without a Dynamic Skill. Skills provide guidance; they never become tool authority. - [x] Auto-enrol only pinned, trusted, built-in Faculties. Stop locally with an actionable not-ready state before provider dispatch when a required Faculty is unavailable. - [x] Require two independent verified successes, matching live descriptor and verifier identities, no uncompensated failure, and operator review before a learned `guidance-faculty-candidate-v2` can become enabled guidance. - [x] Add per-Navi advisory strategy scorecards. Strategy scores may rank guidance but cannot sign, self-enable, select authority, or alter Covenants. **Exit gate:** - [x] Disallowed private or restricted context never reaches a provider. - [x] A declared skillless tool can execute through its normal authority path. - [x] Descriptor, verifier, schema, path, argument, or approval changes fail closed before execution. - [x] Learned guidance cannot self-enable, self-sign, or widen authority. Phase 8.3 evidence recorded 2026-07-29: Phase 8 contracts 11/11, context manifest and context-difference controls 23/23, resource catalog and selection 27/27, guidance strategy and review gates 10/10, real Faculty production path 8/8, Faculty service settlement 19/19, provider error transport 25/25, model broker routing and bounded fallback 35/35, and executor routing 51/51. The tests prove that context admission stays local and content-free in its manifest, skillless tools remain independently usable, descriptor/verifier drift fails closed, novel positive retry hints cannot escape the approved route set or configured attempt bound, and learned guidance cannot authorize itself. #### Built-in tool Faculty signing and discovery checkpoint - [x] Make the Python release signer discover every static AI Echo and kernel tool registration before it creates an official package. - [x] Require every discovered descriptor to be covered by exactly one signed built-in Faculty or one reviewed dedicated-boundary exclusion. - [x] Fail the release when a tool registration has no checked descriptor hash, when a stale hash has no registration, or when signed groups overlap. - [x] Bind 101 reviewed tools into seven ring-0 deterministic Faculty packages. Keep 22 Artifact, extension/browser, developer-JavaScript, and dynamic- indirection tools in their existing dedicated security boundaries. - [x] Provision the exact built-in Faculty just in time for the active Navi and requested tool. Preserve operator-disabled and revoked state. - [x] Reject model text that contains an unexecuted known-tool JSON envelope. Permit fenced examples and answers backed by a matching successful receipt. Checkpoint evidence recorded 2026-07-31: the source scanner found all 123 live registration literals; a synthetic unreviewed registration made signing fail; four Python signer/package checks passed; official package and certificate checks passed 4/4; browser package, provenance, descriptor, authority-envelope, and output checks passed 8/8; the Phase 3 Faculty umbrella passed 120/120; and executor routing passed 110/110. The production bundle then discovered the complete registration set, signed 52 official packages, compiled 2,080 modules with zero skipped, and validated the deploy archive. The WebGPU OS release now stops during signing instead of leaving a newly added tool to fail during a user's first request. ### Phase 8.4: Outputs, Dossiers, and Explainability - [x] Build `workspace-output-index-v1` as a rebuildable index of references. Never move, rename, or duplicate a canonical output to index it. - [x] Record path, originating app, Navi, session, task, MIME type, byte size, hash, revision, modification time, classification, verification, and preview capability. - [x] Cover Notepad, Paint, Wiki, RealmForge, Live Patch, Artifacts, and every app that registers an output contract. - [x] Reserve the term Artifact for canonical Artifact Studio projects. Label other indexed files and app results as workspace outputs. - [x] Add a rebuildable project dossier linking tasks, accepted steering, outputs, evidence, receipts, blockers, decisions, and suggested next action. - [x] Add a local Why projection for task state, evidence, resource selection, routing, approvals, and verification. It must not expose hidden reasoning. - [x] Extend Artifact Studio with Open, Edit, Tweak, Compare, and lazy preview flows over exact revision-qualified references. - [x] Explain Smart Routing with selected, rejected, and bounded counterfactual routes without exposing credentials or private prompt content. - [x] Rank semantic browser actions through the existing Browser Faculty. Bind them to page fingerprints and surface challenges, and retry only while the exact page state remains unchanged. - [x] Add no Playwright, Node.js, raw page JavaScript, credential access, or wildcard browser messaging to the production path. **Exit gate:** - [x] Files and app outputs remain findable with provenance, verification, and a safe preview when supported. - [x] The index points to canonical data and never creates a shadow copy. - [x] AI Echo never claims an output is missing before checking the index and its authoritative source. Phase 8.4 evidence recorded 2026-07-29: Workspace Output Index 10/10, project dossier 11/11, explainability and semantic-browser hardening 20/20, Artifact Studio 8/8, AI Echo tool descriptors 7/7, AI Echo Faculty integration 16/16, and executor routing 51/51. The 2,075-module WebGPU OS bundle dry run also passed with zero skipped modules. Ordinary files and app results are presented as Workspace outputs; only exact Artifact Studio revision contracts use Artifact terminology. Missing-output claims now require canonical VFS plus rebuilt Output Index evidence, receive at most one corrective search round, and then stop with a typed result instead of inventing a missing or existing file. ### Phase 8.5: Consolidation and Release #### Route, cognition, and Companion release hardening checkpoint - [x] Compile task-stage model requirements before ranking, including purpose, modality, context, privacy, structured-output protocol, exact provider parameters, toolset hash, schema hash, and protected verification reserve. - [x] Preserve full model capability evidence, endpoint protocol, `supported_parameters`, quality, reliability, and provider-ranked order from the catalog through Smart Routing, AI Echo, and the Navi Model Broker. - [x] Require exact endpoint evidence for strict structured output. Bind OpenRouter requests to strict `response_format` plus `provider.require_parameters`; reject unknown or unsupported parameter contracts before provider dispatch. - [x] Classify OpenRouter `openrouter/free` and `openrouter/auto` as volatile router aliases. Keep them available for compatible ordinary chat, prefer concrete models, and expand an explicitly selected alias only into the unchanged approved catalog pool. Never authorize an alias itself for strict, effectful, delegated, or autonomous work. - [x] Canonicalize runtime camelCase model capabilities exactly once at the signed resource-contract boundary (`strictJsonSchema` becomes `strict-json-schema`). Preserve the exact broker requirement hash and route descriptor evidence, reject canonical alias collisions, and keep the global Navi identifier grammar strict instead of weakening every signed contract. - [x] Keep tools model-independent and independently usable without Skills, while binding every planner round to the exact selected tool descriptors and the content-free toolset hash used to construct its plan. - [x] Keep Artifact creation deterministic after one failed mixed-discovery plan: an exact corrective round exposes only the already-authorized `os.ai-echo.artifacts.create` and `os.ai-echo.artifacts.update` schemas, and redundant tool search, app/command listing, status polling, or Terminal probing cannot consume another execution round while the Artifact obligation remains unsatisfied. - [x] Treat an explicit “try/use the Artifact tool” follow-up as a bounded correction to only the immediately preceding Artifact request. Restore that obligation without allowing ordinary acknowledgements or unrelated older turns to reactivate stale mutations. - [x] Reject final-answer tool-call JSON and validator control envelopes before commit. A control envelope cannot satisfy the default answer schema locally; one bounded model correction receives explicit natural-language-only rules, and still-invalid output stops without becoming visible answer content. - [x] Define `terminal.command` as a read-only WebGPU OS command surface, never a host shell. Translate bounded Unix, cmd, and PowerShell navigation/read aliases into canonical VFS syscalls; reject host paths, shell launchers, chaining, redirection, substitution, and mutations with typed evidence. - [x] Bind reliability evidence to the exact provider, model, endpoint, protocol, purpose, and requirement hash. Decay observations and quarantine only the affected route after repeated typed incompatibility evidence. - [x] Treat append-only reliability samples as operational telemetry during reviewed-plan handoff. Preserve fail-closed dispatch checks for eligibility, route order, selection, attempt bounds, endpoint capabilities, privacy and access evidence, circuit state, and route configuration without letting a concurrent model completion invalidate an otherwise identical route. - [x] Refresh changed Smart Routing configuration for an existing Navi so stale endpoint-capability evidence cannot survive a catalog refresh. - [x] Classify HTTP, mid-stream, timeout, failed-finish, empty, malformed, and strict-schema failures, preserve bounded `Retry-After`, and attempt only a typed, policy-approved fallback without replaying a mutation. - [x] Validate repaired plans through the same strict task-graph compiler used before authorization. Scope repeated-output fingerprints to the logical planner state, consume repaired plans once, and stop only true same-state repetition without replaying a tool action. - [x] Exclude music, image, audio, video, embedding, moderation, reranking, and other specialist generators from conversational Smart Routing unless the provider explicitly declares chat capability. Preserve ordinary and local text-model fallback. - [x] Bind every displayed Smart Routing provider, model, reason, count, and explanation to the final kernel decision. Keep preliminary catalog screening totals separate and non-authoritative. - [x] Validate Inner Monologue and autonomous structured output before task completion or journal persistence. Reject malformed, truncated, partial, unknown-field, and schema-invalid output without committing a success record. - [x] Preserve signed malformed legacy cognition without rewriting it, but project it read-only as failed and quarantined so it cannot appear as successful canonical cognition. - [x] Bind background context classification to a kernel-owned provenance envelope, reserve the classified prompt plus fallback and verification lanes, retire undersized pre-update active tasks before reuse, and settle every terminal path. - [x] Preserve bounded typed provider failures through Companion 1.18.4. Type recognized Chrome runtime, message-port, and missing-response failures at the relay boundary; permit exactly one already-approved alternate only when a modern Companion violates its typed-status contract. Explicit auth, policy, cancellation, HTTP status, meaningful provider code, and non-retryable evidence remains terminal. - [x] Preserve the bounded provider-returned concrete model identifier through direct, development Companion, and Store Companion completion streams so a requested router alias cannot masquerade as the actual model in results. - [x] Preserve canonical endpoint `supported_parameters` evidence through the browser page, direct bridge, development Companion, Store Companion, cache, candidate normalization, Smart Routing, and the Navi broker. Reject stale or malformed cache records instead of using them as compatibility evidence. - [x] Require current, versioned, endpoint-matched catalog evidence before admitting a route to an explicitly requested strict-output lane. Bind the exact capability, schema, and tool parameter projections to SHA-256 evidence; a bare `response_format` declaration or legacy compatibility label is not sufficient authority. Refresh this evidence once when it may be stale. - [x] Compile locally validated planning and Artifact lanes independently from ordinary chat, including while the operator keeps a manual chat model selected. Provider-enforced strict JSON remains an optional explicit output contract. An explicit non-empty approved pool may supply the planning lane while every other lane remains pinned to the manual route; an empty pool never widens to discovered models. Show live eligible counts in Connections and warn before provider dispatch when the approved pool has no endpoint-verified planner. - [x] On `selection:no-eligible-model`, perform at most one bounded metadata refresh when evidence may be stale, rerank the unchanged approved pool, then emit a typed terminal result with grouped policy causes and bounded exact provider/model exclusions. Never guess, relax privacy, or widen authority. - [x] Serialize structured console diagnostics with bounded depth, size, cycle handling, accessor isolation, Error identity, and secret-key redaction so routing and Faculty state no longer degrades to `[object Object]`. - [x] Classify privacy on the exact route tuple: model, provider, product, endpoint, account setting, and request controls. Never infer privacy from a model family, creator, coding label, or `free` suffix. - [x] Keep billing access (`zero-cost`, free tier, research credit, promotional credit, paid, or local compute) independent from data-policy eligibility. A zero-cost route can remain public-only, while a paid route can remain conditional until its exact controls are attested. - [x] Route sensitive and private-Navi context only through `local-private` or `private-verified` evidence. Route proprietary code privately by default; if the operator explicitly relaxes that requirement, still require documented no-training behavior plus known bounded retention and collection. - [x] Bind training, retention, zero-data-retention, collection, evidence authority, expiry, and account/request-control hashes through resource selection and broker dispatch. Missing, stale, contradictory, or provider-self-asserted evidence fails closed. - [x] Preserve requested-model and provider-reported-model evidence separately. A dynamic router alias or request fallback remains non-concrete and cannot inherit the privacy or capability proof of an unobserved model. - [x] Treat Inner Monologue and autonomous reflection as sensitive operational cognition. Manual destination approval authorizes disclosure but does not substitute for current route-bound no-training, zero-retention, and data-collection evidence; unknown or public-only routes fail before dispatch. - [x] Assign every failed provider route a stable public `AE-RTE-*` error number and a request-bound `AEI-*` incident ID. Preserve a lower-layer classification when present and use `AE-RTE-1401` when typed status evidence is missing instead of inferring a cause from provider prose. - [x] Persist the terminal failed-run report before rendering the error. Restore route, duration, outcome, request ID, error number, incident ID, and bounded attempt evidence from the newest durable run when Diagnostics refreshes or AI Echo remounts. - [x] Dispatch local, remote, streaming, and synchronous model work through one kernel-owned fair scheduler. Keep FIFO order per Navi, rotate among Navis, enforce global/provider/exact-route/free-route and queue limits, and release capacity exactly once across success, error, timeout, and cancellation. - [x] Keep the complete reviewed, ordered Smart fallback plan under generic token or model-call pressure; do not convert its winner into a one-route pin. Change routes only when one measured binding dimension has a provably better compatible alternative: lower known cost, local network avoidance, remote GPU/VRAM avoidance, or lower known latency. Preserve the reviewed and selected route IDs plus the binding dimensions in content-free pipeline and copied diagnostic evidence. - [x] Treat an installed local GGUF record, a saved file handle, and an automatic-routing-ready model as separate states. Admit LLM Runtime to Smart Routing only when the driver is initialized, WebGPU has an attached device, the exact selected source is attached in the current browser session, and its tokenizer is complete. Require the exact model graph to pass the local executor capability probe too: architecture, tensors, tokenizer, device, and registered WebGPU primitives must form an executable graph. Keep unavailable local models visible for manual reconnection in LLM Runtime without advertising them as an online fallback. - [x] Preserve only allowlisted typed provider evidence across the direct and Companion transports: error number, incident/request/attempt/provider request IDs, bounded code and status, retryability, retry delay, provider, and safe status headers. Exclude prompts, response bodies, credentials, endpoints, arbitrary headers, causes, and stacks. - [x] Prepare development and Store Companion 1.18.6 with the same protocol-v4 typed-failure and bounded-concurrency behavior, unchanged permission and remote-code boundaries, duplicate-request rejection, cancellation, and request deadlines. - [x] Admit partial model evidence only when the provider explicitly marks a successful partial result and supplies visible answer or reasoning text. Do not reinterpret an ordinary nested error response as usable partial output or let it hide the route's typed HTTP failure. - [x] When a provider supplies a safe HTTP status but no safe structured reason, tell the operator the exact bounded status, explain that AI Echo stopped rather than guessing, and direct support to the preserved Error and Incident IDs in Diagnostics. - [x] Keep generic response formatting separate from strict JSON Schema execution authority. Ordinary plans and Artifacts use provider-native output plus exact local validation; only an explicitly requested provider-enforced schema requires endpoint-attested `structured_outputs`. A generic `response_format` declaration remains discovery evidence and cannot satisfy that optional strict contract. - [x] Transport planner actions through one closed provider-portable wire envelope with JSON-string arguments, validate the raw envelope before local compatibility normalization using exact `JSON.parse`, reject fenced or prose-prefixed JSON, and keep the complete correction schema separate from its bounded repair context. - [x] Keep the initial broker boundary limited to the exact planner transport envelope. Apply local argument, dependency, tool, and task-graph semantics after the response returns so a schema-valid but semantically invalid plan enters the bounded repair loop instead of consuming every route attempt. - [x] Keep repaired planner output under the complete semantic and task-graph validator, and prohibit every tool call until the repaired plan passes. Emit the stable validation reason before repair so the transition remains visible in Run Details and copied Diagnostics. - [x] Run the Navi broker's exact route-compatibility preflight before asking for remote-disclosure approval. A manually selected route incompatible with an explicit strict-output request stops locally with `NAVI_MODEL_STRICT_OUTPUT_UNSUPPORTED` or `NAVI_MODEL_STRICT_OUTPUT_UNVERIFIED`, performs no approval prompt, and sends no provider request. Ordinary locally validated planning does not require this provider capability. Bind the reviewed configuration revision and decision hash through approval and dispatch; cross-tab revision or decision drift stops before approval or provider execution. - [x] Carry the exact immutable, single-use broker execution plan produced by route preflight across the approval boundary instead of recomputing a second timestamped decision. Keep reviewed plans content-free, bounded to 128 entries, expiring after ten minutes, cleared on route reconfiguration and shutdown, and consumed at most once. Re-evaluate the semantic decision while excluding evaluation time, time-decayed scores and sample weights, score components, and derived healthy/degraded labels. Configuration, destination, policy, ranking, eligibility, verified reliability evidence, circuit, requirements, or capability drift still stops before provider dispatch. - [x] Give genuine reviewed-route drift the stable public error number `AE-RTE-1414`. Preserve reviewed and actual decision hashes, route revisions, and configuration hashes through the kernel stream, FinalReport, encrypted AI Echo state, and copied diagnostic report without exporting prompts, provider bodies, credentials, endpoints, or raw arguments. - [x] Preserve a failed preflight as a bounded `navi-model-route-blocker-v1` through the FinalReport, encrypted AI Echo state, restored conversation, and copied diagnostic report. Record required capabilities and provider parameters, bounded rejection reasons, route revision and decision hash, and explicit `dispatched=false`/`disclosureRequested=false` evidence. Map unsupported strict output to `AE-RTE-1410` instead of the generic route family. - [x] Render an in-chat structured-route recovery card for zero-dispatch strict-output blockers. Keep the manual chat model unchanged, state that no provider was called, open Connections with the endpoint-verified Planner filter active, and offer Smart Routing only when the already-saved explicit approved pool contains an eligible planner. Restored failed turns retain the same card. - [x] Project one content-free `ai-echo-pipeline-trace-v1` from the canonical resumable kernel run stream when FinalReport closes. Preserve retained ordered boundaries, timings, route attempts, settlement, terminal code, error number, and incident ID while excluding prompts, provider bodies, credentials, endpoints, raw arguments, and reasoning deltas. TaskLedger evidence remains separately canonical in FinalReport. Persist a differing served model only when local provider evidence binds its canonical ID to the exact requested route. - [x] Project one deterministic, allowlisted `ai-echo-diagnostic-report-v1` for the selected latest incident, latest run, or bounded session scope. Cap the canonical report at 256 KiB and include only typed incident, route, pipeline, model-attempt, filtered-log, environment, and sanitized JavaScript-location evidence. - [x] Add one-click Markdown copy and local canonical-JSON download to Diagnostics. Copy a precomputed immutable snapshot, preserve focus and text selection, and expose a selected manual-copy fallback when the Clipboard API is unavailable or denied. - [x] Convert OS-worker, browser-page, receipt, and durable-report JavaScript failures into bounded location-only frames. Preserve sanitized file, line, column, function, phase, and correlation evidence while excluding raw stacks, URL credentials/query/fragment data, extension IDs, Windows roots, prompts, provider bodies, and raw tool arguments. - [x] Verify diagnostic projection, redaction, canonical size, clipboard fallback, JSON download, OS-worker and browser-page failures, JavaScript receipts, and encrypted compact-report frame persistence in the existing real-browser harnesses. #### Local planning and bounded self-healing checkpoint - [x] Route ordinary conversation directly to the answer pass without a planner. Use the bounded Sherlock episode only for investigation-shaped work, and use the locally validated tool loop only when selected tools make the request an action task. - [x] Send ordinary planner, Sherlock frame, observation, and assessment calls through provider-native text/JSON transport. Normalize and validate their exact closed contracts locally; do not require provider strict JSON Schema. - [x] Reserve provider-enforced strict JSON only for callers that explicitly request a custom output schema. Local schema, descriptor, dependency, task-graph, Tool Firewall, approval, and verification checks remain the execution authority in every mode. - [x] Preserve OS-generated operational reasoning as inspectable decision, recovery, investigation, progress, authority, and verification summaries. Never request, reconstruct, persist, or display provider-hidden chain of thought. - [x] Apply bounded recovery at existing authoritative boundaries instead of adding a duplicate recovery manager: safe alternate route, local semantic validation, one bounded repair path, circuit/quarantine evidence, progress and repeated-fingerprint stops, outcome-unknown inspection, verification, compensation, and safe terminal escalation. - [x] Classify opaque HTTP 400/404/405/415/422 rejection before any output on a provider-native cognition call as an alternate-route condition. Advance only within the already reviewed attempt plan and disclosure receipts. Auth, policy, cancellation, partial output, and explicit strict-output failures keep their existing terminal semantics. - [x] Hold a newly accepted side-effect-free task for up to ten seconds across one transient Navi operator rebind. Resume only after the kernel authority is ready; otherwise fail closed with no direct provider bypass. - [x] Record route recovery and rebind waiting in the canonical kernel stream, Run Details, FinalReport, and copied content-free Diagnostics. #### Whole-pipeline diagnostic expansion checkpoint - [x] Preserve kernel-stream completeness evidence in FinalReport: the real source-event count, retained and omitted counts, first and last sequence, truncation and completeness state, synthetic-terminal provenance, source registry/executor/projector, and stage coverage. The durable trace now shares the stream registry's 1,000-event retention bound. - [x] Retain the canonical evidence lanes at their existing owners and compose their content-free structural projections in the copied report: TaskLedger task/graph/receipt evidence, model attempts, route checkpoints, encrypted compact-report state, and UI stream cursors. Context and resource records are represented by stable task bindings and trace boundaries; their deeper content-free manifest and settlement projections remain explicitly open below. - [x] Keep the existing deterministic, allowlisted 256 KiB export, redaction, sanitized JavaScript-location, immutable copy, and local-download boundary as the minimum safety contract for every future whole-pipeline report. - [x] Expand the diagnostic report through the versioned `ai-echo-execution-pipeline-v1` projection that composes the existing canonical lanes without creating a second durable ledger or treating UI activity and console logs as authoritative history. - [x] Include a bounded TaskLedger projection with task, graph, planner, tool, approval, receipt, witness, blocker, and verification status/count/hash evidence. Never export prompts, scratchpad content, raw arguments, results, acknowledgement payloads, or unrestricted URIs. - [ ] Include content-free context-admission, disclosure, resource-selection, dispatch-journal, broker-attempt, route-checkpoint, resource-settlement, and post-kernel persistence evidence with stable correlation identifiers. - [ ] Trace the app-owned boundaries before kernel dispatch and after kernel settlement, including configuration sync, Faculty readiness, Smart Routing, attachment admission, context-candidate collection, durable conversation and report persistence, usage accounting, mailbox/scratchpad updates, and the final Diagnostics refresh. - [x] Add UI delivery evidence for subscription, replay cursor, observed sequence, gap detection, remount recovery, and terminal rendering without promoting presentation state to execution authority. - [x] Bind every incident export to one exact request, session, and turn. Reject mismatched execution reports, traces, persistence observations, and stream cursors with explicit correlation-gap codes instead of joining evidence from separate runs that reused an identifier. - [x] Derive delivery completeness from a real `run.completed` boundary, an unbroken cursor, and the retained source sequence. Preserve synthesized terminals for diagnosis, but never use them as proof of kernel completeness or UI delivery. - [x] Verify encrypted state writes by exact readback before reporting a shard as storage-backed. A missing or no-op sandbox remains usable in memory but is reported as non-durable. - [ ] Preserve each bounded session run as an independent `runs[]` entry with its original request, incident, and sequence identities. Do not flatten or renumber events from separate executions into one synthetic pipeline. - [x] Remove the outer 192-event re-truncation of the retained 1,000-event FinalReport trace, or explicitly chunk it. Carry forward source, retained, omitted, and exported counts plus `truncated`, `complete`, stage coverage, and every additional report-size omission so the export cannot claim full coverage when evidence was unavailable or removed. - [ ] Add focused browser tests for every canonical lane, ordering and correlation, complete versus partial status, source-count preservation, over-limit chunking, redaction, restored and cross-tab runs, UI remount and gap recovery, bounded-session `runs[]`, and post-settlement persistence. - [x] Reuse one canonical resource-selection rejection vocabulary across the catalog producer and semantic contract validator so privacy and readiness exclusions cannot be misclassified by stale duplicate lists. - [x] Keep release signing non-mutating across bundle targets. Each release receives a fresh signed Artifact Studio package in its authoritative preamble, while sequential OS and platform builds retain the same checked-in raw-browser fallback bytes so neither target makes the other stale. - [x] Publish a staged release site through a bounded Windows rename retry and a verified file-atomic synchronization fallback when a running server or browser holds the live directory handle. Keep a complete previous-tree copy, verify the replacement manifest, and restore on failure without deleting the live site root. The current policy baseline was reviewed on 2026-07-29 and expires after 90 days unless refreshed. These tiers describe data handling for a route, not model quality, safety alignment, or company reputation. The catalog and policy implementations are in `webgpu-os/browser-extension/services/AIProviderCatalog.js` and `webgpu-os/kernel/ai-hub/SmartModelPolicy.js`. | Route trust tier | Current policy examples | Routing rule and caveat | |---|---|---| | `local-private` | User-controlled local GGUF runtime, Ollama, LM Studio, or llama.cpp | Eligible for sensitive data when inference and tools stay on the device. A local model that invokes a remote tool inherits that tool's separate disclosure policy. | | `private-verified` | Cerebras API; Fireworks open-model Chat Completions under its default zero-data-retention policy; an exact account/request-attested zero-data-retention route | Eligible for sensitive data only while exact, unexpired evidence shows no provider training, no prompt-content collection, and zero retention. Fireworks Responses requests require `store=false`; a stored Responses route is not equivalent. | | `standard-commercial` | OpenAI API, Anthropic commercial/API, and Groq without an attested zero-data-retention control | These services document no training by default, but bounded abuse, reliability, or safety retention can still apply. They are not private routes. They can handle ordinary code only when the code policy permits known temporary retention and collection. | | `conditional` | Together pending a verified zero-data-retention configuration; Mistral Scale or a verified Mistral opt-out route; an exact OpenRouter endpoint with account and request controls | Eligibility depends on account, product, endpoint, or request evidence that the OS cannot infer from the model ID. Until that evidence is attested, do not send sensitive data or proprietary code. | | `public-only` | OpenRouter free/dynamic routing without exact provider controls; Mistral Studio or Vibe Free without verified opt-out; unknown/custom/stale routes | Use only for public, non-sensitive prompts. `:free` proves price, not privacy. Unknown endpoint retention or training behavior fails closed. | Provider caveats come from the providers' current official documentation: [OpenAI API data controls](https://developers.openai.com/api/docs/guides/your-data), [Anthropic commercial training policy](https://privacy.claude.com/en/articles/7996885-how-do-you-use-personal-data-in-model-training), [Anthropic retention](https://privacy.claude.com/en/articles/7996866-how-long-do-you-store-my-organization-s-data), [Groq data controls](https://console.groq.com/docs/your-data), [Fireworks data handling](https://docs.fireworks.ai/guides/security_compliance/data_handling), [Cerebras retention](https://support.cerebras.net/articles/1811589793-does-cerebras-retain-my-data), [Together privacy](https://www.together.ai/privacy), [Mistral training use](https://help.mistral.ai/en/articles/347617-do-you-use-my-user-data-to-train-your-artificial-intelligence-models), [OpenRouter data collection](https://openrouter.ai/docs/guides/privacy/data-collection), [OpenRouter zero data retention](https://openrouter.ai/docs/guides/features/zdr), [OpenRouter provider routing controls](https://openrouter.ai/docs/guides/routing/provider-selection), [OpenRouter structured outputs](https://openrouter.ai/docs/guides/features/structured-outputs), [OpenRouter model metadata API](https://openrouter.ai/docs/api/api-reference/models/get-models), and [OpenRouter free variants](https://openrouter.ai/docs/guides/routing/model-variants/free). - [ ] Retire a legacy scheduler only after every production caller uses the canonical Navi task and stream path. - [ ] Keep one canonical context compiler, stream registry, read-provenance gate, tool-description source, message ledger, and Artifact store. Remove or migrate duplicate paths only after their callers and rollback data are known. - [ ] Preserve provenance, compare-and-swap revisions, receipts, rollback, and Recycle Bin recovery throughout consolidation. - [ ] Pass responsive desktop and mobile, cross-tab, reload, offline, extension, provider-failure, and provider-recovery tests. - [ ] Complete operator exercises for mid-run steering, Investigation Episodes, context differences, resource selection, output discovery, Artifact editing, browser semantic actions, reconnect, and recovery. - [ ] Record exact automated and operator evidence before checking a Phase 8 implementation or release item. Phase 8.5 interim release evidence recorded 2026-07-29: AI Echo browser smoke 475/475; Smart Model Policy 35/35; AI Echo route integration 45/45; Smart Model Picker and task-lane readiness 10/10; raw catalog-to-policy compatibility 5/5; Companion catalog/cache validation 7/7; direct-provider cache validation 3/3; bounded structured console formatting 4/4; typed provider-error transport 27/27; bounded Navi model routing 36/36; executor routing 58/58; resource selection 30/30; cognition service 46/46; Phase 8 intelligence contracts 11/11; kernel cognition 15/15; cognition Store 13/13; cognition resource metering 20/20; resource service 16/16; operational autonomy 13/13; AI Echo autonomy 16/16; kernel agency 10/10; built-in Artifact Studio provenance 5/5; AI Echo Faculty integration 16/16; Chrome Store package and relay security validation 15/15; development and Store provider catalog/service copies byte-identical; and the AI/OS import audit across 336 modules and 187 registered engine/state exports. Production WebGPU OS bundling passed across 2,075 modules with zero skipped modules, classic-script syntax clean, 25 runtime-reachable deployment files validated, and a CRC-verified 1,395-file site archive. The rebuilt Companion 1.18.2 archive contains 38 reviewed files, is 141,058 bytes, and has SHA-256 `21ffdfd353fb01c72c64ac17917bf9dd4bceb29f6059a0f10da12ca3eb5be8a0`. It preserves bounded provider code, HTTP status, retryability, and provider identity plus the concrete response model across direct, segmented, and reattachment relay paths; carries canonical endpoint compatibility evidence; invalidates incompatible pre-v5 catalog caches; and excludes prompt bodies, endpoints, headers, credentials, causes, and stacks. Strict planner repair now shares the authorization task-graph boundary, while volatile router aliases remain outside strict and effectful lanes. The remaining Phase 8.5 boxes stay open until the named operator, responsive-device, recovery, and duplicate-path exercises are completed rather than inferred from automated evidence. Phase 8.5 privacy-route hardening evidence recorded 2026-07-29: Smart Model catalog integration 11/11; Smart Model Picker 11/11; AI Echo route integration 47/47; Smart Model Policy 37/37; Navi Model Broker 44/44; Phase 8 resource selection 31/31; Phase 8 intelligence contracts 11/11; and provider-error transport 32/32. These eight focused suites passed 224/224 checks. Companion 1.18.3 package validation also passed 13/13 checks with unchanged permissions, no remote hosted code, and byte-identical development/Store privacy transports. This evidence does not close the remaining operator, responsive-device, recovery, or duplicate-path release gates. Phase 8.5 typed-transport and route-attestation evidence recorded 2026-07-30: Navi Model Broker 49/49; provider-error transport 36/36; AI Echo route integration 49/49; Smart Model Policy 37/37; Smart Model catalog integration 12/12; Phase 8 resource selection 31/31; executor routing 58/58; cognition service 46/46; and Smart Model Picker 11/11. These nine focused browser suites passed 329/329 assertions. Companion 1.18.4 Store validation passed 14/14 and the static relay projection passed 3/3. The production dry bundle resolved 2,075 modules with zero skipped modules, and the AI/OS import audit resolved 336 files against 187 registered exports. Development and Store relays retain the same typed projection; Store permissions, remote-code policy, and data collection are unchanged. The reproducible 38-file Store archive is 144,626 bytes with SHA-256 `24512e47e8a898845d7827c3c64a3bd24cf75fef6288c7375a4cdaa6317c38a0`. This automated evidence does not close the remaining operator, responsive-device, recovery, or duplicate-path release gates. Phase 8.5 route-diagnostics and dispatch-hardening evidence recorded 2026-07-30: provider-error transport 46/46; Navi Model Broker 50/50; Companion Store validation 15/15; static relay projection 3/3; executor routing 62/62; project dossier 11/11; and explainability plus semantic-browser hardening 20/20. The focused evidence confirms durable failed-route diagnostics, stable `AE-RTE-*` error numbers and `AEI-*` incident IDs, safe typed provider projections, fair per-Navi model dispatch with bounded provider and exact-route concurrency, explicit-only partial-result evidence, and status-specific public failure wording. Development and Store Companion 1.18.5 sources retain the same relay/service protocol. This automated evidence does not close the remaining operator, responsive-device, recovery, duplicate-path, boot, bundle, or complete-suite gates. Phase 8.5 strict-planner, manual-route, and trace evidence recorded 2026-07-30: AI Echo browser smoke 475/475; executor routing 85/85; deterministic Sherlock integration 27/27; resource selection 33/33; durable pipeline trace 7/7; stream continuity 12/12; provider-error transport 47/47; Navi Model Broker 51/51; Smart Model Policy 37/37; AI Echo route integration 49/49; catalog/cache compatibility 8/8; intelligence contracts 11/11; cognition service 47/47; and Store/static/strict-bundle compatibility 20/20. The focused source tree also passes whitespace validation. This evidence proves that incompatible manual models and cross-tab route drift stop before approval or dispatch, that strict transport rejects wrapped JSON, that provider-controlled model labels cannot enter durable diagnostics without route-bound attribution, and that a terminal failure remains traceable under one incident without recording prompt or response content. It does not close the remaining operator, responsive-device, recovery, duplicate-path, boot, or complete-suite gates. Phase 8.5 atomic release evidence recorded 2026-07-30: the final focused matrix passed 897/897 checks. The production OS build and its post-platform dry-run both resolved 2,076 modules and 27,423,166 source bytes; the platform build and its final dry-run both resolved 2,797 modules and 42,389,631 source bytes. Bundle freshness passed 2/2, both development bundles contain four current hardening markers, and neither contains an obsolete marker. The release signing regression passed 4/4 and proves sequential targets do not mutate the shared raw-browser fallback. The reproducible Store Companion 1.18.5 archive contains 38 files, is 148,505 bytes, and has SHA-256 `e1a5529ef3e0375bf1e254527507a16d03a6dccc943741702178d3bccfa63983`; Store validation passed 15/15 and static relay validation passed 3/3 with no remote hosted code, raw runtime JavaScript, or embedded console collection. This automated evidence still does not close the operator, responsive-device, recovery, duplicate-path, boot, or complete-suite gates. Phase 8.5 one-click diagnostic evidence recorded 2026-07-30: the existing AI Echo diagnostic-report real-browser suite passed 13/13 checks, the durable pipeline-trace and encrypted compact-report suite passed 8/8 checks, and the worker/console runtime-boundary suite passed 3/3 checks. These 24/24 focused checks cover strict unknown-field rejection, secret and URL redaction, V8/Firefox/Safari frame parsing, Windows-path minimization, location-only OS-worker and browser-page faults, sanitized JavaScript receipts, deterministic 256 KiB output bounds, clipboard and selected-text fallback, canonical local JSON download, and sanitized frame survival across encrypted state reload. The production WebGPU OS bundle also completed over 2,077 modules, passed classic-script syntax and the 25-file deployment contract, and produced a CRC-verified site archive. This automated evidence does not close the remaining operator, responsive-device, recovery, duplicate-path, boot, or complete-suite release gates. Phase 8.5 manual-chat/planner separation and preflight-recovery evidence recorded 2026-07-30: executor routing passed 85/85; AI Echo route integration 52/52; Smart Model Picker 12/12; diagnostic reports 15/15; durable pipeline trace 9/9; and the complete AI Echo browser smoke suite 481/481. These 654/654 checks prove that an incompatible chat model cannot cross the disclosure or provider boundary, an explicit approved planner pool remains independent from manual chat, an empty pool cannot admit discovered models, restored failures retain their recovery actions, and copied incidents preserve `AE-RTE-1410` plus their content-free route blockers. OpenRouter's live metadata for `cohere/north-mini-code:free` did not advertise `structured_outputs` during this audit, so it remains eligible for compatible chat work but cannot acquire strict planner authority. Capability decisions remain live-catalog and endpoint-evidence driven; no model IDs are hardcoded in routing policy. This automated evidence does not close the remaining operator, responsive-device, recovery, duplicate-path, boot, or complete-suite release gates. The final post-documentation production bundle passed 2,077 modules with zero skipped, classic-script syntax, the 25-file deployment contract, and CRC verification for its 1,396-file site archive. The Chrome Web Store extension package suite passed 15/15; this zero-dispatch planner incident required no extension transport change because it never reached the Companion bridge. Phase 8.5 whole-pipeline diagnostic implementation evidence recorded 2026-07-30: `ai-echo-execution-pipeline-v1` now composes the durable execution report, TaskLedger tasks and graph, planner rounds, tools, blockers, receipts, witnesses, routing, broker attempts, bounded resource-read structure, retention, encrypted state-shard evidence, and UI stream delivery around the canonical 1,000-event trace. Coverage declares each lane complete, observed, incomplete, missing, not required, or not dispatched. It cannot infer app intake from a downstream trace, kernel termination from UI consumption, or in-memory state from durable storage. Invalid identifier-shaped prose, email addresses, and path-like private values are omitted rather than rewritten. Exact request/session/turn binding and correlation-gap codes prevent evidence from separate runs from being joined. Diagnostic projection passed 23/23 checks; durable pipeline trace passed 13/13; stream continuity passed 12/12; executor routing passed 85/85; the complete AI Echo browser smoke suite passed 481/481; and the WebGPU OS release bundle completed with 2,077 modules, zero skipped modules, and a CRC-verified 1,396-file site archive. Deeper context/disclosure/resource manifests, app-owned outer events, independent bounded-session `runs[]`, and their exhaustive cross-tab/mobile matrix remain open above and are reported as gaps rather than fabricated evidence. Phase 8.5 reviewed-plan handoff and route-drift evidence recorded 2026-07-30: the attached incident proved route revision 36 and `planning:smart-2` remained unchanged while independently recomputed `evaluatedAt` values produced two different full decision hashes before any provider attempt. AI Echo now consumes the exact preflight plan after approval, then compares a timestamp-free semantic hash before dispatch. An advancing-clock regression dispatches exactly once, while forged decision hashes, configuration revision changes, and an opened circuit remain fail-closed with zero provider calls. Cognition service passed 50/50; executor routing 86/86; Navi Model Broker 51/51; AI Echo route integration 52/52; kernel cognition 15/15; durable pipeline trace 14/14; copied diagnostic reports 23/23; and the complete AI Echo browser smoke suite 481/481. The first manual Cohere strict-output blocker remains correct and separate: endpoint evidence does not attest `structured_outputs`, so it receives `AE-RTE-1410` and performs no provider call. This OS-only pre-dispatch repair does not change the Companion extension protocol or permissions. The production WebGPU OS bundle completed across 2,077 modules and 27,599,639 source bytes with zero skipped modules, classic-script syntax clean, all 25 runtime deployment files validated, and a CRC-verified 1,396-file site archive. Phase 8.5 planner-validation boundary and bounded-route diagnostic evidence recorded 2026-07-30 for incident `AEI-ai-task-1785460349818-1`: the first two approved routes returned typed strict-dispatch HTTP 400 failures; the third route returned the exact strict JSON envelope but failed local planner semantics. Initial broker validation now proves only the closed wire contract, then the OS performs argument, dependency, tool, and graph validation and sends semantic-invalid output through the existing bounded repair path. Repair output still receives the complete validator, and zero tools may execute beforehand. Copied diagnostics now state the configured, eligible, excluded, attempted, unattempted, and bounded-attempt counts plus a stable stop reason; public wording no longer claims that every approved route ran. Navi Model Broker passed 53/53, executor/planner routing passed 91/91, copied Diagnostics passed 25/25, and the complete AI Echo browser smoke suite passed 481/481. The production WebGPU OS bundle completed across 2,077 modules and 27,618,856 source bytes with zero skipped modules, classic-script syntax clean, all 25 runtime deployment files validated, and a CRC-verified 1,396-file site archive. Companion 1.18.6 and provider-error contract v4 assertions are synchronized; this incident required no new Companion permission or transport surface. Store validation passed 15/15; the reproducible 38-file archive is 150,162 bytes with SHA-256 `ac5dd046b85bc856e3118ce92c7d37373143f27988aa06ccf8f6deb8cc9152e0`. Phase 8.5 stable reviewed-route and repair-operation evidence recorded 2026-07-31 for incident `AEI-ai-task-1785468196552-1`: the reviewed repair route, configuration revision, configuration hash, selected route, and eligibility remained unchanged, but continuously decaying reliability scores changed the former whole-decision comparison during the approval delay. The dispatch-equivalence projection now binds route identity and order, exclusions, requirements, policy, capability and privacy evidence, reliability evidence, circuit state, and the exact selected route while excluding evaluation time, raw scores, sample weights, score components, and derived healthy/degraded labels. New reliability evidence, route reordering, circuit changes, configuration changes, or eligibility changes still fail closed before provider dispatch. Planner-repair route drift is now reported as its own pre-dispatch guard instead of being concatenated with the earlier semantic task-graph failure. Copied diagnostics reconstruct bounded primary and repair model operations from the canonical trace, preserving the three earlier provider attempts even when the terminal repair operation made zero provider calls. Cognition service passed 53/53, Navi Model Broker 53/53, executor/planner routing 92/92, copied Diagnostics 26/26, durable pipeline trace 15/15, resource selection 33/33, and the complete AI Echo browser smoke suite 481/481. The resource-selection runner was aligned with the repository's Chrome-first isolated-browser harness after Edge left its temporary profile locked. This OS-only correction changes no Companion extension permission, message, credential, or provider-transport contract. Phase 8.5 planner-repair correction evidence recorded 2026-07-31 for incident `AEI-ai-task-1785478018291-1`: the primary planner reached a schema-compatible route, but its closed transport contained locally invalid encoded arguments or dependencies. The repair request previously disclosed the complete strict transport schema, available tool names, and a generic validation error while omitting the referenced tools' parameter schemas. The repair model therefore had to guess the executable argument contract. Planner repair now receives a bounded, content-free correction envelope containing the exact referenced tool schema projection, the failing semantic path, the JSON-string argument rule, and the earlier-step dependency rule. The OS still performs complete descriptor and task-graph validation before authorization; repair guidance grants no tool authority and exposes no provider text or decoded arguments. Nested selected tool schemas retain bounded structural constraints so Artifact files and other composite inputs can be repaired without inventing fields. Executor/planner routing passed 95/95, Navi Model Broker 54/54, cognition service 53/53, kernel cognition 15/15, AI Echo route integration 52/52, resource selection 35/35, durable pipeline trace 15/15, copied Diagnostics 27/27, Artifact Workspace 8/8, and complete AI Echo browser smoke 481/481. The WebGPU OS dry bundle resolved 2,077 modules and 27,642,992 source bytes with zero skipped modules. This is an OS planner-correction change and does not alter the Companion extension protocol, permissions, or credential boundary. Phase 8.5 provider-native planning and bounded self-healing evidence recorded 2026-07-31 for incidents `AEI-ai-task-1785479372489-1` and `AEI-ai-task-1785481036097-1`: ordinary conversation now stays on the direct answer path; tool planning and Sherlock contracts use provider-native output with exact local normalization, descriptor checks, schema validation, graph compilation, authority, and verification. Provider strict JSON Schema is no longer a prerequisite for ordinary planning or Artifact creation and remains available only for an explicitly requested custom output contract. A pre-output opaque provider-native HTTP 400/404/405/415/422 now advances within the already reviewed, already disclosed bounded route plan; auth, policy, cancellation, partial output, and explicit strict-output failures remain terminal. The kernel executor also holds a new task across one bounded operator rebind and resumes only when the Navi authority is ready. Recovery is recorded in the canonical stream and copied diagnostics without provider content or hidden reasoning. Executor/planner routing passed 97/97; AI Echo route integration 52/52; Navi Model Broker 54/54; cognition service 53/53; kernel cognition 15/15; Smart Model Policy 38/38; Smart Model Picker 12/12; Sherlock episode, integration, proof-review, and atomic-commit suites 71/71; diagnostic report, pipeline trace, and stream continuity 54/54; Artifact and Faculty checks 29/29; complete AI Echo smoke 481/481; and Store Companion validation 15/15 plus four subtests. The WebGPU OS dry bundle resolved 2,077 modules and 27,653,682 source bytes with zero skipped modules. No Companion permission, message, credential, or transport contract changed. Phase 8.5 Artifact planner-visibility and discovery-loop evidence recorded 2026-07-31 for incident `AEI-ai-task-1785518678180-1`: Artifact Studio was installed, signed, executable, and its create/update descriptors were already selected, but the planner spent eight rounds invoking only tool discovery and one unrelated terminal action. Its fourth model operation then exhausted the bounded route plan on a rate-limited fallback, which masked the original omission. AI Echo 5.22.3 now presents operator-required Artifact mutation schemas first in the bounded provider-visible tool projection without changing local authority. One discovery-only plan is bypassed and receives an exact corrective round; a repeated discovery plan stops locally with `AI_ARTIFACT_DISCOVERY_LOOP` before another tool or fallback route is consumed. A terminal plan also cannot settle while no verified Artifact reference exists. Executor/planner routing passed 114/114, Phase 8 task runtime 21/21, official Artifact package 8/8, Artifact Workspace 8/8, AI Echo Faculty 16/16, complete AI Echo smoke 481/481, and the AI/OS import audit scanned 340 modules with all imports and braces valid. The production bundle discovered and signed 52 official packages, compiled 2,080 modules with zero skipped, verified 33/33 AI Echo modules, validated the 25-file deployment contract, and produced a CRC-verified 1,396-file site archive. Phase 8.5 concurrent route-telemetry evidence recorded 2026-07-31 for incident `AEI-ai-task-1785523584792-2`: the 5.22.2 diagnostic proved that route `planning:smart-10`, configuration revision 69, and the canonical configuration hash were identical at review and dispatch, while an append-only reliability observation changed the former semantic hash. AI Echo 5.22.4 now keeps reliability samples and their provider/model/endpoint bindings in the durable broker evidence but excludes the changing evidence-head hash from dispatch authority. The dispatch-equivalence guard still binds candidate eligibility and order, selected route, maximum attempts, requirements, policy, capability and privacy evidence, and circuit state. Configuration, eligibility, ordering, endpoint capability, policy, selection, attempt-bound, and circuit drift continue to fail closed before provider dispatch. Cognition service passed 56/56 including concurrent reliability telemetry, clock decay, derived health label, configuration drift, and circuit drift regressions; Navi Model Broker passed 56/56, executor/planner routing 114/114, resource selection 35/35, pipeline trace 15/15, copied Diagnostics 27/27, kernel cognition 15/15, and complete AI Echo smoke 481/481. The AI/OS import audit scanned 340 modules with all imports resolved and braces balanced. The production bundle compiled 2,080 modules with zero skipped, signed 52 official packages, verified all 33 AI Echo modules, validated 25 runtime deployment files, and produced a CRC-verified 1,396-file site archive. Phase 8.5 Artifact initiation and Terminal-dialect evidence recorded 2026-07-31 for incident `AEI-ai-task-1785539040249-1`: AI Echo 5.22.4 negotiated the signed Artifact Studio Faculty and selected its create/update descriptors, but the planner spent six tool calls on tool discovery and host-style Terminal probes, produced no Artifact reference or receipt, and eventually surfaced generic `AE-RTE-1499`. AI Echo 5.22.5 preserves the initial model's opportunity to inspect the selected tool set, then projects only the exact Artifact create/update schemas for one correction when any mixed discovery plan leaves the Artifact obligation pending. Mixed tool search, Terminal, app-list, command-list, and status plans are classified as redundant discovery and are never executed in that correction lane. The Terminal tool now declares and enforces one read-only WebGPU OS grammar over VFS, process, network, package, patch, storage, and command-registry observations. Familiar `dir`, `Get-ChildItem`, `type`, `Get-Content`, `Get-Item`, and `Get-Location` aliases translate deterministically into canonical OS reads; host shells, host paths, control operators, redirection, substitution, and mutating commands fail with typed local evidence before a syscall. The Terminal implementation received a separate reviewed descriptor hash so unrelated built-in Faculty authorities do not rotate. Executor/planner routing passed 114/114, Terminal descriptor and alias checks 10/10, built-in signing 4/4, official Artifact package 8/8, Artifact Workspace 8/8, AI Echo Faculty 16/16, and complete AI Echo smoke 481/481. The AI/OS import audit scanned 340 modules and 187 exports with every import resolved and brace balanced. No Companion permission, message, credential, or transport contract changed. Phase 8.5 Artifact follow-up and final-answer boundary evidence recorded 2026-07-31 for request `ai-task-1785545302141-2`: AI Echo 5.22.5 received the explicit correction “try the artifact tool,” but current-turn routing discarded the immediately preceding Artifact objective. The planner therefore executed two mixed discovery/Terminal plans, all four read calls failed, and the final chat route printed unexecuted tool-call JSON. The answer validator rejected the tool JSON correctly, but its own `{ errorCode, tool, invalidAnswer }` control envelope was locally wrapped as `{ answer: string }`, passed the default schema, and was committed as a successful visible reply in three milliseconds. AI Echo 5.22.6 now merges only an exact Artifact capability correction with the immediately prior user request, which activates the existing Artifact obligation and exact-tool correction lane. Finalizer control envelopes are non-answer values, their nested tool evidence is rejected explicitly, and a bounded repair pass receives a content-free natural-language-only correction contract. The original tool envelope, validator wrapper, or a fabricated success can no longer be committed as the answer. Executor/planner routing passed 116/116, official Artifact package 8/8, Terminal/tool descriptors 10/10, built-in signing 4/4, complete AI Echo smoke 481/481, and the AI/OS import audit resolved all imports and balanced braces across 340 modules. No Companion permission, credential, message, or transport contract changed. Phase 8.5 capability-aware planner-repair evidence recorded 2026-08-01 for historical incident `AEI-ai-task-1785510285994-1`: the incident ran roughly ten hours before the current 5.22.6 source and signed bundle. Its primary manual OpenRouter planning call and one bounded repair call both returned content that failed the exact local planner JSON transport, so no graph was admitted and no tool ran. The current diagnostic exporter reported its own 5.22.6 environment, not the historical runtime version, which made the restored incident appear newer than its timestamps. The remaining live defect was in the repair prompt: an explicit Artifact request whose malformed answer contained no parseable tool reference received no Artifact parameter schema. AI Echo 5.22.7 now binds the active saved-Artifact obligation into repair and discloses only the exact negotiated `artifacts.create` and `artifacts.update` schema projections when the rejected answer is prose or otherwise cannot name a tool. Full local descriptor, task-graph, authority, and verification checks remain mandatory before any action. Planner events now include a content-free response-shape projection that distinguishes exact objects, fenced or prose-wrapped candidates, multiple objects, incomplete containers, and no-JSON output without retaining provider text. Executor/planner routing passed 118/118 and copied Diagnostics passed 28/28. This change is OS-local and changes no Companion extension permission, credential, message, or provider-transport contract. Complete AI Echo smoke passed 481/481, the official Artifact package passed 8/8, tool descriptors passed 10/10, and the AI/OS audit resolved every import and balanced braces across 340 modules and 187 engine/state exports. The signed production bundle compiled 2,080 modules from 27,811,750 source bytes with zero skipped modules, verified all 33 AI Echo modules, validated the 25-file deployment contract, signed 52 official packages, and produced a CRC-verified 1,396-file site archive. Phase 8.5 resource-pressure and local-runtime readiness evidence recorded 2026-07-31 for incident `AEI-ai-task-1785548365139-2`: the UI reviewed `planning:smart-10` on OpenRouter, but the kernel's generic 90-percent resource pressure rule silently replaced it with `planning:local-fallback`, pinned the attempt bound to one, and dispatched an attached Gemma runtime that stopped at `budget-prefill-headroom`. The provider and planner-repair lanes were never reached. AI Echo 5.22.8 now retains the reviewed route for token/model-call or ambiguous pressure and changes route only for an exact binding dimension with a strictly better compatible alternative. A content-free `navi.resource.selection` boundary records the pressure ratio, binding dimensions, action, reason, and reviewed/selected route IDs. Local Runtime discovery now fails closed for automatic routing unless the driver, WebGPU device, exact model source, tokenizer, and model-specific executor graph are all ready; a saved handle, attached file, or unsupported graph alone cannot create a local fallback. Cognition service passed 56/56, executor and planner routing 119/119, model broker 56/56, AI Echo routes 53/53, local-runtime readiness and telemetry 13/13, cognition resource metering 20/20, resource service 16/16, copied Diagnostics 28/28, and pipeline trace 16/16. No Companion permission, credential, message, or transport contract changed. Phase 8.5 reviewed-failover and Windows publication evidence recorded 2026-07-31 for incident `AEI-ai-task-1785551498004-1`: AI Echo 5.22.8 correctly kept the reviewed OpenRouter route and excluded the unusable local runtime, but route-neutral token pressure converted the reviewed Smart plan into a manual-style `routePin`. That reduced 18 configured routes to one eligible attempt, so the broker could not advance after the selected NVIDIA endpoint returned typed HTTP 502 `PROVIDER_UNAVAILABLE`. AI Echo 5.22.9 now retains the complete reviewed fallback order and its attempt bound under token/model-call pressure. Manual selection remains one exact route, while an exact measurable cost, network, GPU/VRAM, or latency improvement may still create a bounded pressure-selected route. A regression proves a typed HTTP 502 advances from the reviewed primary to the next approved compatible remote model with both attempt receipts preserved. Separately, the production platform bundler now retries a Windows directory sharing violation and falls back to a verified file-atomic tree synchronization with a complete rollback copy when `release/site` cannot be renamed. The full bundler suite passed 77/77, including seven publication transaction and archive checks; cognition service 56/56, resource metering 20/20, model broker 56/56, executor/planner routing 119/119, AI Echo routes 53/53, copied Diagnostics 28/28, pipeline trace 16/16, and complete AI Echo smoke 481/481 passed. The exact `python bundle_engine.py --target platform --production --release --no-cache` command completed across 2,801 modules with zero skipped, verified all 33 AI Echo modules, validated 25 OS deployment files and 139 Playground module edges, signed 52 official packages, and produced a CRC-verified 349-file site archive. No Companion permission, credential, message, or transport contract changed. ### Phase 8.5 operator-controlled repair duration - [x] Trace incident `AEI-ai-task-1785558485992-1` across primary planning, repair routing, provider attempts, cancellation, and terminal settlement. - [x] Remove the fixed 45-second app-owned JSON-repair deadline. - [x] Keep provider routing attempt bounds, repeated-output detection, task resource authority, schema validation, and verification reserves intact. - [x] Keep explicit Stop authoritative even when provider transport ignores its `AbortSignal`. - [x] Keep steering accepted during repair and discard the stale repair result at the next safe boundary before any action can be authorized. - [x] Label Run Details as operator-controlled recovery rather than displaying an artificial countdown. - [x] Advance AI Echo to 5.22.10 and add focused completion and cancellation regressions. - [x] Rebuild and verify the signed production platform bundle. Incident evidence recorded 2026-08-01: the primary planning operation consumed 41,012 ms across three approved routes. The repair operation then retried the same leading route for 38,367 ms and began a second approved route, but the RepairLoop-wide 45-second timer cancelled that second attempt after 1,933 ms. The provider did not exhaust the reviewed fallback policy; the app-owned timer ended it. AI Echo 5.22.10 therefore gives RepairLoop no independent wall-clock deadline. One repair pass still uses the kernel broker's bounded approved-route policy, and only exact locally validated output can resume execution. The operator's Stop signal is raced against the provider operation, so it remains immediate even for a transport that fails to honor abort. Executor/planner routing passed 120/120, including the no-deadline completion and forced Stop regressions; model broker and cognition passed 56/56 each, resource metering 20/20, resource selection 35/35, copied Diagnostics 28/28, pipeline trace 16/16, resource hardening 6/6, complete AI Echo smoke 481/481, and the AI/OS import audit resolved every import and balanced braces across 340 modules and 187 engine/state exports. The signed production release then completed across 2,801 modules with zero skipped, signed 52 official packages, verified all 33 AI Echo modules, validated 25 OS deployment files and 139 Playground module edges, and produced a CRC-verified 349-file site archive. This is OS-local and changes no Companion extension permission, credential, message, or transport contract. ### Phase 8.5 provider-token accounting boundary - [x] Trace incident `AEI-ai-task-1785560028163-1` through both model operations and the resource authority. - [x] Stop treating cumulative provider input/output tokens as an AI Echo run fuse. - [x] Keep scratchpad and context admission independently bounded per model dispatch from the selected route's catalog context window. - [x] Run the AI Echo model lane without a cumulative OS resource lease; the selected provider/model contract, per-dispatch context admission, routing policy, and operator Stop remain authoritative. - [x] Retain tool authority, approval, duplicate-mutation, stagnation, verification, and receipt protections without presenting them as model context or lifetime token quotas. - [x] Keep provider token usage observable in provider usage, route receipts, and Diagnostics rather than enforcing it as a task lease ceiling. - [x] Advance AI Echo to 5.22.11 and pass focused, smoke, audit, and signed production build gates. Incident evidence recorded 2026-08-01: the first planning operation used three approved routes and completed after 75,216 ms. Its cumulative provider token charge reached 92.34% of the fixed 160,000-token task ceiling. A valid second planning operation then prepared 5,652 tokens of context but was denied before provider dispatch because it could not reserve its reviewed fallbacks plus the verification reserve. The task token and model-call vectors are now zero for AI Echo execution, and the cognition service treats that binding as telemetry-only instead of creating a cumulative model resource lease. Provider tokens remain measured in execution evidence, while the context compiler derives each dispatch's admission limit from the selected model's catalog window (for example, 262,144 advertised tokens minus safety and output reserves) and the scratchpad retains its own bounded section. Verification recorded 2026-08-01: app/context binding 6/6, cognition service 57/57, cognition resource accounting 21/21, model broker 56/56, executor/planner routing 120/120, AI Echo smoke 481/481, resource-hardening 6/6, and the import audit across 340 modules and 187 engine/state exports all passed. The signed production platform build compiled 2,801 modules with zero skipped, signed 52 official packages, verified 33/33 AI Echo modules, validated 25 OS deployment files and 139 Playground module edges, and produced a CRC-verified 349-file site archive. ### Phase 8.5 receipt-bound Artifact delivery - [x] Hold saved-Artifact finalizer deltas out of the canonical chat body until local Artifact receipt reconciliation completes. - [x] Show provisional Artifact generation as a bounded Run Details status without rendering escaped document JSON as assistant prose. - [x] Make the terminal kernel answer authoritative over any longer provisional provider draft after stream replay, remount, or repair. - [x] Replace every saved-Artifact final answer with one deterministic receipt-bound outcome: verified creation with an Artifact card, or an honest no-receipt failure with a Run Details recovery path. - [x] Prevent promises such as "I'll create it now" and duplicated raw work products from satisfying a saved-Artifact obligation. - [x] Keep the new provisional stream event content-free in copied Diagnostics. - [x] Advance AI Echo to 5.22.12 and pass focused Artifact, stream, diagnostics, smoke, import, runtime-boundary, and resource-hardening gates. Verification recorded 2026-08-01: executor/planner routing passed 120/120, stream continuity 14/14, Artifact Workspace 8/8, the signed Artifact Studio package 8/8, copied Diagnostics 28/28, runtime boundary 3/3, complete AI Echo smoke 481/481, resource hardening 6/6, and the import audit resolved all imports and balanced braces across 340 modules and 187 engine/state exports. Saved Artifact provider deltas now use `answer.draft.delta`; AI Echo records only a bounded provisional-character count in Run Details. `run.completed.answer` is the authoritative rendered text, and the finalizer deterministically binds that text to the presence or absence of trusted `artifactRefs` before canonical context synchronization. The signed production platform build then compiled 2,806 modules with zero skipped, signed 52 official packages, verified all 33 AI Echo modules, validated 25 OS deployment files and 144 Playground module edges, and produced a CRC-verified 352-file site archive. ### Phase 8.5 OS-owned saved-Artifact authoring lane - [x] Detect when an explicit saved-Artifact request reaches the end of general planning without a verified `artifacts.create` or `artifacts.update` receipt. - [x] Stop redundant tool discovery after one corrective round instead of spending the remaining planner and provider budget on repeated searches. - [x] Ask the selected model only for the complete work product as ordinary Markdown or plain text, without strict JSON, planner output, or tool-call authority. - [x] Reject empty, incomplete, oversized, promise-only, planner-envelope, and tool-envelope authoring responses before any mutation is proposed. - [x] Construct one exact `os.ai-echo.artifacts.create` task graph locally and route it through the existing signed Faculty, approval, ToolRouter, verification, readback, receipt, and Artifact-card boundaries. - [x] Preserve failed real mutation attempts without silently retrying them; the dedicated lane is only for planner omission or redundant discovery. - [x] Default copied Diagnostics to the latest visible run while retaining **Latest incident** as an explicit scope, preventing a successful current run from exporting an older failure by default. - [x] Advance AI Echo to 5.22.13 and pass focused routing, Artifact, stream, Diagnostics, smoke, import, resource-hardening, and signed production build gates. Verification recorded 2026-08-01: executor/planner routing passed 122/122, stream continuity 14/14, Artifact Workspace 8/8, the signed Artifact Studio package 8/8, copied Diagnostics 28/28, complete AI Echo smoke 481/481, resource hardening 6/6, and the import audit resolved all imports and balanced braces across 340 modules and 187 engine/state exports. The production platform build compiled 2,806 modules with zero skipped, signed 52 official packages, verified all 33 AI Echo modules, validated 25 OS deployment files and 144 Playground module edges, and produced a CRC-verified 352-file site archive. ### Phase 8.5 approved Smart-pool exhaustion - [x] Trace incident `AEI-ai-task-1785568234005-1` through its complete reviewed route decision and all three attempted provider results. - [x] Distinguish the final HTTP 429 symptom from the OS-owned three-attempt ceiling that left 15 eligible approved routes unattempted. - [x] Make automatic Smart Routing traverse every compatible route in the already-reviewed pool, up to the existing 64-route contract bound. - [x] Keep manual routing pinned to exactly one operator-selected route. - [x] Stop immediately for policy, authorization, cancellation, or other typed non-retryable failures; never widen the reviewed route set. - [x] Treat canonical planner JSON, schema, and semantic transport failures as retryable malformed output while preserving their exact typed error evidence. - [x] Keep interactive Navi provider work in telemetry-only resource mode so fallback breadth cannot become a cumulative token, model-call, network, or wall-time fuse; provider limits, context admission, privacy, pricing policy, receipts, and operator Stop remain authoritative. - [x] Remove the obsolete Maximum attempts control. The fallback toggle now states that it continues through the compatible approved pool. - [x] Advance AI Echo to 5.22.14 and add a four-route regression proving malformed output, invalid planner JSON, and HTTP 429 advance to a later approved success. Implementation evidence recorded 2026-08-01: the incident exposed 18 eligible routes, but the persisted `maxAttempts: 3` allowed only the first three. The third endpoint's 429 became the terminal message even though 15 reviewed routes remained. Smart Model Policy now migrates enabled automatic fallback to the complete reviewed pool, while Navi Model Broker and its public contracts retain a finite 64-route structural bound. AI Echo's interactive cognition task uses the kernel's existing zero-token telemetry mode, preventing whole-pool worst-case reservation from blocking dispatch. Smart Model Policy passed 38/38, Smart Model Picker 12/12, Navi Model Broker 57/57, AI Echo routes 53/53, cognition service 57/57, executor/planner routing 122/122, resource selection 35/35, cognition resource accounting 21/21, kernel cognition 15/15, copied Diagnostics 28/28, pipeline trace 16/16, stream continuity 14/14, Artifact Workspace 8/8, signed Faculty integration 16/16, complete AI Echo smoke 481/481, resource hardening 6/6, and the import audit across 340 modules and 187 engine/state exports passed. No Companion permission, credential, message, or transport contract changed; Store Companion 1.18.6 remains compatible. Production release verification compiled 2,806 modules with zero skipped, signed 52 official packages, and verified AI Echo 33/33. Static publication then remained in staging because the unrelated Playground source `tests/playground/src/demos/sandbox3d.js` imports the currently absent `tests/playground/src/demos/sandbox3d/runtime.js`. This routing repair did not invent or modify the unfinished Playground runtime, so the Phase 8 release gate remains open until that separate dependency is completed. ### Phase 8.5 verified Artifact file activity - [x] Trace the no-receipt Artifact failure through the complete signed Faculty execution path and identify the exact lost session context boundary. - [x] Propagate only bounded request, session, and Navi identifiers through the existing Faculty handler context without widening capability authority. - [x] Keep saved-Artifact draft content out of chat while showing the intended file name as soon as the verified mutation starts. - [x] Replace provisional character counters with receipt-bound Artifact file activity in Run Details. - [x] After verification, show the exact VFS revision path, manifest path, revision number, byte size, and SHA-256 status supplied by the trusted local Artifact result. - [x] On failure, show the intended file names as not written without claiming a file, revision, or receipt exists. - [x] Reuse Artifact Workspace paths, hashes, receipts, and cards instead of creating another output ledger or exposing provider draft content. - [x] Advance AI Echo to 5.22.15 and pass the focused Faculty, executor, Artifact, stream, smoke, resource-hardening, and import-audit gates. Implementation evidence recorded 2026-08-01: the planner supplied the active AI Echo session to ordinary ToolRouter calls, but the signed Navi Faculty path dropped that identifier between `TwoPassPlannerFinalizer`, `NaviFacultyService`, and `ToolRouter.callForFaculty`. Artifact Workspace then correctly rejected both create attempts because no active session reached its handler. The Faculty path now carries a strict, non-authoritative handler context containing only the reviewed request, session, and Navi identities. Run Details projects planned file names before mutation and accepts exact file paths, revision data, sizes, and hashes only from a successful `webgpu-os-artifact-tool-result-v1` result. It no longer substitutes a provisional character count for file activity. Verification recorded 2026-08-01: Faculty service passed 19/19, kernel Faculty integration 16/16, executor/planner routing 123/123, stream continuity 15/15, Artifact Workspace 8/8, official Artifact Studio package 8/8, AI Echo Faculty integration 16/16, complete AI Echo smoke 481/481, resource hardening 6/6, and the import audit resolved all imports and balanced braces across 340 modules and 187 engine/state exports. Production release verification compiled 2,806 modules with zero skipped, signed 52 official packages, verified AI Echo 33/33, validated 25 WebGPU OS deployment files and 154 Playground module edges, enforced all 116 Playground source files, and published a CRC-verified 356-file site archive. ### Phase 8.5 adaptive built-in signing and revision activation - [x] Replace fixed built-in Faculty versions with deterministic content-addressed revisions derived from reviewed source, descriptor hashes, schemas, authority, resources, tests, and failure behavior. - [x] Cross-bind the exact Faculty version through its canonical manifest, package binding, signed blockmap, encryption AAD, provenance, and SBOM. - [x] Give each Faculty family one encrypted active-revision pointer and an explicit enabled, disabled, or revoked operator policy. - [x] Stage a newly verified immutable revision inert before atomically switching the family pointer with Web Locks and compare-and-swap. - [x] Preserve operator disable and revocation across upgrades, restarts, and exact reinstalls; keep Browser Semantic automation disabled until explicitly enabled. - [x] Split Browser Semantic automation into its own signed package with exact descriptor ownership and a static isolated-Worker allowlist. - [x] Require every built-in tool descriptor to resolve to one generic signed Faculty, one reviewed dedicated Faculty, or one typed policy exclusion. - [x] Verify every emitted package independently through PRPKG2 framing, AES-GCM AAD, gzip payload, file hashes, Merkle root, manifest commitment, ring-0 certificate, publisher signature, Faculty signature, provenance, SBOM, and revision input hash before publishing any registry or fallback. - [x] Verify, reuse, or atomically refresh development fallback evidence before module-graph discovery; fail closed when stale evidence has no matching local signing material. Production and release builds never mutate the shared development fallback. - [x] Emit a content-free official-package inventory containing exact package, record, envelope, container, certificate, and revision fingerprints, then revalidate it in the source, minified, and deployed outputs. - [x] Make release signing fail closed for missing or mismatched ring-0 keys, malformed manifests, missing entries, unreadable source, duplicate app IDs, or source exceeding the explicit build-integrity guard. Hidden development evidence is never mistaken for app payload. - [x] Make `bundle_engine.py` propagate bundler failures to its process exit status so automation cannot report a failed signing build as successful. Implementation evidence recorded 2026-08-01: the Artifact Studio trust fault was an immutable identity collision. The reviewed signed payload changed while the hard-coded `1.0.0` key remained constant, so a browser that correctly kept the older `faculty:particle-realms:artifact-studio@1.0.0` rejected the new payload. The bundler now derives `+rev.` versions from the entire reviewed authority contract. Identical inputs reproduce the same revision despite rotated certificates, timestamps, signatures, and IVs; any authority-relevant change produces a distinct immutable revision. Runtime installation separates cryptographic verification, inert staging, and atomic authority activation. The first real release run also exposed an old 400 KB source-scan cap that had silently omitted AI Echo's 886 KB entry file. Signed packages no longer skip oversized or unreadable runtime source. The integrity guard is 16 MiB per first-party source file, is separate from user/VFS file limits, and aborts the release with the exact path and size instead of signing an incomplete package. Verification recorded 2026-08-01: signing lifecycle and inventory passed 14/14; Artifact Studio official package passed 9/9; Browser Semantic official package passed 5/5; built-in tool Faculty signing passed 7/7; Faculty service passed 24/24; Kernel Faculty integration passed 21/21; AI Echo Faculty integration passed 16/16; package policy passed 19/19; ToolRouter passed 12/12; Worker isolation passed 13/13; Kernel Faculty resources passed 14/14; agency syscalls passed 7/7; Browser explainability and retry hardening passed 20/20; the complete bundler suite passed 94/94; resource hardening and the AI/OS import audit passed. The production WebGPU OS release compiled 2,082 modules with zero skipped, cryptographically self-verified and inventoried 53 exact official packages, verified AI Echo 33/33, validated 25 deployment files, and produced a CRC-verified 1,396-file site archive. The production platform release then compiled 2,808 modules with zero skipped, repeated exact verification of all 53 packages in source, minified, and deployed form, validated 187 Playground module edges, enforced 131 Playground source files, and produced a CRC-verified 371-file site archive. ### Phase 8.5 trusted-default Faculty reconciliation and visible recovery - [x] Move automatic built-in Faculty recovery behind the kernel boundary. Apps can request built-in provisioning, but they cannot impersonate an operator by calling the public enable syscall during startup. - [x] Reconcile only the exact installed revision whose package-policy record, signed Faculty identity, canonical manifest hash, and authorized-package metadata all agree with the pinned ring-0 release. - [x] Automatically recover only install-default and legacy-migration disabled state. Preserve every explicit operator pause and family revocation across reloads and newer signed revisions. - [x] Keep Browser Semantic automation opt-in even though its signed package is available, so browser authority is never silently widened. - [x] Accept signed SemVer build-metadata revisions and select chronology by verified installation time with a deterministic version tie-break instead of treating a content hash as release precedence. - [x] Collapse immutable revisions into one Faculty-family card, retain older revisions under advanced details, and surface Ready, Preparing, Paused, and Attention directly in AI Echo's Artifacts control. - [x] Let an explicit click on `Artifacts · Paused` resume the trusted Faculty as a real operator action, then re-verify readiness before opening Studio. Implementation evidence recorded 2026-08-01: Artifact Studio had a valid current signed revision, but its family policy could remain disabled after legacy migration or an earlier failed activation. AI Echo previously exposed that state only in deep diagnostics and its attempted automatic fix used the same public syscall reserved for operator intent. `NaviFacultyService` now owns an exact-policy reconciliation operation, `KernelBootstrap` invokes it only for default-on ring-0 packages, and AI Echo merely requests provisioning and renders the resulting state. Explicit pause and revoke remain fail-closed. Verification recorded 2026-08-01: Faculty service passed 29/29, Kernel Faculty integration 22/22, AI Echo Faculty integration 18/18, the complete Phase 3 Faculty matrix 141/141, AI Echo smoke 481/481, Artifact Workspace 11/11, guidance strategy 10/10, Artifact Studio package 9/9, Browser Semantic package 5/5, built-in package signing 7/7, and strict bundle compatibility 2/2. The production platform release compiled 2,809 modules with zero skipped, inventoried 53 official packages, emitted the content-addressed Artifact Studio revision `1.0.0+rev.4dd4dafed2004032`, and produced a 66,538,454-byte site archive. The compressed release contains the reconciliation policy and all four visible Artifacts readiness states. ### Phase 8.5 signed descriptor emission continuity - [x] Separate exact handler and verifier source from durable signed authority. Exact source remains a per-kernel runtime canary; the package-signed portable descriptor remains the cross-release contract. - [x] Reject any callback replacement observed inside one running kernel before capability preparation or tool execution. - [x] Rebind a raw, minified, or otherwise rebuilt runtime emission only after a clean boot verifies the same signed Faculty family, package revision, and portable descriptor. - [x] Require changed signed revisions to be newer and reject rollback, family substitution, malformed approval state, and reused-version drift. - [x] Adopt only strictly shaped legacy and explicit operator descriptor approvals into the current signed built-in family after the live portable descriptor, package, publisher, source, and ring-0 policy all verify. - [x] Migrate existing `ai-descriptor-approval-v2` records to bounded v3 audit records without asking the operator to find or manually enable a Faculty. - [x] Migrate legacy two-field approvals across raw and minified emissions for every Artifact Studio tool while preserving both exact hashes in audit history and retaining the per-kernel live callback tamper canary. - [x] Reject malformed legacy, operator, v2, and v3 predecessor records rather than converting unknown storage state into signed authority. - [x] Preserve content-free rejection evidence in the kernel and AI Echo, including the tool, attestation reason, signed package identity, and previous and current exact-runtime hashes. - [x] Make the official Python release signer launch the browser-native ES module runtime and atomically synchronize all generic, Artifact Studio, and Browser Semantic descriptor fixtures before package signing. - [x] Retain the signer's static ownership, namespace, non-overlap, schema, coverage, package, provenance, and cryptographic verification after the automatic synchronization step. - [x] Advance AI Echo to 5.22.21 and produce a verified production release. Implementation evidence recorded 2026-08-01: the persistent descriptor store treated exact `Function.prototype.toString()` output as cross-release identity. Raw ES modules and production-minified modules legitimately emit different function text, so an older valid approval permanently blocked the current signed Artifact Studio package. `DescriptorHashStore` v3 now keeps exact text as a live-runtime tamper canary and persists the signed portable contract plus a four-entry runtime-emission history. A callback change in the current kernel still fails with `live-runtime-changed`; only a new store instance created by a clean boot can accept a package-verified emission or a newer signed revision. Strict pre-versioned and operator approval records are now adopted into that signed family only through the kernel-owned built-in provisioning path after the current package and portable descriptor verify. Malformed predecessor state still fails closed. This repairs long-lived browser profiles without clearing operator state or weakening the live-runtime canary. The release builder now derives 104 generic, 7 Artifact Studio, and 12 Browser Semantic portable descriptor hashes from the actual browser runtime before it signs packages. The helper atomically refreshes the three reviewed fixture files. Existing Python validation still rejects missing, malformed, overlapping, or unclassified tools before any official registry is published. Verification recorded 2026-08-01: the authority membrane passed 16/16, including v1 and v2 migration, operator adoption, malformed-record rejection, clean-runtime rebinding, live replacement rejection, and rollback rejection. Kernel Faculty integration passed 23/23, including all seven Artifact Studio tools migrating from alternate-emission legacy approvals. The complete Phase 3 matrix passed 155/155. Artifact Studio package verification passed 9/9, Artifact Workspace passed 11/11, production authority passed 8/8, and Python package/signing suites passed 21/21. AI Echo smoke passed 481/481. The production platform release compiled 2,811 modules with zero skipped, synchronized 123 live descriptor hashes with zero remaining drift, cryptographically self-verified 53 package records, verified AI Echo 33/33, validated 25 OS deployment files, and published a CRC-verified 392-file site archive. ### Phase 8.5 Artifact mutation settlement continuity - [x] Preserve the exact request, session, Navi, operation, and tool binding from signed Faculty dispatch through the authoritative ToolDriver verifier. - [x] Classify every thrown mutating handler as `outcome-unknown` until local readback proves whether the state change committed. - [x] Reconcile post-commit Artifact failures through the existing signed Faculty receipt instead of dispatching a duplicate create or update. - [x] Keep the original run and one-use Faculty operation open while an uncertain Artifact mutation is undergoing authoritative VFS readback; do not finalize, replan, or ask the provider to guess during that interval. - [x] Make the readback wait interruptible by the originating operator signal, with no app-owned deadline; steering and Stop remain available. - [x] Bind Artifact source metadata to the exact kernel-created Faculty operation and promote a recovered Artifact result into the signed settlement receipt so the planner receives the real file reference. - [x] Keep verified Artifact files canonical when a provider or intermediate transport reports a stale failure. - [x] Present an uncertain file as `write outcome being reconciled`; never label it `not written` and never tell the user to retry the same mutation blindly. - [x] Bind the final chat answer to verified, known-failed, or outcome-unknown Artifact evidence rather than provisional provider prose. - [x] Advance AI Echo to 5.22.23 and cover the complete settlement path with focused and aggregate regressions. Implementation evidence recorded 2026-08-01: Artifact creation committed its revision and direct working-file projection correctly, but `NaviFacultyService` discarded the exact handler context before post-dispatch verification. Artifact readback therefore lacked the active AI Echo session, the signed Faculty receipt became a false failure, and Run Details showed `guide.md · not written` even though Artifact Studio could open the canonical file. Faculty settlement now forwards the original bound context and live operator signal to the kernel verifier. ToolRouter attaches the kernel-created operation identity to the deterministic handler, and Artifact Workspace stores that identity in the revision source. For an uncertain result, ToolDriver keeps the original run open without a generic timeout while the Artifact verifier polls the canonical VFS. A matching revision is promoted into the same signed Faculty settlement as a recovered success; Stop interrupts the wait. No second mutation or provider repair is dispatched. Verification recorded 2026-08-02: executor routing passed 124/124, Faculty service 32/32, authority membrane 17/17, kernel Faculty integration 23/23, AI Echo stream continuity 17/17, Artifact Workspace 11/11, and the complete Phase 3 matrix 161/161. Artifact Studio package verification passed 9/9 and Faculty package policy passed 19/19. AI Echo smoke passed 481/481. The signed production platform release compiled 2,812 modules with zero skipped, synchronized all 123 live descriptor hashes with zero drift, cryptographically self-verified 53 package records, verified all 33 AI Echo modules, validated 25 deployed OS files, and published a CRC-verified 394-file site archive. ### Phase 8.5 Codex-style incoming Artifact change visibility - [x] Publish the OS-owned incoming Artifact file projection during `tool.reviewed`, before the approval decision and before mutation dispatch. - [x] Distinguish `waiting for approval`, `writing`, `verified`, `reconciling`, and `failed`, and replace the stale safety row when approval resolves. - [x] Record the approval wait duration so a long operator pause cannot look like a hung VFS write or provider request. - [x] Render each proposed create or replacement as an expandable file-change surface with path, change kind, line and character counts, line numbers, and visible added or replacement rows. - [x] Preserve the same file-change surface while the operation is preparing, verified, failed, or outcome-unknown instead of replacing it with a filename-only status row. - [x] Preserve bounded incoming file previews in encrypted AI Echo run history so a remounted view can reconstruct the activity without replaying a tool. - [x] Keep previews local-only and exclude them from provider context, signed receipts, diagnostic exports, and the Companion bridge. - [x] Bound the presentation projection to 32 KiB per file, 64 KiB per activity, and 800 lines, while keeping the complete canonical file in the Artifact Workspace and VFS. - [x] Use text-only DOM rendering for every filename and line so proposed file content cannot inject markup into Run Details. - [x] Advance AI Echo to 5.22.24 and cover pending approval, preparing, settlement, truncation, restoration, and browser rendering with regressions. Implementation evidence recorded 2026-08-02: the existing canonical `fileActivity` event is now version 2 and carries a bounded, explicitly local-only preview of the exact incoming file content. The executor attaches that projection to `tool.reviewed`, so the operator can inspect what will be written before approving the capability. AI Echo presents the projection as Codex-style expandable file changes, follows an active write, preserves open rows across status updates, and restores the same view from encrypted run history. Final Artifact identity, revision, hash, and file references still come only from the verified tool receipt; the preview never becomes execution evidence. Focused verification recorded 2026-08-02: executor routing passed 124/124, AI Echo stream continuity passed 17/17, AI Echo browser smoke passed 483/483, the complete Phase 3 matrix passed 161/161, official Artifact Studio package verification passed 9/9, and Faculty package policy passed 19/19. ### Phase 8.5 durable approval popup recovery - [x] Keep the shell popup synchronized with the authoritative kernel elicitation queue even while the popup is hidden. - [x] Recreate and reveal a missing approval card when mount timing, a missed event, or a transient render failure leaves a kernel request without UI. - [x] Keep approval prompts pending until the operator approves, denies, or stops the owning task; no response can authorize or silently reject work. - [x] Retain opt-in expiry for non-approval questions and explicitly expiring approval workflows through `timeoutPolicy: expire`. - [x] Start the exact one-use approval proof lifetime after the operator clicks Approve, rather than while the request waits for attention. - [x] Cancel every pending elicitation owned by an AI task when that task's AbortSignal settles. Implementation evidence recorded 2026-08-02: `AIOverlay` now runs its bounded 500 ms pending-state watcher for the entire mounted lifetime. The watcher repairs missing cards, removes settled cards, and reopens the popup only while authoritative pending requests exist. `ElicitationManager` keeps ordinary approval prompts inert and durable, supports explicit expiry when required, and issues a fresh two-minute one-use proof only after approval. The executor cancels task-owned prompts on every operator Stop path. Focused verification recorded 2026-08-02: kernel cognition passed 16/16, executor routing passed 124/124, AI Echo browser smoke passed 487/487, the complete Phase 3 matrix passed 161/161, official Artifact Studio package verification passed 9/9, and Faculty package policy passed 19/19. The signed production platform release compiled 2,812 modules with zero skipped, synchronized 123 live descriptor fixtures with zero drift, cryptographically self-verified 53 package records, verified all 33 AI Echo modules, validated 25 deployed OS files, and published a CRC-verified 394-file site archive. Post-build AI Echo smoke passed 487/487 and Artifact Studio package verification passed 9/9. ### Phase 8.5 semantic active steering and follow-up turns - [x] Classify only the new instruction's relationship to the active task; never create a hurry, temperament, or compliance score for the operator. - [x] Record deterministic urgency, adjustment, and deferral basis-point signals with a content-free reason code and Storylet transition. - [x] Actively interrupt only an in-flight model draft for corrections, redirects, checkpoint answers, and explicit urgency while preserving the OS task, verified evidence, in-scope approvals, and tool receipts. - [x] Merge ordinary additive instructions at the next verified task boundary. - [x] Queue explicitly deferred instructions such as `after you finish` and `next turn` as one automatic follow-up after the active task settles. - [x] Keep status requests local and preserve explicit Stop as whole-task cancellation. - [x] Prevent provider dispatch when steering arrives during route preflight or disclosure review. - [x] Apply steering epoch checks to every Sherlock model boundary so a stale frame, observation plan, or assessment cannot survive an interruption. - [x] Expose Active, Boundary, Next turn, Status, and Cancel decisions in Run Details with their deterministic reason code. - [x] Advance AI Echo to 5.22.25 and cover semantic delivery, next-turn epoch isolation, dispatch-scoped interruption, stream continuity, diagnostics, routing, and browser rendering with regressions. Implementation evidence recorded 2026-08-02: `ActiveTurnCoordinator` now emits an immutable `ai-steering-semantic-decision-v1` projection whose scoring target is explicitly `instruction-task-relationship`. The deterministic policy maps the projection to existing task Storylet transitions instead of using the narrative graph's random equal-priority selection. `TwoPassPlannerFinalizer` owns a child AbortController for each model dispatch; active steering aborts that child only, returns a superseded result, applies the new context, and replans the same Navi task. ToolRouter mutations and the task's operator Stop signal remain separate. AI Echo queues explicit future work outside the active steering epoch, starts it after settlement, and renders why each delivery mode was selected. Focused verification recorded 2026-08-02: Phase 8 task runtime passed 24/24, executor routing passed 124/124, stream continuity passed 17/17, whole-pipeline diagnostics passed 16/16, and AI Echo browser smoke passed 487/487. The signed production platform release compiled 2,812 modules with zero skipped, synchronized 123 live tool descriptors with zero drift, cryptographically self-verified 53 package records, verified all 33 AI Echo modules, validated 25 deployed OS files, and published a CRC-verified 394-file site archive. Post-build AI Echo smoke passed 487/487 and the AI Echo Faculty suite passed 18/18. ### Phase 8.5 operation-bound Artifact continuation - [x] Preserve a committed Artifact tool result when only its resource-lease settlement requires recovery; never downgrade the canonical file write to `not written`. - [x] Carry the kernel-created Faculty operation and Navi task identity through the deterministic handler, verifier, signed receipt, and Artifact revision source metadata. - [x] Bind every verified Artifact reference back to the active Navi task and expose its exact stable `artifactId` and current `expectedRevision` to the next planner boundary. - [x] Require same-task continuation to use `artifacts.update`; permit another `artifacts.create` only when the operator explicitly requests a separate Artifact project. - [x] Preserve resource-settlement recovery as typed diagnostic metadata while returning the verified tool result and Artifact reference to the planner. - [x] Advance AI Echo to 5.22.26 and cover the commit/settlement split and duplicate-suppression contract with focused regressions. Implementation evidence recorded 2026-08-02: a successful Artifact handler could commit its immutable revision and working-file projection, then be reported as a failed tool when later Navi resource settlement threw. That false failure withheld the trusted Artifact reference from task state, so a subsequent planning round issued another create and produced a sibling project. Kernel Faculty execution now treats the signed successful tool settlement as canonical and records resource recovery separately. `NaviFacultyService` reconstructs verifier context with the exact operation and task binding, and Artifact source metadata retains the same identity. The executor persists the verified revision reference on the task and gives subsequent planning an exact update contract, preventing a technical retry from becoming a new project. Focused verification recorded 2026-08-02: executor routing passed 125/125, Faculty service passed 32/32, and kernel Faculty integration passed 23/23. The complete Phase 3 matrix passed 161/161, Artifact Workspace passed 11/11, Artifact Studio package verification passed 9/9, and Faculty package policy passed 19/19. AI Echo browser smoke passed 487/487 before and after release. The signed production platform release compiled 2,812 modules with zero skipped, synchronized all 123 live descriptor fixtures with zero drift, cryptographically self-verified 53 package records, verified all 33 AI Echo modules, validated 25 deployed OS files, and published a CRC-verified 395-file site archive. ### Phase 8.6 semantic Artifact formats and generated-code routing - [x] Treat `containsCode` as operator-supplied code evidence when AI Echo supplies it explicitly; requesting generated HTML no longer becomes a sensitive source-code disclosure by keyword accident. - [x] Keep conservative keyword inference for callers that provide no explicit code-presence evidence. - [x] Pre-score saved Artifact requests locally with an inspectable, content-free format scorecard before planner or provider dispatch. - [x] Preserve explicit supported Artifact formats without using the scorecard as an acceptance or authority gate. - [x] Default creative, visual, mixed-format, unfamiliar, and ambiguous Artifact ideas to a flexible modular web project. - [x] Generate default web Artifacts as independently editable `index.html`, `styles.css`, and `app.js` files with correct MIME types and semantic HTML. - [x] Generate requested plans, roadmaps, and checklists as Markdown document Artifacts even when their subject is a website or application. - [x] Detect planner format drift before mutation and author the accepted idea through the OS-owned Artifact lane instead of rejecting it. - [x] Bound every AI Echo tool description to the 512-character capability manifest contract and cover the invariant with a descriptor regression. - [x] Synchronize live browser-normalized descriptor fixtures before the development signer decides whether a Faculty fallback is current. - [x] Advance AI Echo to 5.22.29 and synchronize the changed signed Artifact descriptor through the development and production bundlers. - [x] Keep the AI Echo runtime and application manifest on one release version and regression-test that contract. - [x] Fetch built-in application indexes and manifests without browser-cache reuse so release discovery observes the deployed metadata. - [x] Refresh stale built-in package records when their authoritative manifest, entry point, or release version changes instead of preserving them forever. - [x] Detect a loaded-runtime/deployed-manifest mismatch, perform one guarded automatic reload, and prevent reload loops when deployment is inconsistent. Implementation evidence recorded 2026-08-02: Smart Model Policy previously reclassified the phrase `HTML` as evidence that operator source code was in the prompt, despite AI Echo supplying `containsCode: false`. That false privacy classification excluded almost the complete approved model pool. Explicit boolean evidence is now authoritative while omitted evidence remains conservative. `savedArtifactIntentProfile()` applies hard product contracts first, then deterministic weighted format signals. Unknown or mixed ideas are never rejected by the classifier; the modular web project is their broad host. The scorecard records selected kind, confidence basis points, bounded scores, and reason codes without retaining the operator text or granting a tool. Focused verification recorded 2026-08-02: executor routing passed 129/129, Smart Model Policy passed 39/39, AI Echo route integration passed 54/54, Artifact Workspace passed 11/11, Faculty package policy passed 19/19, Faculty service passed 32/32, kernel Faculty integration passed 23/23, and the complete Phase 3 matrix passed 161/161. AI Echo browser smoke passed 487/487. The bundler atomically refreshed nine development Faculty fallback records, then the signed production platform release compiled 2,813 modules with zero skipped, synchronized 123 descriptor fixtures with zero drift, cryptographically self-verified 53 package records, verified 33/33 AI Echo modules, validated 25 deployed OS files, and published a CRC-verified 395-file site archive. Post-refresh Artifact Studio package verification passed 9/9. Follow-up verification recorded 2026-08-02: the expanded `artifacts.create` description initially exceeded `os.AppAICapabilityManifest`'s 512-character bound. The description is now 480 characters and retains the permissive format policy. Descriptor tests passed 13/13. A signer ordering defect was also corrected: live fixtures are synchronized before fallback freshness is compared, preventing a source descriptor edit from reusing stale signed authority and then creating drift later in the same build. Release-coherence follow-up recorded 2026-08-02: AI Echo's runtime had advanced while its app manifest still identified an older release, and PackageManager's built-in synchronization skipped every previously installed built-in record. That allowed an old signed Faculty descriptor set to survive a correct new bundle. AI Echo 5.22.29 now uses one manifest/runtime version contract, AppRegistry performs no-store discovery, PackageManager authoritatively refreshes changed built-in records while preserving install time, and AI Echo performs one session-guarded reload when the loaded runtime and deployed manifest disagree. Release-coherence verification recorded 2026-08-02: AI Echo smoke passed 487/487, Phase 1 kernel integration passed 24/24, PackageManager lifecycle passed 15/15, Artifact Studio official-package verification passed 9/9, official signer lifecycle passed 10/10, and the Phase 3 production authority path passed 8/8. The signed production platform release compiled 2,827 modules with zero skipped, synchronized 123 descriptor fixtures with zero drift, cryptographically self-verified 53 official package records, verified all 33 AI Echo modules, validated 25 deployed OS files, and published a CRC-verified 396-file site archive. ### Phase 8.7 isolated free-model steering lane - [x] Add `steering` as an independent Navi model purpose instead of borrowing the active chat, planning, or local-runtime route. - [x] Enable free-model steering by default under Smart Routing and expose a saved Connections control plus the count of eligible approved models. - [x] Require a remote route with authoritative known pricing of exactly zero; model-name suffixes and unknown prices never qualify as free evidence. - [x] Rank eligible steering routes by latency, then receipt-derived reliability and provider trust, without changing the main model selection. - [x] Send only a minimal active objective, phase, progress window, and new instruction to the steering classifier. Do not expose tools or full history. - [x] Accept only one exact bounded advisory JSON envelope containing kind, confidence basis points, and reason code. `cancel` is not in its vocabulary. - [x] Let `ActiveTurnCoordinator` choose interrupt, safe boundary, status, or next-turn delivery and invalidate only affected stale model work. - [x] Deduplicate client retries before model dispatch and fail closed when one steering identifier is reused for different content. - [x] Record model-started, model-classified, and local-fallback events in Run Details without letting steering-lane failure fail the main task. - [x] Migrate legacy seven-purpose Navi route configurations by deriving a dormant steering pool from chat routes, then apply current free-only runtime eligibility before any steering request can execute. The free steering lane is deliberately a separate provider request. A route is zero provider charge only when the catalog and broker both hold current zero-cost evidence; it may still consume the provider's free quota and remains subject to rate limits. OpenRouter documents that its free router and `:free` variants have lower rate limits and variable availability, while provider routing can prioritize latency and constrain data collection or zero-data retention. The OS therefore treats this lane as an optional accelerator and always retains a local deterministic fallback. Implementation evidence recorded 2026-08-02: Active Turn runtime passed 30/30, Smart Model Policy 40/40, Smart Model Picker 13/13, AI Echo route integration 54/54, Navi Model Broker 58/58, and executor routing 129/129. The 324 focused checks prove free/paid/local separation, saved settings, isolated dispatch, advisory-only classification, replay safety, scoped stale-output interruption, and non-blocking local fallback. AI Echo browser smoke passed 488/488. The signed production platform release compiled 2,834 modules with zero skipped, synchronized 123 live descriptor fixtures with zero drift, cryptographically self-verified 53 package records, verified 33/33 AI Echo modules, validated 25 deployed OS files, and published a CRC-verified 409-file site archive. ### Phase 8.8 hard Artifact direct authoring and post-dispatch reconciliation - [x] Route explicit saved-Artifact requests into the OS-owned Artifact authoring lane before the generic planner, regardless of prompt difficulty. - [x] Preserve unfamiliar or ambitious visual ideas as one modular web project with `index.html`, `styles.css`, and `app.js`; explicit plans remain Markdown. - [x] Execute one exact signed Artifact mutation and require authoritative Artifact references before a run can report completion. - [x] Convert every post-dispatch infrastructure failure into an operation-bound `outcome-unknown` settlement instead of claiming the write failed or retrying it as a duplicate. - [x] Keep the resource lease until authoritative readback settles a possibly committed mutation, including failures outside delegated Hand execution. - [x] Add typed provisioning, Faculty-catalog, preparation, dispatch, and settlement failures so generic routing errors cannot hide the failed stage. - [x] Coalesce provider stream progress into bounded, content-free cumulative checkpoints rather than recording one pipeline event per text fragment. - [x] Advance AI Echo to 5.22.31 and produce a signed production platform release containing the direct lane and reconciliation boundary. The regression fixture uses the exact hard request, "make a pokedex artifact but for magic cards." The earlier run spent its generic six-minute planner budget, emitted more than 16,000 trace events, then lost a successful Artifact write behind a routing failure. The direct lane now performs one authoring subcall and one signed create operation. A known successful receipt completes the task; an uncertain transport outcome pauses for readback and cannot create a second Artifact. Implementation evidence recorded 2026-08-02: executor routing passed 130/130, kernel Faculty boundaries 23/23, Faculty service 32/32, Artifact Workspace 11/11, Artifact Studio package verification 9/9, AI Echo tool descriptors 13/13, and Faculty resource settlement 14/14. The production release compiled 2,834 modules with zero skipped, synchronized all live descriptor fixtures with zero drift, self-verified 53 signed package records, verified 33/33 AI Echo modules, validated 25 deployed OS files, and published a CRC-verified archive. The live local release booted to the desktop with no browser console errors. ### Phase 8.9 release-coherence crash containment - [x] Align AI Echo's runtime `APP_VERSION` and signed app-manifest version at `5.22.31`. - [x] Compare dotted release versions before scheduling an application reload. - [x] Allow a bounded refresh only when the no-store manifest proves that the loaded app module is older than the deployed manifest. - [x] Block desktop reload when the loaded module is newer or release ordering cannot be proven; surface the mismatch for app-level recovery instead. - [x] Make the official package signer inspect runtime version declarations and reject every runtime/manifest mismatch before signing or publication. - [x] Add lifecycle and browser smoke regressions for version drift and stale manifest crash containment. - [x] Rebuild the signed production platform and verify a live AI Echo mount remains stable beyond the prior reload window. The crash attachment showed a complete kernel boot followed by AI Echo release evidence with `loadedVersion: 5.22.31` and `manifestVersion: 5.22.30`. AI Echo then scheduled `location.reload()`, which restarted the entire browser desktop. The concurrent discovery, CORS, and WebSocket fallback messages were noisy but non-causal: the OS had already reached Ready. A built-in app may now request a refresh only for a proven forward deployment; a stale manifest can no longer restart the OS. Verification recorded 2026-08-02: official-package signing lifecycle passed 12/12, AI Echo smoke passed 489/489, and Phase 1 kernel integration passed 24/24. The release build compiled 2,838 modules with zero skipped, cryptographically self-verified 53 official package records, verified 33/33 AI Echo modules, validated 25 deployed OS files, and produced a CRC-verified 411-file site archive. A live browser boot reached the desktop, mounted AI Echo as 5.22.31, and remained mounted without desktop navigation or reload. ### Phase 8.10 canonical Artifact revision references - [x] Preserve the generic Navi identifier grammar without admitting revision separators into unrelated signed IDs. - [x] Define one canonical Artifact reference grammar for stable project IDs and immutable `@r@` revision references. - [x] Apply the Artifact grammar to signed cognition tasks, investigation evidence, and live task-state Artifact projections. - [x] Validate Artifact references at the task-state producer boundary with a typed error before contract signing or settlement. - [x] Reuse the canonical contract grammar in the planner finalizer instead of maintaining a separate kernel regex. - [x] Regress incident `AEI-ai-task-1785701920949-1` with its exact immutable Artifact reference and reject revision zero and non-Artifact references. The Artifact Workspace correctly returned `artifact_598cc598f1e043e8a64167e916db99c3@r1@38a300c09ccad724bd6e4bdb32f44873a101bcf6521dd55d40f045d8e9f2deb3`. The task-state projection accepted the bounded string, but its strict schema still treated every Artifact as a generic Navi ID and rejected the two `@` revision separators. The fix keeps the generic ID vocabulary closed and gives Artifact identity its own exact contract. Verification recorded 2026-08-02: Navi contracts passed 9/9, Phase 8 intelligence contracts 11/11, task runtime 30/30, and cognition service 57/57. The signed platform release compiled 2,840 modules with zero skipped, cryptographically self-verified 53 official package records, verified 33/33 AI Echo modules, validated 25 deployed OS files, and produced a CRC-verified 411-file site archive. ### Phase 8.11 receipt-warmed Artifact Studio loading - [x] Reuse the exact immutable Artifact revision already read and SHA-256 verified by AI Echo instead of immediately reading the same revision again. - [x] Bind each warm entry to the exact Navi, session, Artifact revision, and content hash; never warm mutable project-head references. - [x] Keep the warm set bounded and invalidate matching entries on Artifact Workspace or storage change events. - [x] Derive revision choices from the already validated manifest history instead of issuing a duplicate revision-manifest read. - [x] Reuse current verified built-in Faculty readiness while it remains valid. - [x] Hydrate the requested Artifact immediately while the complete library refresh continues in the background. - [x] Preserve the explicit, operator-loaded opaque preview sandbox; no HTML, CSS, JavaScript, network, or script execution is prefetched. - [x] Record content-free cold/warm open timing and cache-hit diagnostics. The first Open or Edit action previously repeated signed Faculty reconciliation, scanned every Artifact manifest sequentially, reread the exact revision files and hashes, and then reread its manifest for history. AI Echo had already completed the authoritative readback and hash validation before rendering the Artifact card. Version 5.22.32 carries that verified immutable record into Artifact Studio, starts the library refresh concurrently, and leaves safe preview construction lazy. Verification recorded 2026-08-02: Artifact Workspace passed 12/12 including a zero-additional-read warm-open regression, Artifact Studio official package verification passed 9/9, built-in Faculty packages passed 7/7, official-package signing lifecycle passed 12/12, and AI Echo smoke passed 489/489. The signed production release compiled 2,840 modules with zero skipped, self-verified 53 official package records, verified 33/33 AI Echo modules, validated 25 deployed OS files, copied 419 release files, and produced a CRC-verified 416-file site archive. ### Phase 8.12 provider-native tool planning and endpoint restore containment - [x] Keep provider-side JSON Schema enforcement out of every initial tool planning dispatch, including endpoints that advertise structured output. - [x] Admit only one exact provider-native JSON value and canonicalize common `tool_calls`, `function`, `calls`, `steps`, and direct `{tool,args}` forms. - [x] Validate the canonical result with the closed OS planner schema before graph compilation, descriptor binding, authority review, or execution. - [x] Reject fenced or prose-prefixed tool JSON, malformed arguments, mixed valid/invalid action sets, unknown tools, stale descriptors, and unauthorized effects without executing a subset. - [x] Prefer live OS provider endpoints over stale persisted endpoints for built-in and discovered providers. - [x] Treat an invalid custom remote endpoint as an unavailable route instead of allowing route synchronization to abort AI Echo mount. - [x] Preserve exact local HTTP/OS routes and the existing remote HTTPS, credential, hash, and origin validation boundaries. - [x] Regress the endpoint and planner compatibility boundaries without a Node or provider-runtime dependency. Incident `AEI-ai-task-1786134275620-3` used provider-native planning already; its selected manual OpenRouter endpoint returned an empty completion before any planner round or tool call. That provider failure remains honest and retryable. The accompanying application-load failure was separate: a stale persisted `baseUrl` overrode the current built-in provider endpoint during Navi route synchronization, and the correct route validator then aborted mount. Version 5.22.34 contains that lifecycle fault while retaining the validator at the dispatch boundary. ### Phase 8.13 provider-native tool envelopes and mounted-workspace authority - [x] Separate provider-visible tool definitions from local allowed-tool and authority state; a provider tool definition never grants OS authority. - [x] Send endpoint-attested native tool definitions for OpenAI-compatible and Anthropic transports without requiring provider-side strict JSON Schema. - [x] Canonicalize OpenAI Chat `tool_calls`, legacy `function_call`, Responses API `function_call`, and Anthropic `tool_use` envelopes into one bounded local transport. - [x] Assemble OpenAI and Anthropic streaming argument fragments by stable ordinal, reject conflicts and overflow, and execute only after the complete envelope validates. - [x] Preserve canonical tool calls through the bridge, result broker, and planner finalizer so tool-only completions cannot collapse into empty text. - [x] Validate exact tool names, arguments, descriptor hashes, graph dependencies, current authority, verifier, and receipts locally before any effect. - [x] Keep prompt-mediated exact JSON as a bounded fallback for compatible models and local runtimes that do not implement a native tool protocol. - [x] Never interpret JSON printed in ordinary assistant prose or code fences as an executable tool call. - [x] Keep filesystem operations confined to the selected task workspace root; selecting a Chrome-granted `/mnt/...` root exposes that complete mounted tree without exposing sibling mounts or unrelated OS namespaces. - [x] Preserve browser permission, read provenance, coding-contract, ToolRouter, approval, Web Lock, readback, receipt, and Recycle Bin boundaries for mounted workspaces. - [x] Mirror the native transport in the development and Chrome Web Store Companion sources and advance both to version `1.18.8`. - [x] Advance AI Echo to `5.22.36` and regress native, fallback, mount-scope, extension-parity, signed-Faculty, strict-bundle, and application smoke paths. Provider-side strict schema support remains an optional quality optimization, not a prerequisite for valid tool use. The portable contract is the provider's typed native call envelope followed by exact local validation. Models without a verified native envelope may still plan using one exact locally validated JSON value; neither path may bypass the Tool Firewall. The workspace selector remains the operator-visible scope boundary. A task rooted at `/user/project` cannot jump to `/mnt/work`. A task rooted at the user-granted `/mnt/work` mount may read and write its complete directory tree, subject to the mount handle's live browser permission and the ordinary OS mutation controls. Web applications cannot obtain arbitrary host filesystem access without a user-granted File System Access handle. Focused verification recorded 2026-08-08: provider relay passed 58/58, executor routing 132/132, cognition service 57/57, AI Echo filesystem/tool descriptors 14/14, AI Echo smoke 490/490, signed Faculty policy 19/19, Artifact Studio package 9/9, Browser Semantic package 5/5, strict-bundle compatibility 2/2, and Chrome Web Store package validation 17/17. The signed production platform compiled 3,071 modules with zero skipped, synchronized 123 live descriptor fixtures with one intentional workspace-scope revision, cryptographically self-verified 53 official packages, verified 33/33 AI Echo modules, validated 37 deployed WebGPU OS files, copied 695 release files, and produced a deterministic CRC-verified 690-file site archive. ### Phase 8.14 workload-aware routing and per-Navi execution modes - [x] Separate the provider transport purpose from the task workload family so an HTML Artifact may use the planning protocol while preferring coding models. - [x] Classify conversation, coding, planning, reasoning, tool-use, vision, speech, and fast-utility workloads with bounded, inspectable evidence. - [x] Treat workload affinity as a ranking preference only. General models stay eligible when their verified transport, modality, privacy, readiness, context, output, lifecycle, budget, and operator-policy evidence satisfies the task. - [x] Preserve exact hard compatibility gates for provider-native tools, required modalities, context and output capacity, privacy, route readiness, configured budgets, and the operator-approved pool. - [x] Treat an explicit approved model pool as an exact provider/model allowlist. A dynamic router alias authorizes only that alias; it never approves changing concrete catalog routes, and an empty purpose lane remains non-dispatchable instead of widening to a manual or local fallback. - [x] Bind the optional task family into the model-neutral task fact, broker requirements and decision, execution evidence, resource-selection hashes, and the content-free explainability projection. - [x] Add workload filters and badges to both model pickers without turning a family/name heuristic into authority or a deterministic capability claim. - [x] Preserve provider-backed workload affinity metadata through both the development and Chrome Web Store Companion catalogs. - [x] Add per-Navi `Approval`, `Auto`, and `Bypass` execution modes beside the composer and in Settings, with `Approval` as the default. - [x] Keep the normal ToolActionReview, ToolRouter, Faculty, Covenant, workspace, mount, descriptor, verifier, readback, receipt, and Recycle Bin boundaries in every mode. - [x] Let `Auto` suppress a repeated prompt only after a verified low-risk receipt matches the exact Navi, tool descriptor, authority/data classes, and target scope. Argument values may vary inside that unchanged reviewed scope. - [x] Let `Bypass` suppress elicitation only after the action has passed the ordinary review and current authority checks; it cannot grant authority, widen a mount/workspace, override a denial, or skip sensitive-action review. - [x] Require deliberate confirmation when entering `Bypass`, synchronize the controls live, persist the selection per Navi, and record the mode and reason in run events and receipts. - [x] Apply a live switch to `Bypass` to the active kernel task and settle only that task's already-open approval elicitation. Clarifications, adaptations, unrelated task prompts, denials, and every authority boundary remain active. - [x] Replace the terminal tool's ad-hoc dialect handling with one shared, bounded WebGPU OS grammar used by AI Echo and the interactive Terminal. Normalize common read-only GNU and PowerShell spellings to VFS operations, while rejecting host paths, pipelines, redirection, substitution, chaining, and JavaScript in the AI bridge. - [x] Advance AI Echo to `5.22.37` and both Companion sources to `1.18.9`. The route catalog now separates **hard eligibility** from **soft suitability**. Verified incompatibility excludes a route; terms such as coder, conversational, reasoning, fast, free, paid, popular, or high-benchmark influence scoring unless the operator explicitly promotes one into policy. Unknown soft evidence lowers confidence instead of silently erasing an otherwise compatible general model. Focused verification recorded 2026-08-09: execution approval modes passed 12/12, bounded terminal grammar passed 8/8, task runtime 30/30, authority membrane 17/17, Smart Model policy 43/43, Smart Model picker 15/15, model broker 60/60, cognition service 57/57, resource selection 36/36, explainability/browser hardening 21/21, AI Echo routes 63/63, Smart catalog integration 14/14, AI Echo autonomy 18/18, executor routing 132/132, AI Echo smoke 490/490, provider catalog cache 9/9, extension install policy 14/14, built-in Faculty packages 7/7, Artifact Studio package 9/9, and Chrome Web Store validation 17/17. The reproducible Store ZIP contains 39 files and has SHA-256 `429ee6f9fd3763e14a098c10c3e81e2df6816e42155943eaecdd13a2f0e36849`. The signed production build compiled 3,072 modules with zero skipped, cryptographically verified 53 official packages, verified 33/33 AI Echo modules, validated 37 deployed OS files, copied 695 release files, and produced a deterministic CRC-verified 690-file site archive. ### Phase 8.15 Dodad compatibility naming and shared work-product workspace - [x] Present durable generated work as **Dodads** and the editor as **Dodad Studio** throughout AI Echo, while retaining the canonical `os.ai-echo.artifacts.*` tool names, signed package identity, receipt fields, schema formats, and `/user/artifacts` storage path as stable compatibility contracts. - [x] Accept artifact, gem, dodad, doodad, canvas, preview, site, document, plan, table, chart, data, UI, and code language as weighted routing evidence instead of treating any one alias as an unconditional mutation command. - [x] Rank chat, web, document, code, table, chart, data, and UI candidates from bounded positive, negative, and contextual evidence; preserve score margins, ambiguity, negation, and the top alternatives in content-free run evidence. - [x] Keep uncertain or merely descriptive prompts in conversation, including archaeology, medical imaging, gemstones, Ruby packages, physical canvases, greetings, and questions about HTML canvas that do not request creation. - [x] Default explicit plans to Markdown and visual or interactive work to a modular HTML, CSS, and JavaScript Dodad without rejecting unusual but safe work-product ideas. - [x] Replace the persistent side editor with one central, task-scoped **Chat / Code / Preview** workspace. Chat remains the default; Code and Preview reuse the same Dodad controller, revision, and session state. - [x] Keep Compare inside Dodad Studio, return to Chat when the workspace is closed, preserve narrow-window behavior, and load web previews only inside the existing opaque network-blocked sandbox. - [x] Keep aliases one-way at the presentation and intent layers. No duplicate tools, stores, ledgers, package identities, migrations, or authority paths were introduced. - [x] Open Code or Preview immediately on a fresh profile and show Faculty readiness inside the shared workspace without granting tool authority. - [x] Advance AI Echo to `5.22.39`; the Companion extension remains unchanged because this release changes no browser relay, credential, or extension UI contract. Focused verification recorded 2026-08-08: weighted executor routing passed 132/132, AI Echo routes 56/56, Dodad Workspace 12/12, execution approval modes 10/10, Smart Model policy 43/43, Smart Model picker 15/15, and signed Faculty policy 19/19. The public rename does not claim trademark clearance; stable internal compatibility identifiers deliberately remain unchanged while the operator-facing product language uses Dodad. ### Phase 8.16 human-first Navi and Presence studios - [x] Redesign Navi Studio around one compact companion roster and one focused editor instead of repeating identity and continuity data across the page. - [x] Keep identity basics, purpose, voice, personality, cognition, and continuity as stable accessible sections; preserve unsaved edits while moving between sections and replace the tab strip with a readable picker on narrow screens. - [x] Keep the selected Navi's canonical identity, Covenant, security tier, lineage, and creation evidence in one collapsed technical disclosure beside the roster rather than removing or duplicating it. - [x] Make the live character preview sticky at wide widths and inline at compact widths without creating a second profile or presentation authority. - [x] Use contextual footer actions: identity editing offers **Save Navi changes**, Presence and Recovery expose a clear close path, and unrelated connection testing is hidden outside provider settings. - [x] Redesign Presence as **Presence Studio** with a friendly body rail and a three-step **Task / Destination / Review and sign** workflow. - [x] Select only active or paused tasks for transfer while retaining completed and blocked tasks as disabled audit records. - [x] Show a plain-language task summary first and retain exact task evidence, body capabilities, unsigned handoff envelope, and signed history in collapsed disclosures. - [x] Preserve every existing Manifestation gateway, task-authority, Covenant, signing, review-invalidation, and kernel syscall boundary. Presentation state never becomes execution authority. - [x] Stack the roster, editor, body rail, handoff steps, and actions at compact and phone widths with 44-pixel touch targets and no horizontal overflow. - [x] Explain `NAVI_OPERATOR_UNAVAILABLE` as a missing active OS operator profile, offer **Open User Management** and **Refresh**, and keep every Navi authority service fail-closed until a verified profile-change event rebinds the kernel. - [x] Retain the exact provider and operation in browser-direct chat, model catalog, and stream network failures instead of reporting the generic `model service` label. HTTPS, endpoint allowlisting, CORS, credential, and extension/local-runtime boundaries remain unchanged. - [x] Advance AI Echo to `5.22.40`; the Companion extension remains unchanged because no browser relay, credential, or extension UI contract changed. Focused verification recorded 2026-08-08: AI Echo browser smoke passed 501/501, Phase 1 kernel integration passed 24/24, the complete Phase 6 Manifestation matrix passed 71/71, the real production handoff path passed 6/6, AI Echo route regression passed 56/56, and provider transport diagnostics passed 59/59. The redesign and recovery guidance change only presentation hierarchy and task eligibility display; kernel-owned identity, authority, signing, exact envelopes, and immutable handoff receipts remain unchanged. The signed production build compiled and verified 3,079/3,079 modules with zero skipped, cryptographically verified 53 official packages, verified 33/33 AI Echo modules, validated 37 deployed OS files, copied 695 release files, and produced a deterministic CRC-verified 690-file site archive. ### Phase 8.17 project-aware coding, verified Dodads, and reusable app surfaces - [x] Audit Blackboard's project, progress, preview, and verification patterns as clean-room behavioral references without introducing its Python runtime, regex execution recovery, permissive malformed-argument recovery, or a second AI Echo task loop. - [x] Make **Code** a task-scoped project workbench instead of a synonym for Dodad Studio. Distinguish the selected task root, OS Files, system source, and every browser-granted mount so the Navi can select the real project automatically while the operator can still choose a root explicitly. - [x] Add a bounded content-free project map covering language distribution, project markers, likely entrypoints, scan bounds, and truncation state. Keep discovery read-only and skip dependency, vendor, cache, build, and VCS trees. - [x] Reuse the canonical Notepad factory editor and document renderer in both Code and Dodad Studio instead of maintaining AI Echo-specific text-editor or Markdown-renderer copies. - [x] Verify exact save readback and apply a browser-native verification profile for JSON, manifests, JavaScript, HTML, CSS, and Markdown. Classic JavaScript is compiled without execution; module, JSX, and TypeScript inputs report an honest lexical-only warning until a compatible parser is present. Report the verification receipt beside the project rather than claiming success from a model response. - [x] Preflight the complete modular Dodad project before committing a new immutable revision. Require unique bounded paths, a real entrypoint, valid local HTML/CSS/JavaScript references, and locally valid source structure. - [x] Run interactive web Dodads in an opaque `sandbox="allow-scripts"` iframe with a generated CSP that blocks network, object, frame, and navigation access. Execute only committed local project files, never provider prose or Markdown fences, and surface bounded runtime errors through a token-bound `postMessage` channel. - [x] Keep Preview focused on the work product: hide duplicated metadata, library navigation, inner mode tabs, and redundant single-file controls; retain those controls in Code or in an accessible compact Dodad drawer. - [x] Make the global app-factory port contract fail closed before registry or profile mutation when a part lacks a callable mount. Verify all 40 built-in app parts retain unique IDs, callable mounts, registration, and profiles. - [x] Redesign the Companion popup as an evidence-backed trust dashboard with independent Protection, AI access, and Secure provider status, live metrics, the existing encrypted vault, Activity and Settings views, reduced-motion support, and byte-identical development and Store assets. - [x] Preserve all existing ToolRouter, Faculty, VFS, revision, credential, provider, mount, and Navi authority boundaries. Project intelligence, verification, previews, and dashboard summaries remain projections rather than new sources of authority. Official design evidence recorded 2026-08-09: LSP 3.17 workspace-folder semantics informed multi-root project identity; DOMParser and CSSStyleSheet.replace informed local document and stylesheet checks; sandboxed iframe and postMessage contracts informed the opaque preview boundary. These are browser-native implementation references, not runtime dependencies. Focused verification recorded 2026-08-09: full AI Echo browser smoke passed 508/508, Dodad Workspace passed 15/15, official signed Dodad Studio package verification passed 9/9, Phase 2 executor routing passed 132/132, and the global app-parts contract passed 9/9 across all 40 built-in ports. Companion Store validation passed 19/19, install policy 14/14, encrypted KeyVault schema 9/9, and provider relay static validation 4/4. Development and Store popup HTML, CSS, and JavaScript remain byte-identical. ### Phase 8.18 AI Echo remote cognition boundary - [x] Exclude the built-in `llm-runtime` provider at every AI Echo ingress: restored configuration, provider merging, catalog discovery, capability probes, manual targets, Smart candidate pools, and Navi route compilation. - [x] Migrate historic AI Echo Runtime selections to the approved remote Smart route without changing the standalone LLM Runtime app or generic AI Hub provider support. - [x] Prevent a never-settling local Runtime discovery or readiness probe from blocking healthy remote-provider preflight. - [x] Keep Inner Journal and autonomous reflection on independently selected, approved remote Smart Routing pools. An empty compatible pool skips only the optional auxiliary lane and never falls through to local inference. - [x] Reject explicit AI Echo `localOnly` cognition before task creation, context disclosure, or provider dispatch. - [x] Stop scheduled background cognition before model dispatch when its context cannot cross the remote disclosure boundary; do not silently rewrite the request as local-only. - [x] Preserve task-scoped Covenant approval, privacy classification, exact route authorization, DLP checks, receipts, and settlement on every approved remote journal or background request. - [x] Retain standalone Runtime readiness, telemetry, GGUF attachment, and generic broker behavior for other OS applications. Focused verification recorded 2026-08-09: AI Echo routes passed 62/62, AI Echo autonomy passed 18/18, kernel agency passed 10/10, agency syscalls passed 7/7, standalone local-runtime telemetry passed 13/13, AI Echo runtime boundaries passed 3/3, diagnostic reports passed 29/29, pipeline traces passed 16/16, and the full AI Echo browser smoke passed 509/509. ### Phase 8.19 non-blocking AI Echo request preflight - [x] Trace the apparent Approval, Auto, and Bypass stall to its shared pre-dispatch path rather than treating an execution-approval mode as the cause. - [x] Keep inbound mailbox durability asynchronous so encrypted task intake cannot hold a healthy remote provider route at `Preparing request`. - [x] Move optional preference detection, reviewed adaptation prompts, and synthetic-mood updates behind the completed-turn boundary. These cognition projections no longer delay configuration, Smart Routing, context compilation, or provider dispatch. - [x] Persist the completed inbound/outbound mailbox evidence and task outcome before adaptation reloads cross-tab state. Preserve the stronger invariant that a stale AI Echo instance cannot overwrite newer session shards. - [x] Add explicit preflight stage activities and duration logs so configuration synchronization is distinguishable from queued task intake. - [x] Add a behavioral regression that leaves mailbox intake unresolved while proving the provider request still dispatches and completes within the bounded smoke-test window. - [x] Preserve the exact approved-model authority boundary, remote-only AI Echo cognition policy, ToolRouter checks, receipts, and every Approval, Auto, and Bypass authority rule. Focused verification recorded 2026-08-09: the full AI Echo browser smoke passed 510/510 including the deferred-mailbox preflight regression; AI Echo remote routing passed 63/63; Phase 8 task runtime passed 30/30; runtime boundaries passed 3/3; and OS resource hardening passed 6/6. ### Phase 8.20 exact Bypass prompt suppression - [x] Forward the selected per-Navi execution approval mode into auxiliary Inner Journal and Wiki cognition requests instead of silently reverting those remote-disclosure boundaries to `Approval`. - [x] Let Bypass issue the same exact, short-lived, one-use remote route grant that an approved popup would return. Validate the Navi, task, operation, purpose, route revision, data classes, Covenant rules, and every destination before accepting the proof. - [x] Suppress the changed-descriptor review popup in Bypass only after the ordinary tool review allows the action. Re-read, rehash, and re-attest the current live descriptor before planning or execution continues. - [x] Preserve fail-closed behavior for malformed or widened disclosure grants, stale descriptor hashes, revoked Faculties, ToolRouter denials, workspace or mount violations, and Covenant denials. - [x] Keep Approval and Auto behavior unchanged and record whether a prompt was suppressed in the task's approval evidence. - [x] Align the AI Echo runtime, signed manifest, and smoke contract at release `5.22.59`. Focused verification recorded 2026-08-09: execution approval modes passed 12/12, Phase 2 executor routing passed 132/132, AI Echo remote routing passed 64/64, AI Echo autonomy passed 18/18, and the full AI Echo browser smoke passed 510/510. ### Phase 8.21 provider-native tool-only completion admission - [x] Admit a completed provider-native tool-call batch when the assistant prose field is empty instead of classifying the valid completion as empty or malformed. - [x] Require every normalized call to contain a bounded non-empty tool name and a plain-object argument envelope before the route result is usable. - [x] Pass the normalized native tool batch through the request-bound planner validator, descriptor hashes, graph checks, authority review, ToolRouter, verification, and receipts; provider output never executes directly. - [x] Use the same tool-first transport candidate for initial planning and bounded planner repair. - [x] Reject mixed or structurally malformed native tool batches atomically before semantic validation. - [x] Align the AI Echo runtime, signed manifest, and smoke contract at release `5.22.60`. Focused verification recorded 2026-08-09: Navi model-broker routing passed 62/62, Phase 2 executor routing passed 132/132, provider transport passed 59/59, Navi cognition passed 59/59, AI Echo remote routing passed 64/64, the full AI Echo browser smoke passed 510/510, and OS resource hardening passed 6/6. The signed production platform release validated 3,096/3,096 files, AI Echo 36/36 modules, and 53/53 embedded official packages. ### Phase 8.22 unified Bypass at the signed Faculty boundary - [x] Propagate the active AI Echo execution approval mode into every planner-selected deterministic Faculty invocation. - [x] Suppress the Faculty's second operator prompt in Bypass only after the tool action, signed package, live descriptor, exact scope, dry run, and resource request have passed their existing fail-closed reviews. - [x] Keep Approval behavior unchanged, including consumption of the exact one-use elicitation proof for protected Faculty actions. - [x] Bind suppressed prompts to `os.ai-echo`; kernel Hands and unrelated app callers retain the fail-closed Approval default. - [x] Preserve resource reservation, one-use capability consumption, ToolRouter enforcement, verification, and signed receipts in every mode. - [x] Record Bypass Faculty authorization with the distinct `kernel:navi-faculty-policy:bypass` actor instead of claiming the operator clicked Approve. - [x] Align the AI Echo runtime, signed manifest, and smoke contract at release `5.22.61`. Focused verification recorded 2026-08-09: Phase 3 kernel Faculty passed 24/24, Phase 5 Faculty resource authority passed 14/14, execution approval modes passed 12/12, Phase 2 executor routing passed 132/132, AI Echo remote routing passed 64/64, and the full AI Echo browser smoke passed 510/510. The signed production platform release validated 3,096/3,096 files, AI Echo 36/36 modules, and 53/53 embedded official packages. ### Phase 8.23 live mounted-workspace resolution - [x] Replace the `/user`-only workspace text field with a live Workspace source selector containing Automatic, `/user`, `/mnt`, read-only `/system`, and every currently connected Chrome-granted `/mnt/` folder. - [x] Share one canonical mounted-workspace projection between AI Echo Settings, the Code workspace, context collection, and OS tool discovery so their paths, labels, access modes, and connection state cannot drift. - [x] Resolve explicit `/mnt` and `/mnt/` language against the live mount graph. A single matching mount resolves deterministically; multiple matches require a choice; an unavailable mount never falls back silently to `/user`. - [x] Include the exact resolved mounted root and target path in the request-bound workspace context before provider dispatch. - [x] Make `workspace.status` expose connected mounted workspaces and require an explicit canonical path for `storage.list`, removing its implicit `/user` fallback. - [x] Preserve the browser's independently granted mount authority, coding contract, ToolRouter review, execution approval modes, and read/write receipts; selecting a source does not grant new host access. - [x] Align the AI Echo runtime, signed manifest, and smoke contract at release `5.22.62`. Focused verification recorded 2026-08-09: AI Echo tool descriptors passed 19/19, AI Echo remote routing passed 64/64, the full AI Echo browser smoke passed 510/510, and OS resource hardening passed 6/6. A live browser check confirmed the Workspace source selector renders Automatic, `/user`, `/mnt`, and read-only `/system`; connected mounts populate from the same projection. ### Phase 8.24 final-answer tool-envelope containment - [x] Trace the reported `/mnt` incident through planning, verified tool execution, finalization, and the provider's final chat response. - [x] Reject every unfenced executable tool envelope at the final-answer boundary, including a repeated envelope whose exact tool and arguments already have a successful verified receipt. - [x] Preserve fenced JSON examples and ordinary natural-language answers; only executable declared-tool envelopes enter bounded answer repair. - [x] Tell bounded repair to summarize the matching verified tool result when execution already succeeded, instead of requesting or repeating the tool. - [x] Keep unmatched tool envelopes fail-closed and route any requested action back through the planner, descriptor validation, authority, ToolRouter, verification, and receipt boundaries. - [x] Add the exact leaked `{"tool":"os.ai-echo.storage.list","args":{"path":"/mnt"}}` regression with a matching successful receipt. - [x] Refresh the signed built-in Faculty descriptor fixtures through the repository signing pipeline after live descriptor reconciliation. - [x] Align the AI Echo runtime, signed manifest, and smoke contract at release `5.22.63`. Focused verification recorded 2026-08-09: Phase 2 executor routing passed 133/133, AI Echo remote routing passed 64/64, the official signed Faculty package passed 9/9, and the full AI Echo browser smoke passed 510/510. The signing pipeline synchronized 104 generic, 7 Artifact Studio, and 12 browser descriptor records without embedding private signing material. ### Phase 8.25 non-blocking auxiliary cognition - [x] Trace the reported slow first response across provider discovery, Smart Routing, auxiliary cognition, and foreground model dispatch using measured timestamps rather than catalog latency estimates. - [x] Remove Inner Monologue from the foreground request's serial critical path. Dispatch the main approved model request first and run the optional inspectable journal beside it. - [x] Keep one bounded Inner Monologue lane per AI Echo session. When a slow journal call is active, retain only the newest pending turn instead of accumulating an unbounded remote queue. - [x] Contain auxiliary route, provider, validation, and persistence failures without delaying or relabeling a successful foreground answer. - [x] Preserve remote Smart Routing, Navi disclosure approval, journal validation, encrypted persistence, and provider concurrency limits. Do not race duplicate foreground model calls or duplicate effectful tool plans. - [x] Update restore coverage so durable Run Details remain authoritative even when a late optional journal event appears only in the live view. - [x] Align the AI Echo runtime, signed manifest, and smoke contract at release `5.22.64`. Measured evidence recorded 2026-08-09: the reported turn selected its Smart route in under one second, then waited 273,880 ms for remote Inner Monologue before subscribing the foreground stream. After the change, foreground dispatch precedes journal queuing and the journal is not awaited. Focused verification passed: AI Echo autonomy 19/19, remote routing 64/64, runtime boundary 3/3, and full AI Echo browser smoke 510/510. ### Phase 8.26 terminal next-turn ownership handoff - [x] Trace a queued `next turn` that remained idle after the preceding answer was visibly complete. - [x] Separate terminal interactive ownership from encrypted receipt and conversation persistence so storage latency cannot retain the session lock. - [x] Start the queued operator message immediately after the terminal kernel event while the prior run finishes its durable writes in the background. - [x] Preserve stale-owner protection so the prior run's `finally` block cannot clear, cancel, or overwrite the replacement run. - [x] Add a regression that deliberately freezes the first turn's durable conversation commit and proves the next provider dispatch begins before that commit is released. - [x] Align the AI Echo runtime, manifest, and smoke contract at release `5.22.65`. Evidence recorded 2026-08-09: full AI Echo browser smoke passed 511/511, including the stalled-persistence next-turn regression. AI Echo routing passed 64/64, Phase 8 task runtime passed 30/30, and OS resource hardening passed 6/6. ### Phase 8.27 bounded mounted-workspace follow-up routing - [x] Preserve the literal current user message as canonical conversation, memory, approval, and receipt evidence. - [x] Resolve terse referential follow-ups against only the newest completed exchange before workload classification, Smart Routing, and tool selection. - [x] Carry an immediately preceding `/mnt/...` path and listing request into the next affirmative turn without substituting the configured `/user` root. - [x] Select the typed storage list, read, and search capabilities for the resolved mounted-workspace objective. - [x] Require terminal intent in the literal current turn so quoted assistant offers cannot grant terminal capability during contextual resolution. - [x] Record content-free follow-up-resolution diagnostics and expose the decision in managed-context statistics. - [x] Align the AI Echo runtime, manifest, and smoke contract at release `5.22.66`. Evidence recorded 2026-08-09: full AI Echo browser smoke passed 513/513, including bounded `/mnt/work` follow-up and terminal non-inheritance checks. AI Echo routing passed 64/64, tool-descriptor and mounted-storage checks passed 19/19, Phase 8 task runtime passed 30/30, and OS resource hardening passed 6/6. ### Phase 8.28 fail-closed final-answer tool transport - [x] Trace the reported Dodad-update run through failed planner tool rounds, fallback finalization, and the raw tool envelope shown as a completed answer. - [x] Hold every provider final-answer delta as provisional until the complete response passes local schema and executable-envelope validation. - [x] Detect direct JSON tool calls, the `os.ai-echo.tools.invoke` wrapper, provider-native function and tool calls, and XML tool-call transports. - [x] Resolve dynamic wrappers to the exact target tool before comparing them with verified execution results and saved-Dodad obligations. - [x] Fail closed on malformed, oversized, or truncated tool-shaped output without copying the provider body, tool arguments, HTML, CSS, or JavaScript into durable diagnostics or visible chat. - [x] Preserve the saved-Dodad obligation after an attempted create or update, including terse follow-ups whose latest literal message omits the word Dodad. - [x] Reject an unexecuted final tool envelope and route it into bounded repair; never label the run complete or treat executable JSON/XML as natural prose. - [x] Align the AI Echo runtime, signed manifest, and smoke contract at release `5.22.67`. Evidence recorded 2026-08-10: Phase 2 executor routing passed 134/134, AI Echo Dodad workspace passed 15/15, the official signed Artifact Studio package passed 9/9, the full AI Echo browser smoke passed 513/513, and OS resource hardening passed 6/6. The signed production platform release verified 3,097/3,097 modules, 37/37 AI Echo modules, and 53/53 embedded packages. ### Phase 8.29 bounded background cognition and current-turn journals - [x] Trace the autonomous-reflection resource rejection to its scheduler envelope and prove that the 63-route approved catalog was incorrectly reserved as one simultaneous run. - [x] Cap one background cognition execution at three reviewed sequential route attempts without shrinking the operator's approved Smart Model pool. - [x] Bind the same attempt ceiling into the broker decision, execution plan, resource reservation, and signed decision evidence. - [x] Calculate scheduled token ceilings from the exact kernel-owned prompt, configured output allowance, bounded route attempts, and protected verification reserve. - [x] Keep Inner Monologue on remote Smart Routing while limiting its prompt to the current operator objective and durable identity/preferences. - [x] Exclude stale task state, completed plans, and unrelated scratchboard evidence from a new turn's Inner Monologue; keep that historical evidence available to explicitly scheduled autonomous reflection. - [x] Preserve historical broker hashes when the new per-request attempt bound is absent, while binding an explicit non-default bound into new evidence. - [x] Align the AI Echo runtime, signed manifest, and smoke contract at release `5.22.68`. Evidence recorded 2026-08-10: Navi Model Broker passed 63/63, Phase 8 resource selection passed 36/36, kernel background agency passed 10/10, AI Echo autonomy passed 20/20, and the full AI Echo browser smoke passed 513/513. ### Phase 8.30 Dodad Forge recipes and mounted coding execution - [x] Require every generated Web Dodad to use one modular four-file project: `index.html`, `styles.css`, `app.js`, and `dodad.behavior.json`. - [x] Rank Forge recipes from the whole request rather than hard-switching on one keyword. Cover webpage, dashboard, data explorer, canvas game, storybook, form, documentation, showcase, visualization, and custom work. - [x] Validate complete project structure, local references, selectors, interactions, scenarios, JavaScript syntax, and prohibited browser effects before any Dodad revision can be committed. - [x] Run declared behavior scenarios inside the existing opaque, network-blocked preview sandbox and permit one bounded full-project repair when static or runtime verification fails. - [x] Detect mounted coding work separately from Dodad authoring and preserve the exact resolved `/mnt/...` root through classification, Smart Routing, context compilation, planning, tool execution, and receipt settlement. - [x] Guide mounted coding work to inspect applicable rules, README files, configuration, dependencies, and tests before editing; require read-before- edit, narrow changed-file verification, authoritative readback, and receipts. - [x] Never substitute `/user` for an available requested mount, divert a coding-project request into Dodad creation, or claim an unverified file or test outcome. - [x] Add `dodad_forge`, `mounted_project_coder`, and `live_patch_recipe_operator` as progressive-disclosure Guidance Faculties. They select reviewed procedures but grant no tools or authority. - [x] Reuse the canonical Notepad document renderer for AI Echo responses and add safe Markdown-table rendering instead of creating another message renderer. - [x] Keep Live Patch recipe guidance behind the existing proposal, authority, preview, verification, receipt, rollback, and quarantine boundaries. Evidence recorded 2026-08-10: Dodad Forge and mounted-coding checks passed 13/13, Phase 2 executor routing passed 134/134, AI Echo routing passed 64/64, AI Echo Dodad workspace passed 15/15, the official signed Artifact Studio package and OS resource checks passed 15/15, and the full AI Echo browser smoke passed 513/513 on the final clean rerun. ### Phase 8.31 Dodad Forge and mounted-project hardening - [x] Treat mounted project rules, README files, and configuration as untrusted tool context rather than system instructions while preserving exact source hashes and `/mnt/...` scope. - [x] Reject generated Dodads that introduce remote resources, embedded browsing surfaces, navigation, popup, storage, worker, dynamic-code, or obviously unbounded-loop behavior outside the reviewed sandbox contract. - [x] Require every declared Dodad interaction and control to have a matching deterministic behavior scenario before a revision can commit. - [x] Preflight authored JavaScript in a disposable Worker with a strict execution timeout before exercising behavior scenarios in the opaque preview sandbox. - [x] Require a strong current-content hash for mounted-file edits, revalidate connected and writable mount authority at the mutation boundary, and require atomic compare-and-swap writes with authoritative readback. - [x] Bound reusable Notepad/AI Echo document rendering by source size, line, table-column, and table-row limits without truncating the canonical file. - [x] Make the full AI Echo smoke wait for durable active-turn steering order instead of sampling asynchronous persistence immediately. Evidence recorded 2026-08-10: hardened Dodad Forge and mounted-coding checks passed 18/18, Faculty boundary and receipt checks passed 18/18, Phase 2 executor routing passed 135/135, AI Echo routing passed 64/64, AI Echo Dodad workspace passed 15/15, the official signed Artifact Studio package passed 9/9, and the production platform release rebuilt 3,098 modules with a fresh manifest, SRI, reproducible SLSA provenance, compressed bundles, and site archive. ### Phase 8.32 Surface Intelligence and visual coding context - [x] Add strict `navi-surface-selection-v1`, `navi-surface-snapshot-v1`, `navi-surface-source-binding-v1`, `navi-surface-action-catalog-v1`, and `navi-visual-evidence-v1` contracts. - [x] Capture bounded semantic structure, accessibility, design tokens, nearby context, and source provenance without sending a raw DOM dump. - [x] Adapt DOM, Plauna, compositor/app, Engine, Editor, Dodad, and approved browser surfaces through one read-only Surface Intelligence service. - [x] Keep optional visual crops classified, bounded, opaque, and unavailable for credential or system-secret surfaces. - [x] Add durable Smart Context actions for Ask, Inspect source, Edit with Live Patch, and Make a Dodad; revalidate the exact surface fingerprint before use. - [x] Replay unobserved Smart Context requests when AI Echo mounts, acknowledge them exactly once, and compile only bounded untrusted evidence into the turn. - [x] Add a progressive-disclosure `surface_intelligence_builder` Guidance Faculty that selects existing app-factory, Plauna, Engine, Editor, mounted coding, Live Patch, and Dodad Forge procedures without granting authority. - [x] Keep all mutations behind existing ToolRouter, workspace/mount, approval, verification, receipt, rollback, and quarantine boundaries. - [x] Register `os.surface://` resources and app syscalls without creating a second message ledger, patch store, code editor, or visual renderer. Evidence recorded 2026-08-10: Navi contracts passed, Phase 8 intelligence contracts passed 11/11, Surface Intelligence passed 7/7, AI Echo routing passed 64/64, Surface/Dodad/mounted-coding guidance passed 19/19, signed Faculty package plus OS resource hardening passed 13/13, and the final isolated AI Echo smoke passed 515/515 with diagnostic state attached to its durable-steering wait. The signed production release completed successfully across 3,099/3,099 modules, cryptographically self-verified 53 official packages, verified 37/37 AI Echo modules and the complete platform public contract, and published a deterministic CRC-verified 693-file site archive with fresh SRI and SLSA provenance. ### Phase 8.33 Progressive Skills and specialist Dodad quality - [x] Strengthen built-in Faculty descriptions with explicit what-and-when trigger language while keeping Guidance Faculties authority-free. - [x] Publish reviewed recipe, pattern, quality-gate, and mounted-project resources through a live progressive-disclosure reader instead of loading the complete bodies into every model turn. - [x] Deduplicate canonical guidance resources when several Faculties reuse the same reviewed document; reuse is no longer misclassified as catalog tampering. - [x] Build a deterministic Dodad blueprint that assigns advisory architect, implementer, logic-specialist, visual-specialist, and verifier passes without spawning agents or granting additional tools. - [x] Select task-relevant implementation patterns for design tokens, state machines, fixed-step canvas loops, derived views, procedural generation, sliding spatial windows, texture-field buffers, and occlusion/cutaway state. - [x] Require substantive task-specific JavaScript, explicit state/update/render responsibilities, accessible controls, responsive tokens, and declared behavior scenarios from authored Dodads. - [x] Score the complete modular project locally and fail closed when a canvas game or visualization is missing its defining interaction/rendering behavior. - [x] Classify mounted coding work into advisory responsibility passes while preserving exact `/mnt/...` scope, read-before-edit, CAS writes, verification, and receipts. - [x] Keep every script, resource, and model-authored project behind the existing ToolRouter, Faculty, workspace/mount, sandbox, and receipt boundaries. The implementation follows the Agent Skills progressive-disclosure structure and line-count guidance, while deterministic gates remain OS code rather than prompt instructions. The architecture also follows Godot's scene-organization principle of keeping independently meaningful systems independently testable and Blender's guidance to prefer deterministic data APIs over context-sensitive UI operators for procedural work. Evidence recorded 2026-08-10: Dodad Forge and mounted-coding checks passed 24/24, Phase 2 executor routing passed 135/135, AI Echo routing passed 64/64, Dodad workspace passed 15/15, resource selection passed 36/36, signed Faculty package policy passed 19/19, Faculty resource hardening passed 14/14, AI Echo Faculty integration passed 18/18, and the full AI Echo browser smoke passed 515/515. ### Phase 8.34 AI Echo startup and background crash containment This repair keeps AI Echo responsive when a Navi owns hundreds of autonomy records. It also makes background retries explicit and bounded. The kernel continues to enforce every existing capability, integrity, policy, resource, and mount boundary. - [x] Derive each background cognition task ID from the Navi, branch, job, operation, run sequence, and attempt. Load that task through the exact `NaviCognitionService.task()` key instead of decrypting every persisted task. Reject an existing ID whose immutable task contract differs. (Source: `webgpu-os/kernel/KernelBootstrap.js`) - [x] Pass the deterministic ID to `beginTask()` so restart and replay reuse the same task token without scanning the task Store. (Source: `webgpu-os/kernel/KernelBootstrap.js` and `webgpu-os/kernel/navi/NaviCognitionService.js`) - [x] Keep completed cognition dispatch history out of the cold plaintext recovery path. Persist an encrypted recovery marker atomically with every pending dispatch before provider execution, hydrate at most 16 unresolved markers before readiness, and migrate legacy dispatches in resumable 16-record idle pages with a CAS cursor and one Navi-wide lock. Exact task access filters authenticated record metadata to `taskId:` before decryption, then verifies the derived evidence/checkpoint pair fail-closed. (Source: `webgpu-os/kernel/navi/NaviCognitionService.js` and `webgpu-os/kernel/navi/NaviCognitionStore.js`) - [x] Use IndexedDB primary-key ranges for filtered cognition pages. Prefix, cursor, and limit bounds are validated before storage access; a parent task cannot decrypt a hierarchical child task's history. (Source: `webgpu-os/kernel/navi/NaviCognitionStore.js`) - [x] Treat ordinary and permanent failures as terminal on their first attempt. Permit bounded backoff only for the privately branded `NaviBackgroundTransientExecutionError` outage and throttle kinds. Provider error text never becomes retry authority. (Source: `webgpu-os/kernel/navi/NaviBackgroundCoordinator.js`) - [x] Reconcile an authenticated legacy background job whose historical attempt count exceeds its immutable maximum as terminal without execution. Preserve both counters, validate every other schema and persistence binding, CAS-write one fixed local failure state, propagate the committed revision, and make concurrent repair idempotent. (Source: `webgpu-os/kernel/navi/NaviBackgroundCoordinator.js`) - [x] Retry aggregate Navi authority binding only while every current failure is an explicit dependency, initialization, drain, or operator-rebind state. Operator, degraded, untyped, policy, integrity, configuration, schema, and budget failures schedule no recovery timer; transient recovery remains coalesced and capped at three attempts. (Source: `webgpu-os/kernel/KernelBootstrap.js`) - [x] Reuse only already verified operator-visible autonomy projections. Bind each cache entry to the authority generation, Navi, record identity, classification, revision, envelope hash, and integrity hash. Bypass private Navi records, evict rejected decryptions, and cap the cache at 256 entries. (Source: `webgpu-os/kernel/navi/NaviAutonomyService.js`) - [x] Attach the `.ae-app` shell, wait for two guarded animation frames, and only then hydrate configuration, continuity, journals, and background jobs. Abort late mount work when the root, app, gateway generation, or unmount state changes. (Source: `webgpu-os/apps/ai-echo/factory.js`) - [x] Subscribe to autonomy changes before the single mount snapshot. Coalesce paired refreshes and merge journal or job events through exact `readJournal()` and `jobStatus()` reads without replacing unrelated collections. (Source: `webgpu-os/apps/ai-echo/factory.js`) - [x] Keep `surfaces.onAction` behind the guarded `navi.projections.read` syscall mapping. The default-deny boundary remains active for callers without that capability. (Source: `webgpu-os/kernel/Syscalls.js`) - [x] Reject conflicting Particle route-protocol registry attachments and log route, provider, kind, descriptor, and protocol identifiers separately. Visibility suspension still releases leadership and resume rebuilds the resident route as designed. (Source: `engine/network/endpoint/ParticleEndpointRuntime.js`, `webgpu-os/drivers/NetworkDriver.js`, and `webgpu-os/drivers/EmbeddedParticleNode.js`) - [x] Align the AI Echo runtime, signed manifest, and smoke contract at release `5.22.69`. Evidence recorded 2026-08-11: autonomy foundation passed 17/17, kernel agency passed 12/12, AI Echo autonomy passed 24/24, and the combined Phase 5 agency umbrella passed 205/205. Phases 3, 4, 6, and 7 passed 169/169, 146/146, 71/71, and 179/179. Surface and network checks passed 26/26, 5/5, 10/10, and 29/29. Cognition Store and service recovery passed 13/13 and 59/59; Continuity, kernel cognition, resource metering, production-path, adversarial-boundary, and atomic-transition checks passed 38/38, 16/16, 21/21, 6/6, 7/7, and 6/6. The autonomy and kernel-cognition regressions include one-write legacy attempt overflow reconciliation, exact repaired-revision projection, concurrent repair, permanent-before-timer rejection, transient-to-permanent termination, and the three-attempt transient cap. The AI Echo smoke passed 515/515 twice consecutively after its deliberately overlapped mailbox fixture waited for complete durable settlement. The no-cache production build bundled 2,123 modules with zero skipped and verified all 37 AI Echo modules. ### Phase 8.35 bounded recovery indexes and permanent settlement isolation This follow-up closes the remaining cold-start work shown by profiles with hundreds of historical resource, Faculty, and background records. The repair keeps the existing capability, signature, integrity, quarantine, resource, and operator-review boundaries intact. - [x] Persist a permanent task-local resource settlement failure as an authenticated `operator-review-required` dispatch disposition. Retire the active dispatch-recovery marker after the durable disposition commits, keep the exact accounting evidence, and never replay the provider or settlement. Treat only `NAVI_RESOURCE_INDEX_MIGRATION_PENDING` as deferred migration work. (Source: `webgpu-os/kernel/navi/NaviCognitionService.js`) - [x] Replace branch-wide resource-account plaintext scans with exact task account reads plus encrypted branch membership and migration records. Commit account and branch totals in one batch CAS. Migrate legacy accounts in 16-record scan and verification pages; a changed count or digest rewinds the migration before it can complete. (Source: `webgpu-os/kernel/navi/NaviResourceService.js`) - [x] Give persisted resource branch indexes, resource migration state, Faculty recovery state, and Faculty recovery markers immutable v2 formats and disjoint deterministic v2 record identities. Never open, rewrite, delete, or quarantine retired v1 control ciphertext. Rebuild v2 authority only from authenticated account and operation records in bounded pages. This preserves the observed incompatible 511-byte resource state, 242-byte Faculty state, and one-hash Faculty markers for forensic inspection without allowing them to block startup. (Source: `webgpu-os/kernel/navi/NaviResourceService.js` and `webgpu-os/kernel/navi/NaviFacultyService.js`) - [x] Advance the cognition IndexedDB epoch to version 3. The established `versionchange` invalidation closes version-2 owners, so a pre-v2-index tab cannot write behind a verified recovery cursor. A stale owner loses Store authority rather than bypassing the new index. (Source: `webgpu-os/kernel/navi/NaviCognitionStore.js`) - [x] Open at most one 64-row background inventory page before coordinator readiness. Reuse that verified page for initial due selection and timer arming, hydrate later pages after readiness, and require an explicit operator listing to finish any still-deferred inventory. Job status remains an exact record read. (Source: `webgpu-os/kernel/navi/NaviBackgroundCoordinator.js`) - [x] Persist Faculty operation recovery markers atomically with operations. Hydrate at most 16 active markers before readiness and migrate legacy operation history through 16-row scan plus metadata-verification pages. Completed history no longer enters the cold plaintext path. (Source: `webgpu-os/kernel/navi/NaviFacultyService.js`) - [x] Hold one shared per-operation Web Lock across live Faculty dispatch and use an exclusive recovery lock in other tabs. A live operation is skipped, then re-read exactly once after lock release without polling. Prepared grants get an expiry reaper, receipt retry reuses immutable signed identity across a clock change, and conflicting reconciliation has one lock-ordered winner. (Source: `webgpu-os/kernel/navi/NaviFacultyService.js`) - [x] Page unresolved and pending Faculty recovery projections with an exact authenticated cursor. AI Echo follows unresolved pages only after its visible shell. Kernel resource recovery follows pending-settlement cursors, performs a fresh from-null sweep after every migration or live-lock notification, and retries only the typed resource-index migration state with six bounded backoff attempts. (Source: `webgpu-os/apps/ai-echo/factory.js`, `webgpu-os/kernel/Syscalls.js`, and `webgpu-os/kernel/KernelBootstrap.js`) - [x] Emit one frozen, content-free resource-index completion event per Navi and durable completion timestamp, including when another tab committed the completed state. Only the current Resource service may clear the matching Navi's exhausted Faculty retry keys and request one exact from-null sweep; ordinary observer noise cannot reset the bounded retry budget. (Source: `webgpu-os/kernel/navi/NaviResourceService.js` and `webgpu-os/kernel/KernelBootstrap.js`) - [x] Keep signed official package registries byte-exact through release minification. The bundler no longer applies global internal-name text replacements to application code or signed Base64URL values; safe module-ID compaction remains enabled and the post-minification inventory still verifies every embedded record. (Source: `bundler/builder.py`, `bundler/cli.py`, and `bundler/official_inventory.py`) Evidence recorded 2026-08-11: cognition Store and service passed 13/13 and 60/60. Phase 3 passed all 10 suites with 173/173 assertions, including 36/36 Faculty lifecycle checks. Phase 5 passed all 13 suites with 214/214 assertions, including resource accounting 19/19, cognition resource metering 22/22, background autonomy 18/18, and Kernel Faculty resource recovery 18/18. The adversarial checks include 65 background jobs, 17 active Faculty markers, cross-tab live dispatch, delayed prepared expiry, clock-advanced receipt retry, conflicting reconciliation, transient resource-index recovery, and a marker inserted behind an in-flight continuation cursor. Persisted-schema regressions reproduce the exact incompatible 242-byte Faculty and 511-byte resource v1 records, prove their ciphertext remains unopened and unchanged, and recover through bounded v2 indexes. ### Phase 8.36 clean-room semantic execution and mounted verification This phase transfers behavior, not implementation, from external research. It keeps the existing planner, cognition Store, investigation path, skill catalog, and signed Faculty authority as the only production owners. - [x] Treat Retrodict as unlicensed for this work. Do not copy its code, prompts, tests, assets, or prose, and do not add an import, package, runtime, or build dependency on it. Luna remained untouched and served only as a donor for independently described behaviors; no Luna implementation or dependency entered this repository. All resulting repository work remains within the project and third-party boundaries in `LICENSE` and `NOTICE.md`. - [x] Compile trusted descriptor effects into exact, value-free semantic postconditions bound to descriptor, argument, graph, source, dependency, receipt, and authoritative readback hashes. A mismatch fails the node and stops dependent execution instead of accepting provider success text. (Source: `webgpu-os/kernel/execution/SemanticEffectContract.js`, `webgpu-os/kernel/execution/NaviTaskGraphCompiler.js`, and `webgpu-os/kernel/execution/TwoPassPlannerFinalizer.js`) - [x] Limit the execution horizon by descriptor risk, reversibility, verified sample count, reliability, and mismatch rate. Confidence may only reduce the caller's fixed action, parallel-read, and mutation-before-observation ceilings; it never grants a capability, approval, tool, or wider horizon. Enforce those limits on actual dispatches, defer unstarted nodes without authorizing them, and return to planning after each bounded mutation window. (Source: `webgpu-os/kernel/execution/ExecutionHorizonPolicy.js` and `webgpu-os/kernel/execution/TwoPassPlannerFinalizer.js`) - [x] Save graph checkpoints as restricted encrypted cognition records through one exact read and one compare-and-swap write, never list or scan. Bind every checkpoint and resume decision to graph, source, and descriptor hashes plus bounded node status and authoritative receipt, state, and evidence hashes. Never replay a mutation or an outcome-unknown node; only a verified completed read-only node can be classified as reusable when every binding matches. Before any durable-Navi mutation dispatch, commit an outcome-unknown CAS fence; a missing or conflicting fence dispatches nothing, while a crash after the fence remains blocked until authoritative reconciliation. Carry a bounded, content-free mutation tombstone ledger across graph revisions, including revisions that omit the mutation, and fail closed rather than evicting task-lifetime replay evidence. Use the disjoint v2 exact-record identity; an observed legacy v1 head remains unopened and blocks execution until a trusted migration or terminal cleanup is available. (Source: `webgpu-os/kernel/execution/NaviTaskGraphCheckpoint.js`, `webgpu-os/kernel/navi/NaviCognitionService.js`, and `webgpu-os/kernel/execution/TwoPassPlannerFinalizer.js`) - [x] Keep canonical CommitCoordinator idempotency receipts in their existing non-evicting registry, but isolate tool/provider replay in a 256-entry, two-minute, 8 MiB LRU with a 64-call single-flight bound. Reserve admission before the durable mutation fence, detach and freeze strict-JSON receipts before sizing, and hash descriptor and argument bindings into cache keys instead of retaining raw arguments. Failed and outcome-unknown executions never become settled cache authority. Durable mutation safety comes from the cognition checkpoint fence and tombstone ledger, not the evictable process-local replay cache. (Source: `engine/state/transaction/Idempotency.js`, `webgpu-os/kernel/time/IdempotencyManager.js`, and `webgpu-os/kernel/execution/TwoPassPlannerFinalizer.js`) - [x] Roll bounded context forward as a derived, content-free projection of checked, assumed, contradicted, and unresolved claim hashes; receipt, source, and checkpoint references; data classifications; and truncation counts. Reject raw tool arguments, provider text, hidden reasoning, and content, and create no new persistence service. (Source: `webgpu-os/kernel/execution/NaviContextRollover.js` and `webgpu-os/kernel/execution/TwoPassPlannerFinalizer.js`) - [x] Build deterministic mounted-project intelligence only through the exact mounted storage list/read tools, with bounded content-free facts and advisory suggestions. Run browser-native JavaScript, TypeScript, and JSX verification against the mounted source and scoped-rules hashes; missing local imports and undeclared dependencies fail closed, while unsupported lexical cases remain explicitly inconclusive. (Source: `webgpu-os/kernel/agent/MountedProjectIntelligenceIndex.js`, `webgpu-os/kernel/execution/BrowserNativeJavaScriptVerifier.js`, `webgpu-os/apps/ai-echo/VerificationProfiles.js`, and `webgpu-os/apps/ai-echo/AgentToolset.js`) - [x] Stage mounted file changes in a bounded, source-preserving overlay that owns no storage authority. Promotion requires the exact canonical path manifest, preview hash, and explicit confirmation, then reuses the existing path capability, CAS, provenance, receipt, and readback paths. Promote only create/update operations backed by exact atomic writes. At this phase gate, staged rename/delete operations remained inspectable or discardable but failed before source mutation until revision-bound move/delete syscalls existed. Enforce transaction, change, per-file, and retained-content quotas. Teardown invalidates not-yet-dispatched work, defers active source scrubbing until settlement, and restores capacity. Recheck the exact scoped-rules hash after target observation immediately before create/update CAS. Deterministically invalid JSON and app manifests fail local verification before storage dispatch, while post-write readback remains authoritative. Do not retry or compensate an outcome-unknown mutation automatically. (Source: `webgpu-os/apps/ai-echo/MountedCodingTransaction.js` and `webgpu-os/apps/ai-echo/AgentToolset.js`) - [x] Compare two immutable captures of the same app, adapter, and surface with bounded deterministic semantic, layout, source, and design-token diffs. An allowed-difference contract must reject every unexpected change. Optional visual evidence is accepted only as a bounded payload produced atomically in the same adapter observation; deferred callbacks and caller context are never retained. Credential and system-secret surfaces remain blocked, secret source hashes and coordinates are removed, and every lookup enforces TTL plus per-item and aggregate byte ceilings. OCR, pixel inspection, and visual text extraction are excluded. (Source: `webgpu-os/kernel/navi/SurfaceTemporalVerifier.js` and `webgpu-os/kernel/navi/NaviSurfaceIntelligence.js`) - [x] Keep operational evidence content-free and bounded. Mounted internal read proofs retain revision, rules, and range coverage without source bodies; terminal request/session paths purge proofs. Tool history stores only bounded status, origin, size/count metadata, and domain-separated argument hashes, and app gateways force exact owner-scoped history and health. Public failure text is bounded before replay retention, and handler-supplied resource usage cannot replace Kernel dispatch accounting. (Source: `webgpu-os/apps/ai-echo/ReadProvenanceLedger.js`, `webgpu-os/kernel/ToolDriver.js`, `webgpu-os/kernel/tools/ToolRouter.js`, and `webgpu-os/kernel/AppRegistrationScope.js`) - [x] Reuse the established dynamic-skill guidance and investigation service; do not introduce a parallel skill runtime, investigation engine, planner, or memory Store. Skills remain instruction policy without execution authority. Signed Faculty manifests, capabilities, operations, and receipts retain ownership of delegated execution. (Source: `webgpu-os/apps/ai-echo/DynamicSkillEngine.js`, `webgpu-os/kernel/navi/NaviInvestigationService.js`, `webgpu-os/kernel/execution/TwoPassPlannerFinalizer.js`, `webgpu-os/kernel/navi/NaviCognitionService.js`, and `webgpu-os/kernel/navi/NaviFacultyService.js`) ### Phase 8.37 AI Echo fast-open and correlated diagnostics This phase removes startup decrypt and write amplification without creating a plaintext cache or weakening authenticated persistence. Exact encrypted heads, immutable shards, source-bound secondary indexes, and bounded browser-idle work remain the only acceleration authorities. - [x] Paint an inert, accessible AI Echo mount surface before state hydration, measure the sandbox, active-state, hydration, capability, and interactive phases, and collect a bounded Long Tasks summary when the browser exposes it. Keep the surface read-only until the exact committed state and deferred sandbox readback verification are ready, and reject late mount results after teardown. (Source: `webgpu-os/shell/Desktop.js` and `webgpu-os/apps/ai-echo/factory.js`) - [x] Open only the encrypted global state head and deterministic active-session shard on the fast path. Reuse unchanged immutable session shards, publish all dirty shards plus the manifest head in one atomic batch, verify with exact reads, and hydrate inactive sessions in bounded pages. Cleanup may delete only shards from a previously verified committed generation and must condition its delete on the exact manifest token. The same logical compare-and-swap protects manifest publication even when Web Locks are unavailable; locks remain a scheduling optimization, not authority. A normal concurrent writer produces a read-only conflict, not corruption quarantine. (Source: `webgpu-os/apps/ai-echo/AgentStateStore.js`) - [x] Fence per-app persistence at IndexedDB v5 with a disjoint encrypted v5 generation head, v3 exact-membership inventory pages, and a segmented v8 Files-visible readback. Warm reads open only the head, routed page, and exact requested ciphertext; a deferred bounded full audit still gates mutation and tool authority. Writes hash only touched pages, atomically compare the physical head and optional logical record token, publish immutable encrypted segments before one manifest CAS, and retain authenticated staged/retired cleanup leases. The one escaped v4-head/v2-page/v7-readback layout is migrated only after exact AEAD, schema, byte, ordering, and bijective-coverage verification. Unknown or tampered retired layouts remain byte-preserved and block mutation. IndexedDB version-change fencing closes older connections, while panel teardown cancels deferred work and closes its sandbox. (Source: `webgpu-os/storage/AppSandbox.js` and `webgpu-os/shell/Desktop.js`) - [x] Run Navi migrations and recovery through one lifecycle-aware maintenance scheduler. Each idle or delayed fallback grant advances at most one bounded page, a zero-budget idle callback decrypts nothing, duplicate work identities coalesce, and owner drain cancels queued or active generations. Existing Web Locks, encrypted cursor evidence, Store integrity checks, and compare-and-swap writes remain authoritative. (Source: `webgpu-os/kernel/navi/NaviMaintenanceScheduler.js` and `webgpu-os/kernel/KernelBootstrap.js`) - [x] Maintain operational-journal and background-job secondary indexes as restricted encrypted records atomically with their exact source rows. A schema-versioned scan, verification pass, marker-inventory pass, and warm audit must complete before list or due-execution APIs become readable. Index markers bind source record identity, revision, envelope hash, and integrity evidence; every returned or executable item is exact-reread and authenticated. Migration-pending is an observable recovering state, never an empty result or authority failure. (Source: `webgpu-os/kernel/navi/NaviAutonomyService.js`, `webgpu-os/kernel/navi/NaviBackgroundCoordinator.js`, and `webgpu-os/kernel/navi/NaviCognitionStore.js`) - [x] Give every in-memory log entry a monotonic sequence and explicit retained coverage, and carry closed, bounded operation, span, incident, cache, migration, mount, and lifecycle metadata without arbitrary object or secret serialization. Routine cognition opens emit one terminal correlated span; nested KeyVault decrypt tracing is opt-in. Structured, text, JSON, and JSONL exports use one safe projector and per-export opaque identifier ordinals. (Source: `webgpu-os/kernel/OsLogger.js`, `webgpu-os/kernel/Syscalls.js`, `webgpu-os/kernel/navi/NaviKeyVault.js`, and `webgpu-os/kernel/navi/NaviContinuityService.js`) - [x] Extend Log Viewer with full-buffer export, coverage disclosure, operation, incident, migration, cache, and lifecycle correlation, while retaining a bounded live stream. Extend AI Echo diagnostics with the same coverage and mount-phase evidence so decrypt volume, decrypt latency, recovery work, and UI stalls are distinguishable. (Source: `webgpu-os/factory/apps/log-viewer/LogViewerApp.js`, `webgpu-os/factory/apps/log-viewer/analysis.js`, and `webgpu-os/apps/ai-echo/DiagnosticReport.js`) ### Phase 8.38 revision-bound mounted mutation and Cognition isolation This phase replaces the former rename/delete promotion block with guarded native file moves. It also prevents one retired task's terminal resource disposition from taking Cognition and Presence offline. - [x] Isolate an authenticated terminal resource-recovery disposition when its task row has already retired. Retain the exact dispatch and accounting evidence, recreate no task, provider call, or settlement attempt, and retire only the exact recovery marker with bounded conflict retries. A live task still must become durably blocked, and a marker-retirement failure still fails closed. (Source: `webgpu-os/kernel/navi/NaviCognitionService.js`; test: `tests/navi/phase2-cognition-service.test.js`) - [x] Load signed Manifestation status, adapters, contracts, primary body, and handoffs independently from the Cognition task projection. A typed Cognition operator failure or operator rebind preserves valid body destinations, substitutes an empty task list, and disables task handoff. A malformed task projection or unexpected failure while Cognition reports ready still clears partial Presence state. Refresh only the selected Navi while AI Echo remains mounted. (Source: `webgpu-os/apps/ai-echo/factory.js`; test: `tests/navi/phase6-ai-echo-presence.test.js`) - [x] Bind `writeAtomic()` and `writeBytesAtomic()` to the exact backend and `mountIdentity` under storage coordination. Recheck that authority before dispatch, after dispatch, and through byte-exact readback. Return immutable authority-bearing receipts, and expose `verifyAtomicAuthority()` as a read-only exact-receipt check that never repeats the write. Mounted execution requires Web Locks and never falls back to an ordinary write. (Source: `webgpu-os/storage/StorageManager.js` and `webgpu-os/kernel/Syscalls.js`; test: `tests/storage-atomic.html`) - [x] Serialize mount, restore, unmount, permission, refresh, attach, and detach topology changes under the same `webgpu-os.storage.mutation.v1` Web Lock as guarded storage mutations. Bind mounted authority to the persistent mount authority identifier plus exact graph layer, and invalidate prepared native moves whenever topology changes. (Source: `webgpu-os/storage/StorageCoordination.js` and `webgpu-os/storage/MountDriver.js`; test: `tests/storage-atomic.html`) - [x] Expose `moveIfUnchanged()`, `trashIfUnchanged()`, `restoreTrashIfUnchanged()`, and `observeTrash()` through confined Kernel storage syscalls. The three mutations admit files only, require one backend and writable root or layer, bind the exact source hash and optional revision, require an absent destination, and dispatch only one native `FileSystemHandle.move()`. An unavailable primitive, directory, ambiguous layer, occupied destination, or cross-root request fails before mutation; the strict path never substitutes copy-then-delete. (Source: `webgpu-os/storage/StorageManager.js`, `webgpu-os/storage/MountDriver.js`, `webgpu-os/storage/OPFSDriver.js`, and `webgpu-os/kernel/Syscalls.js`; test: `tests/storage-atomic.html`) - [x] Persist an operation-ID-bound pre-dispatch journal and exact before/after observations. Only a durable `witnessed-commit` phase can become a committed receipt during recovery, and recovery validates it without redispatch. `dispatching`, `verifying`, a mismatching witness, or an uncertain terminal write remains outcome-unknown with no automatic cleanup, retry, or inferred no-effect result. Committed replay rechecks the current mount authority. (Source: `webgpu-os/storage/StorageManager.js`; test: `tests/storage-atomic.html`) - [x] Move a mounted deleted file into the hidden mount-local `.webgpu-os-trash//data` path and bind central metadata to its original path, payload path, backend, mount identity, hash, and optional revision. Mounted strict `observeTrash()` and `listTrash()` use the same cross-context lock as topology changes, read the exact payload inside that lock, and recheck mount authority after the payload read. Observation reports outcome-unknown when the payload is missing, replaced, or remounted, while a list omits a strict item whose exact authority cannot be validated. Restore requires that unchanged payload and an absent destination; permanent purge removes the mounted payload before central metadata. (Source: `webgpu-os/storage/StorageManager.js` and `webgpu-os/storage/MountDriver.js`; test: `tests/storage-atomic.html`) - [x] State the browser boundary in every native-move receipt: `method: native-handle-move`, `consistency: optimistic-cooperative`, `sameOriginSerialized: true`, `externalProcessCAS: false`, and `standardized: false`. Web Locks serialize cooperating same-origin tabs, workers, and mount topology. They cannot exclude a desktop process that edits the shared directory, so identical path or byte readback alone never upgrades external activity into compare-and-swap proof. (Source: `webgpu-os/storage/StorageManager.js`, `webgpu-os/storage/StorageCoordination.js`, `webgpu-os/storage/MountDriver.js`, and `webgpu-os/storage/OPFSDriver.js`; test: `tests/storage-atomic.html`) - [x] Promote AI Echo create/update/rename/delete changes only through the guarded storage methods. Create/update receipts retain the exact conditional write receipt; mounted final verification calls read-only `verifyAtomicAuthority()`. Rename replays the same operation ID and arguments only to revalidate the committed journal without a second move. Delete retains an exact Trash payload observation. The staged create/update expectation passes unchanged into conditional storage, so a deleted target cannot be recreated by rebasing onto absence. Crossing a returned storage commit makes later nested no-effect claims ineligible for retry or rollback. Mounted update and rename never dispatch automatic compensation: a later failure or remount preserves the current root and settles outcome-unknown. OPFS compensation remains exact-witness guarded, and delete restoration stays bound to the exact Trash authority and absent destination. Ordinary mounted write/edit tools also return an authority receipt and use read-only final verification. Per-change receipts preserve backend, mount identity, coordination, consistency, post-commit state, and the truthful external-process limitation. No ordinary-write fallback exists. (Source: `webgpu-os/apps/ai-echo/MountedCodingTransaction.js` and `webgpu-os/apps/ai-echo/AgentToolset.js`; tests: `tests/navi/mounted-coding-transaction.test.js` and `tests/navi/phase3-ai-echo-tool-descriptors.test.js`) Evidence recorded 2026-08-11: storage atomic passed 39/39, storage backup boundary passed 11/11, cognition service passed 66/66, cognition resources passed 22/22, Kernel cognition passed 16/16, AI Echo routing passed 64/64, AI Echo Presence passed 22/22, mounted coding transactions passed 15/15, and AI Echo tool descriptors and runtime passed 41/41. The AI Echo implementation epoch hash is `sha256:256:62c022e951d5139936b180ca8084af0874af19703bb87ce491ebe5f4a219cbe8`. ### Runtime Smart Context and file commands - [x] Present a compact runtime-first command menu and disclose secondary commands through **Show more options**. - [x] Keep Plauna inspection, surface scanning, logs, and other developer commands out of runtime mode while retaining them in developer mode. - [x] Support direct text Copy, Cut, Paste, Undo, Redo, and Select all actions; Cut mutates content only after the Clipboard write succeeds. - [x] Give Files items Open, Cut, Copy, Rename, and **Move to Recycle Bin** as primary commands, with Download, Share, Version history, Duplicate, Copy path, and Properties progressively disclosed. - [x] Give blank Files surfaces New folder, New file, Paste, and Refresh. - [x] Preserve the distinction between an application shortcut on the desktop (**Remove from Desktop**) and a canonical file in Files (**Move to Recycle Bin**); neither command implies permanent deletion. - [x] Provide menu keyboard focus, Arrow/Home/End navigation, typeahead, Escape dismissal with focus restoration, disabled state, danger state, and bounded viewport scrolling. - [x] Keep app-owned menus authoritative and prevent the legacy desktop fallback from opening after Smart Context handles the same event. Evidence recorded 2026-08-10: Smart Context contract checks passed 12/12, shell preference checks passed 9/9, and the complete AI Echo browser smoke passed 515/515. Live shell inspection confirmed a single captured context-menu path and no duplicate legacy desktop menu. **Exit gate:** - [ ] No production caller depends on a retired duplicate path. - [ ] Interrupted tasks and streams recover without replaying a settled action. - [ ] The OS remains bootable and rollback restores the pre-Phase 8 state. - [ ] The complete Phase 8 acceptance checklist passes on desktop and mobile. ### Phase 8 acceptance checklist - [x] A valid declared tool works without a Dynamic Skill. - [x] Stale descriptor, verifier, schema, path, argument, and approval evidence blocks execution. - [x] Sherlock discriminates among competing hypotheses and stops at its bound. - [x] Malformed model JSON produces a bounded, helpful outcome without trapping the task in a repair loop. - [x] A referential follow-up resolves against the active task or the newest completed exchange without inheriting undeclared authority. - [x] Steering invalidates only affected unstarted work and stale approvals. - [x] Context selection drops the least relevant allowed context first and records the reason. - [x] Private and restricted data remain blocked from disallowed routes. - [x] A disconnected AI Echo stream resumes from its exact sequence cursor. - [x] Learned guidance remains pending until its evidence and review gates pass. - [x] The Workspace Output Index resolves canonical files and app outputs without copying them. - [x] Cross-Navi task state, context, outputs, strategies, and evidence remain isolated. - [ ] Every existing Navi, AI Echo, VFS, storage, tool, resource, browser, extension, provider, bundler, and OS suite remains green. ## Verification procedures ### Documentation validation Run from `MD/` after editing this plan: ```bash python tools/build_docs.py python tools/build_llms.py ``` Serve the repository over HTTP and open the Navi page in the zero-build viewer. Verify the navigation entry, tables, checklist boxes, links, and Mermaid source. ### Phase 0 implementation validation The runtime Phase 0 implementation must add focused schema tests and retain the existing project checks. At minimum, run: ```bash python scripts/check_ai_os_imports.py python -m pytest tests/test_os_resource_hardening.py python bundle_engine.py --target webgpu-os ``` Also run the browser-based `tests/storage-atomic.html` and the AI Echo smoke harness over `http://127.0.0.1:9001`. Record exact pass counts and backup checksums in the Phase 0 receipt. A build alone does not prove rollback. ### Mandatory rollback drill 1. Create one unrelated `/user` file and record its checksum. 2. Create representative AI Echo sessions, Soul/Mind settings, Wiki entries, and managed files. 3. Produce and inspect a complete backup and dated AI Echo archive. 4. Trigger a controlled migration failure before Navi continuity initialization. 5. Run the rollback procedure. 6. Verify the unrelated file checksum and every archived AI Echo checksum. 7. Verify that the OS boots, AI Echo opens, and Navi starts automatically with no user/app on/off control. 8. Verify that the failed Navi store is quarantined, reports exact health, and cannot sign or execute. ## See also - [WebGPU OS Architecture](architecture.md) - [Security and Trust Model](../concepts/security-model.md) - [Data Flow](../concepts/data-flow.md) - [Glossary](../getting-started/glossary.md) - [Writing Checklist](../contributing/writing-checklist.md) --- # AI Echo Live Patch AI Echo Live Patch lets the resident Navi inspect and update a mounted interface without rebuilding the OS. It edits registered WebGPU OS app surfaces, selected shell surfaces, AI Echo itself, and browser tabs exposed by the WebGPU OS browser extension. Live Patch is not a raw JavaScript or unrestricted DOM tool. AI Echo proposes a small versioned document. The kernel validates the document, creates a reversible preview, verifies the visible result, and writes a receipt before an OS-surface change becomes durable. (Source: `webgpu-os/kernel/live-patch/LivePatchService.js`.) ## Clean-room research boundary The public behavior of [`philholden/partialupdate`](https://github.com/philholden/partialupdate) informed the product goal: a model can stream partial interface updates into named regions instead of regenerating the entire application. Its public README shows named insertion points and describes HTML, CSS, JavaScript, and SVG generation in a multi-user chat environment. Its public protocol document describes a streaming server-to-browser update channel. ([Public behavior](https://github.com/philholden/partialupdate/blob/main/README.md#L13-L77), [public protocol](https://github.com/philholden/partialupdate/blob/main/spec.md#L8-L85).) The upstream project also states that it is not hardened for production and is intended for local development. It warns that malicious prompts can create unbounded model loops and costs. ([Upstream warning](https://github.com/philholden/partialupdate/blob/main/README.md#L83-L94).) WebGPU OS uses an independent design: - It does not use upstream source code, prompts, delimiters, WebSocket messages, storage records, or client runtime. - It does not execute model-generated JavaScript, event handlers, scripts, SVG, remote styles, or remote media. - The kernel owns target selection, validation, preview, verification, persistence, rollback, and receipts. - Existing Tool Firewall, capability, Faculty, and approval rules remain in force. A generated interface cannot grant itself authority. - Browser editing uses packaged extension functions. It never sends a provider credential or reusable extension authority into the edited page. The upstream repository is MIT licensed, but Live Patch remains a clean-room WebGPU OS implementation under the repository's own source-available license. ([Upstream license](https://github.com/philholden/partialupdate/blob/main/LICENSE).) Chrome's independent declarative-partial-update design likewise separates scoped declarative updates and sanitization from explicitly unsafe script-capable paths. Live Patch adopts that security distinction without adopting Chrome's API or the upstream project runtime. ([Chrome design](https://developer.chrome.com/blog/declarative-partial-updates).) ## Architecture The kernel service owns one `webgpu-os-live-patch-v1` contract. A complete edit uses this sequence: 1. `live.surfaces` lists registered targets. 2. `live.inspect` returns a bounded, redacted structural snapshot. 3. `live.stage` validates a strict patch, records its pre-edit inspection, and binds the exact normalized operations and target fingerprint into the patch hash and approval payload. 4. `live.preview` rechecks the approved fingerprint immediately before applying the patch with an in-memory undo journal. 5. The service reads the surface back and verifies every operation. 6. The operator can inspect the visible preview. 7. `live.commit` compare-and-swaps the surface's causal head, then publishes the canonical patch and SHA-256 receipt as one compensated transaction. 8. `live.rollback` reverts the active edit, advances the same causal head, and records a rollback receipt. ### RealmForge-informed prepared activation Live Patch adopts RealmForge's offside-prepare and last-good activation pattern without importing RealmForge documents, scripts, or runtime authority. During `live.stage`, the kernel treats the normalized operation list as pure input and compiles a `webgpu-os-live-patch-candidate-v1` evidence record twice. The two canonical results must be byte-identical. The candidate binds the operation hash and semantic diff to the exact surface generation, precondition, expected after-state, parent causal head, next `headRevision`, and browser document epochs when the target is a browser tab. A remount, changed target, new head, or non-deterministic compilation invalidates the candidate before activation. A successful preview produces a hashed `webgpu-os-live-patch-activation-v1` proof. It binds the staged patch hash, candidate and operation hashes, surface generation, before-state and expected and observed after-state hashes, causal base and revision, browser epochs, verification hash, and preview time. AI Echo returns that immutable projection as the commit payload. `live.commit` accepts only an exact canonical match to the still-active verified preview and verifies the visible after-state again. Changing one operation, selector, value, surface, generation, causal head, or verification result requires a new stage and preview. This follows the failure-containment principles used by RealmForge's deterministic graph compiler, prepared runtime activation, and last-good retention. Live Patch remains a separate declarative kernel contract. (Sources: `webgpu-os/apps/realmforge/modeler/system-graph/RealmForgeSystemGraphCompiler.js`, `webgpu-os/apps/realmforge/modeler/runtime/RealmForgeRuntimeController.js`, and `webgpu-os/kernel/live-patch/LivePatchService.js`.) The service rejects a commit unless the same patch has an active verified preview. A mounted OS app receives committed patches again after remount through the existing Patch Bus lifecycle. Browser-page patches are scoped to the current page lifecycle and are not replayed after navigation. (Source: `webgpu-os/kernel/live-patch/LivePatchService.js`.) Web Locks serialize mutations to the same surface. A durable per-surface hash chain adds compare-and-swap protection when different tabs stage different patch IDs from the same base. Each patch and receipt bind the parent head, revision, and resulting head. Only the first stale-base commit can advance that head; later commits must inspect and stage again. BroadcastChannel notices invalidate colliding local drafts and causal-head events reconcile every latest patch state in chain order. A recovery launch can add `?livePatchSafeMode=1` to suppress preview and replay while keeping authorized rollback available. ## Surface identities Live Patch accepts only these target forms: | Surface | Meaning | Persistence | | --- | --- | --- | | `app:` | One mounted WebGPU OS app, including `app:os.ai-echo`. | Restored after app remount. | | `shell:desktop` | The desktop content surface. | Restored after shell registration. | | `shell:taskbar` | The taskbar surface. | Restored after shell registration. | | `browser:` | One tab exposed by the extension bridge. | Ends on navigation or tab close. | Apps should mark durable edit points with a stable region name: ```html
...
...
...
``` AI Echo uses stable regions for its workspace shell, sidebar, conversation, composer, and Settings surface. Region names survive normal child-layout changes better than long CSS selectors. The inspector returns a region selector when one is available. (Source: `webgpu-os/apps/ai-echo/factory.js` and `webgpu-os/kernel/live-patch/LivePatchService.js`.) App authors can protect a subtree explicitly: ```html
...
``` The kernel also protects approval, elicitation, credential, password, permission, private/restricted classifications, enabled `contenteditable` regions, host inputs, text areas, selects, and other user-data boundaries. A mutation is denied when its target contains a protected descendant, not only when the target is protected itself. Nested registered surfaces are isolated from their parent's inspection and mutation scope. ## Allowed operations Each patch has an ID, title, rationale, one exact surface ID, and one to 40 operations. Unknown fields and unknown operations fail closed. | Operation | Effect | | --- | --- | | `set-text` | Replace the target's children with plain text. | | `set-attribute` | Set an allow-listed ARIA, role, title, tab index, or bounded state attribute. | | `remove-attribute` | Remove one allow-listed attribute. | | `add-class` | Add one validated class name. | | `remove-class` | Remove one validated class name. | | `set-style` | Set one allow-listed local style property with a validated value. | | `append-markup` | Append sanitized structural markup on OS/app surfaces. Browser surfaces reject it. | | `replace-content` | Replace children with sanitized structural markup on OS/app surfaces. Browser surfaces reject it. | | `remove-node` | Remove a non-root, non-protected target on OS/app surfaces. Browser surfaces reject it. | | `add-css` | Add ordinary, allow-listed CSS rules scoped to the exact surface. | Every selector stays relative to the registered surface. Selectors cannot name `html`, `body`, `:root`, a shadow host, or the surface ownership attribute. One operation can match at most 40 nodes, and one patch can affect at most 160 nodes. Inspection returns at most 400 projected elements and stops scanning after 1,600 candidates. A mounted OS surface is limited to 6,000 elements and 2 MiB of reversible state. Text, markup, CSS, selectors, and metadata have independent byte or character limits. (Source: `webgpu-os/kernel/live-patch/LivePatchService.js`.) ### Example patch This example changes one stable header and adds a local control. The control emits a typed event; it does not call a tool directly. ```json { "id": "live_dashboard_header_01", "title": "Clarify dashboard status", "rationale": "Put the current state and review action together.", "surfaceId": "app:os.dashboard", "operations": [ { "op": "set-text", "region": "header", "text": "System status" }, { "op": "append-markup", "region": "actions", "markup": "" } ] } ``` ## Markup, CSS, and event safety On OS and app surfaces, sanitized markup supports structural text, layout, table, disclosure, buttons, selects, and bounded checkbox, radio, and range controls. It does not accept free-text fields. The sanitizer drops scripts, styles, frames, objects, embeds, links, metadata, images, SVG, MathML, audio, video, templates, canvas, inline handlers, arbitrary URLs, and unsupported attributes. Generated controls may declare: - `data-live-event` for a bounded local event name. - `data-live-field` for a bounded form field name. - `data-live-payload` for a small JSON value. Click, change, and submit events enter a 200-entry in-memory event journal. AI Echo can observe that journal through `live.events`. An event is an observation, not permission to use a tool, access the network, read a secret, or mutate the OS. A later action still crosses the normal Faculty and Tool Firewall boundary. Only trusted user events from controls owned by the currently active OS/app patch are recorded. Scripted `.click()` calls and synthetic events are rejected, and every accepted event is explicitly marked `authoritative: false`. Browser surfaces deliberately reject `append-markup` and `replace-content`. An extension injected after a page has loaded cannot guarantee that its listener runs before capture-phase listeners the host page already registered. Claiming otherwise would create a false event-isolation boundary. Browser patches therefore remain limited to bounded edits of existing text, attributes, classes, styles, and scoped CSS. Generated browser controls must live in a separately owned extension or OS surface rather than the host page DOM. Live CSS accepts ordinary style rules only. It rejects imports, URLs, executable legacy CSS, arbitrary at-rules, global selectors, unsupported declarations, and style markup. Accepted rules are wrapped in a browser `@scope` rooted at the exact `data-live-patch-surface` token. (Source: `webgpu-os/kernel/live-patch/LivePatchService.js`.) ## AI Echo tools and approval behavior AI Echo exposes eight Live Patch tools: | Tool | Type | Risk behavior | | --- | --- | --- | | `live.surfaces` | Read | Lists editable surface projections. | | `live.inspect` | Sensitive read | Returns bounded, redacted structure only after high-risk approval because rendered content can contain operator data. | | `live.stage` | Mutation proposal | Validates, hashes, and returns the exact approval payload; it does not change the UI. | | `live.preview` | Reversible mutation | Applies and verifies an undoable preview; high-risk approval is required because the live DOM changes immediately. | | `live.commit` | Durable mutation | Requires a verified preview and high-risk approval policy. | | `live.rollback` | Durable mutation | Reverts and records a high-risk rollback receipt. | | `live.history` | Read | Lists committed or rolled-back patches. | | `live.events` | Read | Lists bounded typed generated-control events. | The descriptors declare application and device authority, data classes, predicted effects, exact surface or patch parameters, and independent mutation readback. They run through the same registered tool path as other AI Echo tools. (Source: `webgpu-os/apps/ai-echo/AgentToolset.js`.) `live.preview` accepts only the staged patch ID, hash, surface, precondition fingerprint, and normalized operation list. AI Echo compares the canonical approval payload byte-for-byte with the kernel's current draft before any DOM change. Approval cannot be reused after changing a selector, value, surface, or operation order. A verified preview then returns a separate immutable commit payload. It includes the preview activation hash, candidate plan, surface generation, causal base, next revision, and the same normalized operations. `live.commit` re-reads the kernel preview and rejects any payload that is not an exact canonical match. A safe operator request can be direct: > Inspect the AI Echo composer and make the provider row easier to scan. Show me > a reversible preview first. Do not commit until I approve it. For an existing app: > Find the mounted Paint surface, inspect its toolbar regions, and preview a > larger mobile-friendly brush control without changing canvas behavior. ## Storage, history, and recovery Committed records are normal OS files and remain visible through the Files app: ```text /user/live-patches/ heads/ .json patches/ live_.json receipts/ live_receipt_.json ``` The patch record includes its format, version, operations, surface, author context, lifecycle timestamps, verification result, causal parent/revision, and hash. The receipt binds the action, patch hash, target, operation count, time, causal transition, and SHA-256 of the exact stored patch bytes. The receipt and patch are written before one compare-and-swap head advance publishes the transition. A failed head advance restores or removes the patch and receipt and restores the visible projection. Startup rejects a missing, tampered, orphaned, or headless record. (Source: `webgpu-os/kernel/live-patch/LivePatchService.js` and `webgpu-os/storage/StorageManager.js`.) Rollback preserves the record as `rolled-back` and adds a new receipt. It does not erase history. The tree is visible to backup and storage-health tooling, but ordinary app storage syscalls cannot write, move, copy, or delete these kernel-owned control records. Transient candidates are bounded before they enter the in-memory draft table: 64 staged patches and 8 MiB in total, with at most eight patches and 2 MiB per surface. Durable startup and commit paths also enforce record, byte, per-surface, and causal-head limits before allocating or replaying state. Restart clears transient candidates; it never treats an unapproved draft as durable authority. ### Causal replay and last-good remount Startup verifies every stored patch, receipt, and per-surface causal head before replay. A patch is eligible only when the head authorizes its exact patch hash, status, parent, `headRevision`, and resulting head hash. Replay orders committed records by `headRevision`; file names and timestamps never choose the visible state. An OS-surface remount is a transactional activation. The service pins the root and surface generation, removes the current Live Patch projection, reapplies the authorized sequence, and verifies each patch. If preparation or activation fails, it removes the partial candidate projection and restores the previous complete projection. The failed surface enters quarantine while other surfaces remain available. Global safe mode is reserved for unscoped corruption, aggregate journal violations, or compensation whose outcome cannot be proven. This is the DOM-safe counterpart of RealmForge's last-good runtime retention: it preserves node and listener ownership instead of replacing the entire app root. (Sources: `webgpu-os/kernel/live-patch/LivePatchService.js`, `webgpu-os/apps/realmforge/modeler/runtime/RealmForgeRuntimeController.js`, and `webgpu-os/apps/realmforge/modeler/session/ModelerSession.js`.) Ordinary `/user` restore is not an authority-import path. Portable archives and native-folder backups may contain `/user/live-patches/**` or `/user/preferences/permissions.json` for recovery evidence, but merge and replace restores skip those entries. Replace mode also preserves the active copies instead of deleting their parent trees. Backup previews and restore receipts report the protected entries that were skipped. A dedicated, kernel-authorized recovery workflow must restore those control records. (Source: `webgpu-os/storage/StorageManager.js`.) Recycle Bin restore is also not an authority-import path. Trash metadata uses an opaque item ID and an exact contained payload location; restore rejects forged payload paths, root destinations, Recycle Bin destinations, Live Patch records, and permission records before any overwrite. Ordinary storage syscalls cannot write the Recycle Bin control tree or supply an unconfined restore destination. ## Browser extension boundary An OS page cannot safely reach into an arbitrary browser tab by itself. Browser surfaces therefore require the WebGPU OS browser extension and the extension bridge. The kernel sends the already validated, bounded patch to packaged extension methods. Ordinary browser snapshot/click/type actions also use a packaged typed semantic runtime instead of generated source strings; raw browser JavaScript is separate and developer-gated. During staging, the extension hashes the exact matched target state for every normalized operation and returns a `webgpu-os-browser-live-target-precondition-v1` proof. The kernel binds that proof to approval and sends it back with preview. The extension recalculates the proof, then performs one final synchronous state comparison immediately before the first mutation. A changed selector result, attribute, text value, node order, or operation list fails closed. The extension performs inspection, preview, verification, commit-state tracking, and rollback inside the exact tab. Inspection is bounded and redacts protected and restricted subtrees plus form-control values. Snapshot, extraction, wait, verification, status, and Live Patch history are the only immediate read paths. Semantic click/type, raw script or CSS, and every browser Live Patch mutation create a redacted pending request in the extension-owned popup. The OS page cannot list, approve, deny, mint, or consume grants. The operator approves one exact action, then AI Echo retries it. Each grant binds the canonical method and arguments, isolated relay session, target origin, every target frame and Chrome document ID, and a 90-second expiry. It is single-use and consumed before dispatch. The extension executes against those document IDs, so a reload, navigation, frame replacement, changed argument, or second call fails closed rather than retargeting the approval. The popup shows hashes, byte counts, semantic action or patch inventory, origin, and document identities without showing raw JavaScript, CSS, or patch bytes. Pending approvals are bounded to eight per relay session and 40 globally. The edited page receives no API key, extension credential store, reusable kernel token, raw model JavaScript, or general extension API. The kernel requires the exact protocol and target-proof capability handshake, so an older extension asks the operator to reload or update instead of falling back to weaker behavior. This uses Chrome's packaged [`scripting` API](https://developer.chrome.com/docs/extensions/reference/api/scripting) and exact `documentIds`; raw JavaScript remains a separate developer-only Chrome [`userScripts` API](https://developer.chrome.com/docs/extensions/reference/api/userScripts) facility. Large AI-only bridge calls use a separately bounded segmented transport. One request may contain at most 64 MiB and 256 chunks; each session may reserve four pending requests and the extension may hold 12 globally. Character, UTF-8 byte, per-session, and global reservation limits are checked before allocation, and reservations are released on cancellation, expiry, session replacement, tab teardown, successful commit, or failure. Segmented messages cannot call the injection service. Browser patches are intentionally ephemeral across navigation. On invalidation, the runtime reverses only mutations whose exact patch-owned after-state still matches. Drifted host content is preserved, extension-owned styles and markers are removed where ownership is still provable, and the history records `outcome-unknown`. Removed nodes are never automatically reinserted during navigation because absence alone cannot prove that the patch still owns the state. A committed browser patch still receives a durable OS receipt so the operator can review what happened, but the kernel does not silently replay it into a different page. (Source: `webgpu-os/kernel/live-patch/LivePatchService.js`, `webgpu-os/browser-bridge/BrowserBridgeClient.js`, and the extension `services/InjectionService.js` files.) ## Limits and non-goals Live Patch changes the currently rendered interface. It is not a source-code editor, package signer, deployment system, or substitute for a maintained app change. Use the normal workspace tools when a change must alter application source and ship in a package. Live Patch also does not: - bypass app permissions, operator approval, Faculty grants, or the Tool Firewall; - inspect or edit cross-origin frames as part of an OS app surface; - persist a browser-page mutation across navigation; - insert generated markup into an arbitrary browser page DOM; - remove a browser-page node whose absence could be confused with navigation; - expose hidden provider reasoning, credentials, password values, or protected approval parameters; - allow an app or generated control to self-authorize a later mutation; - promise that a selector remains valid after an app redesign. Stable regions are the compatibility contract. The extension prevents an OS page from authorizing an unapproved page mutation; it does not make all same-origin page code trustworthy. Read-only bridge services still rely on the exact configured OS origin, and ordinary `window.postMessage` results remain page-visible. A fully compromised script on that origin could forge how a response is presented even though it cannot approve or consume the extension-owned mutation grant. A future authenticated response channel would require a separately pinned extension key; Live Patch does not claim that boundary today. ## Verification The focused browser suite runs without Node.js or npm: ```bash python tests/live-patch/run_live_patch_tests.py ``` It covers strict schemas, deterministic candidate compilation, unknown fields, executable-operation rejection, relative selectors, staged and durable quotas, aggregate byte/node/depth limits, markup and CSS sanitization, protected descendants, stable regions, preview activation and exact commit approval, after-state drift, rollback, single-write commit and receipt persistence, `headRevision`-authorized restart replay, per-surface tamper quarantine, CAS failure compensation, DOM/CSS drift, trusted typed local events, scoped CSS, transactional last-good remount restoration, safe mode, cross-tab invalidation, rollback lineage, exact browser target proofs, stale-extension rejection, DOM position restoration, causal-head concurrency, nested-surface isolation, editable-data redaction, browser runtime epochs, extension structural-overlap rejection, fail-closed browser generated-DOM rejection, drift-aware SPA invalidation, exact document-bound one-use approvals, semantic-mutation gating, bounded pending/replay state, segmented-transport quotas and cleanup, strict extension sender metadata, and a static check against dynamic JavaScript execution primitives. The hardened service gate passes 60/60 assertions. AI Echo integration passes 432/432 smoke assertions, storage boundary recovery passes 11/11, and atomic storage passes 10/10. (Source: `tests/live-patch/`, `tests/run_ai_echo_smoke.py`, and `tests/storage-backup-boundary.test.js`.) Real browser-page validation additionally requires the current WebGPU OS extension loaded in Chrome or Edge. The cross-tab design follows the browser's same-origin [`Web Locks`](https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API) and [`BroadcastChannel`](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API) contracts. Generated-control trust checks use [`Event.isTrusted`](https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted), and the sanitizer follows the principle that untrusted data must remain in safe DOM/CSS contexts rather than executable contexts described by the [OWASP DOM XSS guidance](https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html). ## See also - [Navi Architecture and Delivery](navi-architecture-and-delivery.md) - [WebGPU OS Architecture](architecture.md) - [Security and Trust Model](../concepts/security-model.md) - [AppForge Contracts](appforge-contracts.md) --- # AI Echo Artifact Studio AI Echo can turn substantial responses into durable work products that open beside the conversation. Documents, code, data, tables, charts, declarative interfaces, and static web presentations remain ordinary WebGPU OS files under `/user/artifacts`. The Files app can browse them, and ordinary deletion sends the complete artifact project to the Recycle Bin. Artifact Studio is separate from [AI Echo Live Patch](ai-echo-live-patch.md). Artifacts are user-owned content. Live Patch is the reviewed, reversible way to promote selected content into an existing OS or browser surface. ## Interaction model 1. AI Echo calls a declared `artifacts.*` tool when a substantial work product should remain editable or previewable. 2. The Artifact Workspace validates the exact project, blocks likely secrets, writes an immutable revision, and verifies every file by SHA-256 readback. 3. Only a small revision-qualified artifact reference travels through the executor, conversation record, and Navi task. It binds the artifact ID, exact revision, and SHA-256 content hash, so an older message never silently resolves to a newer edit. Provider prose never becomes canonical state. 4. The response shows an artifact card. Opening it reveals Artifact Studio without leaving the task. 5. Direct edits create another immutable revision with compare-and-swap protection. Stale editors receive a revision conflict instead of silently overwriting newer work. 6. Copy, download, revision restore, Recycle Bin, and **Open in Files** remain direct user actions. The Studio refreshes through the storage event stream already shared by Files, other apps, tabs, and workers. It does not create a second synchronization or locking layer. ## On-disk contract Each artifact uses a locally generated identifier. Models choose content and metadata, but they never choose an OS path. ```text /user/artifacts/ artifact_/ artifact.json .artifact/ projection.json revisions/ 000001-/ revision.json 000002-/ revision.json ``` The files directly inside `artifact_` are the current, manageable working projection shown by Files and Artifact Studio. Logical project paths such as `src/`, `assets/`, and `data/` stay modular; they are not flattened or hidden under an opaque revision key. `.artifact` and `revisions` are reserved OS-owned metadata directories and cannot be supplied by a model as content. `artifact.json` is the atomically advanced pointer. A revision records its parent revision, parent content hash, entrypoint, file descriptors, source provenance, and aggregate content hash. The manifest retains a bounded history of committed revisions. Artifact Workspace first writes and verifies the immutable revision, then publishes and verifies the direct working projection, and advances `artifact.json` last. A crash may leave unreferenced derived files or a revision directory, but cannot replace the last committed pointer with partially written canonical content. Canonical reads continue to verify the immutable revision and its root-level projection independently. This boundary follows the browser platform rather than pretending it offers a multi-file transaction. The [File System specification](https://fs.spec.whatwg.org/#api-filesystemfilehandle-createwritable) defines safe replacement for one file; the project therefore uses immutable revision files, per-file compare-and-swap, readback hashes, and manifest-last publication to detect an interrupted multi-file projection. Artifact data is still origin storage, so the OS storage-health and backup controls remain authoritative under the [Storage Standard persistence model](https://storage.spec.whatwg.org/#persistence). ## Rendering trust tiers | Tier | Artifact kinds | Execution boundary | |---|---|---| | Native | Document, code, data | DOM nodes built with `textContent`; no generated code runs. | | Declarative | Table, chart, UI | A strict JSON grammar selects known components; unknown fields, nodes, URLs, depth, or size are rejected. | | Opaque sandbox | Static web presentation | A unique-origin iframe with no script, same-origin, form, popup, download, navigation, or network authority and a restrictive content security policy. | Declarative buttons emit typed artifact intents. They cannot call tools, storage, the network, Live Patch, or credentials directly. An intent must re-enter AI Echo's planner, Faculty runtime, Tool Firewall, exact approval, and receipt path. Generated web content is never inserted into AI Echo's DOM. Web previews retain sanitized HTML and local or inline CSS, but all scripts, event handlers, navigation targets, and JavaScript support files are removed. Interactive work uses the strict declarative component renderer, whose current bounded input values accompany each typed intent. ## Tool surface The app-owned tools are: - `os.ai-echo.artifacts.list` - `os.ai-echo.artifacts.read` - `os.ai-echo.artifacts.create` - `os.ai-echo.artifacts.update` - `os.ai-echo.artifacts.revisions` - `os.ai-echo.artifacts.restore` - `os.ai-echo.artifacts.trash` Schemas reject unknown fields. Mutations declare the files authority domain, exact predicted paths, classification access, and verification callback. Update and restore bind the expected revision. Trash uses the OS Recycle Bin; there is no model-facing permanent-delete tool. ## Security invariants - Artifact IDs and revision keys require browser cryptographic randomness. - Every stored file and revision is verified after write. - Likely API keys, tokens, passwords, and private keys are rejected. The Artifact folder is an OS file workspace, not a secret vault. Secret scanning covers titles and summaries as well as file bodies. - File paths cannot escape the artifact project or replace reserved metadata. - Create and update reject ambiguous payloads that combine `files` with the single-file `content` or `filename` form. Entrypoints must name one supplied file, paths are unique case-insensitively, and only one file can have the entry role. - Artifact references are bounded, revision-qualified, and hash-validated before entering durable run or conversation state; content is never copied into those records. Fork/import session remapping detaches references that cannot retain their original task scope. - Private-Navi and restricted artifacts remain locally inspectable, but their metadata, content, paths, and originating tool arguments are withheld from remote provider context. - Catalog discovery and creation are bounded to 512 direct artifact projects; listing never recursively walks arbitrary descendants. - Corrupt manifests and hash mismatches fail closed. - Live Patch cannot target the rendered artifact content root. Only the Studio chrome is eligible for reviewed appearance changes. - The implementation is browser-native ES modules plus the existing Python tooling. It has no Node.js, npm, server runtime, or third-party artifact dependency. ## Choosing artifacts, files, and Live Patch Use an artifact for a coherent work product that benefits from a card, preview, revision history, or continued editing. Use normal workspace file tools when the exact project layout is already known or the file belongs to an existing codebase. Use Live Patch only when the user asks to change a running interface and accepts the exact reviewed patch. ## Verification Run the focused artifact workspace and tool-descriptor checks, followed by the AI Echo smoke suite, import audit, documentation builders, and no-cache OS bundle. The UI checks cover inline card to Studio navigation, session restore, live file refresh, exact Files navigation, responsive layout, hostile declarative input, and sandbox attributes. --- # AI Echo Clicks and Clankers AI Echo supports a hybrid browser workflow. A person can keep using the visible page, while the Navi can discover typed page actions or perform bounded semantic controls through the WebGPU OS browser extension. WebMCP is the preferred path. Semantic inspection and exact target actions are the fallback. The implementation does not use Playwright, copy browser-agent source, evade bot controls, export browser credentials, or expose an unrestricted JavaScript, mouse, keyboard, or Chrome DevTools channel to a model. (Sources: `webgpu-os/browser-extension/services/WebMCPBridgeRuntime.js` and `webgpu-os/browser-extension/services/SemanticAutomationRuntime.js`.) ## Capability ladder AI Echo chooses the narrowest available capability: 1. Discover a same-origin page tool with `browser.webmcp.discover`. 2. Review its untrusted name, description, input schema, annotations, origin, and exact descriptor hash. 3. Invoke that exact descriptor with `browser.webmcp.invoke` after one-use approval. 4. Use semantic snapshot, extract, focus, hover, scroll, click, type, bounded key, wait, and verify controls when the page exposes no suitable tool. 5. Use Live Patch only for a declared, reversible interface edit. 6. Keep raw browser JavaScript behind explicit developer mode and exact-hash approval. The extension feature-detects the current `document.modelContext` API. It keeps the older navigator location as a temporary compatibility branch. WebMCP remains an experimental Community Group draft, so the browser-specific execution method stays behind the extension adapter instead of becoming a durable Navi contract. ([WebMCP draft](https://webmachinelearning.github.io/webmcp/), [Chrome imperative API](https://developer.chrome.com/docs/ai/webmcp/imperative-api).) ## Discovery and invocation Page-provided tools are untrusted resources. They do not enter the kernel tool registry and their annotations never grant authority. Discovery applies strict limits to tool count, text, schemas, JSON depth, and bridge bytes. It excludes cross-origin tools and removes credentials from projected URLs. Each descriptor hash covers the tool name, title, description, input schema, origin, and annotations. Invocation performs a fresh discovery and requires one exact matching name and descriptor hash. The extension binds the approval to the tab, frame, Chrome document ID, origin, descriptor, and canonical argument hash. A navigation, ambiguous tool, changed schema, changed metadata, expired grant, or different arguments fails before dispatch. (Sources: `webgpu-os/browser-extension/services/InjectionService.js` and `webgpu-os/browser-bridge/BrowserBridgeClient.js`.) The runtime redacts likely credentials and bounds returned JSON. AI Echo records the result as untrusted. A timeout after invocation begins becomes `outcome-unknown`; the task must inspect page or domain state before any retry. (Sources: `webgpu-os/browser-extension/services/WebMCPBridgeRuntime.js` and `webgpu-os/apps/ai-echo/AgentToolset.js`.) ## Semantic control The semantic fallback exposes no raw screen coordinates. It identifies visible targets by a selector or a bounded page-derived fingerprint. Click and hover require a successful viewport hit test. Password fields, forms containing a password, and credential, private, restricted, or system-secret surfaces remain blocked. Keyboard control accepts only navigation and control keys. Text entry uses the separate typed-field operation. Every mutation returns target evidence, and AI Echo performs an independent readback before recording success. Synthetic hover and key events are marked `trustedInput: false`; the UI never represents them as hardware input. (Source: `webgpu-os/browser-extension/services/SemanticAutomationRuntime.js`.) ## React and stateful application synchronization The application store remains canonical. The DOM and React tree are projections. A WebMCP tool should read the latest store snapshot when execution begins, apply one domain command, wait for the commit, and return the committed revision. It should not close over render-time state. ```javascript function registerCartTools(store, signal) { document.modelContext.registerTool({ name: 'cart.setQuantity', description: 'Set one cart line quantity.', inputSchema: { type: 'object', properties: { lineId: { type: 'string' }, quantity: { type: 'integer', minimum: 0 }, expectedRevision: { type: 'integer', minimum: 0 }, operationId: { type: 'string' } }, required: ['lineId', 'quantity', 'expectedRevision', 'operationId'], additionalProperties: false }, execute: async (input) => { const before = store.getSnapshot(); if (before.revision !== input.expectedRevision) { return { ok: false, conflict: true, revision: before.revision }; } const receipt = await store.dispatchAndWait({ type: 'cart/setQuantity', lineId: input.lineId, quantity: input.quantity, operationId: input.operationId }); return { ok: true, revision: store.getSnapshot().revision, receipt }; } }, { signal }); } function CartAgentTools({ store }) { React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot); React.useEffect(() => { const controller = new AbortController(); registerCartTools(store, controller.signal); return () => controller.abort(); }, [store]); return null; } ``` Use a stable store facade so React Strict Mode can register, clean up, and register again without duplicating commands. Treat `toolchange` as an invalidation notice and run a complete discovery again. An operation ID makes a retry idempotent, while `expectedRevision` detects simultaneous human edits. ([React `useSyncExternalStore`](https://react.dev/reference/react/useSyncExternalStore), [React `useEffect`](https://react.dev/reference/react/useEffect).) ## Security boundary - WebMCP discovery is same-origin only. - Tool descriptions, schemas, page text, and results are prompt-injection surfaces. - Read-only annotations are hints. Local ToolRouter policy remains authoritative. - Every invocation uses mutation-grade review and one-use approval. - Extension approval UI shows the exact tool, descriptor hash, argument hash, origin, tab, frame, and document. - No default `debugger` permission is requested. Chrome makes that permission broad and non-optional, so hardware-level CDP input is not part of this Faculty. ([Chrome Debugger API](https://developer.chrome.com/docs/extensions/reference/api/debugger).) - Raw JavaScript remains a separate developer-only Faculty. ## See also - [AI Echo Live Patch](ai-echo-live-patch.md) - [Navi Architecture and Delivery](navi-architecture-and-delivery.md) - [Security and Trust Model](../concepts/security-model.md) - [Chrome secure WebMCP tools](https://developer.chrome.com/docs/ai/webmcp/secure-tools) - [WebMCP and server-side MCP](https://developer.chrome.com/docs/ai/webmcp/compare-mcp) --- # AppForge Contracts AppForge is the deterministic assembly layer inside WebGPU OS. It does not replace the kernel, shell, package manager, permission model, or current apps. It registers reusable parts, scores them with tags, assembles blueprints into workspace layouts, records workspace history, and exposes builder tooling. Primary source files: - `webgpu-os/appforge/definitions/index.js` - `webgpu-os/appforge/registry/AppForgeRegistry.js` - `webgpu-os/appforge/tags/index.js` - `webgpu-os/appforge/scoring/index.js` - `webgpu-os/appforge/services/ServiceContainer.js` - `webgpu-os/appforge/context/ContextGraph.js` - `webgpu-os/appforge/commands/commandObjects.js` - `webgpu-os/appforge/layout/LayoutEngine.js` - `webgpu-os/appforge/blueprints/AppFactory.js` - `webgpu-os/appforge/packages/PackageExports.js` - `webgpu-os/appforge/timeline/Timeline.js` - `webgpu-os/appforge/lenses/LensRegistry.js` - `webgpu-os/appforge/packs/StarterPacks.js` - `webgpu-os/appforge/builder/WorkspaceBuilder.js` - `webgpu-os/kernel/KernelBootstrap.js` - `webgpu-os/kernel/Syscalls.js` ## Part Definition Every registered part is a plain object. The shared definition validator accepts these part types: - `panel` - `tool` - `command` - `service` - `layout` - `theme` - `workflow` - `blueprint` - `package` Required fields: | Field | Meaning | | --- | --- | | `id` | Dot or dash namespaced ID that starts with a lowercase letter. | | `type` | One of the supported AppForge part types. | | `title` | Human-readable title. | | `version` | Semver-like string. Defaults to `1.0.0` when omitted. | Common optional fields: | Field | Meaning | | --- | --- | | `description` | Human-readable summary. | | `tags` | Namespaced semantic tags. | | `provides` | Capabilities or outputs this part offers. | | `consumes` | Context, service, or capability dependencies. | | `permissions` | OS permissions this part needs. | | `inputs` / `outputs` | Structured command or tool IO metadata. | | `priority` | Numeric scoring tiebreaker. | | `lifecycle` | Plain object describing lifecycle hooks or module entry data. | | `source` | Provenance metadata such as app manifest, package export, or starter pack. | | `metadata` | Part-specific metadata. | Definitions are cloned on public reads. Callers should treat returned values as snapshots, not live registry objects. ## Tags And Scoring Tags use `namespace.value` form. Supported namespaces are: - `domain` - `action` - `role` - `data` - `runtime` - `risk` - `surface` - `permission` Examples: ```json [ "domain.text", "action.edit", "role.text-editor", "runtime.gpu", "risk.low" ] ``` `AppForgeRegistry.query(criteria)` uses deterministic scoring from tags, type, zone affinity, permissions, available context, co-occurrence data, and risk filters. It returns scored candidates with explanation strings. ## Registry `AppForgeRegistry` is the source of truth for reusable AppForge parts. Public API: ```js registry.register(definition); registry.unregister(id); registry.resolve(id); registry.validate(definition); registry.list(type); registry.query(criteria); registry.count(type); ``` Rules: - Duplicate IDs are rejected unless the caller unregisters the prior part first. - `resolve()` and `list()` return clones. - `query()` returns scored results and never mutates the registry. - Existing app manifests remain in `AppRegistry`; AppForge imports them as panel candidates with `source.kind = "appManifest"`. ## Service Container `ServiceContainer` exposes existing kernel-owned services through stable IDs. Public API: ```js services.register(id, service, metadata); services.unregister(id); services.get(id); services.require(id); services.has(id); services.list(); services.metadata(id); ``` Kernel-provided AppForge services include: | ID | Backing owner | | --- | --- | | `os.appForgeRegistry` | `kernel.appForgeRegistry` | | `os.commandBus` | `kernel.commandBus` | | `os.contextGraph` | `kernel.contextGraph` | | `os.layoutEngine` | `kernel.layoutEngine` | | `os.appFactory` | `kernel.appFactory` | | `os.terminal` | `kernel.terminalService` | | `os.timeline` | `kernel.timeline` | | `os.lenses` | `kernel.lensRegistry` | | `os.starterPacks` | `kernel.starterPacks` | | `os.workspaceBuilder` | `kernel.workspaceBuilder` | ## Context Graph `ContextGraph` stores current OS context as directed nodes and edges. It is used for active file, selection, project, shell cwd, process, theme, panel, registry, layout, terminal, builder, and pack state. Public API: ```js contextGraph.setNode(id, value, metadata); contextGraph.getNode(id); contextGraph.hasNode(id); contextGraph.deleteNode(id); contextGraph.link(sourceId, targetId, relation); contextGraph.unlink(sourceId, targetId, relation); contextGraph.edgesFrom(id); contextGraph.edgesTo(id); contextGraph.invalidate(id, reason); contextGraph.subscribe(id, callback); contextGraph.snapshot(); ``` Invalidations are microtask-batched. Tests that assert subscriber behavior should wait for a tick before reading callback results. ## Command Objects AppForge command objects promote local app actions into typed command contracts. Required shape: ```js { id: "notepad.save", type: "command", title: "Save", tags: ["domain.text", "action.save", "risk.low"], permissions: ["fs.write"], inputs: [{ name: "path", type: "string", required: true }], outputs: [{ name: "saved", type: "boolean" }], undo: "none", risk: "low", handler(ctx, input) {} } ``` `CommandBus.registerObject()` validates the command object, wraps it in the existing `CommandBus`, and exposes public metadata without the handler function. Object pipelines intentionally require exact AppForge command object IDs. ## Layout `LayoutEngine` owns serializable AppForge workspace state. It does not replace the Desktop window manager. Existing floating windows still launch through the current shell path. Required zones: - `top` - `left` - `center` - `right` - `bottom` - `floating` - `modal` - `overlay` - `status` Public API: ```js layout.snapshot(); layout.validate(state); layout.restore(state); layout.preview(nextState); layout.addPanel(zone, panel, options); layout.removePanel(panelId); layout.movePanel(panelId, targetZone, options); layout.setActivePanel(zone, panelId); layout.updateZone(zone, patch); layout.collapseZone(zone, collapsed); layout.pinZone(zone, pinned); layout.diff(currentState, proposedState); layout.on(event, callback); ``` `WorkspaceHost` is the DOM adapter that exposes AppForge zones while keeping the normal Desktop launch behavior intact. ## Blueprints And AppFactory A blueprint is a `type: "blueprint"` part that declares workspace slots. Slots can require exact parts, prefer optional parts, or select parts by wanted tags. Slot shape: ```js { id: "editor", title: "Editor", zone: "center", required: true, limit: 1, partTypes: ["panel"], requires: [], optional: [], wants: ["role.text-editor"], tagMode: "score" } ``` `AppFactory.preview(profileId, context)` resolves a blueprint and returns selections, permission summary, proposed workspace state, and layout diff without mutating live state. `AppFactory.create(profileId, context)` applies a valid preview to the live layout engine. ## Terminal Service `TerminalService` backs the Terminal panel with persistent sessions. Sessions store session ID, cwd, pid, command, stdout/stderr records, exit state, history, and timestamps. The Terminal app attaches to the service and runs commands through the guarded syscall object attached to the session, not through raw kernel syscalls. Exposed syscall namespace: `syscalls.terminal`. ## Package Exports `.prpkg` manifests may include AppForge exports: ```json { "appforge": { "sandbox": "iframe", "permissions": ["files.read"], "tags": ["domain.tools"], "exports": { "panels": [], "tools": [], "commands": [], "services": [], "blueprints": [], "layouts": [], "themes": [], "workflows": [], "packages": [] } } } ``` Rules: - Export groups imply the part type when `type` is omitted. - Exported part permissions must be declared in package `permissions` or `appforge.permissions`. - Export IDs cannot replace parts owned by another package. - Install validates exports after package verification and authorization. - Failed registration restores prior same-package definitions. - Remove and rollback unregister current exports; rollback registers exports from the rollback manifest. See source path `webgpu-os/docs/PACKAGING.md` for package verification and trust flow. ## Timeline `Timeline` records workspace-level events: - layout restores - command dispatch metadata - context invalidations - package export changes - lens activations - builder draft/save/create events - starter pack default enablement Public API: ```js timeline.record(type, payload, metadata); timeline.events(criteria); timeline.latest(count, criteria); timeline.snapshot(criteria); timeline.replay(targets, options); timeline.replayLayout(layoutEngine, options); timeline.subscribe(callback, options); timeline.pause(callback); timeline.clear(); ``` Command events store command ID, caller, status, duration, timestamp, input metadata, result metadata, and error text. They do not store raw command payloads as the public contract. ## Lenses `LensRegistry` derives alternate views from `ContextGraph.snapshot()` output. Lens activation changes private lens view state; it does not replace or mutate source context nodes. Built-in lenses: - `lens.workspace` - `lens.terminal` - `lens.packages` - `lens.all` Public API: ```js lenses.register(definition); lenses.unregister(id); lenses.resolve(id); lenses.list(); lenses.preview(id, options); lenses.activate(id, options); lenses.active(); lenses.on(event, callback); ``` ## Starter Packs `StarterPackRegistry` registers optional pack-owned parts. Built-in packs: - `pack.core.files` - `pack.core.text` - `pack.core.terminal` - `pack.creative.paint` - `pack.admin.os` - `pack.gpu.demos` Rules: - Packs register a `type: "package"` marker plus pack-owned parts. - Every marker and part validates before registry mutation. - Pack-owned IDs carry `source.kind = "starterPack"` and `source.packId`. - Disabling a pack unregisters only pack-owned parts. It does not remove app manifests or other registry entries. ## Workspace Builder `WorkspaceBuilder` is the service behind the AppForge Builder app. Public API: ```js builder.createDraft(options); builder.currentDraft(); builder.validateBlueprint(blueprint); builder.saveBlueprint(blueprint, options); builder.previewBlueprint(blueprintOrId, context); builder.createWorkspace(blueprintOrId, context); builder.registrySnapshot(criteria); builder.packList(); builder.packEnable(id); builder.packDisable(id); ``` The Builder app (`webgpu-os/apps/appforge-builder/`) exposes starter pack controls, registry browsing, blueprint JSON editing, preview, save, and workspace creation. ## AppForge Syscalls The `syscalls.appforge` namespace exposes read-oriented inspection plus guarded builder and pack operations: ```js appforge.available(); appforge.timelineSnapshot(criteria); appforge.timelineEvents(criteria); appforge.timelineLatest(count, criteria); appforge.onTimeline(callback, options); appforge.lensList(); appforge.lensResolve(id); appforge.lensPreview(id, options); appforge.lensActivate(id, options); appforge.lensActive(); appforge.registrySnapshot(criteria); appforge.builderCreateDraft(options); appforge.builderCurrentDraft(); appforge.builderValidateBlueprint(blueprint); appforge.builderSaveBlueprint(blueprint, options); appforge.builderPreviewBlueprint(blueprintOrId, context); appforge.builderCreateWorkspace(blueprintOrId, context); appforge.packList(); appforge.packEnable(id); appforge.packDisable(id); ``` Read methods are audit-open. Mutating builder and pack methods are guarded by existing command capabilities in `guardSyscalls()`. ## Security Invariants - Existing WebGPU OS permission names remain canonical. - AppForge permission names and metadata do not bypass syscall guards. - AppForge registry entries are metadata and handlers; runtime power still flows through guarded syscalls and kernel services. - Package exports run through the existing package trust and verification path. - Timeline replay is not exposed through `syscalls.appforge` because replay can mutate layout state. - Runtime assembly is deterministic and auditable; no runtime LLM planner is part of the contract. --- # WebGPU OS Getting Started Boot the OS and build a minimal app. Assumes [Install & Run](../getting-started/install.md) is done. ## Boot the OS ```bash python start_server.py # then browse to: # http://127.0.0.1:9001/webgpu-os/ ``` Or embed it (see [Quickstart](../getting-started/quickstart.md)): ```javascript import { bootWebGpuOS } from './webgpu-os/index.js'; const os = await bootWebGpuOS(); ``` ## Build a minimal app 1. **Create the folder** `webgpu-os/apps/hello/`. 2. **Add a manifest** `apps/hello/manifest.json`: ```json { "id": "hello", "name": "Hello", "version": "0.1.0", "entry": "main.js", "surface": "window", "icon": "👋", "category": "utility", "permissions": ["ui.notify"] } ``` 3. **Add the entry module** `apps/hello/main.js` — default-export a class with `mount`: ```javascript export default class HelloApp { async mount(root, syscalls) { root.innerHTML = '

Hello, WebGPU OS

'; // syscalls are capability-gated; this requires "ui.notify" await syscalls.ui?.notify?.({ title: 'Hello', body: 'App mounted.' }); } unmount() { /* clean up timers, GPU resources, listeners */ } } ``` 4. **Register it** — add `"hello"` to `webgpu-os/apps/index.json`. 5. **Reload** the OS. The app appears in the Start Menu and is discovered by `AppRegistry`. ## Key rules - Declare **only** the permissions you use; they are checked by `guardSyscalls`. See [Security & Trust Model](../concepts/security-model.md). - Treat GPU resources as reconstructable — handle the `device-lost` fan-out. See [GPU Device Sharing](../concepts/gpu-device-sharing.md). - For distribution, package the app as a `.prpkg` v2 (`pkg-studio` / `PackageBuilder`). ## See also - [Architecture](architecture.md) — the app entry contract and package pipeline. - [App Catalog](app-catalog.md) — existing apps to learn from. - `webgpu-os/templates/` — `template-app` / `template-mod` starters. --- # App Catalog Every app shipped in the OS, grouped by purpose. The authoritative registry is `webgpu-os/apps/index.json`; each app's manifest (`apps//manifest.json`) declares its `entry`, `surface`, `permissions`, and `capabilities`. There are **44 built-in apps**. > **Note:** Permissions listed here are typical for the category. The manifest is authoritative — see [Security & Trust Model](../concepts/security-model.md) for how they are gated. ## System & shell | App | id | Purpose | | --- | --- | --- | | Quick Settings | `quick-settings` | Fast toggles for common system settings. | | Command Palette | `command-palette` | Fuzzy command launcher for OS actions. | | Notification History | `notification-history` | Past notifications from the notification center. | | Control Panel | `control-panel` | Aggregated system configuration hub. | | Settings | `settings` | Primary OS settings app. | | Theme Manager | `theme-manager` | Manage and switch shell themes (`kernel/ThemeEngine`). | | System Monitor | `sysmon` | Live system/resource monitoring. | | Task Manager | `task-manager` | View and manage running app processes (`ProcessTable`). | | Service Manager | `service-manager` | Manage background OS services. | ## Developer & diagnostics | App | id | Purpose | | --- | --- | --- | | Dev Console | `devconsole` | In-OS developer console / REPL. | | Terminal | `terminal` | Command-line terminal. | | Log Viewer | `log-viewer` | Browse OS logs (e.g. `/os/logs/*`). | | Command Registry | `cmd-registry` | Inspect registered commands (`CommandBus`). | | GPU Manager | `gpu-manager` | GPU device/VRAM inspection (`GpuDeviceBroker`, `VRAMTracker`). | ## Files, storage & packages | App | id | Purpose | | --- | --- | --- | | Files | `files` | File browser over the virtual filesystem. | | Storage Manager | `storage-manager` | Manage OPFS/IndexedDB/mounts (`StorageManager`). | | Package Manager | `pkg-manager` | Install/remove/update `.prpkg` packages (`PackageManager`). | | Package Studio | `pkg-studio` | Build, sign, and inspect packages (`PackageBuilder`). | ## Security & accounts | App | id | Purpose | | --- | --- | --- | | Permissions | `permissions` | Review/grant per-app capabilities (`Permissions`/`PermissionStore`). | | User Management | `user-management` | Manage user profiles/sessions (`SessionStore`, `ProfileDriver`). | ## Network & browser | App | id | Purpose | | --- | --- | --- | | Browser | `browser` | Web browser surface (`WebSurfaceDriver`, browser bridge). | | Browser Bridge Manager | `browser-bridge-manager` | Manage the native browser bridge (`browser-bridge/`). | | Tab Manager | `tab-manager` | Manage browser tabs. | | Request Rule Manager | `request-rule-manager` | Manage network request rules / adblock (`RuleGraph`, extension). | | Chatroom | `chatroom` | Networked chat (collab/net). | ## Productivity | App | id | Purpose | | --- | --- | --- | | Calendar | `calendar` | Local-first scheduling with reminders, recurring events, recovery, subscriptions, and ICS, CSV, Google Takeout, Apple, and Outlook interchange. | | Calculator | `calculator` | Calculator. | | Notepad | `notepad` | Plain-text editor (writes via `fs.*`). | | Clock | `clock` | Clock / timers. | Calendar stores a versioned primary file and recovery copy, and uses browser storage as a fallback. Its background service runs reminders, daily-agenda notifications, and public calendar refreshes even when the Calendar window is closed. Month, week, day, and agenda views support quick creation, detail inspection, drag-to-move, time-grid resizing, recurring-event exceptions, tasks, attendees, meeting links, attachments, travel time, duplication, copy and paste, undo, and a 30-day trash. The taskbar date flyout shows the next seven days and exposes quick event creation. Calendar previews imports before applying one undoable batch. It reads and writes RFC 5545 ICS data, including VEVENT, VTODO, RRULE, alarms, attendees, organizers, conferences, and attachments. This supports file exports from Google Calendar, Apple Calendar and iCloud, Microsoft Outlook, and other iCalendar applications. It also imports CSV and Google Takeout ZIP archives and can subscribe to public HTTP, HTTPS, or webcal feeds with conditional refresh and last-known-good recovery. Private Google, Microsoft, and Apple account synchronization is intentionally not presented as connected until the OS has provider-issued OAuth or CalDAV credentials and a secure token-vault flow; Calendar never asks users to paste provider passwords into ordinary settings. Calendar preferences are available from the app and the OS Control Panel. (Sources: `webgpu-os/factory/apps/calendar/store.js`, `webgpu-os/factory/apps/calendar/service.js`, `webgpu-os/factory/apps/calendar/interchange.js`, `webgpu-os/factory/apps/calendar/subscriptions.js`, `webgpu-os/factory/apps/calendar/settings-panel.js`, `webgpu-os/apps/calendar/manifest.json`.) ## Science & engineering | App | id | Purpose | | --- | --- | --- | | [Smith Lab](smith-lab.md) | `os.smith-lab` | Guided 2D/3D Smith Chart learning, Touchstone measurement analysis, and deterministic impedance-matching synthesis. | ## Media & creative | App | id | Purpose | | --- | --- | --- | | Paint | `paint` | Raster drawing app. | | Sound | `sound` | Audio playback/synthesis (`AudioDriver`). | | Particles | `particles` | GPU particle playground (engine `sim/particles`). | | Fractal | `fractal` | GPU fractal explorer. | ## Games | App | id | Purpose | | --- | --- | --- | | Minesweeper | `minesweeper` | Classic minesweeper. | | Snake | `snake` | Classic snake. | | Dimensional Pinball | `pinball` | Authored HDR/PBR pinball machine with deterministic physics, curved rails, gates, mission shots, five realities, multiball, procedural spatial audio, and accessible cabinet controls. | | Solitaire | `solitaire` | Klondike solitaire. | Dimensional Pinball runs its authoritative simulation at a seeded 240 Hz fixed step. The shared Dimensional Foundry layout defines a 6.5-degree playfield, curved cabinet crown, a stateful shooter return, active drain sensors below the resting flipper tips, ball-safe inlanes and outlanes, contact-triggered slingshots, an open flipper drain, dimension routes, and a qualified Shadow lock door. A displacement-based three-phase ball search waits 15 seconds before touching hardware, ignores false collision speed, pauses for a held-flipper cradle, recognizes downward drain progress, and safely re-serves a lone unrecoverable ball without changing score or ball count. (Sources: `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/index.js`, `webgpu-os/factory/apps/pinball/core/PinballSimWorld.js`.) The machine is assembled from 58 immutable instances across 18 reusable semantic types. Ball, cabinet, door, flipper, gate, gravity well, insert, playfield, plunger, pop bumper, rail, ramp, sensor, shot, slingshot, standup target, trough, and wall packages own their physics, visuals, mechanics, wiring, initial runtime, and compatibility records. Coil and switch packages provide shared electromechanical subcomponents. A registry resolves deliberate aliases such as flapper, twanger, launcher, and drain; an order-preserving compiler projects the semantic assembly into the current solver collections; and a runtime adapter instantiates mutable devices with links back to their owning parts. See [Modular Pinball Parts](pinball-parts.md). (Sources: `webgpu-os/factory/apps/pinball/core/parts/index.js`, `webgpu-os/factory/apps/pinball/core/parts/assembly/PinballTableAssembler.js`, `webgpu-os/factory/apps/pinball/core/parts/assembly/PinballTableRuntime.js`.) The electromechanical layer reuses the engine's spring-damper and motor-target math. The plunger stores Hooke-law spring energy and rebounds against a damped barrel stop. Each flipper advances through power stroke, EOS hold, release, and return-spring phases with reaction torque from the ball. Pop bumpers and slings combine passive rubber restitution with a debounced autofire coil and a shared travel state. That same state drives copper-coil PBR emission, linkage motion, bumper-ring travel, particles, and the live 240 Hz mechanism panel. Procedural spring links remain visual followers; deterministic scalar mechanics remain authoritative. (Sources: `engine/core/math/ConstraintMath.js`, `webgpu-os/factory/apps/pinball/core/parts/coil/ElectromechanicalActuator.js`, `webgpu-os/factory/apps/pinball/core/parts/flipper/index.js`, `webgpu-os/factory/apps/pinball/core/parts/plunger/index.js`.) Seven ordered shots lead from the calibrated skill shot to one three-ball lock cycle, multiball, Super Jackpot, and the Chaos wizard mode. Matter, Particle, Gravity, Shadow, and Chaos alter active mechanisms through one atomic dimension event while preserving score and actor attribution. Only the current reality's physical route and shot guidance are rendered; the other dimensional machines leave both the collision world and the visual pass until shifted in. (Sources: `webgpu-os/factory/apps/pinball/core/PinballSimWorld.js`, `webgpu-os/factory/apps/pinball/render/TableRenderer3D.js`, `webgpu-os/factory/apps/pinball/ai/AdaptiveAI.js`.) The GPU path reuses the engine PBR BRDF, renders into an HDR target, and applies selective bloom, ACES tone mapping, physical playfield inclination, fitted player and cinematic cameras, active particles, and a high-contrast ball. The app opens at a full 1180-by-820 workspace size. Windows at least 980 by 620 CSS pixels use one explicit landscape cockpit mode: the cabinet consumes the usable height while mission control and actuator instruments dock directly beside it, and the shooter power readout occupies the right instrument rail instead of covering the table. Short windows retain the safer complete-table fit. The shared UI style injector refreshes changed application CSS during remounts, preventing an older fullscreen layout from surviving a rebuilt app. A provenance-tracked sRGB Dimensional Foundry illustration supplies the printed playfield while the engine retains rails, mechanisms, inserts, materials, and lighting. Canvas 2D projects the same artwork beneath the same authored mechanisms, including the compressing copper spring and powered coils, as the complete fallback. Procedural audio uses separate music, voice, and effects buses and gives each ball-search phase physical feedback. (Sources: `webgpu-os/factory/sdk/ui/index.js`, `webgpu-os/factory/apps/pinball/index.js`, `webgpu-os/factory/apps/pinball/render/PlayfieldArt.js`, `webgpu-os/factory/apps/pinball/render/TableCamera.js`, `webgpu-os/factory/apps/pinball/render/TableRenderer3D.js`, `webgpu-os/factory/apps/pinball/render/PlayfieldRenderer2D.js`, `webgpu-os/factory/apps/pinball/audio/PinballAudio.js`.) Left and Right Shift provide cabinet-style flipper controls alongside keyboard presets and multi-touch zones. Touch affordances appear only on touch-first coarse-pointer devices and remain completely hidden with a desktop mouse or trackpad. Settings cover motion, camera framing, bloom, flash, audio, quality, assistance, and input. F8 opens live render and physics statistics. (Sources: `webgpu-os/factory/apps/pinball/core/PinballInput.js`, `webgpu-os/factory/apps/pinball/index.js`, `webgpu-os/apps/pinball/manifest.json`.) ## Adding an app Create `apps//manifest.json` + an entry module that default-exports a class with `async mount(root, syscalls)`, then add `` to `apps/index.json`. See [Architecture](architecture.md) and the templates in `webgpu-os/templates/`. --- # Modular Pinball Parts The pinball parts system turns each physical mechanism into a reusable, immutable part definition. This guide is for engine contributors who build parts and table authors who assemble those parts into a machine. Use one implementation for each reusable part type. Create left, right, upper, or themed variants as independent instances in a table definition. Do not duplicate the implementation into folders such as `left-flipper/` and `right-flipper/`. ## Use canonical pinball names Canonical names keep table definitions, editor tools, events, saves, and mods interoperable. Compatibility aliases accept familiar informal terms, but new code should use the canonical type. | Informal term | Canonical part | Meaning | | --- | --- | --- | | flapper | `gate` | The current machine uses a spring-return one-way gate. A future route-selecting mechanism should use a separate `diverter` type. | | twanger | `slingshot` | The compatibility alias resolves to the current switch, coil, and rubber slingshot package. | | sensor | `sensor` | A switch-like input that reports contact, occupancy, position, or passage. | | bouncer | `pop-bumper` | A pop bumper applies an active kick. Passive restitution remains a collider-surface property. | | launcher | `plunger` | A manual, automatic, or combined ball-launch mechanism. | | door | `door` | A powered lock or routing barrier. Use `gate` for a passive one-way flap. | | drain | `sensor` and `trough` | A sensor detects the crossing. The trough owns ball inventory and serving. The `drain` alias resolves to the trough assembly. | | flipper | `flipper` | The player-controlled bat and its mechanical state. | | target | `standup-target` | A scoring target with a dedicated switch contract. | | drop target | `drop-target` | A rectangular switch-backed target that moves below the playfield and resets through a coil. | | target bank | `drop-target-bank` | A logical reference group for independent drop-target IDs and a shared reset coil. | | spinner | `spinner` | A freely rotating metal blade that reports one switch pulse per revolution. | | light | `insert` | An addressable playfield lamp or guidance insert. | The public parts index keeps a narrow compatibility layer: | Compatibility name | Canonical name | | --- | --- | | `createFlapperPart` | `createGatePart` | | `createTwangerPart` | `createSlingshotPart` | | `flapper`, `pinball.flapper` | `pinball.gate` | | `twanger`, `pinball.twanger` | `pinball.slingshot` | | `launcher`, `pinball.launcher` | `pinball.plunger` | | `bumper`, `pinball.bumper` | `pinball.pop-bumper` | | `target`, `pinball.target` | `pinball.standup-target` | | `drop-target` | `pinball.drop-target` | | `drop-bank` | `pinball.drop-target-bank` | | `spinner` | `pinball.spinner` | | `drain`, `pinball.drain` | `pinball.trough` | | `light`, `lamp` | `pinball.insert` | `pinball.sensor` remains canonical. The `twanger` alias resolves to `pinball.slingshot` for compatibility, even though authors may use the word for other mechanisms. New table definitions should state the intended canonical type. (Source: `webgpu-os/factory/apps/pinball/core/parts/index.js`.) ## Architecture and dependencies The modular path has four stages: ```text Reusable factory -> definePinballPart() -> PinballPartRegistry -> independent table part instances -> assemblePinballTable() |-> canonical parts, partsByType, and partManifest `-> compatibility segments, circles, flippers, shots, and zones -> instantiatePinballTableRuntime() `-> mutable solver records owned by their source parts ``` `definePinballPart()` owns the immutable authoring contract. `PinballPartRegistry` resolves canonical types and aliases to factories. A table creates independent instances through those factories. `assemblePinballTable()` validates and combines the instances into one frozen table contract. `instantiatePinballTableRuntime()` creates the mutable solver records, retaining a `partId` link to the authored owner. (Sources: `webgpu-os/factory/apps/pinball/core/parts/shared/PartDefinition.js`, `webgpu-os/factory/apps/pinball/core/parts/registry/PinballPartRegistry.js`, `webgpu-os/factory/apps/pinball/core/parts/assembly/PinballTableAssembler.js`, `webgpu-os/factory/apps/pinball/core/parts/assembly/PinballTableRuntime.js`.) The Dimensional Foundry table is an assembly root, not a mechanism implementation. It supplies table metadata, ordered part instances, and the playfield-level compatibility settings required by the current simulator. (Source: `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/index.js`.) ## Target folder contract Keep shared contracts, registry behavior, assembly, reusable parts, and authored tables in separate folders: ```text webgpu-os/factory/apps/pinball/core/ parts/ shared/ PartDefinition.js PartFactoryValues.js PartGeometry.js registry/ PinballPartRegistry.js assembly/ PinballTableAssembler.js PinballTableRuntime.js backbox/ ball/ cabinet/ coil/ ElectromechanicalActuator.js display/ door/ drop-target/ drop-target-bank/ flipper/ gate/ gravity-well/ insert/ playfield/ plunger/ pop-bumper/ rail/ ramp/ sensor/ shot/ slingshot/ spinner/ standup-target/ switch/ trough/ wall/ index.js tables/ dimensional-foundry/ backbox.js cabinet.js constants.js devices.js dimension-routes.js index.js lower-playfield.js machine.js objectives.js progression.js shooter-lane.js ``` Each reusable part folder exposes its public factory through `index.js`. The `coil` and `switch` folders are reusable electromechanical subcomponents used by mechanisms; the other folders define complete semantic parts. Slingshots compose a leaf switch and kick coil, pop bumpers compose a skirt switch and kick coil, targets compose a hit switch and optional powered-assist or reset coil, flippers compose a power coil and end-of-stroke switch, and the trough composes entry and serve switches with an eject coil. A complex part may split physics, visuals, mechanics, wiring, or runtime support into focused sibling modules. Other subsystems should import the folder's public entry rather than its internal files. The shared definition accepts these concerns without forcing them into the table layout: | Field | Purpose | | --- | --- | | `id` | Stable instance identity using lowercase words separated by underscores. | | `type` | Canonical reusable type in the `pinball.part-name` form. | | `version` | Positive schema version. The default is `1`. | | `aliases` | Additional names attached to the part definition. | | `physics` | Collision and physical parameters. | | `visual` | Render-facing description. | | `mechanics` | Moving or actuated mechanism data. | | `wiring` | Connections between sensors, coils, lights, and controllers. | | `runtime` | Initial runtime state. | | `legacy` | Temporary records for established simulation and rendering collections. | | `metadata` | Authoring information that does not belong to the other concerns. | `definePinballPart()` validates the `pinball.*` type and stable instance ID, requires every standard facet, checks identity parity, rejects cyclic or non-finite authoring data, normalizes identity and aliases, and freezes the resulting authoring data. This validation runs before editor or mod data can enter an assembly. (Source: `webgpu-os/factory/apps/pinball/core/parts/shared/PartDefinition.js`.) ## Add a reusable part Follow these steps to add a reusable part type: 1. Create `core/parts//`. 2. Export a factory that calls `definePinballPart()`. 3. Keep instance-specific position, wiring, visuals, and tuning in factory options. 4. Register the canonical `pinball.*` type with `PinballPartRegistry.register()`. 5. Add only deliberate compatibility aliases. 6. Re-export the public factory from `core/parts/index.js`. 7. Create table instances through `registry.create()`. This spinner instance demonstrates the public contract: ```javascript import { createSpinnerPart, } from '../../parts/index.js'; const orbitSpinner = createSpinnerPart({ id: 'spinner_orbit', physics: { center: [302, 302], laneDirection: [0, -1], width: 22, }, visual: { width: 22, height: 19, thickness: 1.8 }, mechanics: { pulsesPerRevolution: 1, score: 300 }, }); ``` `register(type, factory, { aliases, description })` rejects duplicate types and aliases. `create(typeOrAlias, options)` resolves the requested name, runs the factory, validates the result, and requires the factory to return the registered canonical type. (Source: `webgpu-os/factory/apps/pinball/core/parts/registry/PinballPartRegistry.js`.) ## Assemble a table The table definition owns instance order. Keep that order intentional because the compatibility compiler preserves it. ```javascript import { assemblePinballTable } from '../../parts/index.js'; const table = assemblePinballTable({ id: 'example_table', version: 1, parts: [orbitSpinner], legacy: { width: 360, height: 740, ballRadius: 9, playfield: {}, spawn: {}, drain: {}, ballSearch: {}, shooterLane: {}, }, metadata: { title: 'Example Table', }, }); ``` This example satisfies the assembly API. A playable table supplies the complete playfield, spawn, drain, ball-search, and shooter-lane settings expected by its simulation. The production Dimensional Foundry assembly lives in `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/index.js`. `assemblePinballTable()` requires a nonempty part list and unique part IDs. It returns a frozen `pinball.table` value with `parts`, `partsByType`, `partManifest`, `assemblyReport`, and compatibility collections. Use `partsByType` or the exported `partsOfType()` helper when new code needs semantic parts. (Source: `webgpu-os/factory/apps/pinball/core/parts/assembly/PinballTableAssembler.js`.) ## Understand the compatibility compiler The compatibility compiler lets the modular authoring model coexist with the established simulator and renderers. Each part may temporarily publish records under `legacy.segments`, `legacy.circles`, `legacy.flippers`, `legacy.shots`, and `legacy.zones`. `assemblePinballTable()` concatenates those records in authored part order and exposes the resulting arrays on the table. The compiler does not sort or regroup records. That rule preserves deterministic first-contact behavior in the current fixed-step simulation. It rejects duplicate part IDs, duplicate record IDs within a compatibility collection, invalid dimensions, and malformed required settings. (Source: `webgpu-os/factory/apps/pinball/core/parts/assembly/PinballTableAssembler.js`.) Treat `legacy` as a migration boundary. New editor, mod, and tooling features should use canonical parts and their separated concerns. Existing consumers may continue to read the projected collections until they adopt the modular contract. The runtime adapter follows the same boundary. It creates balls through the ball package, the compression-spring launcher through the plunger package, flippers through the flipper package, and solver collections through their semantic owners. Autofire actuator profiles read pulse, power, current, heating, return, travel, and damping values from each mechanism's named coil and mechanical facets. The simulation world receives the completed runtime rather than constructing table hardware itself. (Sources: `webgpu-os/factory/apps/pinball/core/parts/assembly/PinballTableRuntime.js`, `webgpu-os/factory/apps/pinball/core/PinballSimWorld.js`.) ## Build counted spinner and drop-target objectives Use `pinball.spinner` for a pass-through lane mechanism. The part derives a horizontal axle from `center`, `laneDirection`, and `width`. Its blade spins around that axle in both directions. Ball speed along the lane adds signed angular velocity, mechanical damping coasts the blade, and `pulsesPerRevolution` converts accumulated rotation into switch facts. The default is one pulse per complete revolution. The sensor-only contact region does not create an invisible wall or block a shot. (Sources: `webgpu-os/factory/apps/pinball/core/parts/spinner/index.js`, `webgpu-os/factory/apps/pinball/core/PinballSimWorld.js`.) Use one `pinball.drop-target` part per physical plate. Each part owns a rectangular visual, circle collision footprint, hit switch, optional impact coil, and reset coil. A successful hit closes the switch, drops the plate below the surface, and disables only that plate's collider. A target that is already down cannot score or block the ball again. (Sources: `webgpu-os/factory/apps/pinball/core/parts/drop-target/index.js`, `webgpu-os/factory/apps/pinball/core/parts/standup-target/index.js`.) Group targets by ID through `pinball.drop-target-bank`. The bank never contains or duplicates target geometry. It validates every referenced ID during runtime assembly, tracks the down set, publishes completion, waits for `resetOnCompleteSeconds`, and pulses its shared reset coil before raising all members. The same independent target can therefore participate in another bank or ordered rule without moving its physical part. This mirrors Mission Pinball Framework's separation between individual switch-backed drop targets and logical banks with shared reset coils. ([MPF drop targets](https://missionpinball.org/latest/mechs/targets/drop_targets/), [MPF drop-target banks](https://missionpinball.org/latest/config/drop_target_banks/).) The Dimensional Foundry uses three existing left-side target footprints as a drop bank. The bank adds no new obstruction to the seven direct flipper shot cones. A sensor-only Flux spinner crosses the right return lane. The table-authored objective recipe counts 12 spinner revolutions and one complete three-target bank before Particle, Gravity, lock multiball, and Super Jackpot stages. `MissionSystem` compiles data-only event names, field filters, count fields, targets, and reward keys; it contains no Dimensional Foundry part IDs. Mission events expose objective-local `progress` and `target` values while `stageCount` keeps the seven-stage display accurate. (Sources: `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/devices.js`, `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/progression.js`, `webgpu-os/factory/apps/pinball/core/MissionSystem.js`, `webgpu-os/factory/apps/pinball/index.js`.) ## Author playable lower geometry The Dimensional Foundry uses a 360 by 740 unit playfield with a 6.5 degree pitch. Its 2.056 height-to-width ratio leaves separate space for the lower guides, flipper sweep, visible drain approach, and trough. The ball keeps its 9 unit radius. (Sources: `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/constants.js`, `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/machine.js`.) Validate moving mechanisms across their complete travel, not only at their rest and active endpoints. The Foundry regression suite samples both flippers through 120 intermediate poses. It checks the center ball corridor, the distance from each swept flipper capsule to every nearby sling and divider, interpolated outlane widths, and the shooter/apron seam. The authored drain sensors begin at y=710, below the resting flipper envelope, so a ball remains visible while it falls into the trough. (Sources: `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/lower-playfield.js`, `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/shooter-lane.js`, `tests/pinball-modern.html`.) Do not let an upper orbit become a bowling gutter. The Foundry keeps real center and outlane drains, but mirrored two-piece rubber return guards now intercept the long left and right descents above the sling tips. A normal orbit return must reach its inlane, rebound up-table from the active sling, or cross the player-controlled flipper band before it can be consumed; an outlane remains reachable only from a lower-playfield deflection around the divider. The regression suite injects six formerly unsafe approaches, requires a collision with the authored guard, rejects every outlane-first result, and proves a playable return before any later unplayed center drain. (Sources: `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/lower-playfield.js`, `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/objectives.js`, `tests/pinball-modern.html`.) Treat slingshots as side kickers, not central barricades. The Foundry's compact mirrored slings now occupy x=100–126 and x=234–260 instead of reaching inward to x=150 and x=210. Their raw central throat grows from 60 to 108 units; after both rubber envelopes and the 18-unit ball are accounted for, 80 units remain for aimed travel. For every major objective, the regression suite constructs straight launch segments from both active flipper tips, chooses the clearer source, requires at least four units of residual collider clearance, then fires a real simulated ball through the chosen cone. All seven entries must trigger without touching either sling. This complements the 120-pose flipper sweep test: one validates moving hardware, the other validates the player's actual shot fan. (Sources: `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/lower-playfield.js`, `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/objectives.js`, `tests/pinball-modern.html`.) Keep one continuous collider at a physical boundary. The shooter inner rail ends where the lower right apron begins. Adjacent segments may share an endpoint, but they must not overlap for a positive length. Duplicate collinear colliders can resolve the same contact twice and force a ball sideways. (Sources: `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/shooter-lane.js`, `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/lower-playfield.js`.) ## Return drained balls through a physical machine The Foundry never replaces a drained ball at the launcher in the same simulation step. Crossing a drain sensor removes the ball only from live-play physics and starts a `pinball.trough` transfer. The part owns an intake point, gravity-return polyline, four occupancy pockets, serve polyline, drain-fall time, roll time, settle time, eject pulse, and serve time. Its mutable runtime retains the ball ID, exact position, previous position, depth below the playfield, phase, and progress for every fixed step. (Sources: `webgpu-os/factory/apps/pinball/core/parts/trough/index.js`, `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/machine.js`.) The lifecycle is `drain-fall` to `trough-roll` to `trough-settle` to `serve-coil` to `feeder-rise` to `shooter-entry`. Entry closes the trough inventory, the powered ejector removes one stored ball, and a new live runtime is created only when the visible feeder reaches the authored spawn point. `BALL_DRAINED`, `TROUGH_BALL_ENTERED`, `TROUGH_COIL_FIRED`, and `BALL_SERVED` facts make the sequence observable to rules, audio, rendering, diagnostics, and mods. Ball-save and normal reserve rules wait for the same mechanism; game over waits until the final ball has physically settled. (Sources: `webgpu-os/factory/apps/pinball/core/PinballSimWorld.js`, `webgpu-os/factory/apps/pinball/core/PinballEventBus.js`.) This follows a gravity trough and solenoid ejector rather than hidden air propulsion. Real and simulated modern troughs use a drain/input switch, occupied ball positions, and an eject coil that pushes a ball into the plunger lane. Hidden routes may use authored travel time, but visible travel remains continuous; the regression suite rejects any fixed-step disappearance or position jump. See [Visual Pinball Engine troughs and drains](https://docs.visualpinball.org/creators-guide/manual/mechanisms/troughs.html) and its warning that [visible teleportation breaks natural ball flow](https://docs.visualpinball.org/creators-guide/manual/mechanisms/teleporters.html). Both render paths expose the same mechanism through an under-apron service window: paired steel return rails, four pockets, copper eject coil, feeder rails, and the moving steel ball. The HDR path also assembles the surrounding machine from authored parts: deep chassis, full playfield glass, glass channels, lockdown bar, coin-door hardware, start button, four cabinet legs and leveling feet. A separate `pinball.environment` package owns the polished machine-room floor, backdrop, presentation ribs, materials, and accent, keeping non-gameplay staging editable without nesting it into the cabinet or table physics. (Sources: `webgpu-os/factory/apps/pinball/core/parts/cabinet/index.js`, `webgpu-os/factory/apps/pinball/core/parts/environment/index.js`, `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/cabinet.js`, `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/environment.js`, `webgpu-os/factory/apps/pinball/render/TableRenderer3D.js`, `webgpu-os/factory/apps/pinball/render/PlayfieldRenderer2D.js`.) ## Build active rollover sockets, not decorative rings Every shooter-lane ring is a two-part assembly. A `pinball.sensor` owns the circular under-playfield trigger, debounced leaf switch, output signals, score, sequence index, and bank membership. A paired `pinball.insert` owns the recessed socket, addressable RGB lamp, pulse timing, latch state, and the exact sensor ID that drives it. The table assembly contains eight independent switch/insert pairs; the renderer no longer invents their positions. (Sources: `webgpu-os/factory/apps/pinball/core/tables/dimensional-foundry/shooter-lane.js`, `webgpu-os/factory/apps/pinball/core/parts/sensor/index.js`, `webgpu-os/factory/apps/pinball/core/parts/insert/index.js`.) At 240 Hz, the simulation tests each ball against the authored trigger and publishes `SWITCH_CHANGED` facts for close and open edges. A shooter rollover closure latches its linked lamp, scores 150 points, emits `ROLLOVER`, and reports bank progress. Closing all eight awards 2,500 points, emits `ROLLOVER_BANK`, flashes the complete bank for 1.15 seconds, then returns every lamp to its armed dark state. Ball removal forces open any occupied switch so a drain, lock, or reset cannot leave phantom contacts. (Sources: `webgpu-os/factory/apps/pinball/core/PinballSimWorld.js`, `webgpu-os/factory/apps/pinball/core/PinballEventBus.js`.) The same mutable insert records drive the HDR/PBR torus and LED center, the Canvas fallback, spatial switch clicks, rising lamp tones, bank chord, particles, bloom, and HUD bank callout. Reduced-motion mode removes the animated lamp oscillation while preserving immediate state changes and readable illumination. Mods and editor tools can therefore move, recolor, re-address, or regroup a rollover by editing its parts; no renderer-only coordinate must be synchronized. (Sources: `webgpu-os/factory/apps/pinball/render/TableRenderer3D.js`, `webgpu-os/factory/apps/pinball/render/PlayfieldRenderer2D.js`, `webgpu-os/factory/apps/pinball/audio/PinballAudio.js`, `webgpu-os/factory/apps/pinball/index.js`.) ## Adapt phone and tablet play Keep one table simulation across every screen. `PinballResponsive.js` selects a presentation from the mounted app rectangle, not the browser viewport. This distinction keeps phone rotation, tablet split-screen, and a resized WebGPU OS window on the same authority. The available compositions are handset portrait, handset landscape, tablet portrait, tablet landscape, standard window, and desktop cockpit. None of them change part coordinates, collision geometry, objectives, or 240 Hz physics. (Sources: `webgpu-os/factory/apps/pinball/ui/PinballResponsive.js`, `webgpu-os/factory/apps/pinball/index.js`.) Handset portrait uses a compact score and objective header, then gives the remaining height to the table. Handset landscape moves score and objective content to one side rail and cabinet actions to the other, preserving the portrait machine's aspect ratio instead of stretching it. Tablet layouts retain more status fields while keeping the player display outside the flipper reaction area. The handheld `mobile-player` camera uses a steeper fixed authored pose so the long playfield stays readable without tracking the ball or changing angles during multiball. (Sources: `webgpu-os/factory/apps/pinball/ui/PinballBackboxDisplay.js`, `webgpu-os/factory/apps/pinball/render/camera/CameraRailCatalog.js`, `webgpu-os/factory/apps/pinball/render/camera/PinballCameraDirector.js`.) Touch-first layouts expose full lower-screen left and right flipper regions plus the analog pull-and-release shooter lane. They also expose Shift, forward Nudge, Pause, and Help as 44 by 44 CSS pixel actions. Secondary display, Cinema Focus, and settings actions move behind Pause and Help on small touch screens. A hybrid tablet promotes the cabinet to touch presentation after a real touch pointer arrives, while keyboard and pointer controls remain active. The shell uses `safe-area-inset-*` values for camera housings, rounded corners, system bars, and gesture regions. (Sources: `webgpu-os/factory/apps/pinball/core/PinballInput.js`, `webgpu-os/factory/apps/pinball/index.js`, `webgpu-os/index.html`.) The design follows Apple's 44 point game-control target and safe-area guidance, Android's requirement to adapt games across runtime window and input changes, and WCAG 2.2 target-spacing rules. ([Apple game design](https://developer.apple.com/design/human-interface-guidelines/designing-for-games), [Apple adaptable layout](https://developer.apple.com/design/human-interface-guidelines/layout), [Android games for all screens](https://developer.android.com/games/develop/all-screens), [Android edge-to-edge insets](https://developer.android.com/develop/ui/views/layout/edge-to-edge), [WCAG target size](https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum).) ## Keep camera motion readable The camera package separates authored content, spline evaluation, state policy, and projection: ```text render/camera/ CameraRailCatalog.js CameraRail.js PinballCameraDirector.js TableCamera.js ``` Human play uses a stable authored view. Scoring events, locks, bumpers, jackpots, extra balls, and multiball do not change the player's preset, lens, or angle. Attract mode may use the deterministic 22 second closed rail, and game over may use the 2.8 second one-shot pullback. Reduced-motion mode keeps the selected view fixed. (Sources: `webgpu-os/factory/apps/pinball/render/camera/CameraRailCatalog.js`, `webgpu-os/factory/apps/pinball/render/camera/PinballCameraDirector.js`.) `TableCamera` fits the cabinet into the current HUD-safe viewport, then damps eye, target, field of view, and lens shift independently. It builds a new view matrix from the resulting physical pose each frame. It never interpolates matrices. The top view uses a playfield-relative stable up vector to avoid roll flips. (Source: `webgpu-os/factory/apps/pinball/render/camera/TableCamera.js`.) The OS app requests full-size window sizing. At 1280 by 720 and larger gameplay viewports, the cockpit layout places mission and mechanism panels on the outer edges so they do not consume vertical table space. (Sources: `webgpu-os/apps/pinball/manifest.json`, `webgpu-os/factory/apps/pinball/factory.js`, `webgpu-os/factory/apps/pinball/index.js`.) ## Author the cabinet backbox and player display Treat the cabinet head and its content as separate reusable parts. A `pinball.backbox` owns the physical enclosure, LCD aperture, speaker bays, bezel, service hinge, materials, and table-relative mount. A `pinball.display` owns the resolution-independent logical LCD, its data channels, field order, labels, palette, and full/compact mode policy. The Dimensional Foundry assembles one of each in `tables/dimensional-foundry/backbox.js`; the PBR renderer and DOM player display consume those same immutable parts. Moving the backbox, replacing LCD technology, relabeling a field, or creating another table therefore does not require editing the app shell. (Sources: `webgpu-os/factory/apps/pinball/core/parts/backbox/index.js`, `webgpu-os/factory/apps/pinball/core/parts/display/index.js`, `webgpu-os/factory/apps/pinball/ui/PinballBackboxDisplay.js`.) The primary LCD uses a base score slide with Player 1 score, Grand Champion score, ball reserve, dimension, reactor state, live-ball and safety rules, and the current objective. Machine awards temporarily take priority as animated callout slides, then reveal the current score slide again. This follows Mission Pinball Framework's logical-display model and its priority slide stack, where the normal score slide carries score and ball/player context and higher-priority events temporarily replace it. ([MPF logical displays](https://missionpinball.org/latest/mc/displays/), [MPF slide priorities](https://missionpinball.org/latest/mc/slides/).) In a cockpit-sized window the display occupies the unused left cabinet rail. Staged, attract, paused, and game-over states show the complete backbox. Live human play automatically compacts it to score and objective so it cannot cover the playfield. The cabinet control can hide or restore it entirely; renderer insets are recalculated from the actual visible panel rather than a duplicated table coordinate. Narrow windows scale the same logical fields into a top status strip. Presentation breakpoints remain CSS tokens, while machine identity, data fields, state policy, physical dimensions, and mounting coordinates remain authored part data. ## Use Cinema Focus as a staged-ball presentation Cinema Focus is a manual presentation action, not a live-ball tracking camera. Press `C` while the ball is staged to run one deterministic 5.2 second centerline push and return. The move keeps the lower playfield readable, carries smoothly back into the normal table composition, and does not orbit, roll, follow the ball, or react to scoring events. Once the ball is live, the gameplay camera remains stable. Reduced-motion mode suppresses the Cinema Focus move. (Sources: `webgpu-os/factory/apps/pinball/index.js`, `webgpu-os/factory/apps/pinball/render/camera/PinballCameraDirector.js`, `webgpu-os/factory/apps/pinball/render/camera/CameraRailCatalog.js`.) The fixed `Oblique` preset is separate from Cinema Focus. `Oblique` is a persistent authored table view; it does not start the timed rail or opt the player into automatic camera motion. The design follows [Visual Pinball Engine camera framing](https://docs.visualpinball.org/creators-guide/editor/advanced/camera-settings.html), [Unreal Engine VCam RigRail controls](https://dev.epicgames.com/documentation/unreal-engine/unreal-vcam-tools-and-configuration-in-unreal-engine?lang=en-US), [Unity Cinemachine spline paths](https://docs.unity.cn/Packages/com.unity.cinemachine%403.1/manual/CinemachineUsingSplinePaths.html), and [Xbox guidance for camera motion and reduced-motion controls](https://learn.microsoft.com/en-us/xbox/accessibility/xbox-accessibility-guidelines/117). ## Research and see also - [Stern standard playfield glass](https://shop.sternpinball.com/products/high-definition-playfield-glass) provides a physical 21 by 43 inch reference envelope. - [Pinball Makers playfield sizes](https://pinballmakers.com/wiki/index.php?title=Playfield_Sizes) collects common full-size playfield dimensions. - [Visual Pinball Engine camera settings](https://docs.visualpinball.org/creators-guide/editor/advanced/camera-settings.html) treats distance, field of view, inclination, and framing as one authored setup. - [Unreal Engine camera rigs](https://dev.epicgames.com/documentation/en-us/unreal-engine/camera-rigs?application_version=4.27) documents rail-mounted camera motion. - [Unity Cinemachine spline dolly](https://docs.unity.cn/Packages/com.unity.cinemachine%403.0/manual/CinemachineSplineDolly.html) documents authored spline position and automatic dolly movement. - [Xbox accessibility guidance for motion](https://learn.microsoft.com/en-us/gaming/accessibility/xbox-accessibility-guidelines/117) explains why automatic camera motion needs a reduced-motion alternative. - [Apple game design guidance](https://developer.apple.com/design/human-interface-guidelines/designing-for-games) defines touch target and safe-area expectations for iPhone and iPad games. - [Android games for all screens](https://developer.android.com/games/develop/all-screens) covers phone, tablet, foldable, keyboard, mouse, controller, and touch adaptation. - [Android edge-to-edge guidance](https://developer.android.com/develop/ui/views/layout/edge-to-edge) explains system-bar, display-cutout, and gesture insets. - [WCAG 2.2 target size](https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum) defines minimum pointer target sizing and spacing exceptions. - [Visual Pinball Engine component architecture](https://docs.visualpinball.org/creators-guide/editor/unity-components.html) separates main, collider, mesh, and animation components. - [Mission Pinball Framework switches](https://missionpinball.org/latest/mechs/switches/) defines switch roles and active/inactive state. - [Mission Pinball Framework spinners](https://missionpinball.org/latest/mechs/spinners/) defines one switch closure per rotation and counted spinner objectives. - [Mission Pinball Framework drop targets](https://missionpinball.org/latest/mechs/targets/drop_targets/) separates target switches from reset and knockdown coils. - [Mission Pinball Framework drop-target banks](https://missionpinball.org/latest/config/drop_target_banks/) groups independent targets and defines shared reset timing. - [Mission Pinball Framework flippers](https://missionpinball.org/latest/config/flippers/) describes activation switches, coils, and end-of-stroke switches. - [Mission Pinball Framework ball devices](https://missionpinball.org/latest/config/ball_devices/) describes ball inventory, capture, eject, and routing contracts. - [Mission Pinball Framework autofire coils](https://missionpinball.org/latest/mechs/autofire_coils/) covers low-latency switch-to-coil mechanisms. - [Mission Pinball Framework slingshots](https://missionpinball.org/latest/mechs/slingshots/) describes the switch, coil, and rubber assembly. - [Mission Pinball Framework display types](https://missionpinball.org/latest/mc/displays/types/) covers segment, DMD, RGB DMD, and modern LCD hardware. - [Mission Pinball Framework logical displays](https://missionpinball.org/latest/mc/displays/) separates resolution-independent display content from physical output hardware. - [Mission Pinball Framework slide priorities](https://missionpinball.org/latest/mc/slides/) documents the persistent score slide and temporary higher-priority mode or warning slides. - [Visual Pinball Engine troughs](https://docs.visualpinball.org/creators-guide/manual/mechanisms/troughs.html) covers drain, storage, and serve mechanisms. - [App Catalog](app-catalog.md) describes Dimensional Pinball as a built-in WebGPU OS app. - [WebGPU OS Architecture](architecture.md) explains the surrounding OS runtime. --- # Smith Lab Smith Lab is the `os.smith-lab` RF learning and design application. It combines an accessible Smith Chart academy, deterministic matching-network synthesis, bounded Touchstone import, and synchronized SVG and WebGPU visualizations. The same frequency, load, reference impedance, selected marker, and sampled component path drive every visible result. (Source: `webgpu-os/factory/apps/smith-lab/RFPath.js`) The opening surface uses an original generated scientific-cinematic coax and reflection-field illustration. It is stored with its exact prompt and SHA-256 provenance and is explicitly labeled as a not-to-scale concept visualization. It never supplies chart coordinates or calculation results; the SVG, WebGPU, and RF model remain authoritative. ## Start here The opening screen separates three jobs instead of exposing every RF control at once: - **Learn the chart** opens seven interactive lessons covering traveling waves, reflections, impedance, Smith mapping, components, stubs, and measurements. - **Match an impedance** accepts ordinary `R + jX`, frequency, reference impedance, and velocity factor values, then synthesizes and ranks matching networks. - **Open measurement data** accepts Touchstone files or pasted frequency tables and converts them to one canonical frequency-indexed dataset. Guided mode uses plain-language prompts and staged decisions. Engineer mode exposes overlays, exact numerical results, optimization, preferred-value snapping, and tolerance controls. A metric can be selected to inspect its symbolic formula, substitutions, assumptions, result, and units. ## Synchronized workbench The central workbench provides an accessible SVG Smith Chart with impedance, admittance, and combined grids. Its marker supports pointer dragging and arrow keys. The selected point is synchronized with normalized impedance, admittance, reflection coefficient, phase, VSWR, return loss, mismatch loss, reflected power, voltage extrema, wavelength, and electrical length. A circuit strip shows each proposed element in source-to-load order and its value or electrical length. Selecting an element seeks the transformation timeline to that exact operation. The chart draws each impedance, admittance, or line segment separately, while the right panel shows the current substituted state and the calculated terminal residual. The linked Cartesian plot evaluates the selected network at every displayed frequency rather than repeating the unmatched load. (Source: `webgpu-os/factory/apps/smith-lab/index.js`) The path record stores the load, ordered transformation steps, exact sampled impedance and admittance, normalized values, reflection coefficient, metrics, formula, and terminal state. Lossless line samples preserve reflection magnitude. Shunt-stub samples add the calculated branch susceptance in the admittance domain. Exports include project JSON, chart SVG, 3D PNG, calculation CSV, Touchstone 2.1, and a printable report. ## Physical and mathematical 3D The physical RF view renders the current animated reflection coefficient as separate incident, reflected, and total-voltage waves. It derives voltage and current envelopes from the same complex reflection state, uses selected line and stub electrical lengths, and adds energy-flow and voltage-stress cues. Dragging changes orientation and the wheel changes zoom. Smith Lab creates the WebGPU device and pipeline only when this view first opens, then retains that runtime while the user switches views. A visible backend badge reports startup and fallback state. The scene is explanatory rather than a validated electromagnetic field solver. (Source: `webgpu-os/factory/apps/smith-lab/SmithLab3D.js`) Three mathematical views are separate from the engineering chart: - **Calculated network path** lifts the exact per-element Smith trajectory into depth and colors impedance, admittance, and line operations separately. - **Frequency tower** projects the evaluated sweep into a three-dimensional Smith trajectory and synchronizes its selected frequency marker. - **Riemann view** maps the same calculated path onto the spherical complex plane as an optional lesson. These mathematical views lazily create world-space triangle and line geometry, then render it through the engine's WebGPU runtime with a perspective camera, `depth24plus` depth testing, occlusion, orbit controls, and wheel zoom. Network tubes are built from the exact per-element `RFPath` samples; frequency height comes from the evaluated sweep; and the Riemann mesh uses stereographic mapping of the calculated reflection coefficient. A painter-sorted Canvas perspective renderer preserves the same geometry when WebGPU is unavailable. Reduced-motion mode starts at a still frame while retaining direct manipulation. (Source: `webgpu-os/factory/apps/smith-lab/SmithMath3DView.js`) ## RF calculation core `RFMath.js` provides complex arithmetic, `Z ↔ Y ↔ Γ`, mismatch metrics, lossless and lossy line transformations, lumped and distributed component models, ABCD and S conversions, network cascading, parameter conversion, and reference-impedance renormalization. `RFUnits.js` extends the existing safe calculator parser; it does not use `eval`. Accepted expressions include `1.085 GHz`, `36 - j74 ohm`, `2*pi*1.085GHz*13.2nH`, `0.2195468 lambda`, `77 mm / 0.66`, and `-14 dB`. Dimensional validation reports incompatible quantities rather than silently coercing them. Each primary conversion creates immutable ledger entries with a formula ID, symbolic formula, substituted values, intermediate values, result, unit, assumptions, and warnings. This deterministic ledger is the numerical authority used by explanations and exports. ## Matching and tolerance automation The solver enumerates both branches of two-element L networks, three-element π and T candidates, open and short shunt stubs, and a quarter-wave transformer when the load permits it. Candidates are evaluated through the common network model, filtered for finite physical values, scored, and ranked. Band optimization seeds bounded multi-start Nelder–Mead from synthesized networks. It returns convergence evidence and the five best finite candidates. Ranking modes favor best match, broadest band, simplicity, loss, or physical size. E6 through E96 preferred-value snapping is available. Tolerance analysis uses a fixed xorshift seed and 100–5,000 samples. The report contains yield, minimum, median, 90th and 95th percentiles, worst case, and the complete ordered envelope, so a run is reproducible from its project seed. ## Touchstone and datasets `parseTouchstone(text, options)` accepts `.s1p`, `.s2p`, general `.sNp`, and `.ts` sources. It supports RI, MA, and DB values; Hz, kHz, MHz, and GHz; S, Z, Y, and two-port H/G parameters; full, lower, and upper matrices; two-port data ordering; versioned keywords; comments; and per-port reference impedances. Malformed or truncated input is rejected with diagnostics rather than repaired. Imports are bounded to 16 ports, 250,000 frequency points, 2,000,000 complex values, and 16 MiB of source text. A user selects the reflection port or transmission pair used by the analysis. `serializeTouchstone()` emits a Touchstone 2.1 full-matrix dataset while retaining source metadata in the Smith Lab project. The canonical `RfDataset` record contains frequencies, port count, parameter kind, interleaved complex matrices, port references, source metadata, and parser diagnostics. Manual points, pasted sweeps, analytical data, and imported measurements use this same record. ## Public modules | Interface | Purpose | | --- | --- | | `parseTouchstone()` / `serializeTouchstone()` | Bounded measurement interchange. | | `createRfDataset()` / `analyzeRfDataset()` | Canonical RF records and synchronized metrics. | | `convertNetworkParameter()` / `renormalizeNetwork()` | S/Z/Y conversion and port-reference changes. | | `cascadeNetworks()` | Cascades ABCD records or aligned two-port datasets. | | `solveMatchingProblem()` | Closed-form and deterministic topology enumeration. | | `optimizeMatchingNetwork()` | Bounded multi-frequency candidate refinement. | | `analyzeTolerance()` | Seeded tolerance yield and percentile evidence. | | `buildCalculationLedger()` | Structured, exportable RF derivations. | | `buildMatchingPath()` / `sampleMatchingPath()` | Exact per-element visual and explanatory RF states. | The application itself retains the OS lifecycle contract: `mount(root, syscalls)`, `unmount()`, and `getDebugSnapshot()`. ## Verification The deterministic browser suite is `tests/smith-lab.html`. It covers Smith boundaries, round-trip transformations, half-wavelength periodicity, unit parsing, the corrected dual-stub fixture for `100 + j100 Ω` on `50 Ω`, stored source-to-load stub topology, matching-path equivalence and line invariants, Touchstone parsing and export, renormalization, matching synthesis, optimizer determinism, tolerance reproducibility, responsive mounting, cleanup, and live WGSL compilation. The application is also included in normal WebGPU OS app discovery and release bundling. ## Engineering references The line direction, constant-reflection-magnitude rotation, standing-wave envelope, admittance-chart relationship, and shunt-stub construction follow the [MIT 6.013 transmission-line treatment](https://web.mit.edu/6.013_book/www/chapter14/14.6.html). The separation of incident and reflected traveling waves and the distributed line model also follow the [Keysight S-parameter design note](https://www.keysight.com/us/en/assets/7018-06743/application-notes/5952-1087.pdf). These sources define the engineering behavior; all shipped prose, code, and visual assets are original. --- # Particle Realms Studio Particle Realms Studio is the WebGPU OS runtime for running, tuning, validating, and inspecting recipe-built particle simulations. The portable project and typed recipe formats are shared authoring contracts: Paint Studio owns brush-driven construction, while the developing RealmForge owns the reusable node/part builder. Particle Realms consumes those recipes and forms its demos through the same project path. The interface does not treat a visual preview as calibrated or scientifically validated output. ## Studio workspaces The shell exposes six keyboard-accessible workspaces. Arrow keys move among workspace tabs, status updates use an ARIA live region, and the tuning drawer opens only from the explicit Tuning action or `B` keyboard shortcut. (Source: `webgpu-os/factory/apps/particles/ParticleStudioShell.js`) | Workspace | Current behavior | Truth boundary | | --- | --- | --- | | Discover | Searches and filters 40 recipe-backed demos with distinct animated previews, tracks favorites and recent demos, and provides Run Demo, Build from Recipe, and Inspect Recipe Graph actions. | Every demo creates a normal project and typed recipe graph through the same public authoring path. | | Create | Provides the current compatibility scene workbench and bounded top, density, velocity, and history projections from one native sample. New brush-based construction belongs in Paint Studio. | Secondary views are Canvas 2D projections of one bounded readback, not independent solver runs or validated engineering fields. | | Recipe | Builds the portable typed graph visually: add/remove parts, connect compatible sockets, drag nodes, tune parameters, inspect diagnostics, and view a compact measured preview. RealmForge remains the intended reusable cross-product node/part authoring owner as it matures. | The embedded preview is a bounded projection of native readback, not a second solver. Only documented ParticleApp bindings execute; unsupported node families remain authored plan intent. | | Simulate | Hosts the live canvas, playback, camera, interaction, an explicit tuning drawer, and an automatic particle population targeting 60 FPS. | The reported backend identifies the active native, custom WGSL, or recovery path. Population is bounded only by the active runtime/device safety contract, not a user-configurable cap. | | Analyze | Displays accepted measured sensor and runtime series and exports them as CSV or JSON with provenance. | Missing measurements and stage attribution remain absent. The Studio does not synthesize them. | | Compare | Captures explicit settings snapshots and compares compatible measured and imported external series. | A settings snapshot is not a second simulation. External data does not automatically validate the preview. | Create, Recipe, Analyze, and Compare are coordinated by `ParticleStudioAdvanced`. It edits versioned sidecars and displays supplied runtime measurements, but it does not step a solver or invent sensor values. Legacy Artist and Twin sidecar fields remain readable in project v2 so older documents round-trip without data loss, but they are not current workspaces. (Source: `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) ## Recipe-backed demo catalog The catalog contains 40 stable demos across Cosmic, Fields, Matter, Life, and Events. Running a demo creates a fresh project with a canonical typed recipe; building from it creates an editable remix through the same project factory. Every source preset uses one of two classifications: `Artistic` or `Educational Model`. Each record also declares tags, difficulty, fidelity, macro controls, known limitations, and native migration metadata. (Source: `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`) | Category | Presets | | --- | --- | | Cosmic | Spiral Galaxy, Orbital Clusters, Supernova Shell, Black-Hole Accretion, Comet Storm, Planetary Rings, Pulsar Jets, Globular Star Cluster | | Fields | Quantum Vortex, Curl-Noise Nebula, Magnetosphere, Aurora Curtains, Tornado Field, Lightning Cage, Solar Wind Stream, Gravity Lens, Magnetic Reconnection, Vector Weave | | Matter | Thermal Fountain, Reaction Chamber, Cohesive Fluid, Molecular Lattice, Ocean Waves, Waterfall Canyon, Lava Flow, Crystal Growth, Smoke Chamber | | Life | Strange Attractor, Flocking Ribbons, Jellyfish Bloom, Firefly Swarm, Mycelium Growth, Plankton Current, Neural Pulse Web | | Events | Event Fireworks, Meteor Shower, Rainstorm, Snow Globe, Sandstorm Wall, Geyser Burst | `Artistic` means the preset prioritizes visual composition. `Educational Model` means it demonstrates a concept with explicit limitations. Neither classification means the result is calibrated, validated, or suitable for engineering decisions. Built-in preset documents are deeply frozen so a project cannot mutate the catalog definition. (Source: `webgpu-os/factory/apps/particles/ParticleLabProject.js`) Every catalog record also names its animated preview composition. Catalog `id` is stable project identity, while `runtimeId` selects a verified custom-solver family. Variants can reuse an audited family without colliding with catalog identity. Ocean Waves uses dedicated runtime ID 15 for its layered traveling wave sheet; it remains an artistic/educational particle surface, not a CFD or Navier-Stokes result. ## Versioned Studio projects A project is a validated JSON document with schema `particle-realms.particle-project` version `2`. Version 2 keeps the original identity, provenance, seed, timestamps, classification, tags, and normalized settings, then adds the complete Studio authoring state. (Source: `webgpu-os/factory/apps/particles/ParticleLabProject.js`) | Field | Persisted content | | --- | --- | | `studioDocument` | Scene, view, artist, and comparison authoring documents. | | `recipeGraph` | Canonical typed recipe graph. | | `sensorDefinitions` | Validated sensor definitions in stable ID order. | | `twinConfiguration` | Disconnected-safe connector configuration and validated alert rules. Runtime truth and credentials are excluded. | | `externalStudies` | Up to eight normalized studies. Each imported study is limited to 4 MiB. | | `quality` | Authored automatic/profile/target-frame-time intent, not transient device pressure. | Canonical version-2 validation rejects unknown project and settings fields. Serialization is stable and limited to 32 MiB. Version-1 projects migrate deterministically to version 2, and the former `webgpu-os.particles.workspace.v4` settings payload remains an import path. (Source: `webgpu-os/factory/apps/particles/ParticleLabProject.js`) The project layer provides these primary operations: - `createParticleProject()` creates a version-2 project from an immutable built-in preset. - `migrateParticleProjectV1()` upgrades a compatible version-1 document. - `normalizeParticleProject()` repairs compatible input into the canonical current schema. - `validateParticleProject()` reports errors and warnings without silently accepting a non-canonical document. - `migrateParticleWorkspaceV4()` imports the legacy workspace settings. - `serializeParticleProject()` and `deserializeParticleProject()` implement validated JSON export and import. - `remixParticleProject()` creates a new identity and records its source. It preserves the seed unless the caller requests a new one. ### Project API example The following browser module code creates, exports, imports, and remixes a project: ```javascript import { createParticleProject, deserializeParticleProject, remixParticleProject, serializeParticleProject, } from './webgpu-os/factory/apps/particles/ParticleLabProject.js'; const project = createParticleProject( 'particle-realms.preset.galaxy.v1', { name: 'My Spiral Study', seed: 42017 }, ); const exportedJson = serializeParticleProject(project); const importedProject = deserializeParticleProject(exportedJson); const remix = remixParticleProject(importedProject, { name: 'My Spiral Study Remix', }); ``` The project seed initializes both the custom model and the native CPU seed state deterministically for the same settings. This does not promise bit-identical GPU evolution across implementations. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleNativeState.js`) ## Typed recipe graph The `particle-realms.simulation-recipe.graph` version-1 document contains typed node families, typed input and output ports, nodes, and edges. Its validator checks unknown types, endpoint compatibility, required inputs, single-input cardinality, and cycles. Graph changes receive an impact class, and a failed compile can retain the last valid plan for inspection. (Source: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`) The Recipe Builder renders canonical nodes and typed edges on a pannable, horizontally contained canvas. Its palette uses the shared node registry, and all add, remove, connect, disconnect, position, and parameter operations call the same graph helpers used by imported recipes. An incomplete edit remains visible as an authored draft with exact diagnostics while the persisted project and executable plan stay on the last valid graph. Removing or wiring the incomplete part recompiles and persists the recovered graph. The compact preview consumes the same bounded native sample as Create; **Open live Simulate** switches to the single authoritative simulation canvas. (Source: `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) `compileParticleRecipeGraph()` produces a deterministic `particle-realms.simulation-recipe.execution-plan` with the execution model `adapter-bound-native-subsystems`. `ParticleRecipeRuntimeAdapter` applies the validated graph seed, particle count, force, point size, exposure, camera distance, supported solver type, fixed step, and substep count to `ParticleApp`. Direct Quick and Standard edits synchronize those mapped nodes without replacing custom graph topology. An invalid graph leaves the current runtime settings and the controller's last-valid plan in place. Other node families remain validated authoring intent rather than claimed engine execution. (Sources: `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) ## GPU runtime paths The app chooses among three truthful runtime levels: 1. An audited native mode uses `ParticleNativeRuntime` to create and step an engine `ParticleSimWorld`. `ParticleNativeRenderer` reads the world's borrowed position buffer directly. 2. An unsupported, over-limit, or unavailable native mode uses the existing custom compute and HDR render WGSL path. 3. If WebGPU initialization or recovery fails, a generic Canvas 2D preview capped at 5,000 points preserves visual continuity. It does not simulate the selected model. The native adapter currently maps these project modes: | Project mode | Native system | Native state attributes | | --- | --- | --- | | `galaxy`, `nbody` | n-body | mass | | `flock` | flocking | base particle state | | `fluid` | SPH | base particle state | | `chemistry` | chemistry | unsigned element and valence state | | `electromagnetic` | electromagnetic | floating-point charge state | | `molecular` | Lennard-Jones | unsigned element state | The native path requires the granted device to expose at least 10 storage buffers per shader stage. A dedicated device request asks for that exact limit. A shared OS device is immutable, so the Studio validates its granted limit and uses the custom path when it is insufficient. Galaxy and n-body also have a 10,000-particle interactive ceiling in the app; native state has a 100,000-particle ceiling for those modes and a 1,000,000-particle ceiling for the other mapped modes, subject to actual device limits. (Sources: `webgpu-os/factory/apps/shared/GpuLabRuntime.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleNativeState.js`) The native renderer binds the borrowed `vec4` position buffer with a 16-byte stride. It renders additive LDR points and reports HDR and trails as unavailable. Camera controls remain active, but the custom WGSL brush is not connected to the native world. Cleanup destroys only resources owned by the adapter and renderer, not an OS-owned device or borrowed world buffer. (Sources: `webgpu-os/factory/apps/particles/ParticleNativeRuntime.js`, `webgpu-os/factory/apps/particles/ParticleNativeRenderer.js`) ## Bounded views and measured evidence The native frame loop samples Create, Analyze, and Compare no more frequently than once every 500 ms; Create also exposes an explicit sample request. Each sample is a bounded prefix of at most 4,096 particles and contains positions plus velocity and thermal arrays only when the engine exports those readbacks. The sample reports when it is truncated. It does not interpolate, resample, or reconstruct the full field. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleNativeRuntime.js`) `ParticleMultiViewRuntime` projects that one sample into top, density, velocity, and time-history Canvas 2D views. These are interaction aids, not scientific field renderers. The quality governor can select a lower profile from measured frame windows; profiles change secondary-view scale and rate and can suspend extra views. Profiler rows remain empty until the host supplies explicit stage attribution. (Sources: `webgpu-os/factory/apps/particles/ParticleMultiViewRuntime.js`, `webgpu-os/factory/apps/particles/ParticleQualityGovernor.js`) The measured runtime telemetry contract accepts finite non-negative `fps`, `frameMs`, `submitMs`, `gpuMs`, `particleCount`, and `particleBytes` values. Unavailable GPU timing stays absent. Analyze converts accepted measurements into provenance-bearing sensor samples; it never fills missing series with synthetic data. Compare matches only the same quantity and unit when it pairs measured and external series. (Sources: `webgpu-os/factory/apps/particles/ParticleLabTelemetry.js`, `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`, `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`) ## Legacy Twin compatibility boundary Project v2 can still round-trip an older Twin configuration containing a manual, disconnected-safe connector description and alert rules that reference persisted sensor IDs. Credential-like fields are rejected. Loading a project never opens a connection, and the current six-stage Studio exposes no Twin workspace. (Sources: `webgpu-os/factory/apps/particles/ParticleLabProject.js`, `webgpu-os/factory/apps/particles/ParticleTwinRuntime.js`) The retained `ParticleTwinRuntime` remains independently tested for older integrations, but `ParticleApp` does not mount its controls in the current product workflow. This preserves documents and code consumers without making Digital Twin a user-facing simulation-building stage. ## Causal and durable persistence Studio persists a complete `particle-realms.studio-workspace` version-2 snapshot. It loads the app-scoped Causal State Engine (CSE) first, then the encrypted app sandbox, then the old local-storage key as a migration fallback. Writes are debounced, use an expected CSE version, and mirror to the sandbox. The legacy key is removed after either durable service succeeds. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleStudioPersistence.js`) Guarded state syscalls inject the authenticated app ID. `AppStateEngine.put()` creates immutable versions, stamps successful writes with a hybrid logical clock, and appends a hash-chained event. CSE values are limited to 64 KiB, so a larger valid project may be stored by the sandbox mirror even when the CSE write is rejected. The save result reports which persistence service succeeded. (Sources: `webgpu-os/kernel/Syscalls.js`, `webgpu-os/kernel/state/AppStateEngine.js`, `webgpu-os/storage/AppSandbox.js`) An expected-version conflict does not become an invented consensus result. Studio reloads the current CSE head, retries the explicit local edit once as `project.reconciled`, and leaves the conflict visible in the CSE timeline. ## Current limitations - Recipe execution is limited to the mapped ParticleApp settings and clock; arbitrary subsystem, audio, output, and coupling nodes are not dispatched. - Native mode coverage is limited to the seven mappings listed above. - Native rendering is LDR and has no trails or solver-connected brush. - Native readback is bounded and cannot represent a complete scientific field. - Multi-view projections and external comparisons are not scientific validation or calibration. - Compatibility-only Artist/Twin sidecars are not visible workspaces. - Sensors are runtime measurements, not calibrated physical instruments. Use each preset's Discover limitations and the active backend label before interpreting a result. ## See also - [Particle Studio Integration Map](particle-studio-integration-map.md) - [Engine Particle System](../engine/particles.md) - [GPU Device Sharing](../concepts/gpu-device-sharing.md) - [Security and Trust Model](../concepts/security-model.md) --- # Particle Studio User Guide Particle Realms Studio is the Particle Sandbox application inside WebGPU OS. It provides six workspaces for selecting, running, safely tuning, inspecting, and comparing particle projects. Full brush construction belongs in Paint Studio; the reusable node/part builder belongs in the developing RealmForge. Particle Realms reads the same portable project and recipe documents they produce. Results are artistic or educational previews unless your own evidence and validation process establishes otherwise. (Sources: `webgpu-os/factory/apps/particles/ParticleStudioShell.js`, `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`) This guide is for users who want to run and inspect current Studio projects without confusing authored previews with measured or validated evidence. ## Before opening Studio Run WebGPU OS over HTTP in a browser with WebGPU enabled for the native or custom GPU paths. The application can remain accessible in generic Canvas 2D recovery mode when WebGPU is unavailable, but that mode does not execute the selected model. Open **Particle Sandbox** from the WebGPU OS app catalog and check the backend label before interpreting the scene. (Sources: `webgpu-os/apps/particles/factory.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Choose and run a recipe demo 1. Open **Discover** and filter the 40 built-in recipe demos by category, tag, difficulty, or search text. 2. Read the demo's classification, model description, and limitations. 3. Use **Run Demo** to create a fresh normal project from its canonical recipe, or **Build from Recipe** to create an editable remix. **Inspect Recipe Graph** shows the actual typed graph used by the demo. 4. Simulate opens with the full canvas visible. Choose **Tuning** or press `B` only when you want the advanced drawer. Favorites and recent choices are local convenience state. A preset labeled `Artistic` prioritizes composition; `Educational Model` demonstrates a concept with stated limitations. Neither label means calibrated or certified. Each card has an animated composition-specific preview, so an ocean, fountain, galaxy, flock, or storm is recognizable before the full runtime opens. (Sources: `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) ## Tune the live simulation The tuning drawer stays closed when **Simulate** becomes active. Open it with the toolbar action or `B`, and close it with the drawer button, toolbar action, `B`, or `Escape`. Particle population is automatic. Studio samples delivered frame cadence, smooths several observations, and uses hysteresis plus a reallocation cooldown to move population toward a stable 60 FPS. The Simulate row shows the current automatic population but provides no count or cap input. The only ceiling is the current GPU/runtime safety contract; users do not configure it. Population changes rebuild size-dependent resources. Other controls update the active configuration according to their declared impact. The active backend report identifies whether Studio is using the native engine path, the custom WGSL path, or the generic recovery preview. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`) Direct controls synchronize the mapped nodes in the current recipe on save. That synchronization preserves custom graph topology and unsupported authored intent. It does not convert every recipe node into running engine state. (Source: `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js`) Studio has three control-detail levels. **Quick** shows Effect, automatic Particles, Force, and Size. **Standard** also shows Palette and Brush. **Advanced** keeps the Standard row. Changing detail level never opens the tuning drawer. The drawer groups the remaining current settings under Interaction, Dynamics, Matter, and Presentation. Advanced is a broader settings surface, not a promise that every typed recipe node has a dedicated widget. (Source: `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Choose a simulation view The three buttons at the top center of **Simulate** select one authoritative perspective and two bounded inspection views: - **Perspective** (`◈`) shows the live 3D renderer. Drag to orbit, use the mouse wheel to dolly, and choose **Home camera** to restore the complete camera authored for the selected preset. Changing presets also resolves a fresh complete home camera, so yaw or pitch from the previous preset cannot leak into the next scene. - **Top** (`⊤`) shows a fixed X/Z projection of a stratified sample taken across the active particle population. - **Density** (`▦`) bins the same kind of fixed X/Z sample into a heatmap. Top and Density preserve the sampled world aspect ratio. They do not stretch each axis independently. Their fixed projection canvas blocks interactions with the hidden perspective camera, and **Home camera** remains disabled until Perspective is active again. Both projections are bounded inspection views, not independent solver runs or full-state scientific fields. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleMultiViewRuntime.js`) ## Author the scene in Create **Create** edits versioned scene objects organized as domain, geometry, boundaries, materials, emitters, fields, solvers, couplings, sensors, visualizers, cameras, audio, timeline, telemetry, and outputs. Objects carry stable IDs, enabled state, transform, type, label, and free-form parameters. (Source: `webgpu-os/factory/apps/particles/ParticleStudioDocument.js`) The Perspective, Top, Density, Velocity, and History displays are compact views derived from one bounded native sample. They are not independent camera renders, separate solver runs, full-state field slices, or calibrated engineering plots. Scene-tree edits are authored document changes; the current UI is not a complete ECS editor with transform gizmos and undo history. (Sources: `webgpu-os/factory/apps/particles/ParticleMultiViewRuntime.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) ## Edit a recipe **Recipe** opens a full-width visual builder. Use **Add node** to insert a registered typed part, choose compatible **From output** and **To input** sockets to connect it, drag cards to organize the graph, and select any card to edit its safe parameters or exact X/Y position. Connections and selected parts have explicit remove actions. The right-side preview renders the latest bounded native readback; **Open live Simulate** moves to the authoritative simulation canvas. The status badges distinguish `graph valid`, `graph invalid`, `plan current`, and `last-valid plan retained`. An incomplete part stays visible with exact diagnostics, but it is not persisted or applied to the runtime. Complete its required connections or remove it to recover the current executable plan. (Sources: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) The current runtime mapping covers seed, particle count, force, temperature, point size, exposure, camera distance, supported solver mode, fixed step, and substeps. Other node families remain saved and inspectable but do not execute. The Recipe workspace is the Particle Realms compatibility builder for composing and previewing simulations from portable parts. Paint Studio remains the owner of brush-driven construction, and RealmForge remains the developing owner of the reusable cross-product node/part authoring experience. (Sources: `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) ## Analyze measured data **Analyze** displays accepted runtime and sensor series and can export sensor records as JSON or CSV. A sensor definition identifies its quantity, unit, source, sampling rate, reduction, and stale policy. Samples retain sequence, timestamp, quality, and origin provenance. Missing metrics remain absent or explicitly missing; Studio does not fill gaps with plausible values. (Sources: `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`, `webgpu-os/factory/apps/particles/ParticleLabTelemetry.js`) The sensor runtime accepts supplied measurements and can reduce a bounded compact numeric array. It does not currently read arbitrary solver fields or install a full GPU probe/reduction pipeline by itself. ## Compare projects and external data **Compare** can capture a candidate settings snapshot and display compatible measured and external time series. Side-by-side project settings are not a second simultaneously running simulation. Imported CSV or JSON studies are bounded, retain source metadata, and default to unvalidated. Compare only series with matching quantity and unit. (Sources: `webgpu-os/factory/apps/particles/ParticleStudioDocument.js`, `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) An imported study never automatically validates the preview. Studio does not currently submit remote solver jobs, ingest full scientific fields, or align a spatial external field over the 3D viewport. ## Compatibility-only legacy sidecars Project v2 still validates and round-trips older Artist timeline and Twin configuration sidecars so existing files are not destroyed. They are not visible Studio workspaces and are not part of the current recipe-authoring workflow. Credential-like Twin fields and transient runtime truth remain rejected from persisted projects. (Source: `webgpu-os/factory/apps/particles/ParticleLabProject.js`) ## Choose a quality profile Available profiles are **Economy**, **Interactive**, **High**, and **Cinematic**. They control secondary-view scale and rate, maximum secondary views, sensor-rate scale, trails, and post quality. Automatic mode observes a window of measured frame times and changes one profile step after hysteresis and cooldown rules. Critical memory pressure selects Economy; moderate pressure caps the result at Interactive. (Source: `webgpu-os/factory/apps/particles/ParticleQualityGovernor.js`) Only automatic/profile/target-frame-time intent is persisted. Transient memory pressure and profiler history are runtime observations. ## Save, export, import, and recover Studio saves complete project snapshots through app-scoped causal state and the encrypted sandbox, with legacy local storage as a compatibility fallback. Project JSON uses a strict versioned schema and is limited to 32 MiB. Imports from future unknown versions or with unknown canonical fields fail instead of being guessed. (Sources: `webgpu-os/factory/apps/particles/ParticleStudioPersistence.js`, `webgpu-os/factory/apps/particles/ParticleLabProject.js`) If GPU initialization or recovery fails, Studio may display a Canvas 2D recovery preview so the project remains accessible. That preview is generic; verify the backend status before interpreting behavior. Authored project state is preserved across device-loss recovery. (Source: `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Keyboard and accessibility behavior Workspace tabs support arrow-key movement, status changes are announced in an ARIA live region, and the tuning drawer restores focus when closed. Standard form labels and buttons are used throughout the shell. With reduced-motion preference enabled, the tuning drawer transition is disabled. (Source: `webgpu-os/factory/apps/particles/ParticleStudioShell.js`) ## Troubleshooting checklist - **Selected model inactive:** Canvas 2D recovery is active. Retry WebGPU and confirm browser support, adapter access, and device status. - **Native backend not selected:** the mode may be unmapped, the count may exceed its interactive ceiling, or the device may grant fewer than ten storage buffers per shader stage. The labeled custom path is expected. - **Recipe did not apply:** read the exact graph diagnostics. Studio keeps the last valid project and settings when validation fails. - **No chart value:** confirm a matching sensor definition and a supplied provenance-bearing sample. Missing measurements are intentionally empty. - **External series not compared:** quantity and unit must exactly match a measured scalar series; Studio does not convert units or align time. - **Import rejected:** confirm schema/version, canonical fields, size limits, and the absence of credential-like legacy Twin configuration. - **After device loss:** preserve the project, use the labeled recovery view, then retry GPU initialization. Do not treat recovery motion as model output. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`, `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`, `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`, `webgpu-os/factory/apps/particles/ParticleLabProject.js`) Before sharing a result, export the project and measured data, record the backend, preset classification and limitations, seed, recipe signature, fixed step/substeps, quality profile, browser/device, and any fallback or missing measurement. This record makes the result reviewable without elevating it to a validation claim. ## Capability boundary | Status | User-facing capability | | --- | --- | | Implemented | Discover, Create, Recipe, Simulate, Analyze, and Compare; recipe-backed demos; explicit Simulate tuning; automatic 60 FPS particle population; project import/export; measured-data export; local persistence; and labeled recovery. | | Partial | Create uses bounded projections, Recipe executes mapped controls only, and Compare is settings/scalar-series based. | | Unsupported | Editor-native gizmos/undo, Publish, Artist, or Twin workspaces, live connectors, remote solver jobs, full-field overlays, collaboration, and a standalone runtime player. | ## See also - [Particle Realms Studio](particle-realms-studio.md) - [Particle Studio Preset Authoring](particle-studio-preset-authoring.md) - [Particle Recipe Schema](particle-recipe-schema.md) - [Particle Studio Fidelity and Validation](particle-studio-fidelity-and-validation.md) - [Particle Studio External Studies](particle-studio-external-studies.md) --- # Particle Studio Architecture Particle Realms Studio is a WebGPU OS application, not a separate native desktop editor. `ParticleApp` owns its lifecycle and composes the Studio shell, versioned project, GPU runtime, evidence stores, and OS persistence services. The current product exposes Discover, Create, Recipe, Simulate, Analyze, and Compare. Simulate is the default/fallback workspace and keeps its tuning drawer closed until explicitly requested. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleStudioShell.js`) Authoring ownership is deliberately outside the runtime app. Paint Studio owns brush-driven simulation construction, and RealmForge is the developing home of the reusable node/part recipe builder. Particle Realms retains portable recipe inspection and safe parameter tuning so one document can be run, measured, compared, and promoted into a built-in demo without a private second format. This page is for app and engine developers who need the current ownership, data-flow, and integration boundaries. ## Dynamic population controller `ParticleCountGovernor` targets 60 FPS using a settled mean of measured RAF cadence. Sustained pressure reduces particle count multiplicatively; sustained headroom grows it conservatively. A deadband prevents oscillation, a cooldown accounts for GPU reallocation cost, and workgroup-aligned quantization keeps dispatch sizes stable. Decisions stop at the active device/runtime safety maximum. That maximum is not exposed as a preference or user cap. `ParticleApp` applies decisions only while Simulate is visible, running, and GPU-backed. Each accepted change updates the canonical count binding, reports the automatic population, and performs one resource reallocation. Paused, hidden, authoring, fallback, and warm-up samples cannot change population. (Sources: `webgpu-os/factory/apps/particles/ParticleQualityGovernor.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Runtime layers ```mermaid flowchart TD Factory["WebGPU OS app factory"] --> App["ParticleApp"] App --> Shell["Studio shell and workspaces"] App --> Project["Particle project v2"] App --> Recipe["Recipe graph and runtime adapter"] App --> GPU["GpuLabRuntime"] App --> Evidence["Telemetry, sensors, and studies"] App --> Persist["CSE-first persistence"] GPU --> Native["Native ParticleSimWorld path"] GPU --> Custom["Custom WGSL path"] GPU --> Recovery["Canvas 2D recovery preview"] Native --> Direct["Borrowed position-buffer renderer"] Native --> Sample["Bounded prefix readback"] Sample --> Evidence ``` Text equivalent: the factory registers the app. `ParticleApp` creates the shell, selects a runtime, applies validated projects, advances the native or custom simulation, records measured runtime metrics, and coordinates save and recovery. The advanced controller edits project sidecars and renders evidence; it does not step a solver or open a live transport. (Sources: `webgpu-os/apps/particles/factory.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) ## Canonical project state The persisted aggregate is `particle-realms.particle-project` version 2. It contains project identity and settings plus these versioned sidecars: | Sidecar | Responsibility | | --- | --- | | `studioDocument` | Scene objects, view layout, comparison state, and compatibility-only legacy artist data. | | `recipeGraph` | Typed authored graph with stable IDs, ports, edges, and parameters. | | `sensorDefinitions` | Provenance-aware definitions for accepted measurements. | | `twinConfiguration` | Compatibility-only disconnected-safe data retained for lossless legacy project round trips. | | `externalStudies` | Bounded normalized CSV or JSON reference studies. | | `quality` | Authored automatic/profile/target-frame-time intent. | Project validation is strict, serialization is deterministic, and the complete document is capped at 32 MiB. Runtime samples, credentials, live connector state, and transient memory pressure are not canonical project truth. (Source: `webgpu-os/factory/apps/particles/ParticleLabProject.js`) The project dependency graph is deliberately acyclic: `ParticleLabCatalog.js` -> `ParticleProjectCore.js` -> `ParticleRecipeGraph.js` -> `ParticleLabProject.js`. The core layer owns settings, seeds, hashing, and immutable built-in presets; the aggregate layer owns project/graph sidecar composition. This ordering preserves the same public project behavior in raw ES modules and the eager classic release bundle. (Sources: `webgpu-os/factory/apps/particles/ParticleProjectCore.js`, `webgpu-os/factory/apps/particles/ParticleLabProject.js`) ## Recipe-to-runtime seam `ParticleRecipeGraph` validates and compiles a deterministic execution-plan description. `ParticleRecipeRuntimeAdapter` is the current execution seam. It applies the graph seed and the mapped count, force, temperature, point size, exposure, camera distance, solver mode, fixed step, and substep values to `ParticleApp`. Direct Quick and Standard control changes synchronize those named default graph nodes while preserving custom topology, IDs, provenance, and unsupported authored nodes. (Sources: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`, `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) An invalid graph does not replace the live project or settings. The graph compiler and Recipe workspace can report authored diagnostics, while `ParticleApp` retains the last validated runtime configuration. Unsupported solver types and node families remain authored intent; there is no generic dispatcher that instantiates arbitrary engine, audio, telemetry, external-study, or output nodes. (Sources: `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) ### Visual Recipe Builder state boundary `ParticleStudioAdvanced` owns a recoverable authored-draft layer above the canonical project. Valid graph edits compile, update the last-valid execution plan, and commit through project-v2 normalization. Invalid edits keep the authored nodes and edges in the builder, display compiler diagnostics, and do not invoke the project-change callback. A subsequent repair compiles and commits normally. This separation lets users assemble required sockets in multiple steps without allowing an incomplete graph to replace live runtime state. The embedded Recipe preview uses `ParticleMultiViewRuntime` with the latest bounded, explicitly labeled native readback. It is an X/Z projection at a bounded refresh rate, not another `ParticleSimWorld`, a full-state copy, or a validation claim. The Simulate workspace remains the only authoritative live canvas. (Sources: `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`, `webgpu-os/factory/apps/particles/ParticleMultiViewRuntime.js`) ## GPU and recovery paths `GpuLabRuntime` may use an OS-shared device or request a dedicated device. It derives capabilities from granted limits and never destroys a shared device. The native particle path requires at least ten storage buffers per shader stage. Eligible mapped modes create an engine `ParticleSimWorld`, upload deterministic seed state, and render its borrowed position buffer directly. Only a bounded prefix is copied for CPU-side views and exports. (Sources: `webgpu-os/factory/apps/shared/GpuLabRuntime.js`, `webgpu-os/factory/apps/particles/ParticleNativeRuntime.js`, `webgpu-os/factory/apps/particles/ParticleNativeRenderer.js`) Modes or devices that are not native-eligible use the app's custom WGSL simulation. Initialization or recovery failure can fall back to a generic Canvas 2D preview. That recovery preview preserves access to the authored project but is not equivalent to the selected scientific or artistic model. Device-loss recovery preserves authored state and recreates GPU-owned resources. (Source: `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Evidence architecture Studio data uses explicit truth classes: | Class | Current source | Boundary | | --- | --- | --- | | Direct GPU state | Native world buffers | Rendered without an app-owned simulation copy. | | Bounded readback | Prefix of native positions | Supports compact projections and PNG capture, not a full-state export. | | Measured runtime | Supplied frame, submit, GPU, count, and memory samples | Missing metrics remain missing. | | Measured sensors | Provenance-bearing accepted samples | The runtime never reads the solver or fabricates values. | | External reference | Imported bounded studies | Does not automatically validate the preview. | (Sources: `webgpu-os/factory/apps/particles/ParticleLabTelemetry.js`, `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`, `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`) ## Persistence and concurrency `ParticleStudioPersistence` saves complete snapshots through app-scoped causal state first, mirrors them to the encrypted sandbox, and retains legacy local storage as a compatibility fallback. Writes carry an expected version and may perform one reconcile retry. This is storage concurrency, not scientific consensus or network collaboration. (Source: `webgpu-os/factory/apps/particles/ParticleStudioPersistence.js`) ## Capability boundary | Status | Capability | | --- | --- | | Implemented | Six workspaces, recipe-backed demos, project v2, deterministic graph validation/compilation, mapped recipe application, native/custom/recovery runtime selection, bounded telemetry and imports, and CSE-first persistence. | | Partial | Recipe execution covers documented mappings only; Create multi-view uses projections of one sample; sensors accept supplied reductions but are not wired to a complete GPU probe pipeline. | | Unsupported | Standalone native editor, arbitrary recipe-node execution, graphical node-canvas editing, collaboration, remote job systems, full-field scientific overlays, and certified engineering validation. | These boundaries describe the current repository. The design pack is a product direction document and does not override implemented source behavior. ## See also - [Particle Realms Studio](particle-realms-studio.md) - [Particle Studio Integration Map](particle-studio-integration-map.md) - [Particle Recipe Schema](particle-recipe-schema.md) - [Particle Studio Fidelity and Validation](particle-studio-fidelity-and-validation.md) - [Particle Studio Performance](particle-studio-performance.md) --- # Particle Studio Integration Map This map shows the active Particle Realms Studio paths and the boundaries that remain host or engine integration work. It distinguishes direct GPU state, bounded readback, measured evidence, authored configuration, external data, and predictions. ## Active Studio path ```mermaid flowchart TD Factory["Particle app factory"] --> App["ParticleApp lifecycle"] App --> Shell["Six-workspace shell"] App --> Project["Particle project v2"] App --> Advanced["Advanced workspace controller"] App --> Persistence["CSE-first persistence"] App --> Telemetry["Bounded runtime telemetry"] App --> Device["GpuLabRuntime"] Device --> Shared["OS-shared GPUDevice"] Device --> Dedicated["Dedicated GPUDevice"] Device --> Eligible{"Mapped mode, count, and native limits eligible?"} Eligible -->|Yes| Native["ParticleNativeRuntime"] Native --> World["Engine ParticleSimWorld"] World --> Direct["Borrowed position buffer renderer"] World --> EvidenceReadback["Bounded prefix evidence readback"] World --> ProjectionReadback["Bounded stratified Simulate readback"] EvidenceReadback --> Advanced ProjectionReadback --> Shell Eligible -->|No or unavailable| WGSL["Custom HDR compute/render WGSL"] Device -->|Initialization or recovery failure| CPU["Generic Canvas 2D recovery preview"] Persistence --> CSE["App-scoped causal state"] Persistence --> Sandbox["Encrypted app sandbox"] ``` Text equivalent: the app factory mounts `ParticleApp`. The app owns the shell, project, persistence, telemetry, advanced controller, and runtime selection. Eligible modes create and step an engine `ParticleSimWorld`; the native renderer binds its borrowed position buffer directly. Other WebGPU cases use the custom WGSL model, while Canvas 2D is a generic recovery preview. ## Active modules | Module | Main symbols | Current responsibility | | --- | --- | --- | | `webgpu-os/apps/particles/factory.js` | Factory registration | Registers the Particle Sandbox app for WebGPU OS. | | `webgpu-os/factory/apps/particles/ParticleApp.js` | `ParticleApp`, custom WGSL exports | Owns lifecycle, runtime selection, native stepping, custom simulation, interaction, reporting, persistence snapshots, and recovery. | | `webgpu-os/factory/apps/particles/ParticleStudioShell.js` | `ParticleStudioShell`, `PARTICLE_STUDIO_WORKSPACES` | Builds accessible Discover, Create, Recipe, Simulate, Analyze, and Compare workspaces and owns automatic tuning visibility. | | `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js` | `ParticleStudioAdvanced` | Coordinates the four visible authoring/evidence workspaces without stepping a solver. | | `webgpu-os/factory/apps/particles/ParticleLabCatalog.js` | `PARTICLE_MODES`, `technologySummary()` | Defines the 40 classified presets, catalog identities, custom-solver family IDs, animated preview compositions, limitations, macros, and migration metadata. | | `webgpu-os/factory/apps/particles/ParticleProjectCore.js` | Settings, seed, hash, and immutable preset functions | Provides the cycle-free project primitives shared by graph and aggregate layers. | | `webgpu-os/factory/apps/particles/ParticleLabProject.js` | Project create, migrate, validate, remix, serialize, deserialize, and graph-sidecar functions | Defines the strict project-v2 aggregate, composes recipe graphs, and re-exports the core preset API. | | `webgpu-os/factory/apps/particles/ParticleStudioDocument.js` | Scene, view, artist, and comparison normalizers and edit helpers | Defines versioned Studio authoring sidecars embedded in project v2. | | `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js` | Typed graph edit, validation, migration, serialization, impact, and compilation functions | Defines recipe graph v1 and deterministic plan descriptions. It does not execute a plan. | | `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js` | `adaptParticleRecipeExecutionPlan()`, `synchronizeParticleRecipeGraphSettings()` | Applies the validated ParticleApp subset of a plan and keeps direct controls synchronized with mapped graph nodes. | | `webgpu-os/factory/apps/particles/ParticleNativeState.js` | `createNativeParticleState()`, `nativeSystemsForMode()` | Maps seven project modes to audited systems and creates deterministic typed CPU seed state. | | `webgpu-os/factory/apps/particles/ParticleNativeRuntime.js` | `ParticleNativeRuntime` | Discovers native engine exports, validates granted limits, owns a `ParticleSimWorld`, uploads state, steps systems, exposes borrowed buffers, and performs bounded readback. | | `webgpu-os/factory/apps/particles/ParticleNativeRenderer.js` | `ParticleNativeRenderer` | Renders the borrowed native position buffer as additive LDR points without copying it into an app-owned simulation buffer. | | `webgpu-os/factory/apps/particles/ParticleMultiViewRuntime.js` | `ParticleMultiViewRuntime`, `fitParticleProjection()` | Produces bounded Canvas 2D projections and measured history from one runtime sample while preserving world-space aspect ratio. | | `webgpu-os/factory/apps/particles/ParticleLabTelemetry.js` | `ParticleLabTelemetry` | Retains bounded measured runtime metrics without synthetic values. | | `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js` | Sensor definition, sample, reduction, and runtime APIs | Validates definitions and provenance-bearing measured samples. | | `webgpu-os/factory/apps/particles/ParticleExternalStudy.js` | Import, validation, comparison, and serialization APIs | Parses bounded CSV/JSON studies and compares only compatible quantity/unit series. | | `webgpu-os/factory/apps/particles/ParticleQualityGovernor.js` | `ParticleQualityGovernor`, `ParticleProfilerAttribution` | Applies authored quality policy from observed frame windows and keeps unsupported attribution absent. | | `webgpu-os/factory/apps/particles/ParticleTwinRuntime.js` | `ParticleTwinConnector`, `ParticleTwinRuntime` | Retained internal compatibility module; it is not exposed as a current Studio workspace. | | `webgpu-os/factory/apps/particles/ParticleStudioPersistence.js` | `ParticleStudioPersistence` | Debounces complete workspace snapshots and writes through CSE and the sandbox, with legacy local storage as fallback. | | `webgpu-os/factory/apps/shared/GpuLabRuntime.js` | `requestLabDevice()`, `deriveGpuCapabilities()`, `destroyGpuResources()` | Wraps shared or dedicated devices, validates exact required limits, observes loss, and respects device ownership. | ## Project and authoring contracts The canonical project schema is `particle-realms.particle-project` version 2. It embeds `studioDocument`, `recipeGraph`, `sensorDefinitions`, `twinConfiguration`, `externalStudies`, and authored `quality` beside the project's identity, provenance, seed, classification, tags, and normalized settings. Version-1 projects migrate deterministically, and legacy workspace v4 settings remain importable. (Source: `webgpu-os/factory/apps/particles/ParticleLabProject.js`) Strict v2 validation rejects unknown project and settings fields. Sensor definitions and external studies receive stable ordering. Persisted Twin configuration rejects credential-like keys and excludes runtime truth, checkpoints, replay state, branches, predictions, alerts, and connector state. Serialization has a 32 MiB project limit; each external study has a 4 MiB limit, and a project may contain at most eight studies. ### Recipe graph boundary ```mermaid flowchart LR Edit["Typed node and parameter edits"] --> Validate["Ports, edges, cardinality, cycles"] Validate -->|Valid| Plan["Deterministic adapter-bound plan"] Validate -->|Invalid| Previous["Keep last valid plan and runtime settings"] Plan --> Adapter["ParticleApp runtime adapter"] Adapter --> Mapped["Mapped settings and fixed-step clock"] Plan -. "Unsupported nodes remain authored intent" .-> Boundary["No claimed subsystem dispatch"] ``` Graph compilation classifies change impact and orders enabled nodes. The advanced controller remains solver-free, while `ParticleApp` consumes a valid plan through `ParticleRecipeRuntimeAdapter`. The adapter binds seed, count, force, point size, exposure, camera distance, supported solver types, and the fixed-step/substep clock. Direct controls update the same mapped graph nodes. Unsupported graph subsystems are preserved and reported without being claimed as executed. (Sources: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`, `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) ## GPU device and limit contract `requestLabDevice()` accepts strict `requiredLimits`. For a dedicated device, it checks adapter limits before calling `requestDevice()` and passes the exact requirements. For an OS-shared device, it validates the already granted, immutable limits. Its errors distinguish adapter insufficiency from a shared device that was created without enough capacity. (Source: `webgpu-os/factory/apps/shared/GpuLabRuntime.js`) The native Studio path currently requires `maxStorageBuffersPerShaderStage >= 10`. The WebGPU OS device bootstrap asks for up to 10 when the adapter exposes it. A shared device that was created with a lower limit remains usable by the custom Studio path, but cannot be upgraded in place for the native path. (Sources: `engine/core/gpu/GpuDevice.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) `GpuLabRuntime` derives capacity only from the granted `GPUDevice`. It never destroys an OS-owned device. A dedicated browser device remains available when the OS device syscall is absent. `createSyscalls()` and `guardSyscalls()` gate device access with the app's GPU permission. (Sources: `webgpu-os/factory/apps/shared/GpuLabRuntime.js`, `webgpu-os/kernel/Syscalls.js`) `SurfaceManager.allocate()` remains an available kernel-owned surface seam. The current Studio uses a canvas in its app shell and the shared-device seam; it does not claim kernel surface ownership. (Source: `webgpu-os/kernel/SurfaceManager.js`) ## Native lifecycle For an eligible mapped mode, `ParticleApp` performs this lifecycle: 1. Resolve the system mapping, required attributes, and interactive count ceiling with `nativeSystemsForMode()`. 2. Acquire a shared or dedicated device and verify the native storage-binding limit. 3. Initialize `ParticleNativeRuntime`, which loads the engine particle exports, validates the requested systems and memory against the granted device, and creates `ParticleSimWorld`. 4. Create deterministic typed CPU state and upload positions, velocities, metadata, thermal state, owners, UVs, and any required elements or charges. 5. Initialize `ParticleNativeRenderer` and bind the world's borrowed position buffer with a 16-byte `vec4` stride. 6. Step the world and render the same buffer each frame. 7. Drain pending readback before destroying the world. Destroy only resources owned by the app runtime and renderer. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleNativeState.js`, `webgpu-os/factory/apps/particles/ParticleNativeRuntime.js`, `webgpu-os/factory/apps/particles/ParticleNativeRenderer.js`, `engine/sim/particles/ParticleSimWorld.js`) ### Active native mappings | Studio preset/mode | Engine system | Required extra state | App ceiling | | --- | --- | --- | --- | | Spiral Galaxy / `galaxy` | n-body | mass | 10,000 interactive particles | | Orbital Clusters / `nbody` | n-body | mass | 10,000 interactive particles | | Flocking Ribbons / `flock` | flocking | none beyond base state | 1,000,000 native-state particles | | Cohesive Fluid / `fluid` | SPH | none beyond base state | 1,000,000 native-state particles | | Reaction Chamber / `chemistry` | chemistry | unsigned elements and valence | 1,000,000 native-state particles | | Magnetosphere / `electromagnetic` | electromagnetic | floating-point charges | 1,000,000 native-state particles | | Molecular Lattice / `molecular` | Lennard-Jones | unsigned elements | 1,000,000 native-state particles | Every ceiling is further constrained by the granted device. Unmapped modes, over-limit n-body projects, insufficient native limits, and native initialization failures use the custom WGSL backend. A complete WebGPU failure uses the generic Canvas 2D recovery preview. (Sources: `webgpu-os/factory/apps/particles/ParticleNativeState.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) The direct native renderer is intentionally smaller than the custom renderer. It reports `directNativePositionBuffer: true`, `hdr: false`, and `trails: false`. It does not connect the custom brush to the world. These are reported capabilities, not hidden degradations. ## Readback and evidence flow ```mermaid flowchart LR World["ParticleSimWorld buffers"] -->|Direct GPU binding| Render["Native LDR renderer"] World -->|At most 4,096-particle prefix| EvidenceSample["Evidence positions and optional velocity/thermal"] World -->|At most 16,384 particles in stratified blocks| ProjectionSample["Simulate X/Z visual sample"] ProjectionSample --> Views["Aspect-correct Top and Density projections"] EvidenceSample --> Sensors["Accepted measured samples"] Sensors --> Analyze["Analyze and export"] Sensors --> Compare["Compatible external comparison"] ``` The native frame loop samples Create, Analyze, and Compare no more frequently than once every 500 ms; Create also exposes an explicit sample request. `samplePositions()` copies exactly the requested prefix of each 16-byte `vec4` stream and maps only that copied range. Simulate Top and Density instead copy small deterministic blocks distributed across the active position buffer, up to 16,384 particles, so ordered particle layouts do not collapse to a prefix strip. The same stratified policy applies to the custom WGSL position buffer. Projection fitting uses one uniform world-to-canvas scale for both axes. App-level samples are marked as truncated when active particle count is larger. Optional velocity and thermal readbacks are included only when the loaded engine module exports them. No interpolation, full-state reconstruction, or independent camera solver occurs. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleNativeRuntime.js`) The advanced workspaces enforce these boundaries: | Area | Accepted source | Explicit exclusion | | --- | --- | --- | | Multi-view | One bounded native sample and measured frame history | Independent solver views or validated engineering fields | | Analyze | Accepted runtime metrics and sensor samples with provenance | Fabricated missing values or invented profiler stage attribution | | Compare | Explicit settings snapshots and same-quantity, same-unit measured/external series | A hidden second simulation or automatic validation | ## Causal state and sandbox storage `ParticleStudioPersistence` stores a complete `particle-realms.studio-workspace` version-2 snapshot. Loading checks CSE, then the encrypted sandbox, then the legacy local-storage key. Writes use an expected CSE version, retry one detected conflict as `project.reconciled`, and mirror to the sandbox. This preserves causal history without claiming domain or network consensus. (Source: `webgpu-os/factory/apps/particles/ParticleStudioPersistence.js`) `guardSyscalls()` injects the authenticated app ID into state operations. `AppStateEngine` stores immutable entity versions and hash-chained hybrid-logical-clock events. Its per-value limit is 64 KiB. A project can be valid under the 32 MiB export limit yet too large for CSE; in that case the sandbox mirror can still be the successful durable target. (Sources: `webgpu-os/kernel/Syscalls.js`, `webgpu-os/kernel/state/AppStateEngine.js`, `webgpu-os/storage/AppSandbox.js`) ## Remaining integration boundaries The following capabilities require additional source paths before the Studio can claim them: - Dispatching a compiled recipe plan into native subsystem configuration. - Native adapters for the 33 currently unmapped preset modes. - Full-field scientific renderers, calibrated probes, and validation against a declared reference method. - A host prediction model that supplies model ID and version provenance. - Native HDR, trails, and solver-connected brush interactions. - Per-stage GPU profiler attribution supplied by measured instrumentation. These boundaries do not remove the current authoring and inspection tools; they define how far the evidence supports each claim. ## See also - [Particle Realms Studio](particle-realms-studio.md) - [Engine Particle System](../engine/particles.md) - [GPU Device Sharing](../concepts/gpu-device-sharing.md) - [WebGPU OS Architecture](architecture.md) --- # Particle Recipe Schema Particle recipes use the strict JSON schema `particle-realms.simulation-recipe.graph` version 1. The graph is an authored, typed description. Compilation produces a deterministic `particle-realms.simulation-recipe.execution-plan` version 1; the plan is not itself a general-purpose runtime. (Source: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`) This page is for app developers and preset authors who create, inspect, or integrate current recipe documents. ## Related schema family The current repository uses a family of bounded documents rather than the design pack's proposed monolithic `particle-realms.simulation-recipe` file: | Document | Current schema/version | | --- | --- | | Persisted project aggregate | `particle-realms.particle-project`, version 2 | | Immutable built-in preset | `particle-realms.particle-preset`, version 1 | | Recipe graph | `particle-realms.simulation-recipe.graph`, version 1 | | Compiled plan description | `particle-realms.simulation-recipe.execution-plan`, version 1 | | Scene sidecar | `particle-realms.scene`, version 1 | | View sidecar | `particle-realms.views`, version 1 | | Artist sidecar | `particle-realms.artist`, version 1 | | Compare sidecar | `particle-realms.compare`, version 1 | | Sensor definition/sample | `particle-realms.sensor.v1` / `particle-realms.sensor-sample.v1` | | Twin project configuration | `particle-realms.twin-configuration`, version 1 | | External study | `particle-realms.external-study`, version 1 | (Sources: `webgpu-os/factory/apps/particles/ParticleProjectCore.js`, `webgpu-os/factory/apps/particles/ParticleLabProject.js`, `webgpu-os/factory/apps/particles/ParticleStudioDocument.js`, `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`, `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`, `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`) Project v2 is the save/load envelope. Its exact top-level fields are `schema`, `version`, `id`, `name`, `sourcePresetId`, `classification`, `tags`, `seed`, `createdAt`, `modifiedAt`, `provenance`, `settings`, `studioDocument`, `recipeGraph`, `sensorDefinitions`, `twinConfiguration`, `externalStudies`, and `quality`. Unknown v2 fields fail validation. Runtime settings are limited to the canonical mode, palette preset, interaction, count, force, size, exposure, pause, camera, trails, bloom, orbit, brush, gravity, drag, turbulence, cohesion, temperature, reaction, charge, and seed keys declared by `DEFAULT_PARTICLE_SETTINGS`. (Source: `webgpu-os/factory/apps/particles/ParticleLabProject.js`) ## Module boundary `ParticleProjectCore.js` owns cycle-free preset construction, setting normalization, seed normalization, and deterministic project hashing. `ParticleRecipeGraph.js` may consume those primitives but never imports the project aggregate. `ParticleLabProject.js` then composes both layers into the strict project-v2 envelope. This dependency direction is required by the classic release bundler, whose eager named-import snapshots cannot emulate ES-module live bindings across a cycle. Project/graph sidecar helpers are exported by `ParticleLabProject.js`: `attachRecipeGraphToParticleProject()`, `recipeGraphFromParticleProject()`, `serializeParticleProjectWithRecipeGraph()`, and `deserializeParticleProjectWithRecipeGraph()`. Callers that previously imported these four helpers from `ParticleRecipeGraph.js` must update only the module path; their document contracts are unchanged. (Sources: `webgpu-os/factory/apps/particles/ParticleProjectCore.js`, `webgpu-os/factory/apps/particles/ParticleLabProject.js`) ## Graph document The normalized document contains schema and version identifiers, graph identity and revision, metadata and provenance, a seed, nodes, edges, and extensions. Node and edge IDs are stable and serialization is canonical even when input arrays arrive in a different order. A graph is limited to 2 MiB, 512 nodes, and 2,048 edges. Unknown graph, node, port, and edge fields are rejected by strict validation. (Source: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`) The supported node families are: - Project/Metadata, World/Units, Domain/Coordinates, Geometry, and Discretization. - Boundary, Material, Substance, Emitter, Initial Condition, Field, Force, Solver, Coupling, Constraint, and Physics Body. - Sensor, Reduction, Visualizer, Camera, View Layout, Timeline, Audio Input, Audio Graph/Patch, Telemetry Input, Data Transform, and Alert/Rule. - External Study and Export/Output. The type system includes `Metadata`, `World`, `Domain`, `Geometry`, `Surface`, `Volume`, `Discretization`, `Scalar`, `Vector`, `Tensor`, `Field2D`, `Field3D`, `ParticleSet`, `SubstanceSet`, `Material`, `BoundaryCondition`, `SolverState`, `PhysicsBody`, `Constraint`, `TimeSeries`, `Event`, `AudioSignal`, `TelemetryStream`, `RenderLayer`, `Camera`, `ExternalStudy`, and `Output`. (Source: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`) ## Validation and compilation Validation checks the schema and version, identifiers, limits, registered node types, port names, edge direction and type compatibility, input cardinality, required inputs, cycles, and declared subsystem availability. Compilation only runs for a valid graph and produces a deterministic topological step list, required-subsystem list, output bindings, source-graph snapshot, graph hash, signature, and aggregate change impact. The plan validator can independently confirm that output against its source graph. (Source: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`) If a current graph is invalid, the compiler may return a separately validated previous plan marked stale. An invalid previous plan is ignored. `ParticleApp` does not apply invalid authored settings to the running simulation. (Sources: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Change impact Every node declares one of these impacts, ordered from least to most invasive: | Impact | Runtime meaning | | --- | --- | | `none` | No runtime mutation is required. | | `authoring-only` | The change is retained as authored metadata. | | `uniform-update` | Mapped live settings may be updated without rebuilding resources. | | `resource-resize` | Size-dependent resources may need replacement. | | `pipeline-specialization` | Shader or pipeline specialization may change. | | `solver-reset-required` | Solver state must be reset. | | `full-graph-rebuild` | The mapped runtime must rebuild from the plan. | The compiler reports impact; the current adapter and app decide which mapped effects they can apply. Unsupported graph families do not become executable merely because they have an impact declaration. (Sources: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`, `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js`) ## Current runtime bindings `adaptParticleRecipeExecutionPlan()` validates the plan before constructing a normalized ParticleApp settings patch and fixed-step clock. These are the implemented bindings: | Plan data | Applied setting or runtime state | | --- | --- | | Graph `seed` | Project seed. | | `extensions.sourceModeId` | Mode when it names a registered Particle preset. | | `discretization.particles.targetCount` | Particle `count`. | | `field.vector.strength` | `force`. | | `initial-condition.state.temperature` | `temperature`. | | `visualizer.native.pointSize` | Point `size`. | | `visualizer.native.exposure` | `exposure`. | | `camera.view.distance` | `cameraDistance`. | | Solver `nativeType: sph` | `fluid` mode. | | Solver `nativeType: n-body` | `nbody` mode. | | Solver `fixedStep` and `substeps` | Fixed simulation clock; fixed step is clamped to 0.000001..1 second and substeps to 1..64. | `particle-runtime`, `sph`, and `n-body` are the adapter's bound solver types. Unsupported solver types produce a warning and retain the current mode. A visualizer other than `point-particles` also produces a warning. Count is normalized against the runtime maximum and the result records any clamp. (Source: `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js`) `ParticleApp` advances the native world using the adapted fixed step and substeps. A clock change resets the native time accumulator so time from the previous clock is not reinterpreted under the new one. (Source: `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Direct-control synchronization Quick and Standard controls remain usable. On save, `synchronizeParticleRecipeGraphSettings()` updates only enabled mapped default nodes: `discretization.main`, `emitter.main`, `field.main`, `visualizer.main`, and `camera.main`, plus the graph seed and `extensions.sourceModeId`. It preserves custom nodes, edges, stable IDs, and provenance, and increments the revision only when normalized graph state changes. (Sources: `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) This representative fragment shows the exact count binding in a default graph. It is a node fragment, not a standalone graph document: ```json { "id": "discretization.main", "type": "discretization.particles", "enabled": true, "parameters": { "targetCount": 150000, "representation": "particles" } } ``` (Source: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`) ## Editing and migration The graph module provides immutable helpers for node, edge, parameter, and enabled-state edits. These source-level APIs support complete graph editing, but the current Recipe workspace presents parameter and enabled-state editing rather than a full graphical node canvas. Version-0 graph documents migrate to version 1; documents from an unknown future version fail instead of being silently reinterpreted. (Sources: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) Project-v1 documents and the legacy `webgpu-os.particles.workspace.v4` settings payload migrate into project v2. Canonical project JSON is limited to 32 MiB; graph JSON is limited to 2 MiB; each external study is limited to 4 MiB. Twin configuration is scanned recursively for credential-like fields, and runtime Twin truth/state is rejected from the persisted project. Unknown future versions fail closed. (Source: `webgpu-os/factory/apps/particles/ParticleLabProject.js`) ## Capability boundary | Status | Recipe capability | | --- | --- | | Implemented | Strict graph validation, canonical serialization, deterministic compilation and plan validation, immutable edits, version-0 migration, last-valid-plan retention, mapped ParticleApp bindings, and direct-control synchronization. | | Partial | Current UI edits the authored graph but is not a complete visual graph editor; execution covers only the table in Current runtime bindings. | | Unsupported | Arbitrary node instantiation, generic subsystem dispatch, audio execution, remote studies/jobs, output publishing, graph collaboration/history, and a standalone runtime recipe player. | ## See also - [Particle Studio Architecture](particle-studio-architecture.md) - [Particle Studio Preset Authoring](particle-studio-preset-authoring.md) - [Particle Studio Test Plan](particle-studio-test-plan.md) - [Particle Studio Integration Map](particle-studio-integration-map.md) --- # Particle Studio Preset Authoring Particle Realms presets are curated source records in `ParticleLabCatalog.js`. The catalog currently contains 40 immutable built-in presets. It is not a user-installable preset marketplace, and importing a project does not register a new global preset. (Sources: `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`, `webgpu-os/factory/apps/particles/ParticleLabProject.js`) This guide is for developers who maintain the built-in catalog and its project and recipe defaults. ## Required preset record Each `PARTICLE_MODES` entry supplies: | Field | Contract | | --- | --- | | `presetId` | Stable, versioned catalog identity. | | `label` and `title` | Short and display names. | | `id` | Stable numeric catalog identity used by projects and discovery. | | `runtimeId` | Numeric custom-solver family ID. Variants may share an audited solver family, while a dedicated solver uses its own ID. | | `previewKind` | Named animated Discover composition. It must visually distinguish the preset rather than reuse a generic particle cloud. | | `category` | One of `cosmic`, `fields`, `matter`, `life`, or `events`. | | `classification` | Exactly `Artistic` or `Educational Model`. | | `tags` | Search and discovery labels. | | `difficulty` and `fidelity` | User-facing complexity and model-fidelity description. | | `systems`, `model`, and `description` | Concise account of the behavior that is actually present. | | `limitations` | Explicit omissions and interpretation limits. | | `macros` | Keys from the shared macro registry. | | `nativeMigration` | Honest native-engine connection status, systems, and note. | | `defaults` | Complete normalized ParticleApp starting settings. | `defineMode()` freezes tags, limitations, defaults, and resolved macro descriptors. Unknown macro keys throw during module evaluation. Keep IDs and `presetId` values stable after release; project provenance depends on them. (Source: `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`) ## Current catalog | Category | Built-in presets | | --- | --- | | Cosmic | Spiral Galaxy, Orbital Clusters, Supernova Shell, Black-Hole Accretion, Comet Storm, Planetary Rings, Pulsar Jets, Globular Star Cluster | | Fields | Quantum Vortex, Curl-Noise Nebula, Magnetosphere, Aurora Curtains, Tornado Field, Lightning Cage, Solar Wind Stream, Gravity Lens, Magnetic Reconnection, Vector Weave | | Matter | Thermal Fountain, Reaction Chamber, Cohesive Fluid, Molecular Lattice, Ocean Waves, Waterfall Canyon, Lava Flow, Crystal Growth, Smoke Chamber | | Life | Strange Attractor, Flocking Ribbons, Jellyfish Bloom, Firefly Swarm, Mycelium Growth, Plankton Current, Neural Pulse Web | | Events | Event Fireworks, Meteor Shower, Rainstorm, Snow Globe, Sandstorm Wall, Geyser Burst | The classification is intentionally conservative and declared independently on every record. A title alone must never imply a solver that the model does not implement. For example, Quantum Vortex explicitly states that its name is thematic rather than a quantum-fluid solve, while Ocean Waves identifies its layered procedural wave sheet and its non-CFD limitation. (Source: `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`) ## Macro controls Authors select controls from a shared registry rather than defining ad hoc UI ranges inside a preset: | Key | Range | Unit | | --- | --- | --- | | `count` | 1,000..10,000,000, integer step 1,000 | particles | | `force` | 0.1..4 | relative | | `size` | 0.35..8 | px | | `exposure` | 0.35..3 | EV | | `gravity` | -3..3 | relative | | `drag` | 0.94..1 | ratio | | `turbulence` | 0..4 | relative | | `cohesion` | 0..4 | relative | | `temperature` | 50..15,000 | K | | `reactionRate` | 0..3 | relative | | `charge` | -3..3 | relative | | `trailPersistence` | 0.7..0.98 | ratio | | `bloom` | 0..2 | relative | | `autoOrbit` | 0..1 | speed | Use the shared label, type, minimum, maximum, step, and unit exactly. The runtime normalizer remains authoritative and may clamp against device or app limits. A physical-looking unit on one control does not make the entire model calibrated. (Sources: `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`, `webgpu-os/factory/apps/particles/ParticleLabProject.js`) ## Defaults and reproducibility Defaults should form a complete, finite settings patch accepted by the project normalizer. Preserve a fixed seed in derived project fixtures when a visual or behavioral comparison must be repeatable. Count affects allocation and native eligibility; do not use a large default merely to make the preset look dense. Camera distance, palette, exposure, size, and optional trails should produce a legible first frame without hiding the model's limitations. (Sources: `webgpu-os/factory/apps/particles/ParticleLabProject.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Model and limitation text A useful preset description answers four separate questions: 1. What algorithm or approximation moves the particles? 2. Which controls have meaningful effects in that implementation? 3. Which familiar physical process is only suggested visually? 4. Which conclusions must not be drawn from the result? Do not call procedural curl noise CFD, a global cohesion field SPH, a thematic vortex quantum physics, or a rule-based color change molecular kinetics. The existing catalog follows this separation in every `model` and `limitations` record. (Source: `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`) ## Native-engine status `nativeMigration.status` is descriptive runtime truth: | Status | Current presets | | --- | --- | | `runtime-connected-with-fallback` | Spiral Galaxy, Flocking Ribbons, Magnetosphere, Reaction Chamber, Cohesive Fluid, Molecular Lattice, Orbital Clusters | | `available-not-connected` | The other 33 presets, including the 25 authored variants and the eight original custom-model presets. | Connected presets map to audited native systems on compatible devices and retain a fallback path. The status does not mean both paths are numerically equivalent. `technologySummary()` reports the current connection and its limitations; update the status only when the active app path is actually wired and verified. (Sources: `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`, `webgpu-os/factory/apps/particles/ParticleNativeState.js`) ## Recipe and project generation `createParticleProject()` creates a project-v2 document from a catalog preset, including its provenance, normalized settings, default Studio document, and default typed recipe graph. `remixParticleProject()` creates a derived project without mutating the frozen source preset. Mapped direct controls synchronize default graph nodes, while custom and unsupported nodes remain authored. (Sources: `webgpu-os/factory/apps/particles/ParticleLabProject.js`, `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`, `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js`) ## Author review checklist - Use a new stable `presetId` and an unused numeric catalog `id`. - Reuse an audited `runtimeId` only when the model and limitations truthfully match that solver family; otherwise add and verify a dedicated runtime branch. - Give every preset a distinct `previewKind` and review its animated card. - Select an existing category and an exact supported classification. - Reuse only registered macro keys and keep defaults inside their ranges. - State the implemented model and at least one concrete limitation. - Name only engine systems that exist and report their actual connection status. - Verify creation, normalization, serialization, remix provenance, recipe compilation, both available runtime paths, and recovery behavior. - Confirm all user-facing claims remain true at low and high supported counts. The checked-in browser suites are the source of executable coverage; visual review supplements them but does not replace schema and runtime tests. (See `tests/particle-project-v2.html`, `tests/particle-recipe-graph.html`, and the native particle integration tests under `tests/`.) ## Capability boundary | Status | Preset capability | | --- | --- | | Implemented | Immutable 40-preset catalog, categories, distinct animated previews, search metadata, truthful classifications, shared macros, defaults, limitations, project/remix creation, and native connection metadata. | | Partial | Seven presets have native runtime mappings; other presets run the custom model or recovery path. | | Unsupported | Runtime installation of third-party catalog presets, preset marketplace, arbitrary preset scripts, and a claim that native and custom paths are numerically identical. | ## See also - [Particle Studio User Guide](particle-studio-user-guide.md) - [Particle Recipe Schema](particle-recipe-schema.md) - [Particle Studio Fidelity and Validation](particle-studio-fidelity-and-validation.md) - [Particle Studio Test Plan](particle-studio-test-plan.md) --- # Particle Studio Fidelity and Validation Particle Realms Studio separates an attractive interactive result from a validated result. A functioning GPU path, deterministic seed, high particle count, smooth frame rate, or imported reference file does not establish physical accuracy. Claims must be supported by the implemented model and explicit evidence. (Sources: `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`, `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`) This page is for users and reviewers who decide what a Studio result can and cannot support. ## Interpretation labels | Label or state | Meaning in the current product | | --- | --- | | `Artistic` | The preset prioritizes composition and motion. Physical names may be thematic. | | `Educational Model` | The preset demonstrates a concept with explicit approximations and omissions. | | `runtime-connected-with-fallback` | A compatible device may use mapped engine systems; another path remains available. | | `available-not-connected` | A relevant engine system exists, but the preset is not wired to it in the app. | | External `unvalidated` | Imported data has no review claim. | | External `reference` | Data is retained as a comparison reference. | | External `reviewed` | Review is asserted in the imported provenance. | | External `validated` | The study supplies reviewer, solver, and solver-version provenance. It still does not validate Studio automatically. | (Sources: `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`, `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`) ## Runtime-path fidelity The native path and custom WGSL path are different implementations. Seven preset modes can map to native engine systems on compatible devices. Other modes use the custom visual model. The Canvas 2D path is a generic recovery preview. Backend status therefore belongs in every reproducibility record. (Sources: `webgpu-os/factory/apps/particles/ParticleNativeState.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) Native rendering binds the engine world's position buffer directly, while CPU-side views use a bounded readback prefix. The direct renderer proves that the displayed positions came from the native world; it does not prove that the world is calibrated. The Create secondary views are projections of one compact sample, not full-resolution solution fields. (Sources: `webgpu-os/factory/apps/particles/ParticleNativeRenderer.js`, `webgpu-os/factory/apps/particles/ParticleNativeRuntime.js`, `webgpu-os/factory/apps/particles/ParticleMultiViewRuntime.js`) ## Evidence classes Keep these records distinct: | Evidence | Required provenance | Permitted conclusion | | --- | --- | --- | | Runtime telemetry | Supplied timestamp and measured metric | Runtime behavior for the recorded session. | | Sensor sample | Sensor ID, quantity, unit, source ID, sequence, timestamp, quality, and origin | The accepted measurement represented by that definition. | | Compact reduction | Explicit finite values and, for integrals, explicit weights | The stated reduction over the supplied compact input. | | External study | Source, author, solver/version, coordinate system, units, review metadata, assumptions, and limitations as applicable | Comparison to that imported reference. | Missing measurements remain missing. Profiler stages remain empty until the host supplies them. Compatibility-only prediction modules are not part of the current six-workspace Studio. (Sources: `webgpu-os/factory/apps/particles/ParticleLabTelemetry.js`, `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`, `webgpu-os/factory/apps/particles/ParticleQualityGovernor.js`) ## External-study boundary Every normalized study sets `validatesNativePreview` to `false`; validation rejects any other value. A study marked `validated` must name a reviewer, solver, and solver version, but this describes the study's provenance only. An unspecified coordinate system disables spatial-overlay claims. The current Compare workspace matches measured and external series by exact quantity and unit and displays an index-aligned comparison. (Sources: `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) The current implementation does not perform time interpolation, coordinate registration, mesh conversion, uncertainty propagation, norm computation, full-field comparison, or automatic pass/fail acceptance. Do those operations in a reviewed external workflow before claiming validation. ## Reproducible comparison record For a meaningful review, retain at least: - project JSON, project schema version, preset ID, classification, and provenance; - recipe graph and compiled graph signature; - seed, supported mapped recipe settings, fixed step, and substeps; - selected backend, browser/device information, granted limits, and quality profile; - sensor definitions and exported samples with units and quality; - external-study source, solver/version, coordinate system, assumptions, limitations, and reviewer metadata; - the metric, alignment rule, tolerance, and decision made outside Studio. Studio already persists or exports many of these records, but it does not assemble a certification package or choose scientific tolerances. (Sources: `webgpu-os/factory/apps/particles/ParticleLabProject.js`, `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`, `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`, `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`) ## Determinism boundary Project seeds, canonical graph ordering, stable plan signatures, and fixed-step recipe clock values support repeatable authored intent. They do not guarantee bit-identical output across every GPU, browser, runtime path, or floating-point implementation. The quality governor can also change secondary-view and post-processing policy during automatic operation. (Sources: `webgpu-os/factory/apps/particles/ParticleRecipeGraph.js`, `webgpu-os/factory/apps/particles/ParticleRecipeRuntimeAdapter.js`, `webgpu-os/factory/apps/particles/ParticleStudioDocument.js`, `webgpu-os/factory/apps/particles/ParticleQualityGovernor.js`) ## Engineering-use gate Do not use the interactive preview for safety, design certification, control decisions, or engineering predictions unless an external process has verified all of the following: 1. The executed equations, boundaries, material properties, units, and initial conditions match the intended problem. 2. The active runtime path is the one that was reviewed. 3. Grid or particle convergence, time-step sensitivity, and conservation or stability checks are appropriate and pass. 4. Measurements are complete, calibrated, and traceable. 5. Comparison alignment and uncertainty are documented. 6. Independent reference results and acceptance tolerances are reviewed. Studio currently provides no certification workflow and no calibrated probe chain. Preset limitations remain the controlling interpretation when these conditions have not been met. ## Capability boundary | Status | Fidelity or validation capability | | --- | --- | | Implemented | Honest demo classifications and limitations, backend reporting, provenance-bearing measurements, explicit missing data, and bounded external-study validation levels. | | Partial | Deterministic authored graph and clock state support repeatable studies; external comparison is compatible-series and index aligned only. | | Unsupported | Automatic validation transfer, full-field overlays, uncertainty propagation, calibrated probes, solver verification/certification, hard scientific performance claims, and guaranteed cross-device bitwise determinism. | ## See also - [Particle Studio External Studies](particle-studio-external-studies.md) - [Particle Studio Telemetry](particle-studio-telemetry.md) - [Particle Studio Preset Authoring](particle-studio-preset-authoring.md) - [Particle Studio Test Plan](particle-studio-test-plan.md) - [Particle Studio Integration Map](particle-studio-integration-map.md) --- # Particle Studio Telemetry Particle Realms Studio accepts measured values; it does not generate missing measurements. Runtime metrics, sensor evidence, and external references use separate contracts so derived values cannot silently become canonical truth. (Sources: `webgpu-os/factory/apps/particles/ParticleLabTelemetry.js`, `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`) This page is for integrators and users who ingest, export, or interpret current Studio measurements. ## Runtime telemetry `ParticleLabTelemetry` accepts a sample only when it has a finite, non-negative timestamp and at least one finite, non-negative supported metric. Its default history is 120 samples; configured limits are clamped to 1..10,000. Integer metrics are rounded and absent metrics remain absent. (Source: `webgpu-os/factory/apps/particles/ParticleLabTelemetry.js`) | Metric | Meaning | Value handling | | --- | --- | --- | | `fps` | Observed frames per second | Finite, non-negative number. | | `frameMs` | Observed frame duration | Finite, non-negative milliseconds. | | `submitMs` | Measured queue-submit duration | Recorded only when supplied. | | `gpuMs` | Measured GPU duration | Recorded only when supplied. | | `particleCount` | Active particle count | Rounded non-negative integer. | | `particleBytes` | Allocated particle bytes | Rounded non-negative integer. | Each metric can be exported as timestamp/value points. Summaries report count, latest, minimum, maximum, average, and p95; an unsampled metric has a `null` summary. Studio records an app runtime sample at an approximately 500 ms cadence when those observations are available. (Sources: `webgpu-os/factory/apps/particles/ParticleLabTelemetry.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Sensor definitions Sensor definitions use schema `particle-realms.sensor.v1`. A definition has a stable ID, sensor type, quantity, unit, source ID, sampling rate, reduction, value type, and stale policy. The runtime supports up to 4,096 definitions (default 256) and 1..10,000 samples per sensor (default 600). (Source: `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`) | Contract | Supported values | | --- | --- | | Sensor type | `point`, `line`, `plane`, `surface`, `region-average`, `region-integral`, `min-max`, `histogram`, `particle-count`, `compact-stream`, `performance` | | Reduction | `latest`, `mean`, `sum`, `integral`, `min`, `max`, `min-max`, `histogram`, `count`, `rms` | | Value type | `scalar`, `vector2`, `vector3`, `vector4`, `range`, `histogram` | | Data quality | `good`, `uncertain`, `stale`, `missing`, `substituted`, `outlier`, `invalid` | Sampling rates are bounded to 0.001..1,000 Hz. Validation checks that the selected reduction and value type are compatible and that IDs remain unique. (Source: `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`) ## Sensor samples and provenance Samples use schema `particle-realms.sensor-sample.v1`. Validation requires the sample's sensor ID, quantity, unit, and source provenance to match its definition. Sequence and timestamp must remain monotonic. Normal samples carry a value; only `missing` and `invalid` quality permit a null value. The origin identifies an ingested or compact-reduction source. (Source: `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`) Staleness is calculated from the latest timestamp and the definition's stale policy. It does not rewrite the recorded sample's original quality or value. Rejected samples increment a diagnostic count rather than being repaired into apparently valid measurements. ## Compact reductions The reducer accepts at most 65,536 explicit finite values. It implements the supported scalar reductions over that supplied input. An integral requires explicit weights; the module does not guess cell size, area, volume, or time spacing. Histogram output is bounded and explicit. (Source: `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`) This is a data-contract and compact-reduction seam. It does not locate probes in a solver, read arbitrary GPU fields, schedule a GPU reduction pass, or calibrate a sensor. A host must supply the measured compact values and their provenance. ## Analyze and export The Analyze workspace displays registered definitions, accepted series, latest values, quality, origin, rejection count, and bounded diagnostics. JSON and CSV exports are sorted and retain provenance. Runtime metrics are projected into predefined performance-sensor samples only when the corresponding metric was supplied. Missing sources remain empty. (Sources: `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`, `webgpu-os/factory/apps/particles/ParticleSensorRuntime.js`) ## Stage attribution and adaptive quality `ParticleProfilerAttribution` accepts only explicitly supplied timing for `solver`, `sensor`, `view`, `post`, `preview`, and `readback` stages. Analyze shows an empty row until a host supplies that stage; it does not divide frame time heuristically. The quality governor separately uses observed `frameMs` windows and authored policy to select Economy, Interactive, High, or Cinematic behavior. (Sources: `webgpu-os/factory/apps/particles/ParticleQualityGovernor.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) ## Legacy Twin runtime compatibility `ParticleTwinRuntime` can maintain an append-only measured-truth history from accepted sensor samples. Checkpoints reference historical truth for replay. What-if branches are isolated from truth, and predicted records require a model ID and version. Deterministic alert rules operate on accepted values; confidence remains unestimated unless an external model supplies it. Acknowledgement requires an actor. (Source: `webgpu-os/factory/apps/particles/ParticleTwinRuntime.js`) This module is retained for project and integration compatibility. The current six-stage Studio exposes no Twin workspace and does not attach WebSocket, REST, server-sent events, MQTT, industrial protocol, or other live transport. No built-in prediction model or telemetry-to-solver actuation path is present. (Sources: `webgpu-os/factory/apps/particles/ParticleTwinRuntime.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) The project persists only disconnected-safe Twin configuration and alert rules. Credential-like configuration keys are rejected. Runtime truth, checkpoints, branches, connector state, predictions, and acknowledgements are process-local runtime state rather than project-v2 content. (Source: `webgpu-os/factory/apps/particles/ParticleLabProject.js`) ## Capability boundary | Status | Telemetry capability | | --- | --- | | Implemented | Bounded measured runtime metrics, strict sensor definitions and samples, compact reductions, explicit data quality, JSON/CSV export, and supplied stage attribution. | | Partial | ParticleApp metrics populate performance sensors; other solver quantities require a host measurement/reduction integration. The legacy Twin runtime remains independently testable but is not a workspace. | | Unsupported | Fabricated gap filling, live transport, automatic GPU probe pipelines, calibrated sensors, full-field capture, and telemetry actuation. | ## See also - [Particle Studio User Guide](particle-studio-user-guide.md) - [Particle Studio Fidelity and Validation](particle-studio-fidelity-and-validation.md) - [Particle Studio Performance](particle-studio-performance.md) - [Particle Studio External Studies](particle-studio-external-studies.md) - [Particle Studio Integration Map](particle-studio-integration-map.md) --- # Particle Studio External Studies Particle Studio can retain and compare bounded local scalar-series studies in CSV or JSON. An external study is reference evidence with its own provenance; it never automatically validates the active native or custom preview. (Source: `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`) This page is for users and reviewers who prepare and interpret local external study imports. ## Schema and limits The canonical schema is `particle-realms.external-study` version 1. A project may retain up to eight studies in canonical ID order. Each imported document is limited to 4 MiB, each study to 64 series, and each series to 100,000 finite samples. (Sources: `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`, `webgpu-os/factory/apps/particles/ParticleLabProject.js`) | Field | Purpose | | --- | --- | | `id`, `name` | Stable study identity and display name. | | `solver`, `solverVersion` | Producer provenance. | | `coordinateSystem` | Declared spatial frame or `unspecified`. | | `units` | Optional quantity-to-unit metadata. | | `source`, `author`, `reviewedBy` | Origin and review provenance. | | `validation` | `unvalidated`, `reference`, `reviewed`, or `validated`. | | `assumptions`, `limitations` | Explicit interpretation constraints. | | `importedAt` | Canonical import timestamp. | | `series` | Quantity, unit, and finite scalar samples. | | `validatesNativePreview` | Always `false`. | Every series has a stable ID, label, quantity, unit, and samples. A sample has an index, numeric time, finite value, optional canonical timestamp, and quality label. (Source: `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`) ## CSV format CSV requires one header row and at least one data row. A `time` or `timestamp` column is recognized case-insensitively. Other headers may declare a unit as `quantity [unit]`; without brackets, the unit defaults to `1`. Quoted fields and doubled quotes are supported. Non-finite value cells are skipped. (Source: `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`) ```csv time,frame duration [ms],active particle count [count] 0.0,8.4,100000 0.5,8.7,100000 1.0,8.5,100000 ``` Numeric time values are stored as time. Non-numeric time text is parsed as a timestamp when possible. If there is no time column, row order supplies time indices. CSV import options may add the study name, solver/version, coordinate system, source, author, review metadata, assumptions, and limitations. ## JSON format JSON may already use the canonical schema. For compatible object input without the schema marker, the parser supplies the current schema/version and forces `validatesNativePreview: false` before validation. The document must contain at least one series with at least one finite sample. Serialization validates the study before writing canonical JSON. (Source: `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`) ## Provenance and validation levels Validation requires an explicit supported level and rejects any claim that the study validates the native preview. A study marked `validated` must include a reviewer, a named solver, and a solver version. This validates the imported record's minimum provenance requirements only; it does not review equations, mesh, convergence, calibration, or compatibility with the Studio model. (Source: `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`) An unspecified coordinate system produces a warning and disables any spatial-overlay interpretation. The current UI performs time-series comparison only, so even a specified coordinate system does not activate a 3D overlay. ## Import workflow 1. In **Compare**, select a local CSV or JSON document. 2. Studio parses and normalizes the document within the import bounds. 3. Validation errors stop the import; warnings remain visible context. 4. A study with the same ID replaces the retained copy; otherwise it is added subject to the eight-study project limit. 5. Saving the project persists the normalized study as project-v2 content. The UI labels every retained study as not validating the native preview and logs the local import. (Sources: `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`, `webgpu-os/factory/apps/particles/ParticleLabProject.js`) ## Comparison semantics The Compare workspace selects a measured sensor series only when its quantity and unit exactly match an external series. `compareExternalSeries()` compares up to the shorter series length by array index and reports baseline, external, delta, and ratio. A zero baseline produces a null ratio. The helper reports whether units are equal, but callers must enforce compatibility; the Studio UI does so before comparison. (Sources: `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`) This comparison does not interpolate time, align timestamps, convert units, transform coordinate systems, propagate uncertainty, or compute spatial error norms. Array-index alignment is suitable only when the reviewer has established that the records correspond. ## Security and interpretation Imports are text-only, bounded, parsed locally, normalized to finite scalar series, and stored as data. The current path does not execute scripts or send a job to the named solver. Source and author fields are provenance strings, not authenticated identities. Review metadata should therefore be verified outside Studio when it matters. (Sources: `webgpu-os/factory/apps/particles/ParticleExternalStudy.js`, `webgpu-os/factory/apps/particles/ParticleLabProject.js`) ## Capability boundary | Status | External-study capability | | --- | --- | | Implemented | Bounded local CSV/JSON scalar-series import, canonical schema and serialization, provenance fields, four validation levels, project persistence, compatible quantity/unit selection, and index-aligned delta/ratio. | | Partial | Coordinate-system provenance is retained, but no spatial comparison is rendered; validation levels record provenance rather than certify model equivalence. | | Unsupported | Remote job submission or status, commercial-solver adapter, geometry/boundary export, meshes, surface or volume fields, particle/pathline imports, spatial overlays, coordinate transforms, unit conversion, time interpolation, and automatic validation transfer. | ## See also - [Particle Studio Fidelity and Validation](particle-studio-fidelity-and-validation.md) - [Particle Studio Telemetry](particle-studio-telemetry.md) - [Particle Studio User Guide](particle-studio-user-guide.md) - [Particle Studio Test Plan](particle-studio-test-plan.md) --- # Particle Studio Performance Particle Realms Studio chooses a runtime from granted browser and device capabilities. Particle count alone is not a performance guarantee, and no single frame-rate claim applies across modes, GPUs, browsers, display sizes, or quality profiles. Report measured results together with their runtime path and configuration. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/shared/GpuLabRuntime.js`) This page is for developers and reviewers who tune Studio or publish measured performance results. ## Runtime tiers | Tier | Selection | Performance boundary | | --- | --- | --- | | Native engine | Mapped mode, eligible count, required exports, known device limits, and at least ten storage buffers per shader stage. | Steps `ParticleSimWorld` systems and renders the borrowed native position buffer. | | Custom WGSL | WebGPU is available but the native mapping, eligibility, or native limit is unavailable. | Runs the preset's lightweight app model with an app-owned HDR pipeline. | | Canvas 2D recovery | WebGPU initialization or recovery is unavailable. | Draws 5,000 generic points for continuity; the selected model is inactive. | The app first considers an OS-shared GPU device. If native eligibility needs a limit the shared device lacks, it may request a dedicated device for the app's WebGPU fallback. A shared device is never destroyed by the app. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/shared/GpuLabRuntime.js`) ## Native eligibility and ceilings The seven native-mapped modes are Galaxy and Orbital Clusters (`n-body`), Flocking Ribbons (`flocking`), Cohesive Fluid (`sph`), Reaction Chamber (`chemistry`), Magnetosphere (`electromagnetic`), and Molecular Lattice (`lennard-jones`). Native CPU seed-state creation has a one-million-particle hard bound. N-body profiles declare a 100,000-state bound, while the interactive app further caps Galaxy and Orbital Clusters native selection at 10,000 because their current pairwise solve is expensive. All bounds remain subject to the granted device limits. (Sources: `webgpu-os/factory/apps/particles/ParticleNativeState.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) Other catalog modes are not native-connected and use the custom WGSL path. The catalog macro permits counts up to ten million, but project normalization and the tier selector clamp to the active runtime's recommended maximum. (Sources: `webgpu-os/factory/apps/particles/ParticleLabCatalog.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) ## GPU limits and ownership `ParticleNativeRuntime` derives its hard maximum from granted storage-buffer, buffer-size, dispatch, and workgroup limits and requires `maxStorageBuffersPerShaderStage >= 10`. Initialization fails closed when required native exports, limits, buffers, or configuration are invalid. (Source: `webgpu-os/factory/apps/particles/ParticleNativeRuntime.js`) The native runtime owns its `ParticleSimWorld` and readback staging buffers. The native renderer owns its pipelines, bind groups, and uniforms but borrows the world's position buffer. Teardown drains pending readback, destroys owned world and renderer resources, and leaves a borrowed shared `GPUDevice` alive. (Sources: `webgpu-os/factory/apps/particles/ParticleNativeRuntime.js`, `webgpu-os/factory/apps/particles/ParticleNativeRenderer.js`) ## Direct rendering and readback Native presentation binds one 16-byte `vec4` position record per particle and renders additive LDR billboards without copying positions into a second app simulation buffer. The renderer reports no HDR or trail capability. The custom path instead stores 48 bytes of particle state and uses the app's HDR compute/render/tone pipeline. (Sources: `webgpu-os/factory/apps/particles/ParticleNativeRenderer.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) Advanced workspaces request a native sample no more often than every 500 ms in Create, Analyze, or Compare. Each automatic sample is capped at 4,096 particles; each requested vector stream allocates exactly count × 16 bytes. The result is labeled `native-readback` and reports truncation. This is bounded inspection, not full particle-state readback. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleNativeRuntime.js`) ## Quality profiles | Profile | View scale | View rate | Max secondary views | Sensor-rate scale | Trails | Post quality | | --- | ---: | ---: | ---: | ---: | --- | ---: | | Economy | 0.5 | 5 Hz | 1 | 0.5 | off | 0.35 | | Interactive | 0.7 | 15 Hz | 3 | 1 | on | 0.7 | | High | 1 | 30 Hz | 5 | 1 | on | 1 | | Cinematic | 1 | 60 Hz | 7 | 1 | on | 1.25 | The current advanced UI applies the maximum-secondary-view policy and optional view quality behavior. Not every profile field controls every native/custom solver or renderer feature yet. In particular, the native renderer reports no trails even when the authored profile permits them. (Sources: `webgpu-os/factory/apps/particles/ParticleQualityGovernor.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`, `webgpu-os/factory/apps/particles/ParticleNativeRenderer.js`) Automatic quality uses a 45-sample frame window by default, at least 15 samples before a decision, a two-second cooldown, and separate degrade and upgrade thresholds around a 4..100 ms target. It changes one profile at a time. Critical memory pressure selects Economy; moderate pressure caps the profile at Interactive. Studio currently has the pressure API but no complete automatic OS memory-pressure feed. (Source: `webgpu-os/factory/apps/particles/ParticleQualityGovernor.js`) ## Measurements and attribution The app records observed FPS, frame duration, queue-submit duration, measured GPU duration when supplied, particle count, and allocated particle bytes at an approximately 500 ms reporting cadence. History is bounded and missing values remain missing. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleLabTelemetry.js`) Stage attribution accepts explicit `solver`, `sensor`, `view`, `post`, `preview`, and `readback` timings. It does not infer a decomposition from total frame time. Until instrumentation supplies a stage, its summary remains empty. (Source: `webgpu-os/factory/apps/particles/ParticleQualityGovernor.js`) ## Device loss and recovery Device loss logs the reason, destroys GPU-owned state, preserves the authored project, activates the generic Canvas 2D recovery preview, and exposes retry. Recovery mode should be reported as a different runtime, never as an equivalent performance result for the selected model. (Source: `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Performance report checklist Record the browser and version, OS, GPU/driver, display and canvas size, device kind (shared or dedicated), granted limits, preset and seed, recipe signature, runtime backend, particle count, fixed step/substeps, quality profile, sample duration, warm-up, FPS/frame-time distribution, submit/GPU measurements when available, memory estimate, readback activity, and any device loss or fallback. Compare like-for-like runs and publish raw samples with the summary. Avoid marketing a best frame as sustained performance. ## Capability boundary | Status | Performance capability | | --- | --- | | Implemented | Capability-based runtime selection, strict native limits, shared-device ownership, direct native position rendering, bounded readback, measured runtime telemetry, four quality profiles, hysteresis/cooldown, and device-loss recovery. | | Partial | Quality policy currently governs optional views more completely than solver/render state; memory-pressure handling requires a caller; profiler stages require supplied measurements. | | Unsupported | Universal hardware claims, complete pass/draw/dispatch attribution, automatic benchmark matrix, full-state chart readback, performance-equivalent recovery preview, and guaranteed allocation-free playback without measurement. | ## See also - [Particle Studio Architecture](particle-studio-architecture.md) - [Particle Studio Telemetry](particle-studio-telemetry.md) - [Particle Studio Test Plan](particle-studio-test-plan.md) - [Particle Studio Fidelity and Validation](particle-studio-fidelity-and-validation.md) --- # Particle Studio Test Plan This plan verifies current repository behavior and records gaps against the broader Simulation Studio design pack. Passing structural and runtime tests does not establish scientific validity or performance on hardware that was not measured. This page is for developers and release reviewers who need repeatable coverage and explicit acceptance-test gaps. ## Evidence levels | Level | Evidence | | --- | --- | | Contract | Pure validation, normalization, migration, serialization, and deterministic helper checks. | | Browser integration | DOM, controller, persistence seam, and fallback behavior in a served ES-module page. | | Real WebGPU | Pipeline creation or real engine world execution on an actual granted `GPUDevice`. | | Manual UX | Keyboard, focus, responsive layout, warning semantics, reduced motion, and recovery observation. | | Scientific validation | Independent equation, convergence, calibration, uncertainty, and reference review. Not supplied by current tests. | All browser pages must be served over HTTP. Start the repository server with the repository command, then open the relevant test route under `http://127.0.0.1:9001/`. (Source: `AGENTS.md`) ```bash python start_server.py ``` ## Automated inventory | Suite | Current scope | | --- | --- | | `tests/particle-project-v2.html` | 29 project-v2 creation, deterministic serialization, migration, strict-field, Studio-sidecar, sensor, Twin, external-study, quality, and round-trip cases. | | `tests/particle-recipe-graph.html` | 28 graph registry, type, topology, validation, deterministic compile, impact, migration, last-valid, runtime-adapter, direct-sync, and observability cases. | | `webgpu-os/factory/apps/particles/tests/particle-studio-advanced-controller.html` | 36 checks covering the four current advanced workspaces, visual Recipe add/connect/remove/recovery behavior, measured preview, compatibility-only Artist/Twin controller contracts, canonical edits, bounded samples, external import, overflow, and ownership. | | `webgpu-os/factory/apps/particles/tests/particle-runtime-tests.html` | Browser harness for sensor and Twin runtime unit modules. | | `webgpu-os/factory/testing/smoke/particle-studio-advanced.html` | 20 advanced-domain checks including automatic count pressure, headroom, quantization, and hardware-ceiling decisions. | | `webgpu-os/factory/testing/smoke/particle-camera-views.html` | Focused home-camera, stratified readback, projection aspect-ratio, render, and sample-provenance checks. | | `webgpu-os/factory/apps/particles/tests/ParticleSensorRuntime.test.js` | Definition, sample, quality, reduction, export, and provenance contracts. | | `webgpu-os/factory/apps/particles/tests/ParticleTwinRuntime.test.js` | Connector state, append-only truth, replay, branches, predictions, and alerts. | | `webgpu-os/factory/testing/smoke/particle-native-state.html` | Deterministic native state generation and mapped-mode contracts. | | `webgpu-os/factory/testing/smoke/particle-native-runtime.html` | Native discovery, limits, world lifecycle, stepping, bounded readback, and teardown. | | `webgpu-os/factory/testing/smoke/particle-native-renderer.html` | Borrowed-buffer validation, rendering, ownership, and teardown. | | `webgpu-os/factory/testing/smoke/particle-sim-world-regressions.html` | Engine-world regressions used by the app's native path. | | `webgpu-os/factory/apps/particles/tests/particle-app-native-integration.html` | 22 real-device checks covering native selection, closed-by-default tuning, automatic population UI and reallocation, recipe mapping, invalid-plan retention, fixed clock, readback, layout, and unmount ownership. | | `tests/particle-runtime-compile-smoke.html` | Fourteen real-WebGPU render/compute pipeline compile checks for exported particle shaders. | (Sources: the listed test files.) ## Core contract gate Run the project, recipe, sensor, and compatibility Twin suites and require zero failures. Confirm these negative paths explicitly: - unknown project-v2, settings, Studio-sidecar, graph, node, port, and edge fields fail closed; - future project and graph versions fail closed; - project-v1, graph-v0, and legacy workspace-v4 compatible inputs migrate deterministically; - duplicate IDs, cycles, incompatible ports, cardinality violations, missing required inputs, and unavailable required subsystems report exact errors; - a tampered previous plan is rejected and an invalid current graph cannot replace the live settings; - credentials and Twin runtime truth cannot enter the project document; - external studies cannot claim to validate the native preview; - missing measurements remain missing and integral reduction requires weights. (Sources: `tests/particle-project-v2.html`, `tests/particle-recipe-graph.html`, `webgpu-os/factory/apps/particles/tests/ParticleSensorRuntime.test.js`, `webgpu-os/factory/apps/particles/tests/ParticleTwinRuntime.test.js`) ## Recipe-runtime gate Verify both pure and app-integrated behavior: 1. The compiled plan validates against its source graph and has a stable signature and topological order. 2. Seed, count, force, temperature, point size, exposure, camera distance, supported solver type, fixed step, and substeps apply through the adapter. 3. An unsupported solver or visualizer reports a warning and retains safe runtime state. 4. Direct controls update only mapped enabled default nodes and preserve custom topology, IDs, provenance, and source immutability. 5. Uniform changes preserve the native world; resize or rebuild impacts follow the app policy. 6. A fixed-step/substep change resets accumulated native time and requests one solver rebuild. 7. An invalid recipe preserves the complete last-valid project and settings. 8. The visual builder can add, connect, disconnect, position, and remove typed parts through canonical graph helpers. 9. A disconnected required part remains visible with exact diagnostics and a stale last-valid plan, then commits only after repair. 10. The embedded preview accepts only explicitly native bounded samples and opens the shared Simulate workspace for the full live view. (Sources: `tests/particle-recipe-graph.html`, `webgpu-os/factory/apps/particles/tests/particle-app-native-integration.html`) ## GPU and lifecycle matrix Exercise at least these environments: | Environment | Expected result | | --- | --- | | WebGPU, mapped mode, sufficient limits | Native runtime and direct renderer become ready. | | WebGPU, mapped mode, fewer than ten storage buffers per stage | Native path is deferred; supported custom WGSL path remains usable. | | WebGPU, unmapped mode | Custom WGSL path runs and backend labeling is accurate. | | No WebGPU or failed initialization | Generic Canvas 2D recovery preview is labeled selected-model inactive. | | OS-shared device | App teardown leaves the borrowed device alive. | | Dedicated device | App teardown releases app-owned GPU resources. | | Device loss | Authored project survives, recovery preview appears, and retry is exposed. | For every native mapped mode, validate finite deterministic seed arrays, exact required attributes, granted maximums, one solver step, direct position-buffer binding, a bounded sample, busy-readback handling, and idempotent destruction. (Sources: `webgpu-os/factory/apps/particles/ParticleNativeState.js`, `webgpu-os/factory/apps/particles/ParticleNativeRuntime.js`, `webgpu-os/factory/apps/particles/ParticleNativeRenderer.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Manual UX and accessibility gate - At 660 × 480 and representative larger containers, confirm no advanced root has horizontal overflow and the main canvas remains usable. - Use keyboard only to traverse all six workspace tabs, open and close the tuning drawer, activate primary actions, edit Recipe controls, import a local study, and export measured data. - Confirm Simulate and Advanced detail entry keep tuning closed; the Tuning action and `B` shortcut open it explicitly and focus remains trapped/restored. - Confirm no particle count, maximum, or cap input exists. Sustained low cadence must reduce the automatic population once, sustained headroom must grow it, and runtime/device safety ceilings must remain enforced internally. - Switch among Perspective, Top, and Density. Confirm preset changes and Home restore the selected preset's complete camera, Top and Density preserve world aspect ratio, fixed projections do not change the hidden orbit camera, and returning to Perspective re-enables Home. - At narrow and wide sizes, confirm Recipe fills its workspace, graph overflow stays inside the graph scroller, controls wrap without root overflow, and the measured-preview label remains visible. - Confirm focus enters the drawer and returns to its opener; status changes are announced; warnings contain text or icons in addition to color. - With reduced motion enabled, confirm the tuning transition is disabled. - Play and Remix a preset without opening Recipe; Reveal Recipe then exposes exact validation and adapter-bound status. - Confirm backend, classification, limitation, missing/stale, external, historical replay, and predicted labels remain visible at narrow widths. - Import malformed, oversized, future-version, credential-bearing, and validation-claiming documents and confirm actionable failures. (Sources: `webgpu-os/factory/apps/particles/ParticleStudioShell.js`, `webgpu-os/factory/apps/particles/ParticleStudioAdvanced.js`, `webgpu-os/factory/apps/particles/ParticleApp.js`) ## Performance and resource gate Warm each runtime before measurement. Record raw telemetry and the environment listed in the performance guide. Verify bounded 500 ms/4,096-particle prefix readback for evidence workspaces, bounded 500 ms/16,384-particle stratified readback for active Simulate projections, no full-state chart readback, stable resource counts during playback, owned-resource release across preset rebuilds, shared-device preservation, quality hysteresis/cooldown, manual memory-pressure decisions, and empty profiler stages when attribution is not supplied. Use browser/GPU diagnostics to check allocation behavior; source inspection alone is not proof of no per-frame allocation. (Sources: `webgpu-os/factory/apps/particles/ParticleApp.js`, `webgpu-os/factory/apps/particles/ParticleQualityGovernor.js`) ## Master Prompt acceptance traceability `Implemented` means current source and a listed gate cover the core claim. `Partial` means only the narrower behavior shown is present. `Unsupported` means the target feature is absent; a passing adjacent test must not be used as evidence for it. | Acceptance | Status | Current evidence or gap | | ---: | --- | --- | | 1 | Partial | WebGPU OS app reuses engine simulation but owns app presentation paths; it is not an editor-native workspace. | | 2 | Partial | A validated plan reaches documented ParticleApp bindings only, not arbitrary native APIs. | | 3 | Unsupported | No representative playground-demo conversion gate is part of this work. | | 4 | Implemented | Native app integration and runtime/renderer smoke tests verify owned teardown and shared-device boundaries. | | 5 | Partial | Create shows four compact projections/charts from one bounded native sample, not full fields. | | 6 | Unsupported | No independent second-camera execution test or general multi-camera renderer exists. | | 7 | Partial | Quality policy suspends excess optional views; there is no general renderer-pane scheduler. | | 8 | Implemented | Optional-view policy is separate from the recipe fixed-step clock. | | 9 | Partial | The Studio document emits a 2.5D interpretation warning; verify the visible label manually. | | 10 | Partial | Compare labels a settings snapshot and does not create a second solver. | | 11 | Unsupported | Mapped controls synchronize, but general gizmo, timeline-to-solver, and collaboration sync are absent. | | 12 | Implemented | Recipe and real native app tests verify uniform edits preserve the native world. | | 13 | Partial | Impact classes and rebuild/reset policy exist; manually verify warning copy for every rebuild path. | | 14 | Implemented | Exact graph errors and last-valid project/settings retention are automated. | | 15 | Partial | Project round-trip preserves current sidecars, IDs, seed, views, graph, and sensors; a general macro document is absent. | | 16 | Partial | Project-v1, graph-v0, and workspace-v4 migration preserve supported provenance; incompatible-feature warning coverage is limited. | | 17 | Partial | Compact reductions avoid full-field input, but no solver-connected GPU probe pipeline exists. | | 18 | Partial | Analyze shows quantity/unit/latest/quality; complete range/time/dataset legend coverage requires manual review. | | 19 | Implemented | Missing values and unsupported attribution remain absent. | | 20 | Implemented | Sensor CSV/JSON export is covered against accepted records. | | 21 | Unsupported | Ocean in a Bottle is not a current built-in preset. | | 22 | Partial | Galaxy and Orbital Clusters map to native n-body with deterministic seed state; “Black Hole” is not a current preset. | | 23 | Implemented | Tornado Field exposes `Educational Model` and limitations in the catalog. | | 24 | Unsupported | Rocket and car wind-tunnel presets and Engineering Preview classification are absent. | | 25 | Partial | Seven mapped presets reuse engine systems; no converted-demo equivalence suite exists. | | 26 | Implemented | Twin replay and isolated what-if branch behavior are covered without truth mutation. | | 27 | Implemented | Missing, stale, and numeric zero remain distinct sensor states. | | 28 | Partial | Provenance is retained, but spatial overlay is unsupported. | | 29 | Implemented | Schema and controller tests enforce non-transfer of validation. | | 30 | Partial | Six attribution fields exist, but remain empty unless supplied by a host. | | 31 | Partial | Stable-playback allocation must be measured; current suites do not prove it across hardware. | | 32 | Implemented | Evidence sampling is a bounded prefix; Simulate projections use bounded stratified blocks; telemetry charts do not request full state. | | 33 | Partial | Rebuild and teardown release owned resources; repeat-switch memory measurement remains manual. | | 34 | Implemented | Device-loss recovery preserves authored project state and activates labeled recovery. | | 35 | Partial | Governor handles explicit pressure and reduces optional quality; no complete OS pressure feed is attached. | | 36 | Implemented | Discover Play and Remix are available without opening Recipe. | | 37 | Partial | The typed registry covers all recipe families, but current UI is not a complete graphical editor. | | 38 | Implemented | Tab keyboard behavior, focus management, labels, and live status are present; keep manual regression coverage. | | 39 | Partial | Warnings include text; complete contrast and non-color-only visual review remains manual. | | 40 | Partial | The app follows WebGPU OS shell conventions; editor-native layout preservation is outside current scope. | ## Release gates After code and docs stop moving: 1. Run every suite in the automated inventory on at least one real WebGPU adapter and record browser/device details. 2. Run `python bundle_engine.py --target webgpu-os`; require zero bundle errors. 3. Run `python MD/tools/build_docs.py` and `python MD/tools/build_llms.py`; require clean navigation and generated discovery output. 4. Serve the bundled target and repeat mount, native/custom/recovery, persistence, import/export, keyboard, responsive, and unmount smoke tests. 5. Archive raw results, failures, console logs, screenshots, and environment metadata. Do not convert an unsupported acceptance item to passing because a related lower-scope check succeeded. ## Known gaps There is no complete editor-native, standalone runtime-player, Publish, collaboration, external-job, calibrated-field, scientific convergence, reference-image, video-export, or cross-hardware performance suite. Real-device WebGPU coverage is necessarily adapter-specific. These are product and validation gaps, not reasons to weaken the current strict tests. ## Capability boundary | Status | Test coverage | | --- | --- | | Implemented | Strict project/graph/sensor/Twin contracts, advanced-controller behavior, native state/runtime/renderer smoke pages, engine regressions, real app-native integration, and shader compilation. | | Partial | Device-loss, memory pressure, stable-allocation, responsive, accessibility, and cross-device performance require manual and multi-environment evidence. | | Unsupported | Certification of scientific accuracy and automated coverage for absent editor-native, Publish, collaboration, remote-job, full-field, video, and runtime-player features. | ## See also - [Particle Studio Architecture](particle-studio-architecture.md) - [Particle Recipe Schema](particle-recipe-schema.md) - [Particle Studio Fidelity and Validation](particle-studio-fidelity-and-validation.md) - [Particle Studio Performance](particle-studio-performance.md) - [Particle Studio Integration Map](particle-studio-integration-map.md) --- # WebGPU OS GPU-first compositor, shell, kernel, and package system that boots in a browser tab. Source: `webgpu-os/`. ## In this section - [Overview](overview.md) — what it is, tier framing, subsystems. - [Architecture](architecture.md) — kernel, shell, packages, storage, drivers, app contract. - [Realm Network](realm-network.md) — portable identity, content, resumable links, semantic replication, governance, discovery, V3 compatibility, and one-shot deployment policy. - [Navi Architecture and Delivery](navi-architecture-and-delivery.md) — persistent identity, cognition, Faculties, causal memory, bounded autonomy, Manifestations, and recovery gates. - [AI Echo Live Patch](ai-echo-live-patch.md) — clean-room declarative, reversible live editing for OS apps, shell surfaces, AI Echo, and extension-backed browser tabs. - [AI Echo Artifact Studio](ai-echo-artifact-studio.md) — file-backed, versioned work products with native, declarative, and opaque-sandbox previews beside the conversation. - [AI Echo Clicks and Clankers](ai-echo-clicks-and-clankers.md) — clean-room WebMCP discovery, verified semantic browser control, exact approvals, receipts, and React state synchronization. - [AppForge Contracts](appforge-contracts.md) — modular part registry, deterministic assembly, context graph, layout zones, package exports, timeline, lenses, starter packs, and builder contracts. - [Getting Started](getting-started.md) — boot the OS and build an app. - [App Catalog](app-catalog.md) — all 35 built-in apps. - **API Reference** — per-file symbols from `kernel/`, `shell/`, `packages/`, `storage/`, `drivers/`, `browser-bridge/`, `browser-extension/` (browse `webgpu-os/reference/`). ## Module map ```text webgpu-os/ index.js / boot.js bootWebGpuOS entry kernel/ KernelBootstrap, Syscalls, AppRegistry, ModRegistry, Permissions, TrustStore, GpuDeviceBroker, VRAMTracker, ThemeEngine, VirtualFS, ... shell/ Desktop, Taskbar, StartMenu, StatusTray, DialogManager, NotificationCenter packages/ PackageManager, PackageLoader, PackageBuilder, PackageVerifier, UpdateManager, ... storage/ VirtualFS, SystemFS, OPFSDriver, IndexedDBDriver, MountDriver, AppSandbox appforge/ Definitions, registry, tags, scoring, services, context, commands, layout, blueprints, packages, timeline, lenses, packs, builder drivers/ AudioDriver, CryptoDriver, NetDriver, ProfileDriver, WebSurfaceDriver browser-bridge/ browser-extension/ native browser integration + adblock apps/ 35 runtime-discovered apps (apps/index.json) ``` ## Related concepts - [Boot Sequence](../concepts/boot-sequence.md) - [GPU Device Sharing](../concepts/gpu-device-sharing.md) - [Security & Trust Model](../concepts/security-model.md) - [Data Flow](../concepts/data-flow.md) --- # API Reference The stack's API is documented in two complementary forms: - **Curated public API maps** — hand-authored tables of the common exports for each subsystem, on the [Capabilities](../guides/capabilities.md) page. - **Auto-generated per-symbol reference** — generated from source by `tools/extract_api.py` and browsable per subsystem (use the sidebar **API Reference** groups, or the links below). ## Public entry points | Surface | Import | Notes | | --- | --- | --- | | Engine (source) | `engine/EngineBootstrap.js` | All engine exports — math, ECS, render, sim, GPU, gameplay, saves. | | Engine (compiled) | `window.PE` / `window.ParticleEngine` | After loading a built bundle. | | Plauna | `plauna/index.js` | UI framework — app, widgets, services. | | AGI Core | `agi/index.js` | Training, observations, rewards, brains, motion. | | Editor | `editor/js/EditorApp.js` | Editor app orchestration + `ProjectManager.js`. | See [Engine Stack Usage](../guides/engine-stack-usage.md) for source-mode vs bundle-mode loading patterns. ## Per-subsystem reference Each subsystem ships a generated, per-file symbol reference (browse via the sidebar **API Reference** group under each section): - **Engine** — [overview](../engine/index.md), reference under `engine/reference/`. - **Editor** — [overview](../editor/index.md), reference under `editor/reference/`. - **Plauna** — [overview](../plauna/index.md), reference under `plauna/reference/`. - **AGI** — [overview](../agi/index.md), reference under `agi/reference/`. - **WebGPU OS** — [overview](../webgpu-os/index.md), reference under `webgpu-os/reference/`. > The reference is **hybrid**: signatures are regenerated from source on every run, while hand-authored notes below the `` marker are preserved. See the [API Reference Standard](../contributing/api-reference-standard.md). ## Machine-readable catalog Agents and tools should start with [`api-index.json`](../api-index.json). It combines all subsystem indexes and records the exact source path, source-server import specifier, source SHA-256, detected exports, signatures, and summaries when the source JSDoc provides them. Its `summaryCoverage` object quantifies missing module and export prose instead of filling gaps with invented descriptions. The per-subsystem `_index.json` files use the same record shape and remain compatible with the documentation viewer. The catalog's `runtimeLoading` contract distinguishes source mode from compiled mode: absolute module imports assume `start_server.py` is serving the repository root, while the compact production site may expose only generated bundles. For incremental indexing, use [`api-symbols.jsonl`](../api-symbols.jsonl). Each line contains one module or detected export and repeats the source path, import specifier, and source hash required to verify its context. Use [`docs-chunks.jsonl`](../docs-chunks.jsonl) when the task needs bounded prose from guides and generated references without loading the full search index. Both feeds have byte-identical copies at the site root and in `MD/`. The catalog describes ES modules, not an HTTP API. Do not infer REST endpoints, request schemas, or behavior that is absent from the linked source. Regenerate the catalog with `python tools/extract_api.py` followed by `python tools/build_llms.py`. --- # Docs Style Guide How to write docs for this project so they are clear, consistent, accessible, and easy for both AI tools and humans to read. ## Voice and clarity - **Active voice, present tense.** "The kernel guards syscalls," not "syscalls are guarded by the kernel." - **One idea per sentence.** Prefer short sentences and short paragraphs (3–5 sentences). - **Define terms on first use** and add them to the [Glossary](../getting-started/glossary.md). - **Be specific.** Reference real file paths, functions, and symbols in `code font`. - **No filler.** Every sentence should inform; cut marketing language. ## Inclusive language - Use gender-neutral terms ("they/them", "the user"). - Avoid loaded metaphors. Prefer `allowlist`/`denylist` and `primary`/`secondary`. - Avoid idioms that don't translate well. ## Accessibility - **Descriptive link text** — link the thing, not "click here". Good: "see the [Boot Sequence](../concepts/boot-sequence.md)". - **Alt text** on every image and diagram. - **No layout-relative references** ("above"/"below"/"on the right") — refer to sections by name. - **Meaningful headings** in order (don't skip levels). ## Structure Every page should have: 1. An H1 title matching its purpose. 2. A one- or two-sentence intro stating what the page is and who it's for. 3. Body sections with descriptive H2/H3 headings. 4. At least one example where relevant. 5. A "See also" / next-steps section with cross-links. Use the skeletons in `_templates/` (overview, guide, tutorial, api-entry). ## Formatting conventions - **Code font** for files, functions, classes, symbols, and literal values: `kernel/Syscalls.js`, `mount()`, `fs.write`. - **Fenced code blocks** with a language tag (` ```javascript `, ` ```bash `, ` ```json `, ` ```mermaid `). - **Tables** for option/parameter/field lists. - **Mermaid** for diagrams (see [Diagram Guide](diagram-guide.md)). - Use relative links to other `.md` files so all three viewers resolve them. ## Citing source When you state how something works, point at the source: ``(Source: `webgpu-os/AUDIT.md` §4)`` or a file path. This keeps docs verifiable and makes drift obvious. ## AI-readability - Keep Markdown plain and standard (the zero-build viewer has only a minimal fallback parser). - Prefer explicit tables and lists over prose for structured data. - Put the most important information first. ## See also - [Writing Checklist](writing-checklist.md) - [Page Templates](page-templates.md) - [API Reference Standard](api-reference-standard.md) --- # Writing Checklist Run through this before merging any documentation change. It operationalizes the [Docs Style Guide](docs-style-guide.md). ## Audience & scope - [ ] The intro states **what** the page is and **who** it's for. - [ ] The page is in the correct section and appears in `_config/nav.json` (or an auto-generated reference index). ## Structure & navigation - [ ] Single H1; headings are ordered and meaningful. - [ ] Cross-links to related pages; a "See also" / next-steps section exists. - [ ] Internal links use relative `.md` paths and resolve in the viewer. ## Content quality - [ ] Active voice, short sentences, short paragraphs. - [ ] New terms are defined and added to the [Glossary](../getting-started/glossary.md). - [ ] Claims about behavior cite a source file/section. ## Required sections (by page type) - [ ] **Overview:** what/who, module map, next steps. - [ ] **Guide/how-to:** prerequisites, numbered steps, at least one example. - [ ] **Reference entry:** description, parameters, returns, errors, example. See [API Reference Standard](api-reference-standard.md). ## Examples - [ ] At least one code/command example where relevant. - [ ] Examples are runnable/accurate and tagged with a language. ## Diagrams - [ ] Mermaid diagrams render; each has surrounding explanatory text and alt-text-equivalent context. ## Accessibility & style - [ ] Descriptive link text (no "click here"). - [ ] No layout-relative references ("above"/"below"). - [ ] Inclusive, neutral language. ## Build verification - [ ] `python tools/build_docs.py` passes (search index builds; nav paths resolve). - [ ] `python tools/build_llms.py` regenerated root discovery files. - [ ] `python tools/validate_docs.py` passes API, crawler, and wrapper contracts. - [ ] If you touched the API reference, `python tools/extract_api.py` ran and external overlays under `_notes/` were reinjected below ``. - [ ] (If using MkDocs) `mkdocs build --strict -f _config/mkdocs.yml` has no broken-link errors. ## Review - [ ] A second contributor proofread the change. --- # Page Templates Copy-paste skeletons for new pages. The full files live in `MD/_templates/`; this page explains when to use each and shows the shape. ## When to use which | Template | Use for | | --- | --- | | `_templates/overview.md` | A subsystem or major-area landing page (what/who, module map). | | `_templates/guide.md` | A task-based how-to (prerequisites → steps → verify). | | `_templates/tutorial.md` | A longer, end-to-end learning path with a concrete goal. | | `_templates/api-entry.md` | A hand-written reference entry (most reference is auto-generated). | ## Overview skeleton ```markdown # Overview ## What it provides - ... ## Module map | Module | Path | Purpose | | --- | --- | --- | ## Next steps - [Architecture](architecture.md) - [Getting Started](getting-started.md) ``` ## Guide skeleton ```markdown # ## Prerequisites - ... ## Steps 1. ... ## Verify - ... ## See also - ... ``` ## API entry skeleton ```markdown # `functionName(param1, param2)` **Description:** **Parameters:** - `param1` (`type`): - `param2` (`type`, optional): **Returns:** **Raises:** - `ErrorType`: **Example:** ```js // runnable example ``` ``` ## See also - [Docs Style Guide](docs-style-guide.md) - [API Reference Standard](api-reference-standard.md) --- # API Reference Standard The reference is **hybrid**: `tools/extract_api.py` generates per-file signature stubs from source; contributors add prose and examples in a **separate `_notes/` overlay tree** that the extractor injects below the `` marker. This page defines the standard both halves follow. ## How generation works - The extractor walks each subsystem's JS source and writes `MD//reference/.md` plus a `_index.json` consumed by the viewers. - The **whole page is regenerated** every run (signatures *and* the Notes & Examples section), so the ~1700 reference files stay purely generated and can be rebuilt from scratch. - Hand-authored notes live **outside** the pages in `MD/_notes/` and are injected on every run — so regenerating never clobbers your prose. ```bash python tools/extract_api.py # all subsystems python tools/extract_api.py webgpu-os # just one python tools/build_docs.py # refresh search index python tools/build_bundle.py # repack the single deploy bundle ``` ## Hand-authored notes (the `_notes/` overlay) There are two ways to add notes — see `MD/_notes/README.md` in the repo for the full guide. **Per-page notes** — `_notes//.md` (the reference path with the `reference/` segment dropped). The file becomes the page's Notes & Examples body verbatim. Example: notes for `engine/reference/core/math/MathVec3.md` live in `_notes/engine/core/math/MathVec3.md`. Use normal relative links here. **Shared blocks** — `_notes/_shared.json`. Write a block once and apply it to many pages via `applies` globs (matched against the reference path, e.g. `engine/reference/core/gpu/*`). This is how common context is authored **once** instead of copied onto every page. Because a shared block lands on pages at varying depths, use **docroot-absolute** links like `[Virtual GPU](/engine/vgpu.md)` (leading `/`). A page's composed notes are its per-page overlay first, then every matching shared block. If nothing applies, a placeholder is shown. ## What a generated page contains - File path and a **Source** link to the real file. - The file-level description (from a leading `/** ... */` JSDoc, or leading `//` comments). - **Classes** with their methods (signature + JSDoc summary). - **Functions** with parameters (`@param`), return (`@returns`), and summary. - **Constants** and **re-exports**. ## What contributors add (in the overlay) Each non-trivial symbol should gain: - **Purpose** — what it's for and when to use it (beyond the one-line summary). - **Parameters** — full sentences. Booleans: "If `true`, do X; otherwise Y." Objects: describe each field. - **Returns** — start with "The …" for objects ("The resolved trust profile."); booleans use "`true` if …; `false` otherwise." - **Raises/errors** — what throws and when. - **Example** — a short, runnable snippet with error handling where relevant. - **See also** — related symbols/pages. ## Improve the source, improve the docs Because file descriptions and `@param`/`@returns` come from JSDoc, the best way to improve a generated page is to **add JSDoc to the source** (upstream), then re-run the extractor. Per the project's composition rule, fix documentation at the source rather than only in the generated Markdown. ## Formatting - All symbols in `code font`, matching source casing. - One page per source file; one H3 per symbol. - Keep examples self-contained and language-tagged. ## See also - [Docs Style Guide](docs-style-guide.md) - [Contribution Workflow](doc-contribution-workflow.md) --- # AI & Accessibility This documentation is built to be **AI-safe** (readable by and guiding to LLM agents) and **human-safe** (accessible, accurate, and clear). This page records those conventions. They draw on the emerging [llmstxt.org](https://llmstxt.org/) proposal, the [agents.md](https://agents.md/) convention, the [Diátaxis](https://diataxis.fr/) framework, and AI/RAG writing guidance. `llms.txt` is supplemental discovery metadata, not a replacement for canonical Markdown and source code. ## Making the docs AI-safe ### Discovery files (guide the AI to its places) - **`/llms.txt`** — a curated, machine-readable index at the web root so agents can discover it without knowing the documentation layout. A portable copy also lives in `MD/`. - **`llms-full.txt`** — the curated pages concatenated for full-context ingestion (the large generated reference is linked, not inlined). - **`/api-index.json`** — an ES-module catalog with the source path, source-server import specifier, source hash, detected exports, and signatures. Summaries appear only where source JSDoc provides them; `summaryCoverage` quantifies the remaining gaps and `runtimeLoading` distinguishes repository source mode from compiled production mode. - **`/docs-chunks.jsonl`** — bounded documentation chunks generated from the search index. Each UTF-8 line is an independent JSON object with source metadata, a stable chunk position, and a SHA-256 content hash. - **`/api-symbols.jsonl`** — the API catalog flattened to one source-backed module or detected export per UTF-8 line. It preserves module paths, source imports, source hashes, signatures, and empty summaries when JSDoc has no description. - **`/robots.txt` and `/sitemap.xml`** — crawler discovery files generated alongside the LLM indexes. Curated pages point to raw Markdown, API catalogs point to JSON, and bundled generated references use stable `/MD/viewer/?doc=...` URLs. - **`AGENTS.md`** (at the `MD/` root) — a "README for agents": where things live, which commands to run, what may be changed, and the hard boundaries. AI agents should read it first. Regenerate discovery files after content changes: ```bash python tools/build_llms.py python tools/validate_docs.py ``` `build_llms.py` refreshes both the `MD/` copies and the web-root discovery files. It generates the canonical `https://particlerealms.online` sitemap by default; pass `--site-url` and `--base-url` only for another deployment. The validator rejects stale local ports, malformed or stale JSONL records, oversized feeds, malformed enriched API indexes, known nonexistent GPU symbols, missing root discovery files, and public wrappers that expose documentation only through an iframe. ### Self-contained sections LLMs retrieve **chunks**, not whole pages, and document order is not preserved. So each section must make sense in isolation: - **Front-load context** — start a section by naming the subsystem/feature it concerns. - Use **descriptive headings** that say what the section accomplishes. - Avoid back-references like "as mentioned above," "now that you've," or "with everything configured." - Include complete steps within a section rather than relying on earlier ones. ### Page metadata (frontmatter) Pages may begin with a YAML frontmatter block. The viewer strips it (showing the description as a subtitle) and the build tools use it for richer search and freshness signals: ```yaml --- title: Boot Sequence description: How the WebGPU OS comes up, from the HTML page to a mounted desktop. audience: app developers updated: 2026-06-05 --- ``` `title` and `description` improve retrieval; `updated` is a freshness signal valued by AI search. ### Verifiability over fluency - Every behavioral claim must be **traceable to a source file** — cite it. - The per-symbol API reference is **machine-extracted** and may lag the source; the generated banner marks it. Improve accuracy by editing **JSDoc upstream**, then regenerating. - Prefer Markdown/HTML over PDFs; keep semantic structure (real headings, lists, tables) so crawlers and models parse it cleanly. ## Making the docs human-safe ### Accessibility - **Descriptive link text** — never "click here". - **Alt text** on every image; **text equivalents** near every diagram (a screen reader may not read a rendered SVG). - **No layout-relative references** ("above"/"below"/"on the right") — refer to sections by name. - Meaningful, ordered headings; sufficient color contrast in the dark theme. - The viewer honors **`prefers-reduced-motion`**, exposes `aria-current`/`aria-expanded` on navigation, and provides a skip-link and keyboard shortcuts. ### Safety & accuracy - **Never include secrets** (keys, tokens, passwords) in docs or examples. - Parts of the reference are **auto-generated** — verify against the cited source before relying on them. - Keep the [Security & Trust Model](../concepts/security-model.md) accurate; do not weaken or misstate capability/permission behavior. - Curated pages link to their raw Markdown source. Generated references identify the repository source path and offer the bundled Markdown as a download; the source hash in `/api-index.json` exposes drift. ## Diátaxis alignment This set roughly follows the four Diátaxis modes; keep new pages in the right mode: | Mode | Purpose | Where | | --- | --- | --- | | Tutorial (learning) | Get a newcomer to a first success | `getting-started/`, `_templates/tutorial.md` | | How-to (task) | Accomplish a specific goal | subsystem `getting-started.md`, guides | | Reference (information) | Look up exact facts | `/reference/**` | | Explanation (understanding) | Understand the "why" | `concepts/` | ## See also - [Docs Style Guide](docs-style-guide.md) - [API Reference Standard](api-reference-standard.md) - [Contribution Workflow](doc-contribution-workflow.md) - [`AGENTS.md`](../AGENTS.md) --- # Diagram Guide Diagrams help readers grasp complex flows faster. This project uses **Mermaid** so diagrams live in Markdown, are versioned with text, and render in all three viewers. ## When to use a diagram - Architecture/component relationships. - Sequences (boot, request flows, IPC). - State machines and pipelines. Use a diagram to **complement** prose, not replace it. Always introduce a diagram with a sentence saying what it shows. ## How to author Use a fenced ` ```mermaid ` block: ````markdown ```mermaid flowchart LR A[Source] --> B[Process] --> C[Output] ``` ```` The zero-build viewer converts these blocks into rendered diagrams via the vendored `mermaid.min.js`. If the vendor libs aren't present, the block falls back to showing the diagram source as code — still readable. ## Conventions - **Flowcharts** (`flowchart LR/TD`) for architecture/pipelines. - **Sequence diagrams** (`sequenceDiagram`) for ordered interactions. - **Timelines** (`timeline`) for evolution/history. - Keep node labels short; put detail in the surrounding text. - Use `\n` inside labels for line breaks rather than very wide nodes. - Prefer 5–12 nodes per diagram; split larger ones. ## Accessibility - Mermaid is not a substitute for text. Ensure the key information in a diagram is **also** stated in nearby prose, since screen readers may not read the rendered SVG well. - Reference diagrams by what they depict, not "the diagram above". ## Theming The viewer initializes Mermaid with the `dark` theme and `securityLevel: "strict"`. Don't rely on custom colors for meaning — use labels. ## Example ```mermaid sequenceDiagram participant App participant Kernel App->>Kernel: fs.write(path, data) Kernel-->>App: ok / throws if capability denied ``` ## See also - [Docs Style Guide](docs-style-guide.md) - Examples in use: [Boot Sequence](../concepts/boot-sequence.md), [Architecture Overview](../concepts/architecture-overview.md). --- # Contribution Workflow How to add or change documentation and keep it from drifting. Docs are treated as code: edited in Markdown, validated by tooling, and reviewed. ## The loop ```mermaid flowchart LR write[Write/edit Markdown in MD/] --> gen[Run extractors/builders] gen --> verify[Verify locally] verify --> review[Peer review] review --> merge[Merge] merge --> feedback[Gather feedback / file issues] feedback --> write ``` ## 1. Edit Markdown - All docs live under `C:\Coding\game\MD`. This is the single source of truth. - Existing docs elsewhere (`docs/`, `webgpu-os/docs/`, `engine/docs/`, per-component `.md`) are **read-only references** — don't edit them as part of docs work; fold needed content into `MD/`. - Add new curated pages to `_config/nav.json`. - Follow the [Docs Style Guide](docs-style-guide.md) and use `_templates/`. ## 2. Regenerate derived artifacts ```bash # from C:\Coding\game\MD python tools/extract_api.py # refresh signatures and inject external note overlays python tools/build_docs.py # rebuild search index + validate nav paths python tools/build_llms.py # refresh MD/ and web-root discovery assets python tools/validate_docs.py # validate API, crawler, URL, and wrapper contracts ``` If the viewer's libs aren't vendored yet: ```bash python tools/fetch_vendor.py ``` ## 3. Verify locally - **Zero-build viewer:** `python start_server.py` → `http://127.0.0.1:9001/MD/viewer/`. Click through changed pages; confirm no "Page not found", search works, diagrams render. - **MkDocs (optional):** `mkdocs build --strict -f _config/mkdocs.yml` — fails on broken links. - Run the [Writing Checklist](writing-checklist.md). ## 4. Keep docs in sync with code - When you change an API or user-visible behavior, update the docs in the same change. - Improve **source JSDoc** so the generated reference improves too (see [API Reference Standard](api-reference-standard.md)). - Record notable doc changes in [CHANGELOG.md](../CHANGELOG.md) (Keep-a-Changelog format). ## 5. Review & publish - Have a second contributor proofread. - The three viewers all read the same `MD/` files, so a merged change is immediately reflected once artifacts are rebuilt and the site/app is served. ## Suggested CI (optional) A CI job can run, on every change touching `MD/`: 1. `python tools/extract_api.py` (source hashes and detected exports are current). 2. `python tools/build_docs.py` (must exit 0 — all nav paths resolve). 3. `python tools/build_llms.py` (root discovery files are regenerated). 4. `python tools/build_bundle.py` (the compact deployed viewer payload is current). 5. `python tools/validate_docs.py` (API, crawler, URL, and wrapper contracts pass). 6. `mkdocs build --strict` (no broken links). 7. A Markdown link checker and a style linter (e.g. Vale). ## See also - [Docs Style Guide](docs-style-guide.md) - [Writing Checklist](writing-checklist.md) - [Diagram Guide](diagram-guide.md) --- # AGENTS.md — Guide for AI Agents Working on These Docs > A "README for agents." If you are an AI assistant reading, navigating, or editing this documentation, **read this first.** It tells you where things live, what you may change, and the hard boundaries. This follows the [agents.md](https://agents.md/) convention and complements [`llms.txt`](llms.txt). ## Project overview This `MD/` folder is the **single source of truth** for the WebGPU OS stack documentation. The stack has five subsystems: `engine`, `editor`, `plauna`, `agi`, and `webgpu-os`. Start at [`index.md`](index.md) for the human entry point and [`llms.txt`](llms.txt) for a curated machine index. ## Where things are (navigate here) - **Curated, hand-authored prose:** `getting-started/`, `concepts/`, and each subsystem's `overview.md` / `architecture.md` / `getting-started.md` / `index.md`. - **Generated API reference:** `/reference/**` — produced from source by `tools/extract_api.py`. - **Navigation manifest:** `_config/nav.json` (the one place that defines curated nav for all viewers). - **Tooling:** `tools/` (Python only — no Node). - **Conventions:** `contributing/` (style guide, API standard, AI & accessibility, workflow). ## Commands (run from `MD/`) ```bash python tools/extract_api.py # regenerate API reference from source JS python tools/build_docs.py # rebuild search index + validate nav paths python tools/build_llms.py # regenerate llms.txt / llms-full.txt python tools/fetch_vendor.py # vendor viewer libs (network; ask the human first) ``` After editing Markdown, run `build_docs.py`. After touching source code that has reference pages, run `extract_api.py` then `build_docs.py`. ## What you MAY change - Curated `.md` pages under `MD/` (follow the [style guide](contributing/docs-style-guide.md)). - The **`Notes & Examples`** section (everything **below** the `` marker) in any generated reference page — this is preserved across regenerations. - `_config/nav.json` when adding/removing curated pages. ## Hard boundaries (do NOT do these) - **Do not edit generated content above ``** in `/reference/**` — it is overwritten on the next `extract_api.py` run. To fix a signature or description, **edit the JSDoc in the source file upstream**, then regenerate. - **Do not edit files outside `MD/`** as part of docs work. The originals under `../docs/`, `../webgpu-os/docs/`, `../engine/docs/`, and per-component `.md` files are **read-only reference sources**. (The single exception, already made, is the `docs` app under `../webgpu-os/apps/docs/`.) - **Do not invent APIs, file paths, or behavior.** Every claim about how something works must be verifiable against a source file — cite it (e.g. ``(Source: `webgpu-os/AUDIT.md` §4)``). If unsure, say so rather than guessing. - **Do not auto-run** network or destructive commands (e.g. `fetch_vendor.py`, deletes) without explicit human approval. ## Code & writing style - Active voice, short sentences, descriptive link text, alt text on images/diagrams. See [Docs Style Guide](contributing/docs-style-guide.md). - Keep Markdown plain and standard (the zero-build viewer has only a minimal fallback parser). - Make sections **self-contained**: front-load context, avoid "as mentioned above," so a chunk read in isolation still makes sense. See [AI & Accessibility](contributing/ai-and-accessibility.md). ## Security considerations - **Never put secrets** (keys, tokens, passwords) in documentation or examples. - The docs describe a real security/trust model; keep [Security & Trust Model](concepts/security-model.md) accurate and do not weaken or misstate capability/permission claims. - Treat the generated reference as **machine-extracted**: it can lag the source. Verify against the cited source file before relying on it. ## Verify your work - Run `python tools/build_docs.py` — it must exit 0 (all nav paths resolve). - Open `viewer/` over HTTP and click through changed pages (no "Page not found"). - Run through the [Writing Checklist](contributing/writing-checklist.md). --- # Changelog All notable changes to this documentation set are recorded here. Format follows [Keep a Changelog](https://keepachangelog.com/); this set is versioned independently of the code. ## [Unreleased] ### Changed - Updated Particle Realms Studio to the six-stage recipe workflow: recipe-backed demos, Simulate-first tuning, project schema v2, typed recipe plans, native `ParticleSimWorld` adapters, bounded evidence paths, and CSE/sandbox persistence. Legacy Artist/Twin sidecars remain losslessly compatible without appearing as workspaces. - Expanded Recipe into a full-width visual typed builder with add/remove/connect/disconnect operations, draggable persisted node positions, exact invalid-draft diagnostics, last-valid execution-plan retention, a bounded measured native-readback preview, and direct navigation to the authoritative Simulate canvas. Scoped dialog styling now prevents the Recipe workspace from inheriting modal width and height constraints. - Changed Simulate to keep its tuning drawer closed until explicitly requested and replaced user-selectable particle tiers with an automatic, measured population controller targeting stable 60 FPS. Population uses smoothed cadence, hysteresis, cooldown, workgroup quantization, and only internal device/runtime safety ceilings. ### Added - Initial restructured documentation set in `MD/` (single source of truth). - Zero-build HTML viewer (`viewer/`) with sidebar nav, search, in-page TOC, code copy, and Mermaid support, plus a built-in fallback Markdown renderer. - **Viewer QoL pass:** collapsible/nested API-reference tree (lazy-rendered, per-folder counts), sidebar filter box (`Ctrl+Shift+F`) with highlighted matches, custom themed scrollbars, breadcrumbs, reading-progress bar, back-to-top button, collapse-all control, and persisted open/scroll state via `localStorage`. Active reference pages auto-expand their folders and scroll into view. - **AI-safe & human-safe pass:** `AGENTS.md` (agent boundaries/commands), `llms.txt` + `llms-full.txt` (llmstxt.org discovery standard) generated by `tools/build_llms.py`, YAML frontmatter support across the viewer + build tools (title/description/updated; reference pages stamped `kind: reference` + `source`), a [AI & Accessibility](contributing/ai-and-accessibility.md) conventions page, a home-page accuracy/safety notice, per-page **View source** links, and accessibility upgrades (`prefers-reduced-motion`, `aria-current`/`aria-expanded`). - **Discovery & metadata pass:** `robots.txt` (allows crawlers, references `sitemap.xml` + the `llms.txt` indexes); a repo-wide root `AGENTS.md` for coding agents (the `MD/AGENTS.md` one stays docs-scoped); git-based "last updated" fallback — `tools/build_docs.py` now emits `_config/git-dates.json` and the viewer uses it when a page has no `updated` frontmatter; and hand-authored `title`/`description`/`updated` frontmatter on every curated page (Getting Started, Concepts, all five subsystems, and Contributing). - **Author attribution:** [Author & Credits](about/credits.md) page, a persistent "Built by Jake Wehmeier" viewer footer credit, and SPDX license headers across the docs tooling and the wider source tree (see root `AUTHORS`, `LICENSE`, and `LICENSES/`). - **Ported website guides:** the curated guides from `tests/guide` were hand-ported into MD as the single source of truth — a new **Guides (How-To)** section ([Capabilities — What You Can Build](guides/capabilities.md), [Engine Stack Usage](guides/engine-stack-usage.md)) plus Engine deep-dives ([Virtual GPU](engine/vgpu.md), [ECS v2](engine/ecs.md), [Rendering](engine/rendering.md), [Shaders & WGSL](engine/shaders.md), [Particle System](engine/particles.md), [Physics](engine/physics.md), [GPU Physics Engine](engine/gpu-physics.md), [Math Library](engine/math.md), [Audio](engine/audio.md)). - **Website single-source docs:** the public site's **Guide** and **API** tabs now embed the MD zero-build viewer (`tests/guide/index.html` + `tests/api/index.html` are thin shells over `MD/viewer/`), backed by a new [API Reference](api/index.md) hub. `bundle_engine.py` now ships `MD/` into `release/site/MD/` on every build (fresh cache, no manual copy) for both the website embeds and the WebGPU OS `DocsApp`, refreshing the search index first; the dev `../../MD/` embed path is rewritten to `../MD/` for the release layout. - **Hand-authored notes overlay for the API reference:** notes now live *outside* the generated pages in `MD/_notes/`, so the ~1700 reference files stay purely generated (regenerable from scratch) while prose is never clobbered. `tools/extract_api.py` injects them below the `` marker on every run: **per-page notes** (`_notes//.md`) and **reusable shared blocks** (`_notes/_shared.json`) applied to many pages by glob — write common context once instead of copying it onto every page. **Expanded to 13 shared blocks** with detailed runnable examples: GPU device sharing, package trust tiers, AGI training loop, Plauna lifecycle, ECS pattern (complex queries, system groups, events), audio graph (asset loading, spatial audio, mixing buses), physics integration (raycasting, constraints, CCD), input handling, voxel world, world streaming, math conventions, command bus, and editor extensions — covering **~1000+ pages**. **Added 8 per-page overlays** for high-traffic modules: MathVec3, MathMat4, MathQuat, MathScalar, MathRandom, Renderer, Camera, Shader, PackageLoader, and NetworkArchitecture — each with complete API examples and gotchas. The viewer's `rewriteLinks` gained docroot-absolute (`/path.md`) link support so shared blocks link correctly from pages at any depth; `_notes/` is excluded from the search index and bundle. - **Single-file deploy bundle:** `tools/build_bundle.py` packs the nav, search index, git-dates, every Markdown page, and the reference indexes into one gzipped `_config/docs-bundle.json.gz` (~1700 files → 1 file, 5.8 MB → 1.2 MB). The viewer fetches and gunzips it in-browser (`DecompressionStream`), serving all pages from memory; it falls back to per-file fetch when the bundle is absent (dev). The release build now ships only the viewer + vendored libs + the single bundle, keeping deploys well under static-host file caps (e.g. Cloudflare Pages' 1000-file limit). The viewer's fallback Markdown renderer also gained GFM table support so tables render without the vendored `marked` library. - Navigation manifest `_config/nav.json` consumed by all viewers. - Python tooling (`tools/`): `fetch_vendor.py` (offline vendor libs), `build_docs.py` (search index + nav validation), `extract_api.py` (hybrid API-reference generation with preserved hand-notes). - Getting Started: overview, install, quickstart, glossary, FAQ. - Whole-stack concepts: architecture overview, history & evolution, boot sequence, GPU device sharing, security & trust model, data flow. - Per-subsystem docs (overview/architecture/getting-started/index) for engine, editor, plauna, agi, and webgpu-os; AGI training guide; WebGPU OS app catalog (35 apps). - Contributing standards: style guide, writing checklist, page templates, API reference standard, diagram guide, contribution workflow. - Page templates in `_templates/`. - MkDocs Material configuration (`_config/mkdocs.yml`). ### Notes - Existing docs under `docs/`, `webgpu-os/docs/`, `engine/docs/`, and per-component `.md` files remain in place as read-only reference sources. ## [0.1.0] — 2026-06-05 ### Added - Documentation overhaul scaffolding and plan baseline. --- # Author & Credits The entire WebGPU OS stack — the **engine**, the **editor**, **Plauna**, **AGI**, and the **WebGPU OS** that composes them — was designed and built by **Jake Wehmeier**. ## About the author Jake Wehmeier is a **Canada-based developer** who works across the whole stack, from small scripts and Python tools to a from-scratch, browser-resident, GPU-first operating system. He is the **sole author** of this project, which also carries its original name **Particle Realms** ([ParticleRealms.Online](https://particlerealms.online)). On GitHub ([@BTSpaniel](https://github.com/BTSpaniel)) his profile reads, plainly, *"I make Batch Scripts Because I'm lazy."* — but the work collected here tells a larger story: a hand-built WebGPU engine, an editor, a UI framework, a reinforcement-learning rig, and an OS, assembled without heavy third-party framework dependencies. > The biographical details on this page are limited to what is publicly verifiable (his GitHub profile) and what the author has stated directly. If anything here is wrong or you'd like to expand it, edit this page — it is the canonical place the project credits its author. ### Selected work - **`particlerealms.engine`** — the WebGPU engine at the heart of this stack. - **NodesIn.Space** — frontend project (JavaScript). - **Dubtitles** — Python project. - **Augment** — Python project. ## Connect - **GitHub:** [github.com/BTSpaniel](https://github.com/BTSpaniel) - **Threads:** [@zisishans](https://www.threads.com/@zisishans) - **Project site:** [ParticleRealms.Online](https://particlerealms.online) ## Credits & acknowledgements - **Design, architecture, and implementation:** Jake Wehmeier. - **Documentation viewer — vendored open-source libraries** (used by the zero-build viewer, all permissively licensed): - [marked](https://github.com/markedjs/marked) — Markdown parser (MIT). - [highlight.js](https://github.com/highlightjs/highlight.js) — syntax highlighting (BSD-3-Clause). - [Mermaid](https://github.com/mermaid-js/mermaid) — diagrams (MIT). ## License See the project `LICENSE` and `NOTICE.md` at the repository root for licensing and attribution terms.