@forgeax/engine-devkit 0.0.0-dev.8d955ade1c79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +334 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/__tests__/archive.test.d.ts +2 -0
  5. package/dist/__tests__/archive.test.d.ts.map +1 -0
  6. package/dist/__tests__/assets.test.d.ts +2 -0
  7. package/dist/__tests__/assets.test.d.ts.map +1 -0
  8. package/dist/__tests__/bootstrap-commands.test.d.ts +2 -0
  9. package/dist/__tests__/bootstrap-commands.test.d.ts.map +1 -0
  10. package/dist/__tests__/cli-output.unit.test.d.ts +2 -0
  11. package/dist/__tests__/cli-output.unit.test.d.ts.map +1 -0
  12. package/dist/__tests__/dist.test.d.ts +2 -0
  13. package/dist/__tests__/dist.test.d.ts.map +1 -0
  14. package/dist/__tests__/gltf-source-key-diagnostics.integration.test.d.ts +2 -0
  15. package/dist/__tests__/gltf-source-key-diagnostics.integration.test.d.ts.map +1 -0
  16. package/dist/__tests__/host.test.d.ts +2 -0
  17. package/dist/__tests__/host.test.d.ts.map +1 -0
  18. package/dist/__tests__/init.test.d.ts +2 -0
  19. package/dist/__tests__/init.test.d.ts.map +1 -0
  20. package/dist/__tests__/plugin-authoring.test.d.ts +2 -0
  21. package/dist/__tests__/plugin-authoring.test.d.ts.map +1 -0
  22. package/dist/__tests__/preview-port.integration.test.d.ts +2 -0
  23. package/dist/__tests__/preview-port.integration.test.d.ts.map +1 -0
  24. package/dist/__tests__/project.test.d.ts +2 -0
  25. package/dist/__tests__/project.test.d.ts.map +1 -0
  26. package/dist/__tests__/rhi-debug-build-graph.integration.test.d.ts +2 -0
  27. package/dist/__tests__/rhi-debug-build-graph.integration.test.d.ts.map +1 -0
  28. package/dist/__tests__/rhi-debug-cold-start.integration.test.d.ts +2 -0
  29. package/dist/__tests__/rhi-debug-cold-start.integration.test.d.ts.map +1 -0
  30. package/dist/__tests__/rhi-debug-error-consumer.test-d.d.ts +2 -0
  31. package/dist/__tests__/rhi-debug-error-consumer.test-d.d.ts.map +1 -0
  32. package/dist/__tests__/rhi-debug-operations.test-d.d.ts +2 -0
  33. package/dist/__tests__/rhi-debug-operations.test-d.d.ts.map +1 -0
  34. package/dist/__tests__/rhi-debug-operations.unit.test.d.ts +2 -0
  35. package/dist/__tests__/rhi-debug-operations.unit.test.d.ts.map +1 -0
  36. package/dist/__tests__/sdk-install.test.d.ts +2 -0
  37. package/dist/__tests__/sdk-install.test.d.ts.map +1 -0
  38. package/dist/__tests__/sdk-update.unit.test.d.ts +2 -0
  39. package/dist/__tests__/sdk-update.unit.test.d.ts.map +1 -0
  40. package/dist/__tests__/skill-install.test.d.ts +2 -0
  41. package/dist/__tests__/skill-install.test.d.ts.map +1 -0
  42. package/dist/__tests__/software-browser-session.unit.test.d.ts +2 -0
  43. package/dist/__tests__/software-browser-session.unit.test.d.ts.map +1 -0
  44. package/dist/__tests__/software-capture-pixels.unit.test.d.ts +2 -0
  45. package/dist/__tests__/software-capture-pixels.unit.test.d.ts.map +1 -0
  46. package/dist/__tests__/software-capture.unit.test.d.ts +2 -0
  47. package/dist/__tests__/software-capture.unit.test.d.ts.map +1 -0
  48. package/dist/archive.d.ts +6 -0
  49. package/dist/archive.d.ts.map +1 -0
  50. package/dist/assets.d.ts +6 -0
  51. package/dist/assets.d.ts.map +1 -0
  52. package/dist/bootstrap-commands.d.ts +12 -0
  53. package/dist/bootstrap-commands.d.ts.map +1 -0
  54. package/dist/cli-output.d.ts +4 -0
  55. package/dist/cli-output.d.ts.map +1 -0
  56. package/dist/cli.d.ts +2 -0
  57. package/dist/cli.d.ts.map +1 -0
  58. package/dist/cli.mjs +5657 -0
  59. package/dist/cli.mjs.map +1 -0
  60. package/dist/commands.d.ts +20 -0
  61. package/dist/commands.d.ts.map +1 -0
  62. package/dist/dist.d.ts +24 -0
  63. package/dist/dist.d.ts.map +1 -0
  64. package/dist/host/__tests__/bootstrap-root-owner.test-d.d.ts +2 -0
  65. package/dist/host/__tests__/bootstrap-root-owner.test-d.d.ts.map +1 -0
  66. package/dist/host/base-host.d.ts +18 -0
  67. package/dist/host/base-host.d.ts.map +1 -0
  68. package/dist/host/project-bootstrap.d.ts +13 -0
  69. package/dist/host/project-bootstrap.d.ts.map +1 -0
  70. package/dist/host/resource-bootstrap.d.ts +25 -0
  71. package/dist/host/resource-bootstrap.d.ts.map +1 -0
  72. package/dist/host.d.ts +14 -0
  73. package/dist/host.d.ts.map +1 -0
  74. package/dist/index.d.ts +35 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.mjs +6393 -0
  77. package/dist/index.mjs.map +1 -0
  78. package/dist/init.d.ts +21 -0
  79. package/dist/init.d.ts.map +1 -0
  80. package/dist/plugin-authoring.d.ts +4 -0
  81. package/dist/plugin-authoring.d.ts.map +1 -0
  82. package/dist/project.d.ts +4 -0
  83. package/dist/project.d.ts.map +1 -0
  84. package/dist/rhi-debug/cli-context.d.ts +3 -0
  85. package/dist/rhi-debug/cli-context.d.ts.map +1 -0
  86. package/dist/rhi-debug/operations.d.ts +83 -0
  87. package/dist/rhi-debug/operations.d.ts.map +1 -0
  88. package/dist/sdk-bootstrap.d.ts +34 -0
  89. package/dist/sdk-bootstrap.d.ts.map +1 -0
  90. package/dist/sdk-cli.d.ts +2 -0
  91. package/dist/sdk-cli.d.ts.map +1 -0
  92. package/dist/sdk-cli.mjs +5902 -0
  93. package/dist/sdk-cli.mjs.map +1 -0
  94. package/dist/sdk-install.d.ts +7 -0
  95. package/dist/sdk-install.d.ts.map +1 -0
  96. package/dist/sdk-update.d.ts +23 -0
  97. package/dist/sdk-update.d.ts.map +1 -0
  98. package/dist/sdk.d.ts +74 -0
  99. package/dist/sdk.d.ts.map +1 -0
  100. package/dist/shader-check.d.ts +3 -0
  101. package/dist/shader-check.d.ts.map +1 -0
  102. package/dist/skill-install.d.ts +16 -0
  103. package/dist/skill-install.d.ts.map +1 -0
  104. package/dist/software-capture.d.ts +102 -0
  105. package/dist/software-capture.d.ts.map +1 -0
  106. package/dist/tools/__tests__/browser-host-port.test.d.ts +2 -0
  107. package/dist/tools/__tests__/browser-host-port.test.d.ts.map +1 -0
  108. package/dist/tools/__tests__/carrier-faults.integration.test.d.ts +2 -0
  109. package/dist/tools/__tests__/carrier-faults.integration.test.d.ts.map +1 -0
  110. package/dist/tools/__tests__/carrier-provider.integration.test.d.ts +2 -0
  111. package/dist/tools/__tests__/carrier-provider.integration.test.d.ts.map +1 -0
  112. package/dist/tools/__tests__/commands.test.d.ts +2 -0
  113. package/dist/tools/__tests__/commands.test.d.ts.map +1 -0
  114. package/dist/tools/__tests__/coverage-gaps.test.d.ts +2 -0
  115. package/dist/tools/__tests__/coverage-gaps.test.d.ts.map +1 -0
  116. package/dist/tools/__tests__/domain-catalog.test.d.ts +2 -0
  117. package/dist/tools/__tests__/domain-catalog.test.d.ts.map +1 -0
  118. package/dist/tools/__tests__/preview-owner-gate.test.d.ts +2 -0
  119. package/dist/tools/__tests__/preview-owner-gate.test.d.ts.map +1 -0
  120. package/dist/tools/__tests__/preview-publication.test.d.ts +2 -0
  121. package/dist/tools/__tests__/preview-publication.test.d.ts.map +1 -0
  122. package/dist/tools/__tests__/realm-dispatch.integration.test.d.ts +2 -0
  123. package/dist/tools/__tests__/realm-dispatch.integration.test.d.ts.map +1 -0
  124. package/dist/tools/benchmark/__tests__/admission-fixtures.test.d.ts +2 -0
  125. package/dist/tools/benchmark/__tests__/admission-fixtures.test.d.ts.map +1 -0
  126. package/dist/tools/benchmark/__tests__/benchmark-vocabulary-owner.test-d.d.ts +2 -0
  127. package/dist/tools/benchmark/__tests__/benchmark-vocabulary-owner.test-d.d.ts.map +1 -0
  128. package/dist/tools/benchmark/harness.d.ts +17 -0
  129. package/dist/tools/benchmark/harness.d.ts.map +1 -0
  130. package/dist/tools/benchmark/index.d.ts +4 -0
  131. package/dist/tools/benchmark/index.d.ts.map +1 -0
  132. package/dist/tools/benchmark/report.d.ts +54 -0
  133. package/dist/tools/benchmark/report.d.ts.map +1 -0
  134. package/dist/tools/benchmark/statistics.d.ts +8 -0
  135. package/dist/tools/benchmark/statistics.d.ts.map +1 -0
  136. package/dist/tools/bootstrap.d.ts +49 -0
  137. package/dist/tools/bootstrap.d.ts.map +1 -0
  138. package/dist/tools/browser-host.d.ts +27 -0
  139. package/dist/tools/browser-host.d.ts.map +1 -0
  140. package/dist/tools/cache.d.ts +14 -0
  141. package/dist/tools/cache.d.ts.map +1 -0
  142. package/dist/tools/capability.d.ts +2 -0
  143. package/dist/tools/capability.d.ts.map +1 -0
  144. package/dist/tools/carrier-provider.d.ts +31 -0
  145. package/dist/tools/carrier-provider.d.ts.map +1 -0
  146. package/dist/tools/carrier-rendezvous.d.ts +16 -0
  147. package/dist/tools/carrier-rendezvous.d.ts.map +1 -0
  148. package/dist/tools/catalog.d.ts +66 -0
  149. package/dist/tools/catalog.d.ts.map +1 -0
  150. package/dist/tools/cli-adapter.d.ts +5 -0
  151. package/dist/tools/cli-adapter.d.ts.map +1 -0
  152. package/dist/tools/client.d.ts +18 -0
  153. package/dist/tools/client.d.ts.map +1 -0
  154. package/dist/tools/commands.d.ts +11 -0
  155. package/dist/tools/commands.d.ts.map +1 -0
  156. package/dist/tools/contributions.d.ts +6 -0
  157. package/dist/tools/contributions.d.ts.map +1 -0
  158. package/dist/tools/library.d.ts +3 -0
  159. package/dist/tools/library.d.ts.map +1 -0
  160. package/dist/tools/migration.d.ts +36 -0
  161. package/dist/tools/migration.d.ts.map +1 -0
  162. package/dist/tools/native-preview.d.ts +4 -0
  163. package/dist/tools/native-preview.d.ts.map +1 -0
  164. package/dist/tools/offline-analysis.d.ts +22 -0
  165. package/dist/tools/offline-analysis.d.ts.map +1 -0
  166. package/dist/tools/preview-catalog.d.ts +8 -0
  167. package/dist/tools/preview-catalog.d.ts.map +1 -0
  168. package/dist/tools/preview-contributions.d.ts +12 -0
  169. package/dist/tools/preview-contributions.d.ts.map +1 -0
  170. package/dist/tools/preview-host.d.ts +85 -0
  171. package/dist/tools/preview-host.d.ts.map +1 -0
  172. package/dist/tools/preview-migration.d.ts +4 -0
  173. package/dist/tools/preview-migration.d.ts.map +1 -0
  174. package/dist/tools/private-executor.d.ts +3 -0
  175. package/dist/tools/private-executor.d.ts.map +1 -0
  176. package/dist/tools/project-tools.d.ts +23 -0
  177. package/dist/tools/project-tools.d.ts.map +1 -0
  178. package/dist/tools/realms.d.ts +22 -0
  179. package/dist/tools/realms.d.ts.map +1 -0
  180. package/dist/tools/run-command.d.ts +17 -0
  181. package/dist/tools/run-command.d.ts.map +1 -0
  182. package/dist/tools/runtime.d.ts +5 -0
  183. package/dist/tools/runtime.d.ts.map +1 -0
  184. package/dist/tools/service-transport.d.ts +17 -0
  185. package/dist/tools/service-transport.d.ts.map +1 -0
  186. package/dist/tools/service.d.ts +22 -0
  187. package/dist/tools/service.d.ts.map +1 -0
  188. package/dist/types.d.ts +101 -0
  189. package/dist/types.d.ts.map +1 -0
  190. package/package.json +96 -0
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ Apache License 2.0
2
+
3
+ Copyright 2026 ForgeaXGame
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,334 @@
1
+ # @forgeax/engine-devkit
2
+
3
+ DevKit is the Node-only external-project seam for ForgeaX. It derives project
4
+ commands, authoring-preview contributions, and one AI-facing RHI-debug path from
5
+ the existing project authorities. It owns orchestration and file access; Engine
6
+ owns rendering, RHI events, replay backends, and preview execution.
7
+
8
+ > [!IMPORTANT]
9
+ > Keep one artifact reference across the RHI-debug flow. `rhi.summary` and
10
+ > `rhi.inspect` never rediscover a tape, infer a file pair, or parse error text.
11
+
12
+ ## Navigation
13
+
14
+ - [CLI and catalog](#cli-and-catalog)
15
+ - [CPU-only full-page capture](#cpu-only-full-page-capture)
16
+ - [Startup diagnostics](#startup-diagnostics)
17
+ - [RHI-debug operations](#rhi-debug-operations)
18
+ - [Authoring preview](#authoring-preview)
19
+ - [Project authority](#project-authority)
20
+ - [Migration and carrier](#migration-and-carrier)
21
+
22
+ ## CLI and catalog
23
+
24
+ The normal project commands remain available through the `forgeax` CLI:
25
+
26
+ ```text
27
+ forgeax new [directory] [--template empty|game-3d]
28
+ forgeax init
29
+ forgeax doctor
30
+ forgeax skill install
31
+ forgeax skill verify
32
+ forgeax test
33
+ forgeax dev
34
+ forgeax build
35
+ forgeax capture --software --require-ui --output artifacts/capture/game-ui.png --json
36
+ forgeax preview
37
+ forgeax package [--output release/game-web.zip]
38
+ forgeax list --json
39
+ forgeax describe project.build --json
40
+ forgeax run project.build --input request.json --json
41
+ forgeax exec program.mjs --json
42
+ forgeax run rhi.summary --artifact .forgeax-debug/{runId}/frame.rhitape --digest {sha256}
43
+ forgeax run rhi.inspect --artifact .forgeax-debug/{runId}/frame.rhitape --digest {sha256} --work-index {workIndex}
44
+ ```
45
+
46
+ > [!IMPORTANT]
47
+ > `forgeax dev` is a source-development server and `forgeax preview` is a
48
+ > verified static `dist/` server. Their `--json` startup envelopes expose
49
+ > `mode`, `serves`, and the current `rhi.capture` capability. Neither command
50
+ > silently invents a live capture attachment.
51
+
52
+ Static deployment is an Engine-owned build product. A publishing host supplies
53
+ the project root, public URL base, and dedicated output directory; DevKit owns
54
+ the generated host, asset cooking, shader compilation, Pack index, and
55
+ `forgeax-dist.json` closure.
56
+
57
+ > [!IMPORTANT]
58
+ > DevKit also closes the Engine builtin-mesh dependency boundary. During a
59
+ > standalone build it adds a generated Pack descriptor only for builtin mesh
60
+ > GUIDs absent from the project; the Geometry decoder turns those descriptors
61
+ > into validated primitive meshes. Project-authored descriptors remain the
62
+ > single declaration, so the generated Pack never creates a GUID collision.
63
+
64
+ ```bash
65
+ forgeax build ./games/my-game \
66
+ --base /games/my-game/ \
67
+ --out-dir ./website-staging/games/my-game \
68
+ --json
69
+ ```
70
+
71
+ `--out-dir` resolves relative to the game project root unless it is absolute.
72
+ The selected directory is a derived build root and is emptied before writing.
73
+ `forgeax preview` continues to verify and serve the default `dist/` directory.
74
+
75
+ `forgeax new` accepts an absent or empty target only when that target is outside the unpacked SDK
76
+ root. An SDK-owned target fails before template copying with `project-target-inside-sdk`; use a
77
+ sibling directory or an absolute path outside the SDK.
78
+
79
+ `forgeax package` rebuilds with relative URLs, verifies the complete `forgeax-dist.json` closure,
80
+ and emits a deterministic Web ZIP plus an adjacent SHA-256 file. The archive contains the bundled
81
+ Engine JavaScript/WASM runtime and game assets at its root for HTTPS static or HTML-game hosting;
82
+ it does not contain source, `node_modules`, or a local development server. Use `forgeax preview`
83
+ for local HTTP acceptance. Opening the archived `index.html` through `file://` is unsupported.
84
+
85
+ `discoverRhiDebugOperations()` returns the same descriptors used by help and
86
+ schema output. The operation manifest is the single discovery and recovery
87
+ surface for RHI-debug.
88
+
89
+ ## CPU-only full-page capture
90
+
91
+ > [!IMPORTANT]
92
+ > `forgeax capture --software` is an explicit advanced Linux development path for machines with no
93
+ > physical GPU and no display server. It is not part of the ordinary player, preview, or release
94
+ > acceptance path.
95
+
96
+ The command starts the source-development host on an ephemeral loopback port, creates an Xvfb display
97
+ when `$DISPLAY` is absent, launches Chrome Beta with SwiftShader WebGPU, waits for a non-empty canvas,
98
+ then adaptively rejects uniform **canvas** frames before taking a Playwright **page screenshot**. A page
99
+ screenshot composites the WebGPU canvas with normal DOM and open ShadowRoot UI;
100
+ `canvas.toDataURL()` cannot provide that proof. `--wait-ms` is an additional settle interval after the
101
+ first non-flat canvas frame, not a guess for CPU startup time.
102
+
103
+ ```bash
104
+ forgeax capture --software --require-ui \
105
+ --output artifacts/capture/game-ui.png \
106
+ --width 1280 --height 720 --wait-ms 4000 --json
107
+ ```
108
+
109
+ The adjacent `game-ui.json` is the schema-v2 run manifest. Its run-level fields record the browser,
110
+ viewport, X display, lavapipe ICD discovery, and browser errors; its ordered `captures[]` rows record
111
+ each PNG digest, checkpoint, actual `GPUAdapterInfo`, canvas/UI witnesses, and canvas-only sampled luma
112
+ range. The witness screenshot temporarily hides every non-canvas element, so a visible HUD cannot
113
+ disguise a black 3D frame; the written PNG remains the complete page compositor output.
114
+ `--require-ui` requires at least one mounted child under the generated host's `#game-ui` root; unrelated
115
+ Engine or browser ShadowRoots are only diagnostics and cannot satisfy the gate. A uniform black frame
116
+ also fails even when canvas and adapter structure exist. Use `--browser` only when Chrome Beta is not at
117
+ `/opt/google/chrome-beta/chrome`.
118
+
119
+ The browser context fixes the viewport and screen size, DPR 1, sRGB colour profile, light colour
120
+ scheme, `en-US` locale, UTC timezone, and waits for `document.fonts.ready`. Projects must ship the same
121
+ Web font files on every machine; a system-font fallback is not a colour or layout parity contract.
122
+
123
+ For local/remote pixel or colour comparison, add `--deterministic`. The command navigates with
124
+ `?forgeaxCapture=1`. The Engine App publishes
125
+ `document.documentElement.dataset.forgeaxFrameSubmitted` (the monotonic frame id) after the Renderer
126
+ crosses its real queue-submit boundary and dispatches `forgeax:frame-submitted` on the canvas. DevKit
127
+ waits for that engine signal and a non-flat canvas crop before consuming the game's
128
+ `document.documentElement.dataset.forgeaxCaptureReady` checkpoint; it never guesses startup time. The
129
+ game remains the time authority: in capture mode it must pin its random seed, viewport-independent
130
+ state, local web fonts, and logical time/frame, render that state, then publish the ready marker. A
131
+ wall-clock delay is useful only as extra settle and is not parity evidence.
132
+
133
+ ```bash
134
+ forgeax capture --software --require-ui --deterministic \
135
+ --width 1280 --height 720 --output artifacts/capture/parity.png --json
136
+ ```
137
+
138
+ ### Persistent playthrough capture
139
+
140
+ `capture` is the one-shot adapter over the same browser owner. For one game boot followed by input,
141
+ assertions, and multiple compositor captures, compose the persistent session through `forgeax exec`:
142
+
143
+ ```js
144
+ export default async function playthrough({ browser }) {
145
+ const session = await browser.open({
146
+ software: true,
147
+ deterministic: true,
148
+ requireUi: true,
149
+ outputDir: 'artifacts/playthrough/boss-flow',
150
+ });
151
+ try {
152
+ const { page } = session;
153
+ await page.getByRole('button', { name: 'Start' }).click();
154
+ const spawn = await session.capture('spawn');
155
+ await page.keyboard.press('KeyW');
156
+ const arena = await session.capture('arena');
157
+ await page.getByRole('button', { name: 'Cast' }).click();
158
+ const bossHit = await session.capture('boss-hit');
159
+ return { report: session.reportPath, captures: [spawn, arena, bossHit] };
160
+ } finally {
161
+ await session.close();
162
+ }
163
+ }
164
+ ```
165
+
166
+ ```bash
167
+ forgeax exec tests/boss-playthrough.mjs --json
168
+ ```
169
+
170
+ The Engine App frame signal and the game checkpoint are separate composable authorities:
171
+ `session.capture('boss-hit')` waits for the engine frame signal, then the exact
172
+ `document.documentElement.dataset.forgeaxCaptureReady` value and non-flat pixels. Playwright remains
173
+ the input/assertion owner through the unwrapped `session.page`.
174
+ DevKit owns Xvfb/Chrome/Vite lifecycle, compositor stabilization, PNG validation, numbering, digests,
175
+ and one `run.json`. A live `Page` or session may not be returned from the program; `exec` accepts only
176
+ JSON-safe results and closes leaked sessions on exit.
177
+
178
+ | CPU backend | Owner | What it proves |
179
+ |:--|:--|:--|
180
+ | Mesa lavapipe | Dawn/Node smoke and explicit GPUTexture readback | Offscreen render pixels without a display; no HTML UI |
181
+ | Chrome SwiftShader under Xvfb | `forgeax capture --software` or `forgeax exec` browser session | Browser WebGPU canvas plus HTML/Shadow DOM in ordered viewport PNGs |
182
+
183
+ > [!CAUTION]
184
+ > Software pixels are iteration evidence. They do not prove physical-GPU performance, vendor-driver
185
+ > behavior, HDR-display output, or release visual acceptance.
186
+
187
+ Physical realm consumers use `createRealmDispatch`. Each descriptor is routed to
188
+ one owner for its declared `build`, `host`, or `engine` realm. A missing owner
189
+ returns `tool-capability-unavailable` with the realm in `detail`; it never falls
190
+ through to another realm.
191
+
192
+ ## Startup diagnostics
193
+
194
+ The generated game host renders structured startup failures recursively instead
195
+ of coercing thrown objects to `[object Object]`. It preserves `name`, `message`,
196
+ `code`, `expected`, `hint`, `reason`, and bounded nested
197
+ `cause/detail/webgpuError/wgpuError/error` fields. Generic objects use bounded
198
+ JSON serialization and circular objects receive an explicit diagnostic.
199
+
200
+ When the resulting evidence mentions WebGPU, adapter absence, or no usable
201
+ backend, the host also states that ForgeaX supports browser WebGPU and a
202
+ wgpu/WebGL2 fallback. This note is intentionally not a fallback decision: the
203
+ structured cause remains the authority. A publishing Agent must not infer
204
+ unsupported hardware, swallow the entry error, or inject a replacement Canvas
205
+ game merely to remove an uncaught exception.
206
+
207
+ ## RHI-debug operations
208
+
209
+ The operation manifest describes the complete host contract, but a standalone
210
+ CLI process does not own a running browser App. Consequently,
211
+ `forgeax run rhi.capture --json` is a structured capability probe and returns
212
+ `capture-unavailable` until a recorder-enabled live host supplies the
213
+ `rhiCapture` eval root. Use the browser live bridge described by the
214
+ `forgeax-engine-cli` skill to invoke that root; preserve the resulting tape's
215
+ `digest` and `path` for the offline commands below. `rhi.summary` and
216
+ `rhi.inspect` remain directly executable because they consume the persisted
217
+ artifact rather than live App state.
218
+
219
+ ```mermaid
220
+ sequenceDiagram
221
+ participant AI as "AI or CLI"
222
+ participant H as "Host"
223
+ participant D as "DevKit"
224
+ participant R as "Fresh replay backend"
225
+ AI->>H: "rhiCapture.captureFrame through the live host"
226
+ H-->>AI: "one ArtifactRef"
227
+ AI->>D: "rhi.summary + ArtifactRef"
228
+ D-->>AI: "FrameModel and workIndex"
229
+ AI->>R: "rhi.inspect + ArtifactRef + workIndex"
230
+ R-->>AI: "WorkInspection or structured failure"
231
+ ```
232
+
233
+ | Operation | Input | Output | Owner |
234
+ |:--|:--|:--|:--|
235
+ | `rhi.capture` | Optional abort signal | One `ArtifactRef` plus capture bytes | Host and recorder attachment |
236
+ | `rhi.summary` | One `ArtifactRef` | Strict v7 tape decode and `FrameModel` | Protocol decoder and frame model |
237
+ | `rhi.inspect` | One `ArtifactRef`, one `workIndex`, optional fields | Fresh-backend `WorkInspection` | Replay session and readback matrix |
238
+
239
+ ### ArtifactRef
240
+
241
+ `ArtifactRef` is the handoff SSOT:
242
+
243
+ | Field | Type | Meaning |
244
+ |:--|:--|:--|
245
+ | `kind` | `'rhi-tape'` | The only RHI-debug artifact kind. |
246
+ | `digest` | `string` | Digest of the canonical v7 tape payload. |
247
+ | `source` | `string` | Host or operation that produced the artifact. |
248
+ | `path` | `string` | Optional Node-side path owned by the host. |
249
+ | `bytes` | `Uint8Array` | Capture payload supplied at the host boundary. |
250
+
251
+ Consumers switch on `RhiDebugError.code`, then narrow `.detail`. `.expected`
252
+ and `.hint` provide the next action without message parsing. Unknown operation
253
+ names, fields, artifact kinds, and tape versions fail at the boundary.
254
+
255
+ ## Authoring preview
256
+
257
+ Preview defaults to four explicit Engine-owned domain descriptors:
258
+ `material.preview`, `mesh.preview`, `vfx.preview`, and `texture.preview`.
259
+ Each follows the same `list -> describe -> run -> terminal` path and binds its
260
+ report and evidence to the requested subject and snapshot.
261
+
262
+ ```mermaid
263
+ flowchart LR
264
+ catalog["Digest-bound catalog"] --> descriptor["Domain descriptor"]
265
+ descriptor --> owner["Engine realm owner"]
266
+ owner --> terminal["One terminal result"]
267
+ terminal --> evidence["PNG, RHI tape, and profile refs"]
268
+ ```
269
+
270
+ The generic `asset.preview` and `preview.run` shapes are not discoverable. A
271
+ private legacy proof helper may remain for migration tests, but it cannot appear
272
+ in the default catalog or act as a second domain owner. Browser and Dawn
273
+ consumers must verify subject pixels and structured evidence; DOM liveness and
274
+ RhiNull readiness are not visual proof.
275
+
276
+ ## Project authority
277
+
278
+ Game projects keep authority in `forge.json`, package manifests,
279
+ `package.json#forgeax.assets`, source Meta/Pack files, and imported game code.
280
+ DevKit derives Vite and producer assembly from those facts.
281
+ The [asset authority audit schema](../../asset-authority.schema.json) records
282
+ the subject, execution, lifecycle, and runtime boundary for each producer; use
283
+ the producer's inspect/rebuild or cold-cook evidence when a derived Catalog is
284
+ stale instead of treating the runtime projection as author authority.
285
+
286
+ `forge.json#entry` is the required game bootstrap authority. When that module
287
+ is not also named by `forge.json.plugins[]`, DevKit adapts its named
288
+ `bootstrap(world, gameHost)` export into the native plugin lifecycle after the
289
+ declared project plugins are ready. Plugin install/uninstall updates
290
+ `forge.json.plugins[]`; a dependency failure restores the original manifest.
291
+ The next dev/build generation deterministically adds or removes the literal
292
+ Catalog import and production bundle reachability.
293
+
294
+ SDK-created games keep all Engine usage skills as ordinary, committable files
295
+ under root `skills/`. `skill install` idempotently projects those files into the
296
+ supported Agent discovery roots with relative symlinks and narrow managed
297
+ `.gitignore` blocks. `skill verify` checks the source inventory, local manifest,
298
+ links, and ignore rules; foreign content at a managed destination fails closed.
299
+ SDK-backed installs disable pnpm's side-effects cache so the manifest-bound
300
+ offline store remains unchanged.
301
+
302
+ Game modules default-export native Cordis plugins. Plugin install/uninstall
303
+ updates `forge.json.plugins[]`; a dependency failure restores the original
304
+ manifest. The next dev/build generation deterministically adds or removes the
305
+ literal Catalog import and production bundle reachability.
306
+
307
+ ## Migration and carrier
308
+
309
+ Only operations with committed, owner-attributed ArtifactRef proofs are admitted
310
+ to the migration roster. Operations without a verifiable digest remain absent:
311
+
312
+ | Operation | Owner | Evidence | Fallback |
313
+ |:--|:--|:--|:--|
314
+ | `preview.run` | Preview host | RHI, ProfileCapture, and PNG refs | Private executor |
315
+ | `preview.offline-analysis` | RHI-debug consumer | RHI and ProfileCapture refs | Private executor |
316
+
317
+ `resolveMigration` rechecks target realm, catalog digest, RHI backend, and
318
+ evidence before selecting a service. Service admission is optional; absent or
319
+ invalid admission selects the private executor.
320
+
321
+ `createCarrierProviderService` owns an authenticated, ephemeral provider
322
+ process. It exposes only POD carrier routes and keeps no provider registry after
323
+ `close()`. Consumers validate descriptor and recipe digests before execution.
324
+ A provider exit after `started` returns a structured terminal failure and never
325
+ migrates the run to a private executor.
326
+
327
+ <details>
328
+ <summary>Ownership boundary</summary>
329
+
330
+ DevKit does not own World, Renderer, Canvas, Context, Fiber, RHI events, a
331
+ second operation registry, or a replay backend. The host supplies capture and
332
+ backend factories; Engine supplies the actual rendering and replay behavior.
333
+
334
+ </details>