@forgeax/engine-rhi 0.1.28 → 0.1.30

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.
package/dist/errors.d.ts CHANGED
@@ -66,12 +66,21 @@ export interface RhiAssetNotRegisteredDetail {
66
66
  * message: string }` so downstream `switch (err.code)` handlers can narrow
67
67
  * the inner error (`.code` / `.expected` / `.hint`) without an `as` cast.
68
68
  */
69
+ /**
70
+ * Structured non-RHI causes carried by a `webgpu-runtime-error` wrapper.
71
+ *
72
+ * Pipeline-spec failures retain their own detail record here so callers can
73
+ * reach the backend cause without parsing `Error.message` or losing the
74
+ * producer-owned fields during initialization fan-out.
75
+ */
76
+ export interface RhiWebgpuRuntimeCause {
77
+ readonly code: string;
78
+ readonly message: string;
79
+ readonly name?: string;
80
+ readonly detail?: object;
81
+ }
69
82
  export interface RhiWebgpuRuntimeDetail {
70
- readonly error: RhiError | {
71
- code: string;
72
- message: string;
73
- name?: string;
74
- };
83
+ readonly error: RhiError | RhiWebgpuRuntimeCause;
75
84
  }
76
85
  /**
77
86
  * Detail structure exclusive to the `limit-exceeded` path.
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AA6FA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,YAAY,GACpB,qBAAqB,GACrB,qBAAqB,GACrB,gBAAgB,GAChB,uBAAuB,GACvB,mBAAmB,GACnB,sBAAsB,GACtB,0BAA0B,GAC1B,uBAAuB,GACvB,qBAAqB,GACrB,kCAAkC,GAClC,yBAAyB,GACzB,4BAA4B,GAC5B,2BAA2B,GAC3B,sBAAsB,GACtB,aAAa,GACb,KAAK,GACL,gBAAgB,GAChB,kBAAkB,GAClB,uBAAuB,GACvB,wBAAwB,GACxB,gCAAgC,GAChC,4BAA4B,GAC5B,kCAAkC,GAClC,2CAA2C,CAAC;AAEhD;;;;;;;;;GASG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,gBAAgB,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC7D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,2BAA2B,EAAE,MAAM,CAAC;IAC7C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,WAAW,oCAAoC;IACnD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,eAAe,CAAC;CAC5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,0EAA0E;AAC1E,MAAM,WAAW,2CAA2C;IAC1D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,cAAc,GACtB,sBAAsB,GACtB,2BAA2B,GAC3B,sBAAsB,GACtB,mBAAmB,GACnB,mBAAmB,GACnB,oCAAoC,GACpC,wBAAwB,GACxB,2CAA2C,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC;gBAEhC,IAAI,EAAE;QAChB,IAAI,EAAE,YAAY,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;KACrC;CAQF;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,cAAc,GACpB,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAoCxB;AAOD,OAAO,EACL,GAAG,EACH,EAAE,EACF,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,QAAQ,GACd,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts"],"names":[],"mappings":";;;;AAoYO,IAAM,QAAA,GAAN,cAAuB,KAAA,CAAM;AAAA,EACzB,IAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EAET,YAAY,IAAA,EAKT;AACD,IAAA,KAAA,CAAM,CAAA,UAAA,EAAa,KAAK,IAAI,CAAA,YAAA,EAAe,KAAK,QAAQ,CAAA,QAAA,EAAW,IAAA,CAAK,IAAI,CAAA,CAAE,CAAA;AAC9E,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AACrB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AAAA,EACrB;AACF;AAyCO,SAAS,gBAAA,CACd,YACA,KAAA,EACwB;AACxB,EAAA,IAAI,eAAe,CAAA,EAAG;AACpB,IAAA,OAAO,GAAA;AAAA,MACL,IAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAM,4BAAA;AAAA,QACN,QAAA,EAAU,qCAAA;AAAA,QACV,IAAA,EAAM;AAAA,OACP;AAAA,KACH;AAAA,EACF;AACA,EAAA,MAAM,EAAE,WAAA,EAAa,aAAA,EAAc,GAAI,KAAA;AACvC,EAAA,MAAM,UAAA,GAAa,CAAC,KAAA,KAClB,CAAC,MAAA,CAAO,UAAU,KAAK,CAAA,IAAK,KAAA,GAAQ,CAAA,IAAK,KAAA,IAAS,UAAA;AAGpD,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,IAAA,OAAO,GAAA;AAAA,MACL,IAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAM,kCAAA;AAAA,QACN,QAAA,EAAU,wEAAA;AAAA,QACV,IAAA,EAAM,gGAAA;AAAA,QACN,QAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,aAAa,UAAA;AAAW,OAC1D;AAAA,KACH;AAAA,EACF;AACA,EAAA,IAAI,UAAA,CAAW,aAAa,CAAA,EAAG;AAC7B,IAAA,OAAO,GAAA;AAAA,MACL,IAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAM,kCAAA;AAAA,QACN,QAAA,EAAU,4EAAA;AAAA,QACV,IAAA,EAAM,2GAAA;AAAA,QACN,QAAQ,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,eAAe,UAAA;AAAW,OAC9D;AAAA,KACH;AAAA,EACF;AACA,EAAA,OAAO,GAAG,MAAS,CAAA;AACrB","file":"errors.mjs","sourcesContent":["// @forgeax/engine-rhi/src/errors - RhiError + closed RhiErrorCode union + Result<T, E>.\n//\n// Shape:\n// - RhiErrorCode = closed union 23 members (charter P3: closed-union\n// exhaustive switch needs no default fallback; tsc strict mode guards\n// completeness). Extended from 6 to 10 in feat-20260508-rhi-surface-completion\n// w7 (D-S3): added 'command-encoder-finished' / 'render-pass-not-ended' /\n// 'queue-submit-failed' / 'queue-write-buffer-out-of-bounds'.\n// Extended from 10 to 14 in feat-20260509-ecs-render-bridge-mvp w6 (D-S7):\n// added 'render-system-no-camera' / 'render-system-multi-camera' /\n// 'render-system-multi-light' / 'asset-not-registered'.\n// Extended from 14 to 17 in feat-20260511-rhi-spec-realign-aggressive w6\n// (D-P4 + R-02 §2.1 W3C spec 22.2 subtypes): added 'device-lost' / 'oom' /\n// 'internal-error' so the onError fan-out can disambiguate spec error\n// subclasses without falling back to the bucket 'webgpu-runtime-error'.\n// Extended from 17 to 18 in feat-20260511-asset-system-v1 w4\n// (D-P2 + requirements §9 row 8 + AC-04 + AC-21): added\n// 'hierarchy-broken' for `propagateTransforms` stale ChildOf ref fail-fast\n// (ChildOf component references a destroyed entity); same\n// render-system / schedule semantic domain as\n// 'render-system-multi-camera' / 'render-system-no-camera'. Minor add-only\n// per AGENTS.md evolution contract (no reorder / rename / deprecate).\n// Extended from 18 to 19 in feat-20260612-rhi-destroy-renderer-dispose-gpu-\n// lifecycle M1 (D-6 + D-7 + AC-02 / AC-03): added 'destroy-after-destroy'\n// for second `destroyBuffer` / `destroyTexture` on the same handle. The\n// shim layer (rhi-webgpu + rhi-wgpu) tracks per-handle `destroyed: boolean`\n// in WeakMap-backed meta and fail-fasts the second call rather than\n// forwarding it to the underlying GPU (research F-1 wgpu wasm `destroy()`\n// is idempotent void; F-8 WebGPU spec is also idempotent void; D-7 prefers\n// fail-fast over silent idempotency because double-destroy is almost always\n// a lifecycle bug). Minor add-only per AGENTS.md evolution contract.\n// Extended from 19 to 20 in feat-20260619-wasm-fault-isolation M3 w7:\n// added 'rhi-descriptor-invalid' for `createRenderPipeline` (and other\n// create* entries) descriptor parse failures surfaced through the wgpu-wasm\n// backend (Rust `#[wasm_bindgen(catch)]` Err). The prefix-based\n// classification (D-1 / D-2) routes wasm exceptions with the stable marker\n// `[wgpu-wasm] failed to parse` to this code; exceptions without the prefix\n// remain in 'webgpu-runtime-error'. Semantics: descriptor parse failure =\n// caller bug (malformed descriptor data passed from TS), distinct from\n// 'webgpu-runtime-error' = runtime condition (valid descriptor rejected by\n// wgpu backend). Minor add-only per AGENTS.md evolution contract.\n// Extended from 20 to 21 in feat-20260622-chunk-gpu-instancing-sprite-\n// tilemap M2 w10 (D-2 + AC-05 + research N-1): added\n// 'instancing-exceeds-uniform-cap' for the WebGL2 uniform-fallback path\n// when a record-stage fold bucket carries more than 128 instances\n// (128 = MAX_UNIFORM_INSTANCES; 128 * 64B = 8192B comfortably fits the\n// WebGL2 minimum 16384B UBO size, leaving headroom for the per-frame\n// material UBO slice — research N-1 implements the locked value). The\n// record-stage dispatch site fires the error AND falls the offending\n// bucket back to per-entity drawIndexed (the same exit the mode-gate\n// bypass uses — plan-strategy D-9 \"shared fallback exit\"). Semantics:\n// distinct from 'limit-exceeded' (byte-cap against\n// maxStorageBufferBindingSize) — this code targets the per-bucket\n// instance-count cap, which is a backend-capability ceiling rather than\n// an allocation-size ceiling. AI users branch on .code first then read\n// detail.requested / .limit / .scope through property access (charter\n// P3 + plan-strategy 8.3 actionable hint). Minor add-only\n// per AGENTS.md evolution contract.\n// Extended from 21 to 23 in feat-20260708-composited-multi-world-rendering\n// M3 (D-5): added 'render-system-empty-worlds' + 'render-system-owner-out-of-\n// range' for draw(worlds, { cameraOwner, resourceOwner }) entry validation. The\n// owner-out-of-range path exposes .detail = RhiOwnerOutOfRangeDetail\n// ({ role, owner, worldCount } after feat-20260709-editor-world-partition\n// M1 / w7: role ∈ {'camera','resource'} names which of the two split draw\n// owners is out of range); empty-worlds carries no .detail. The pure\n// validateDrawArgs(worldCount, { cameraOwner, resourceOwner })\n// helper (World-free primitives) emits both and is consumed by the runtime\n// createRenderer draw entry (the codes' SSOT stays in rhi). Checks run\n// empty-worlds -> cameraOwner -> resourceOwner; the first out-of-range owner\n// wins (role='camera' when both offend). Add-only (no new code, 0 net Δ per\n// D-3) per AGENTS.md evolution contract.\n// - RhiError class has readonly .code / .expected / .hint three-field surface\n// (AGENTS.md \"Errors are structured\" / D-5); the 'shader-compile-failed' path\n// exposes .detail = RhiShaderCompileDetail (compilerMessages array);\n// the 'asset-not-registered' path exposes .detail = RhiAssetNotRegisteredDetail\n// ({ assetHandle: number }, D-S6); the 'webgpu-runtime-error' path optionally\n// exposes .detail = RhiWebgpuRuntimeDetail ({ error: RhiError | fallback }, D-S8) for\n// RenderSystem internal exception fan-out; the 'limit-exceeded' path\n// exposes .detail = LimitExceededDetail ({ maxStorageBufferBindingSize,\n// requestedBytes }, feat-20260513-instanced-mesh M5 reshape from legacy\n// { renderableCount, limit }); the other 15 paths leave\n// .detail = undefined per charter proposition 4 baseline.\n// - Result<T, E> = binary tag union ('ok' / 'err'), per AGENTS.md \"Errors are\n// structured\" convention.\n//\n// Related: requirements AC AC-10 + MVP-1.7 + AC-RSC-07 + hard-constraint 8 +\n// AI User Affordances; plan-strategy 2 S-6 (types/rhi single source) +\n// 7.3 error-info table; plan-decisions OQ-P2 (forward all 6 fields of\n// GPUCompilationMessage); D-S3 (4 command/queue members) + D-S6 / D-S7\n// / D-S8 (4 RenderSystem / AssetRegistry members + .detail structure).\n\n/// <reference types=\"@webgpu/types\" />\n\nimport { err, ok, type Result } from '@forgeax/engine-types';\n\n/**\n * Closed RhiErrorCode union. `switch` exhaustive checks need no default\n * fallback - tsc strict mode guards union completeness (charter proposition 4\n * + proposition 3: machine-readable union > prose).\n *\n *\n * The executable union below is the machine-readable source of truth for\n * the 23 members. The package README owns the AI-facing trigger and recovery\n * table; keeping that projection in one documentation owner avoids a second\n * member ledger drifting from the union.\n *\n * @example AI-user exhaustive switch on the 4 command/queue members (no default fallback)\n * ```ts\n * import type { RhiError, RhiErrorCode } from '@forgeax/engine-rhi';\n *\n * function recover(code: RhiErrorCode): string {\n * switch (code) {\n * // ... 6 baseline members elided ...\n * case 'command-encoder-finished': return 'recreate encoder via device.createCommandEncoder()';\n * case 'render-pass-not-ended': return 'call pass.end() before next beginRenderPass()';\n * case 'queue-submit-failed': return 'audit buffer/pipeline lifetimes before submit';\n * case 'queue-write-buffer-out-of-bounds': return 'realign offset and re-check buffer.size';\n * default: return 'baseline path';\n * }\n * }\n * ```\n */\nexport type RhiErrorCode =\n | 'adapter-unavailable'\n | 'feature-not-enabled'\n | 'limit-exceeded'\n | 'shader-compile-failed'\n | 'rhi-not-available'\n | 'webgpu-runtime-error'\n | 'command-encoder-finished'\n | 'render-pass-not-ended'\n | 'queue-submit-failed'\n | 'queue-write-buffer-out-of-bounds'\n | 'render-system-no-camera'\n | 'render-system-multi-camera'\n | 'render-system-multi-light'\n | 'asset-not-registered'\n | 'device-lost'\n | 'oom'\n | 'internal-error'\n | 'hierarchy-broken'\n | 'destroy-after-destroy'\n | 'rhi-descriptor-invalid'\n | 'instancing-exceeds-uniform-cap'\n | 'render-system-empty-worlds'\n | 'render-system-owner-out-of-range'\n | 'rhi-texture-format-capability-unavailable';\n\n/**\n * Detail structure exclusive to the `shader-compile-failed` path.\n *\n * `compilerMessages` directly forwards the 6 standardized fields of\n * `GPUCompilationMessage` from `@webgpu/types` v0.1.69 (`message` / `type` /\n * `lineNum` / `linePos` / `offset` / `length`); research F-3 finding;\n * plan-decisions OQ-P2 locks full-field forwarding.\n *\n * @see {@link GPUCompilationMessage}\n */\nexport interface RhiShaderCompileDetail {\n readonly compilerMessages: readonly GPUCompilationMessage[];\n}\n\n/**\n * Detail structure exclusive to the `asset-not-registered` path (D-S6).\n *\n * `assetHandle` carries the offending u32 handle the caller passed via\n * `MeshFilter.assetHandle`; AI users access it through property access\n * (`err.detail.assetHandle`) rather than parsing the message string\n * (charter proposition 4 + F-3 contract surface).\n */\nexport interface RhiAssetNotRegisteredDetail {\n readonly assetHandle: number;\n}\n\n/**\n * Detail structure exclusive to the `webgpu-runtime-error` path (D-S8).\n *\n * `error` carries the underlying exception object so AI users can inspect the\n * root cause (`.code` / `.expected` / `.hint` for `RhiError` paths, or\n * `.code` + `.message` for non-RhiError falls) without parsing the\n * RhiError.message field. Optional: the K-9 silent-skip fan-out root path\n * may emit `webgpu-runtime-error` without `.detail` when the underlying\n * exception is unavailable.\n *\n * feat-20260608-mesh-ssbo-dynamic-grow-l1-lift-1024-entity-cap M4 / T-M4-02:\n * `error` field type widened from `string` to `RhiError | { code: string;\n * message: string }` so downstream `switch (err.code)` handlers can narrow\n * the inner error (`.code` / `.expected` / `.hint`) without an `as` cast.\n */\nexport interface RhiWebgpuRuntimeDetail {\n readonly error: RhiError | { code: string; message: string; name?: string };\n}\n\n/**\n * Detail structure exclusive to the `limit-exceeded` path.\n *\n * `maxStorageBufferBindingSize` carries the device-reported storage cap\n * (`device.limits.maxStorageBufferBindingSize`); `requestedBytes`\n * carries the byte count the caller attempted to allocate. AI users\n * access these through typed property access (`err.detail.maxStorageBufferBindingSize`\n * / `err.detail.requestedBytes`) rather than parsing the message string\n * — charter proposition 4 structured-error consumption path; `err.hint`\n * is for human eyeballs only.\n *\n * Single live emit point: the RenderSystem record stage per-entity\n * instance buffer upload path\n * (`packages/runtime/src/render-system-record.ts`). The 18-member\n * `RhiErrorCode` union is unchanged (`'limit-exceeded'` discriminant\n * preserved); evolution major rename + replace of the discriminated\n * `detail` shape per AGENTS.md Change stance + plan-strategy D-3.\n *\n * Migration history:\n * - feat-20260513-instanced-mesh M5: detail reshape from\n * `{ renderableCount, limit }` to `{ maxStorageBufferBindingSize,\n * requestedBytes }`. Emit point at the time was\n * `AssetRegistry.createInstancedBuffer`.\n * - feat-20260907-case01-case05-engine-convergence: explicit instance\n * matrices are supplied by the renderer-owned collection projection;\n * `requestedBytes` describes the resident record payload at the record\n * stage, independent of ECS managed-array capacity.\n */\nexport interface LimitExceededDetail {\n readonly maxStorageBufferBindingSize: number;\n readonly requestedBytes: number;\n}\n\n/**\n * Detail structure exclusive to the `'render-system-multi-light'` path.\n * The only remaining cardinality rule is one global DirectionalLight; all\n * PointLight, SpotLight, and RectArea lights are admitted through the shared\n * shared Cluster corpus and are admitted by the same local-light contract.\n */\nexport interface RhiMultiLightDetail {\n readonly type: 'directional';\n readonly got: number;\n}\n\n/**\n * Detail structure exclusive to the `'instancing-exceeds-uniform-cap'` path\n * (feat-20260622-chunk-gpu-instancing-sprite-tilemap M2 / w10 +\n * plan-strategy 2 D-2 + research N-1).\n *\n * Emitted by the record-stage fold dispatch loop\n * (`packages/runtime/src/render-system-record.ts`) when\n * `caps.storageBuffer === false` AND a fold bucket carries more than\n * `limit` instances. The engine fires the error AND falls the offending\n * bucket back to per-entity drawIndexed via the same exit the mode-gate\n * bypass uses (plan-strategy D-9 \"shared fallback exit\"), so the frame\n * is still visually correct (no identity-collapse / black screen) and\n * the cap event surfaces structurally for AI users to observe.\n *\n * Fields:\n * - `requested` — the offending bucket's instance count\n * (`FoldBucket.bucketSize`); always strictly greater than `limit` at\n * emit time (the cap-check helper guards `requested > limit`).\n * - `limit` — the literal 128. The value is locked at the type level\n * because the cap is structurally tied to the WebGL2 minimum 16384 B\n * UBO size (128 * 64 B mat4 stride = 8192 B leaves headroom for the\n * per-frame material UBO slice — research N-1). A future cap change\n * would be a major evolution, not a runtime knob.\n * - `scope` — closed `'sprite' | 'tilemap-chunk'` discriminator that\n * pinpoints the dispatch site (sprite-pass entry that came directly\n * from a user-spawned Sprite vs one derived by\n * `tilemap-chunk-extract-system`). AI users branch on `.scope` to\n * decide whether to shrink the sprite batch size or the tilemap\n * chunk size.\n *\n * AI-user consumption (charter P3 + plan-strategy 8.3):\n * ```ts\n * if (err.code === 'instancing-exceeds-uniform-cap') {\n * const d = err.detail as RhiInstancingExceedsUniformCapDetail;\n * if (d.scope === 'sprite') shrinkSpriteBatchSize(d.requested);\n * else if (d.scope === 'tilemap-chunk') shrinkTileChunkSize(d.requested);\n * }\n * ```\n * — never parse `err.message`. The discriminated `detail` field is the\n * surface; the human-readable `err.message` is for logs only.\n */\nexport interface RhiInstancingExceedsUniformCapDetail {\n readonly requested: number;\n readonly limit: 128;\n readonly scope: 'sprite' | 'tilemap-chunk';\n}\n\n/**\n * Detail structure exclusive to the `'render-system-owner-out-of-range'` path\n * (feat-20260708-composited-multi-world-rendering M3 / D-5).\n *\n * Emitted by `renderer.draw(worlds, { cameraOwner, resourceOwner })` when one\n * owner index is not valid for `worlds` (`owner < 0` or `owner >= worlds.length`).\n * An out-of-range index cannot resolve, so the frame is skipped before extract.\n *\n * Fields:\n * - `role` — WHICH of the two draw-owner indices was out of range\n * (feat-20260709-editor-world-partition M1 / w7). `draw(worlds, {\n * cameraOwner, resourceOwner })` carries two independent indices; `role`\n * tells the AI user whether the camera-source index (`'camera'`) or the\n * singleton-resource index (`'resource'`) is the offender, so the fix is\n * unambiguous from the text channel (no new error code — D-3 keeps 0 net\n * new codes; the discriminator lives in `.detail`). When both indices are\n * out of range the first offender is reported: `cameraOwner` is validated\n * before `resourceOwner`, so `role === 'camera'`.\n * - `owner` — the offending index the caller passed (the `role` index's\n * value).\n * - `worldCount` — `worlds.length` at call time (the valid range is\n * `0 .. worldCount - 1`).\n *\n * AI users branch via property access (`err.detail.role` / `err.detail.owner` /\n * `err.detail.worldCount`) after narrowing on `.code`, rather than parsing the\n * message string (charter P3 structured-failure surface).\n *\n * The sibling `'render-system-empty-worlds'` path carries no `.detail` — an\n * empty array is fully described by `.code`, and the entry check short-circuits\n * to that code before the owner-range check runs (the two codes are\n * non-exclusive).\n */\nexport interface RhiOwnerOutOfRangeDetail {\n readonly role: 'camera' | 'resource';\n readonly owner: number;\n readonly worldCount: number;\n}\n\n/** Detail for an incomplete device-owned texture-format profile probe. */\nexport interface RhiTextureFormatCapabilityUnavailableDetail {\n readonly stage: string;\n readonly deviceGeneration: number;\n readonly reason: string;\n}\n\n/**\n * Tagged union of `.detail` shapes carried by structured errors.\n *\n * Entries:\n * - `RhiShaderCompileDetail` (carries `compilerMessages`) - emitted on the\n * `'shader-compile-failed'` path.\n * - `RhiAssetNotRegisteredDetail` (carries `assetHandle`) - emitted on the\n * `'asset-not-registered'` path (D-S6).\n * - `RhiWebgpuRuntimeDetail` (carries `error: RhiError | { code, message }`) - optionally emitted\n * on the `'webgpu-runtime-error'` path when a captured `Error.message` is\n * available (D-S8).\n * - `LimitExceededDetail` (carries `maxStorageBufferBindingSize` +\n * `requestedBytes`) - emitted on the `'limit-exceeded'` path when\n * the RenderSystem record stage's per-entity Instances upload\n * exceeds `device.limits.maxStorageBufferBindingSize`\n * (feat-20260514-ecs-children-instances-managed-buffer-array M3 / w15;\n * emit point migrated from the deleted\n * `AssetRegistry.createInstancedBuffer` factory).\n *\n * The other 15 paths leave `.detail = undefined` (charter proposition 4\n * baseline).\n */\nexport type RhiErrorDetail =\n | RhiShaderCompileDetail\n | RhiAssetNotRegisteredDetail\n | RhiWebgpuRuntimeDetail\n | LimitExceededDetail\n | RhiMultiLightDetail\n | RhiInstancingExceedsUniformCapDetail\n | RhiOwnerOutOfRangeDetail\n | RhiTextureFormatCapabilityUnavailableDetail;\n\n/**\n * Structured RHI error.\n *\n * Three readonly fields aligned with AGENTS.md \"Errors are structured\":\n * - `.code` - closed union member (L1 key signal).\n * - `.expected` - expected-state description (L2 detail).\n * - `.hint` - actionable recovery guidance (L2 detail; charter proposition 3:\n * machine-readable hint > prose).\n *\n * `.detail` is populated on four paths:\n * - `code === 'shader-compile-failed'` -> `RhiShaderCompileDetail`\n * - `code === 'asset-not-registered'` -> `RhiAssetNotRegisteredDetail`\n * - `code === 'webgpu-runtime-error'` -> `RhiWebgpuRuntimeDetail` (optional)\n * - `code === 'limit-exceeded'` -> `LimitExceededDetail`\n * (feat-20260513-instanced-mesh M5 reshape; carries\n * `maxStorageBufferBindingSize` + `requestedBytes`)\n *\n * The other 15 paths leave `.detail = undefined` (charter proposition 4\n * baseline).\n *\n * Note: `RhiErrorDetail` is currently a flat tagged union without a\n * `code` discriminant field on each variant; AI users perform typed\n * narrowing via outer `switch (err.code)` then a one-time `as` cast on\n * `err.detail` per the documented variant. Full discriminated-union\n * refactor (each variant carrying its own `code` literal field) is left\n * to `feat-future-rhi-error-detail-discriminant` spinoff.\n */\nexport class RhiError extends Error {\n readonly code: RhiErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail: RhiErrorDetail | undefined;\n\n constructor(args: {\n code: RhiErrorCode;\n expected: string;\n hint: string;\n detail?: RhiErrorDetail | undefined;\n }) {\n super(`[RhiError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);\n this.name = 'RhiError';\n this.code = args.code;\n this.expected = args.expected;\n this.hint = args.hint;\n this.detail = args.detail;\n }\n}\n\n/**\n * The two split draw-owner indices carried by\n * `draw(worlds, { cameraOwner, resourceOwner })`\n * (feat-20260709-editor-world-partition M1 / w6). `cameraOwner` selects the\n * world whose cameras are surfaced; `resourceOwner` selects the world whose\n * skylight / skybox / postProcessParams are surfaced. Declared here (World-free\n * primitives) so the validator and the `RhiOwnerOutOfRangeDetail.role`\n * discriminator live in one SSOT package (architecture-principles §1).\n */\nexport interface DrawOwnerSplit {\n readonly cameraOwner: number;\n readonly resourceOwner: number;\n}\n\n/**\n * Validate `renderer.draw(worlds, { cameraOwner, resourceOwner })` arguments at\n * the draw entry (feat-20260708 M3 / D-5, extended by\n * feat-20260709-editor-world-partition M1 / w6-w7).\n *\n * The validator takes primitives (`worldCount = worlds.length`, plus the owner\n * index/indices) — no `World`, no math — so it lives in `@forgeax/engine-rhi`\n * alongside the `RhiErrorCode` members it emits (architecture-principles §1\n * SSOT). The runtime `createRenderer` draw entry calls it before any extract; a\n * non-`ok` result skips the frame with a structured error (charter P3), never a\n * silent no-op.\n *\n * Checks, in order (D-5 + w6):\n * 1. `worldCount === 0` -> `'render-system-empty-worlds'` (no `.detail`).\n * 2. `cameraOwner` is not a valid index -> `'render-system-owner-out-of-range'`\n * with `.detail = { role: 'camera', owner: cameraOwner, worldCount }`.\n * 3. `resourceOwner` is not a valid index -> `'render-system-owner-out-of-range'`\n * with `.detail = { role: 'resource', owner: resourceOwner, worldCount }`.\n * The `Number.isInteger` guard rejects a `NaN` / fractional / undefined-coerced\n * index a JS caller could pass despite the compile-time requirement. When both\n * indices are out of range the FIRST offender wins: `cameraOwner` is checked\n * before `resourceOwner`, so `role === 'camera'` (D-3 / w3 contract).\n *\n * The empty-worlds guard short-circuits before either owner-range check.\n */\nexport function validateDrawArgs(\n worldCount: number,\n owner: DrawOwnerSplit,\n): Result<void, RhiError> {\n if (worldCount === 0) {\n return err(\n new RhiError({\n code: 'render-system-empty-worlds',\n expected: 'worlds array has at least one world',\n hint: 'pass at least one world: draw([world], { cameraOwner: 0, resourceOwner: 0 })',\n }),\n );\n }\n const { cameraOwner, resourceOwner } = owner;\n const outOfRange = (index: number): boolean =>\n !Number.isInteger(index) || index < 0 || index >= worldCount;\n // cameraOwner is validated first: it is the first offender when both indices\n // are out of range (w3 contract). role names which index the AI user fixes.\n if (outOfRange(cameraOwner)) {\n return err(\n new RhiError({\n code: 'render-system-owner-out-of-range',\n expected: 'cameraOwner is an index into worlds (0 <= cameraOwner < worlds.length)',\n hint: 'cameraOwner must be in 0..worlds.length-1; the cameraOwner world supplies the surfaced cameras',\n detail: { role: 'camera', owner: cameraOwner, worldCount },\n }),\n );\n }\n if (outOfRange(resourceOwner)) {\n return err(\n new RhiError({\n code: 'render-system-owner-out-of-range',\n expected: 'resourceOwner is an index into worlds (0 <= resourceOwner < worlds.length)',\n hint: 'resourceOwner must be in 0..worlds.length-1; the resourceOwner world supplies skylight/skybox/postProcess',\n detail: { role: 'resource', owner: resourceOwner, worldCount },\n }),\n );\n }\n return ok(undefined);\n}\n\n// Result<T, E> + ok / err live in `@forgeax/engine-types` (tweak-20260612-result-\n// into-types). They were duplicated here (\"byte-for-byte aligned\" by prose) and\n// in packages/ecs/src/result.ts; SSOT consolidated upstream. The barrel here\n// re-exports them so existing `import { err, ok, Result, ResultOk, ResultErr }\n// from '@forgeax/engine-rhi'` consumers stay unchanged.\nexport {\n err,\n ok,\n type Result,\n type ResultErr,\n type ResultOk,\n} from '@forgeax/engine-types';\n"]}
1
+ {"version":3,"sources":["../src/errors.ts"],"names":[],"mappings":";;;;AAkZO,IAAM,QAAA,GAAN,cAAuB,KAAA,CAAM;AAAA,EACzB,IAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EAET,YAAY,IAAA,EAKT;AACD,IAAA,KAAA,CAAM,CAAA,UAAA,EAAa,KAAK,IAAI,CAAA,YAAA,EAAe,KAAK,QAAQ,CAAA,QAAA,EAAW,IAAA,CAAK,IAAI,CAAA,CAAE,CAAA;AAC9E,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AACrB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AAAA,EACrB;AACF;AAyCO,SAAS,gBAAA,CACd,YACA,KAAA,EACwB;AACxB,EAAA,IAAI,eAAe,CAAA,EAAG;AACpB,IAAA,OAAO,GAAA;AAAA,MACL,IAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAM,4BAAA;AAAA,QACN,QAAA,EAAU,qCAAA;AAAA,QACV,IAAA,EAAM;AAAA,OACP;AAAA,KACH;AAAA,EACF;AACA,EAAA,MAAM,EAAE,WAAA,EAAa,aAAA,EAAc,GAAI,KAAA;AACvC,EAAA,MAAM,UAAA,GAAa,CAAC,KAAA,KAClB,CAAC,MAAA,CAAO,UAAU,KAAK,CAAA,IAAK,KAAA,GAAQ,CAAA,IAAK,KAAA,IAAS,UAAA;AAGpD,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,IAAA,OAAO,GAAA;AAAA,MACL,IAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAM,kCAAA;AAAA,QACN,QAAA,EAAU,wEAAA;AAAA,QACV,IAAA,EAAM,gGAAA;AAAA,QACN,QAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,aAAa,UAAA;AAAW,OAC1D;AAAA,KACH;AAAA,EACF;AACA,EAAA,IAAI,UAAA,CAAW,aAAa,CAAA,EAAG;AAC7B,IAAA,OAAO,GAAA;AAAA,MACL,IAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAM,kCAAA;AAAA,QACN,QAAA,EAAU,4EAAA;AAAA,QACV,IAAA,EAAM,2GAAA;AAAA,QACN,QAAQ,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,eAAe,UAAA;AAAW,OAC9D;AAAA,KACH;AAAA,EACF;AACA,EAAA,OAAO,GAAG,MAAS,CAAA;AACrB","file":"errors.mjs","sourcesContent":["// @forgeax/engine-rhi/src/errors - RhiError + closed RhiErrorCode union + Result<T, E>.\n//\n// Shape:\n// - RhiErrorCode = closed union 23 members (charter P3: closed-union\n// exhaustive switch needs no default fallback; tsc strict mode guards\n// completeness). Extended from 6 to 10 in feat-20260508-rhi-surface-completion\n// w7 (D-S3): added 'command-encoder-finished' / 'render-pass-not-ended' /\n// 'queue-submit-failed' / 'queue-write-buffer-out-of-bounds'.\n// Extended from 10 to 14 in feat-20260509-ecs-render-bridge-mvp w6 (D-S7):\n// added 'render-system-no-camera' / 'render-system-multi-camera' /\n// 'render-system-multi-light' / 'asset-not-registered'.\n// Extended from 14 to 17 in feat-20260511-rhi-spec-realign-aggressive w6\n// (D-P4 + R-02 §2.1 W3C spec 22.2 subtypes): added 'device-lost' / 'oom' /\n// 'internal-error' so the onError fan-out can disambiguate spec error\n// subclasses without falling back to the bucket 'webgpu-runtime-error'.\n// Extended from 17 to 18 in feat-20260511-asset-system-v1 w4\n// (D-P2 + requirements §9 row 8 + AC-04 + AC-21): added\n// 'hierarchy-broken' for `propagateTransforms` stale ChildOf ref fail-fast\n// (ChildOf component references a destroyed entity); same\n// render-system / schedule semantic domain as\n// 'render-system-multi-camera' / 'render-system-no-camera'. Minor add-only\n// per AGENTS.md evolution contract (no reorder / rename / deprecate).\n// Extended from 18 to 19 in feat-20260612-rhi-destroy-renderer-dispose-gpu-\n// lifecycle M1 (D-6 + D-7 + AC-02 / AC-03): added 'destroy-after-destroy'\n// for second `destroyBuffer` / `destroyTexture` on the same handle. The\n// shim layer (rhi-webgpu + rhi-wgpu) tracks per-handle `destroyed: boolean`\n// in WeakMap-backed meta and fail-fasts the second call rather than\n// forwarding it to the underlying GPU (research F-1 wgpu wasm `destroy()`\n// is idempotent void; F-8 WebGPU spec is also idempotent void; D-7 prefers\n// fail-fast over silent idempotency because double-destroy is almost always\n// a lifecycle bug). Minor add-only per AGENTS.md evolution contract.\n// Extended from 19 to 20 in feat-20260619-wasm-fault-isolation M3 w7:\n// added 'rhi-descriptor-invalid' for `createRenderPipeline` (and other\n// create* entries) descriptor parse failures surfaced through the wgpu-wasm\n// backend (Rust `#[wasm_bindgen(catch)]` Err). The prefix-based\n// classification (D-1 / D-2) routes wasm exceptions with the stable marker\n// `[wgpu-wasm] failed to parse` to this code; exceptions without the prefix\n// remain in 'webgpu-runtime-error'. Semantics: descriptor parse failure =\n// caller bug (malformed descriptor data passed from TS), distinct from\n// 'webgpu-runtime-error' = runtime condition (valid descriptor rejected by\n// wgpu backend). Minor add-only per AGENTS.md evolution contract.\n// Extended from 20 to 21 in feat-20260622-chunk-gpu-instancing-sprite-\n// tilemap M2 w10 (D-2 + AC-05 + research N-1): added\n// 'instancing-exceeds-uniform-cap' for the WebGL2 uniform-fallback path\n// when a record-stage fold bucket carries more than 128 instances\n// (128 = MAX_UNIFORM_INSTANCES; 128 * 64B = 8192B comfortably fits the\n// WebGL2 minimum 16384B UBO size, leaving headroom for the per-frame\n// material UBO slice — research N-1 implements the locked value). The\n// record-stage dispatch site fires the error AND falls the offending\n// bucket back to per-entity drawIndexed (the same exit the mode-gate\n// bypass uses — plan-strategy D-9 \"shared fallback exit\"). Semantics:\n// distinct from 'limit-exceeded' (byte-cap against\n// maxStorageBufferBindingSize) — this code targets the per-bucket\n// instance-count cap, which is a backend-capability ceiling rather than\n// an allocation-size ceiling. AI users branch on .code first then read\n// detail.requested / .limit / .scope through property access (charter\n// P3 + plan-strategy 8.3 actionable hint). Minor add-only\n// per AGENTS.md evolution contract.\n// Extended from 21 to 23 in feat-20260708-composited-multi-world-rendering\n// M3 (D-5): added 'render-system-empty-worlds' + 'render-system-owner-out-of-\n// range' for draw(worlds, { cameraOwner, resourceOwner }) entry validation. The\n// owner-out-of-range path exposes .detail = RhiOwnerOutOfRangeDetail\n// ({ role, owner, worldCount } after feat-20260709-editor-world-partition\n// M1 / w7: role ∈ {'camera','resource'} names which of the two split draw\n// owners is out of range); empty-worlds carries no .detail. The pure\n// validateDrawArgs(worldCount, { cameraOwner, resourceOwner })\n// helper (World-free primitives) emits both and is consumed by the runtime\n// createRenderer draw entry (the codes' SSOT stays in rhi). Checks run\n// empty-worlds -> cameraOwner -> resourceOwner; the first out-of-range owner\n// wins (role='camera' when both offend). Add-only (no new code, 0 net Δ per\n// D-3) per AGENTS.md evolution contract.\n// - RhiError class has readonly .code / .expected / .hint three-field surface\n// (AGENTS.md \"Errors are structured\" / D-5); the 'shader-compile-failed' path\n// exposes .detail = RhiShaderCompileDetail (compilerMessages array);\n// the 'asset-not-registered' path exposes .detail = RhiAssetNotRegisteredDetail\n// ({ assetHandle: number }, D-S6); the 'webgpu-runtime-error' path optionally\n// exposes .detail = RhiWebgpuRuntimeDetail ({ error: RhiError | fallback }, D-S8) for\n// RenderSystem internal exception fan-out; the 'limit-exceeded' path\n// exposes .detail = LimitExceededDetail ({ maxStorageBufferBindingSize,\n// requestedBytes }, feat-20260513-instanced-mesh M5 reshape from legacy\n// { renderableCount, limit }); the other 15 paths leave\n// .detail = undefined per charter proposition 4 baseline.\n// - Result<T, E> = binary tag union ('ok' / 'err'), per AGENTS.md \"Errors are\n// structured\" convention.\n//\n// Related: requirements AC AC-10 + MVP-1.7 + AC-RSC-07 + hard-constraint 8 +\n// AI User Affordances; plan-strategy 2 S-6 (types/rhi single source) +\n// 7.3 error-info table; plan-decisions OQ-P2 (forward all 6 fields of\n// GPUCompilationMessage); D-S3 (4 command/queue members) + D-S6 / D-S7\n// / D-S8 (4 RenderSystem / AssetRegistry members + .detail structure).\n\n/// <reference types=\"@webgpu/types\" />\n\nimport { err, ok, type Result } from '@forgeax/engine-types';\n\n/**\n * Closed RhiErrorCode union. `switch` exhaustive checks need no default\n * fallback - tsc strict mode guards union completeness (charter proposition 4\n * + proposition 3: machine-readable union > prose).\n *\n *\n * The executable union below is the machine-readable source of truth for\n * the 23 members. The package README owns the AI-facing trigger and recovery\n * table; keeping that projection in one documentation owner avoids a second\n * member ledger drifting from the union.\n *\n * @example AI-user exhaustive switch on the 4 command/queue members (no default fallback)\n * ```ts\n * import type { RhiError, RhiErrorCode } from '@forgeax/engine-rhi';\n *\n * function recover(code: RhiErrorCode): string {\n * switch (code) {\n * // ... 6 baseline members elided ...\n * case 'command-encoder-finished': return 'recreate encoder via device.createCommandEncoder()';\n * case 'render-pass-not-ended': return 'call pass.end() before next beginRenderPass()';\n * case 'queue-submit-failed': return 'audit buffer/pipeline lifetimes before submit';\n * case 'queue-write-buffer-out-of-bounds': return 'realign offset and re-check buffer.size';\n * default: return 'baseline path';\n * }\n * }\n * ```\n */\nexport type RhiErrorCode =\n | 'adapter-unavailable'\n | 'feature-not-enabled'\n | 'limit-exceeded'\n | 'shader-compile-failed'\n | 'rhi-not-available'\n | 'webgpu-runtime-error'\n | 'command-encoder-finished'\n | 'render-pass-not-ended'\n | 'queue-submit-failed'\n | 'queue-write-buffer-out-of-bounds'\n | 'render-system-no-camera'\n | 'render-system-multi-camera'\n | 'render-system-multi-light'\n | 'asset-not-registered'\n | 'device-lost'\n | 'oom'\n | 'internal-error'\n | 'hierarchy-broken'\n | 'destroy-after-destroy'\n | 'rhi-descriptor-invalid'\n | 'instancing-exceeds-uniform-cap'\n | 'render-system-empty-worlds'\n | 'render-system-owner-out-of-range'\n | 'rhi-texture-format-capability-unavailable';\n\n/**\n * Detail structure exclusive to the `shader-compile-failed` path.\n *\n * `compilerMessages` directly forwards the 6 standardized fields of\n * `GPUCompilationMessage` from `@webgpu/types` v0.1.69 (`message` / `type` /\n * `lineNum` / `linePos` / `offset` / `length`); research F-3 finding;\n * plan-decisions OQ-P2 locks full-field forwarding.\n *\n * @see {@link GPUCompilationMessage}\n */\nexport interface RhiShaderCompileDetail {\n readonly compilerMessages: readonly GPUCompilationMessage[];\n}\n\n/**\n * Detail structure exclusive to the `asset-not-registered` path (D-S6).\n *\n * `assetHandle` carries the offending u32 handle the caller passed via\n * `MeshFilter.assetHandle`; AI users access it through property access\n * (`err.detail.assetHandle`) rather than parsing the message string\n * (charter proposition 4 + F-3 contract surface).\n */\nexport interface RhiAssetNotRegisteredDetail {\n readonly assetHandle: number;\n}\n\n/**\n * Detail structure exclusive to the `webgpu-runtime-error` path (D-S8).\n *\n * `error` carries the underlying exception object so AI users can inspect the\n * root cause (`.code` / `.expected` / `.hint` for `RhiError` paths, or\n * `.code` + `.message` for non-RhiError falls) without parsing the\n * RhiError.message field. Optional: the K-9 silent-skip fan-out root path\n * may emit `webgpu-runtime-error` without `.detail` when the underlying\n * exception is unavailable.\n *\n * feat-20260608-mesh-ssbo-dynamic-grow-l1-lift-1024-entity-cap M4 / T-M4-02:\n * `error` field type widened from `string` to `RhiError | { code: string;\n * message: string }` so downstream `switch (err.code)` handlers can narrow\n * the inner error (`.code` / `.expected` / `.hint`) without an `as` cast.\n */\n/**\n * Structured non-RHI causes carried by a `webgpu-runtime-error` wrapper.\n *\n * Pipeline-spec failures retain their own detail record here so callers can\n * reach the backend cause without parsing `Error.message` or losing the\n * producer-owned fields during initialization fan-out.\n */\nexport interface RhiWebgpuRuntimeCause {\n readonly code: string;\n readonly message: string;\n readonly name?: string;\n readonly detail?: object;\n}\n\nexport interface RhiWebgpuRuntimeDetail {\n readonly error: RhiError | RhiWebgpuRuntimeCause;\n}\n\n/**\n * Detail structure exclusive to the `limit-exceeded` path.\n *\n * `maxStorageBufferBindingSize` carries the device-reported storage cap\n * (`device.limits.maxStorageBufferBindingSize`); `requestedBytes`\n * carries the byte count the caller attempted to allocate. AI users\n * access these through typed property access (`err.detail.maxStorageBufferBindingSize`\n * / `err.detail.requestedBytes`) rather than parsing the message string\n * — charter proposition 4 structured-error consumption path; `err.hint`\n * is for human eyeballs only.\n *\n * Single live emit point: the RenderSystem record stage per-entity\n * instance buffer upload path\n * (`packages/runtime/src/render-system-record.ts`). The 18-member\n * `RhiErrorCode` union is unchanged (`'limit-exceeded'` discriminant\n * preserved); evolution major rename + replace of the discriminated\n * `detail` shape per AGENTS.md Change stance + plan-strategy D-3.\n *\n * Migration history:\n * - feat-20260513-instanced-mesh M5: detail reshape from\n * `{ renderableCount, limit }` to `{ maxStorageBufferBindingSize,\n * requestedBytes }`. Emit point at the time was\n * `AssetRegistry.createInstancedBuffer`.\n * - feat-20260907-case01-case05-engine-convergence: explicit instance\n * matrices are supplied by the renderer-owned collection projection;\n * `requestedBytes` describes the resident record payload at the record\n * stage, independent of ECS managed-array capacity.\n */\nexport interface LimitExceededDetail {\n readonly maxStorageBufferBindingSize: number;\n readonly requestedBytes: number;\n}\n\n/**\n * Detail structure exclusive to the `'render-system-multi-light'` path.\n * The only remaining cardinality rule is one global DirectionalLight; all\n * PointLight, SpotLight, and RectArea lights are admitted through the shared\n * shared Cluster corpus and are admitted by the same local-light contract.\n */\nexport interface RhiMultiLightDetail {\n readonly type: 'directional';\n readonly got: number;\n}\n\n/**\n * Detail structure exclusive to the `'instancing-exceeds-uniform-cap'` path\n * (feat-20260622-chunk-gpu-instancing-sprite-tilemap M2 / w10 +\n * plan-strategy 2 D-2 + research N-1).\n *\n * Emitted by the record-stage fold dispatch loop\n * (`packages/runtime/src/render-system-record.ts`) when\n * `caps.storageBuffer === false` AND a fold bucket carries more than\n * `limit` instances. The engine fires the error AND falls the offending\n * bucket back to per-entity drawIndexed via the same exit the mode-gate\n * bypass uses (plan-strategy D-9 \"shared fallback exit\"), so the frame\n * is still visually correct (no identity-collapse / black screen) and\n * the cap event surfaces structurally for AI users to observe.\n *\n * Fields:\n * - `requested` — the offending bucket's instance count\n * (`FoldBucket.bucketSize`); always strictly greater than `limit` at\n * emit time (the cap-check helper guards `requested > limit`).\n * - `limit` — the literal 128. The value is locked at the type level\n * because the cap is structurally tied to the WebGL2 minimum 16384 B\n * UBO size (128 * 64 B mat4 stride = 8192 B leaves headroom for the\n * per-frame material UBO slice — research N-1). A future cap change\n * would be a major evolution, not a runtime knob.\n * - `scope` — closed `'sprite' | 'tilemap-chunk'` discriminator that\n * pinpoints the dispatch site (sprite-pass entry that came directly\n * from a user-spawned Sprite vs one derived by\n * `tilemap-chunk-extract-system`). AI users branch on `.scope` to\n * decide whether to shrink the sprite batch size or the tilemap\n * chunk size.\n *\n * AI-user consumption (charter P3 + plan-strategy 8.3):\n * ```ts\n * if (err.code === 'instancing-exceeds-uniform-cap') {\n * const d = err.detail as RhiInstancingExceedsUniformCapDetail;\n * if (d.scope === 'sprite') shrinkSpriteBatchSize(d.requested);\n * else if (d.scope === 'tilemap-chunk') shrinkTileChunkSize(d.requested);\n * }\n * ```\n * — never parse `err.message`. The discriminated `detail` field is the\n * surface; the human-readable `err.message` is for logs only.\n */\nexport interface RhiInstancingExceedsUniformCapDetail {\n readonly requested: number;\n readonly limit: 128;\n readonly scope: 'sprite' | 'tilemap-chunk';\n}\n\n/**\n * Detail structure exclusive to the `'render-system-owner-out-of-range'` path\n * (feat-20260708-composited-multi-world-rendering M3 / D-5).\n *\n * Emitted by `renderer.draw(worlds, { cameraOwner, resourceOwner })` when one\n * owner index is not valid for `worlds` (`owner < 0` or `owner >= worlds.length`).\n * An out-of-range index cannot resolve, so the frame is skipped before extract.\n *\n * Fields:\n * - `role` — WHICH of the two draw-owner indices was out of range\n * (feat-20260709-editor-world-partition M1 / w7). `draw(worlds, {\n * cameraOwner, resourceOwner })` carries two independent indices; `role`\n * tells the AI user whether the camera-source index (`'camera'`) or the\n * singleton-resource index (`'resource'`) is the offender, so the fix is\n * unambiguous from the text channel (no new error code — D-3 keeps 0 net\n * new codes; the discriminator lives in `.detail`). When both indices are\n * out of range the first offender is reported: `cameraOwner` is validated\n * before `resourceOwner`, so `role === 'camera'`.\n * - `owner` — the offending index the caller passed (the `role` index's\n * value).\n * - `worldCount` — `worlds.length` at call time (the valid range is\n * `0 .. worldCount - 1`).\n *\n * AI users branch via property access (`err.detail.role` / `err.detail.owner` /\n * `err.detail.worldCount`) after narrowing on `.code`, rather than parsing the\n * message string (charter P3 structured-failure surface).\n *\n * The sibling `'render-system-empty-worlds'` path carries no `.detail` — an\n * empty array is fully described by `.code`, and the entry check short-circuits\n * to that code before the owner-range check runs (the two codes are\n * non-exclusive).\n */\nexport interface RhiOwnerOutOfRangeDetail {\n readonly role: 'camera' | 'resource';\n readonly owner: number;\n readonly worldCount: number;\n}\n\n/** Detail for an incomplete device-owned texture-format profile probe. */\nexport interface RhiTextureFormatCapabilityUnavailableDetail {\n readonly stage: string;\n readonly deviceGeneration: number;\n readonly reason: string;\n}\n\n/**\n * Tagged union of `.detail` shapes carried by structured errors.\n *\n * Entries:\n * - `RhiShaderCompileDetail` (carries `compilerMessages`) - emitted on the\n * `'shader-compile-failed'` path.\n * - `RhiAssetNotRegisteredDetail` (carries `assetHandle`) - emitted on the\n * `'asset-not-registered'` path (D-S6).\n * - `RhiWebgpuRuntimeDetail` (carries `error: RhiError | { code, message }`) - optionally emitted\n * on the `'webgpu-runtime-error'` path when a captured `Error.message` is\n * available (D-S8).\n * - `LimitExceededDetail` (carries `maxStorageBufferBindingSize` +\n * `requestedBytes`) - emitted on the `'limit-exceeded'` path when\n * the RenderSystem record stage's per-entity Instances upload\n * exceeds `device.limits.maxStorageBufferBindingSize`\n * (feat-20260514-ecs-children-instances-managed-buffer-array M3 / w15;\n * emit point migrated from the deleted\n * `AssetRegistry.createInstancedBuffer` factory).\n *\n * The other 15 paths leave `.detail = undefined` (charter proposition 4\n * baseline).\n */\nexport type RhiErrorDetail =\n | RhiShaderCompileDetail\n | RhiAssetNotRegisteredDetail\n | RhiWebgpuRuntimeDetail\n | LimitExceededDetail\n | RhiMultiLightDetail\n | RhiInstancingExceedsUniformCapDetail\n | RhiOwnerOutOfRangeDetail\n | RhiTextureFormatCapabilityUnavailableDetail;\n\n/**\n * Structured RHI error.\n *\n * Three readonly fields aligned with AGENTS.md \"Errors are structured\":\n * - `.code` - closed union member (L1 key signal).\n * - `.expected` - expected-state description (L2 detail).\n * - `.hint` - actionable recovery guidance (L2 detail; charter proposition 3:\n * machine-readable hint > prose).\n *\n * `.detail` is populated on four paths:\n * - `code === 'shader-compile-failed'` -> `RhiShaderCompileDetail`\n * - `code === 'asset-not-registered'` -> `RhiAssetNotRegisteredDetail`\n * - `code === 'webgpu-runtime-error'` -> `RhiWebgpuRuntimeDetail` (optional)\n * - `code === 'limit-exceeded'` -> `LimitExceededDetail`\n * (feat-20260513-instanced-mesh M5 reshape; carries\n * `maxStorageBufferBindingSize` + `requestedBytes`)\n *\n * The other 15 paths leave `.detail = undefined` (charter proposition 4\n * baseline).\n *\n * Note: `RhiErrorDetail` is currently a flat tagged union without a\n * `code` discriminant field on each variant; AI users perform typed\n * narrowing via outer `switch (err.code)` then a one-time `as` cast on\n * `err.detail` per the documented variant. Full discriminated-union\n * refactor (each variant carrying its own `code` literal field) is left\n * to `feat-future-rhi-error-detail-discriminant` spinoff.\n */\nexport class RhiError extends Error {\n readonly code: RhiErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail: RhiErrorDetail | undefined;\n\n constructor(args: {\n code: RhiErrorCode;\n expected: string;\n hint: string;\n detail?: RhiErrorDetail | undefined;\n }) {\n super(`[RhiError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);\n this.name = 'RhiError';\n this.code = args.code;\n this.expected = args.expected;\n this.hint = args.hint;\n this.detail = args.detail;\n }\n}\n\n/**\n * The two split draw-owner indices carried by\n * `draw(worlds, { cameraOwner, resourceOwner })`\n * (feat-20260709-editor-world-partition M1 / w6). `cameraOwner` selects the\n * world whose cameras are surfaced; `resourceOwner` selects the world whose\n * skylight / skybox / postProcessParams are surfaced. Declared here (World-free\n * primitives) so the validator and the `RhiOwnerOutOfRangeDetail.role`\n * discriminator live in one SSOT package (architecture-principles §1).\n */\nexport interface DrawOwnerSplit {\n readonly cameraOwner: number;\n readonly resourceOwner: number;\n}\n\n/**\n * Validate `renderer.draw(worlds, { cameraOwner, resourceOwner })` arguments at\n * the draw entry (feat-20260708 M3 / D-5, extended by\n * feat-20260709-editor-world-partition M1 / w6-w7).\n *\n * The validator takes primitives (`worldCount = worlds.length`, plus the owner\n * index/indices) — no `World`, no math — so it lives in `@forgeax/engine-rhi`\n * alongside the `RhiErrorCode` members it emits (architecture-principles §1\n * SSOT). The runtime `createRenderer` draw entry calls it before any extract; a\n * non-`ok` result skips the frame with a structured error (charter P3), never a\n * silent no-op.\n *\n * Checks, in order (D-5 + w6):\n * 1. `worldCount === 0` -> `'render-system-empty-worlds'` (no `.detail`).\n * 2. `cameraOwner` is not a valid index -> `'render-system-owner-out-of-range'`\n * with `.detail = { role: 'camera', owner: cameraOwner, worldCount }`.\n * 3. `resourceOwner` is not a valid index -> `'render-system-owner-out-of-range'`\n * with `.detail = { role: 'resource', owner: resourceOwner, worldCount }`.\n * The `Number.isInteger` guard rejects a `NaN` / fractional / undefined-coerced\n * index a JS caller could pass despite the compile-time requirement. When both\n * indices are out of range the FIRST offender wins: `cameraOwner` is checked\n * before `resourceOwner`, so `role === 'camera'` (D-3 / w3 contract).\n *\n * The empty-worlds guard short-circuits before either owner-range check.\n */\nexport function validateDrawArgs(\n worldCount: number,\n owner: DrawOwnerSplit,\n): Result<void, RhiError> {\n if (worldCount === 0) {\n return err(\n new RhiError({\n code: 'render-system-empty-worlds',\n expected: 'worlds array has at least one world',\n hint: 'pass at least one world: draw([world], { cameraOwner: 0, resourceOwner: 0 })',\n }),\n );\n }\n const { cameraOwner, resourceOwner } = owner;\n const outOfRange = (index: number): boolean =>\n !Number.isInteger(index) || index < 0 || index >= worldCount;\n // cameraOwner is validated first: it is the first offender when both indices\n // are out of range (w3 contract). role names which index the AI user fixes.\n if (outOfRange(cameraOwner)) {\n return err(\n new RhiError({\n code: 'render-system-owner-out-of-range',\n expected: 'cameraOwner is an index into worlds (0 <= cameraOwner < worlds.length)',\n hint: 'cameraOwner must be in 0..worlds.length-1; the cameraOwner world supplies the surfaced cameras',\n detail: { role: 'camera', owner: cameraOwner, worldCount },\n }),\n );\n }\n if (outOfRange(resourceOwner)) {\n return err(\n new RhiError({\n code: 'render-system-owner-out-of-range',\n expected: 'resourceOwner is an index into worlds (0 <= resourceOwner < worlds.length)',\n hint: 'resourceOwner must be in 0..worlds.length-1; the resourceOwner world supplies skylight/skybox/postProcess',\n detail: { role: 'resource', owner: resourceOwner, worldCount },\n }),\n );\n }\n return ok(undefined);\n}\n\n// Result<T, E> + ok / err live in `@forgeax/engine-types` (tweak-20260612-result-\n// into-types). They were duplicated here (\"byte-for-byte aligned\" by prose) and\n// in packages/ecs/src/result.ts; SSOT consolidated upstream. The barrel here\n// re-exports them so existing `import { err, ok, Result, ResultOk, ResultErr }\n// from '@forgeax/engine-rhi'` consumers stay unchanged.\nexport {\n err,\n ok,\n type Result,\n type ResultErr,\n type ResultOk,\n} from '@forgeax/engine-types';\n"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { AddressMode, CompareFunction, FilterMode, TextureFormat } from '@forgeax/engine-types';
2
2
  import type { RhiTextureFormatCapabilityReceipt } from './capability/texture-format';
3
- import type { Result, RhiError } from './errors';
3
+ import type { Result, RhiError } from './errors.js';
4
4
  declare const RhiBufferBrand: unique symbol;
5
5
  declare const RhiMappedBufferBrand: unique symbol;
6
6
  /**
@@ -1741,8 +1741,8 @@ export interface RhiComputePipelineOps {
1741
1741
  getBindGroupLayout(index: number): BindGroupLayout;
1742
1742
  }
1743
1743
  export { type CreateUnavailableR32FloatReceiptOptions, createUnavailableR32FloatReceipt, R32FLOAT_MIP_SAMPLED_STORAGE_PROFILE, R32FLOAT_PROBE_STAGES, type RhiTextureFormatCapabilityReceipt, type RhiTextureFormatProbeEvidence, type RhiTextureFormatProbeStage, type RhiTextureFormatProbeStageReceipt, type RhiTextureFormatProbeVerdict, type RhiTextureFormatReadback, validateR32FloatReceipt, } from './capability/texture-format';
1744
- export type { DrawOwnerSplit, LimitExceededDetail, Result, ResultErr, ResultOk, RhiAssetNotRegisteredDetail, RhiErrorCode, RhiErrorDetail, RhiOwnerOutOfRangeDetail, RhiShaderCompileDetail, RhiWebgpuRuntimeDetail, } from './errors';
1745
- export { err, ok, RhiError, validateDrawArgs } from './errors';
1744
+ export type { DrawOwnerSplit, LimitExceededDetail, Result, ResultErr, ResultOk, RhiAssetNotRegisteredDetail, RhiErrorCode, RhiErrorDetail, RhiOwnerOutOfRangeDetail, RhiShaderCompileDetail, RhiWebgpuRuntimeCause, RhiWebgpuRuntimeDetail, } from './errors.js';
1745
+ export { err, ok, RhiError, validateDrawArgs } from './errors.js';
1746
1746
  export type { AddressMode, CompareFunction, FilterMode, TextureFormat };
1747
1747
  /**
1748
1748
  * Build a TextureDescriptor for a cube-array depth texture suitable for
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/capability/texture-format.ts","../src/index.ts"],"names":["ok","err"],"mappings":"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","file":"index.mjs","sourcesContent":["// @forgeax/engine-rhi/src/errors - RhiError + closed RhiErrorCode union + Result<T, E>.\n//\n// Shape:\n// - RhiErrorCode = closed union 23 members (charter P3: closed-union\n// exhaustive switch needs no default fallback; tsc strict mode guards\n// completeness). Extended from 6 to 10 in feat-20260508-rhi-surface-completion\n// w7 (D-S3): added 'command-encoder-finished' / 'render-pass-not-ended' /\n// 'queue-submit-failed' / 'queue-write-buffer-out-of-bounds'.\n// Extended from 10 to 14 in feat-20260509-ecs-render-bridge-mvp w6 (D-S7):\n// added 'render-system-no-camera' / 'render-system-multi-camera' /\n// 'render-system-multi-light' / 'asset-not-registered'.\n// Extended from 14 to 17 in feat-20260511-rhi-spec-realign-aggressive w6\n// (D-P4 + R-02 §2.1 W3C spec 22.2 subtypes): added 'device-lost' / 'oom' /\n// 'internal-error' so the onError fan-out can disambiguate spec error\n// subclasses without falling back to the bucket 'webgpu-runtime-error'.\n// Extended from 17 to 18 in feat-20260511-asset-system-v1 w4\n// (D-P2 + requirements §9 row 8 + AC-04 + AC-21): added\n// 'hierarchy-broken' for `propagateTransforms` stale ChildOf ref fail-fast\n// (ChildOf component references a destroyed entity); same\n// render-system / schedule semantic domain as\n// 'render-system-multi-camera' / 'render-system-no-camera'. Minor add-only\n// per AGENTS.md evolution contract (no reorder / rename / deprecate).\n// Extended from 18 to 19 in feat-20260612-rhi-destroy-renderer-dispose-gpu-\n// lifecycle M1 (D-6 + D-7 + AC-02 / AC-03): added 'destroy-after-destroy'\n// for second `destroyBuffer` / `destroyTexture` on the same handle. The\n// shim layer (rhi-webgpu + rhi-wgpu) tracks per-handle `destroyed: boolean`\n// in WeakMap-backed meta and fail-fasts the second call rather than\n// forwarding it to the underlying GPU (research F-1 wgpu wasm `destroy()`\n// is idempotent void; F-8 WebGPU spec is also idempotent void; D-7 prefers\n// fail-fast over silent idempotency because double-destroy is almost always\n// a lifecycle bug). Minor add-only per AGENTS.md evolution contract.\n// Extended from 19 to 20 in feat-20260619-wasm-fault-isolation M3 w7:\n// added 'rhi-descriptor-invalid' for `createRenderPipeline` (and other\n// create* entries) descriptor parse failures surfaced through the wgpu-wasm\n// backend (Rust `#[wasm_bindgen(catch)]` Err). The prefix-based\n// classification (D-1 / D-2) routes wasm exceptions with the stable marker\n// `[wgpu-wasm] failed to parse` to this code; exceptions without the prefix\n// remain in 'webgpu-runtime-error'. Semantics: descriptor parse failure =\n// caller bug (malformed descriptor data passed from TS), distinct from\n// 'webgpu-runtime-error' = runtime condition (valid descriptor rejected by\n// wgpu backend). Minor add-only per AGENTS.md evolution contract.\n// Extended from 20 to 21 in feat-20260622-chunk-gpu-instancing-sprite-\n// tilemap M2 w10 (D-2 + AC-05 + research N-1): added\n// 'instancing-exceeds-uniform-cap' for the WebGL2 uniform-fallback path\n// when a record-stage fold bucket carries more than 128 instances\n// (128 = MAX_UNIFORM_INSTANCES; 128 * 64B = 8192B comfortably fits the\n// WebGL2 minimum 16384B UBO size, leaving headroom for the per-frame\n// material UBO slice — research N-1 implements the locked value). The\n// record-stage dispatch site fires the error AND falls the offending\n// bucket back to per-entity drawIndexed (the same exit the mode-gate\n// bypass uses — plan-strategy D-9 \"shared fallback exit\"). Semantics:\n// distinct from 'limit-exceeded' (byte-cap against\n// maxStorageBufferBindingSize) — this code targets the per-bucket\n// instance-count cap, which is a backend-capability ceiling rather than\n// an allocation-size ceiling. AI users branch on .code first then read\n// detail.requested / .limit / .scope through property access (charter\n// P3 + plan-strategy 8.3 actionable hint). Minor add-only\n// per AGENTS.md evolution contract.\n// Extended from 21 to 23 in feat-20260708-composited-multi-world-rendering\n// M3 (D-5): added 'render-system-empty-worlds' + 'render-system-owner-out-of-\n// range' for draw(worlds, { cameraOwner, resourceOwner }) entry validation. The\n// owner-out-of-range path exposes .detail = RhiOwnerOutOfRangeDetail\n// ({ role, owner, worldCount } after feat-20260709-editor-world-partition\n// M1 / w7: role ∈ {'camera','resource'} names which of the two split draw\n// owners is out of range); empty-worlds carries no .detail. The pure\n// validateDrawArgs(worldCount, { cameraOwner, resourceOwner })\n// helper (World-free primitives) emits both and is consumed by the runtime\n// createRenderer draw entry (the codes' SSOT stays in rhi). Checks run\n// empty-worlds -> cameraOwner -> resourceOwner; the first out-of-range owner\n// wins (role='camera' when both offend). Add-only (no new code, 0 net Δ per\n// D-3) per AGENTS.md evolution contract.\n// - RhiError class has readonly .code / .expected / .hint three-field surface\n// (AGENTS.md \"Errors are structured\" / D-5); the 'shader-compile-failed' path\n// exposes .detail = RhiShaderCompileDetail (compilerMessages array);\n// the 'asset-not-registered' path exposes .detail = RhiAssetNotRegisteredDetail\n// ({ assetHandle: number }, D-S6); the 'webgpu-runtime-error' path optionally\n// exposes .detail = RhiWebgpuRuntimeDetail ({ error: RhiError | fallback }, D-S8) for\n// RenderSystem internal exception fan-out; the 'limit-exceeded' path\n// exposes .detail = LimitExceededDetail ({ maxStorageBufferBindingSize,\n// requestedBytes }, feat-20260513-instanced-mesh M5 reshape from legacy\n// { renderableCount, limit }); the other 15 paths leave\n// .detail = undefined per charter proposition 4 baseline.\n// - Result<T, E> = binary tag union ('ok' / 'err'), per AGENTS.md \"Errors are\n// structured\" convention.\n//\n// Related: requirements AC AC-10 + MVP-1.7 + AC-RSC-07 + hard-constraint 8 +\n// AI User Affordances; plan-strategy 2 S-6 (types/rhi single source) +\n// 7.3 error-info table; plan-decisions OQ-P2 (forward all 6 fields of\n// GPUCompilationMessage); D-S3 (4 command/queue members) + D-S6 / D-S7\n// / D-S8 (4 RenderSystem / AssetRegistry members + .detail structure).\n\n/// <reference types=\"@webgpu/types\" />\n\nimport { err, ok, type Result } from '@forgeax/engine-types';\n\n/**\n * Closed RhiErrorCode union. `switch` exhaustive checks need no default\n * fallback - tsc strict mode guards union completeness (charter proposition 4\n * + proposition 3: machine-readable union > prose).\n *\n *\n * The executable union below is the machine-readable source of truth for\n * the 23 members. The package README owns the AI-facing trigger and recovery\n * table; keeping that projection in one documentation owner avoids a second\n * member ledger drifting from the union.\n *\n * @example AI-user exhaustive switch on the 4 command/queue members (no default fallback)\n * ```ts\n * import type { RhiError, RhiErrorCode } from '@forgeax/engine-rhi';\n *\n * function recover(code: RhiErrorCode): string {\n * switch (code) {\n * // ... 6 baseline members elided ...\n * case 'command-encoder-finished': return 'recreate encoder via device.createCommandEncoder()';\n * case 'render-pass-not-ended': return 'call pass.end() before next beginRenderPass()';\n * case 'queue-submit-failed': return 'audit buffer/pipeline lifetimes before submit';\n * case 'queue-write-buffer-out-of-bounds': return 'realign offset and re-check buffer.size';\n * default: return 'baseline path';\n * }\n * }\n * ```\n */\nexport type RhiErrorCode =\n | 'adapter-unavailable'\n | 'feature-not-enabled'\n | 'limit-exceeded'\n | 'shader-compile-failed'\n | 'rhi-not-available'\n | 'webgpu-runtime-error'\n | 'command-encoder-finished'\n | 'render-pass-not-ended'\n | 'queue-submit-failed'\n | 'queue-write-buffer-out-of-bounds'\n | 'render-system-no-camera'\n | 'render-system-multi-camera'\n | 'render-system-multi-light'\n | 'asset-not-registered'\n | 'device-lost'\n | 'oom'\n | 'internal-error'\n | 'hierarchy-broken'\n | 'destroy-after-destroy'\n | 'rhi-descriptor-invalid'\n | 'instancing-exceeds-uniform-cap'\n | 'render-system-empty-worlds'\n | 'render-system-owner-out-of-range'\n | 'rhi-texture-format-capability-unavailable';\n\n/**\n * Detail structure exclusive to the `shader-compile-failed` path.\n *\n * `compilerMessages` directly forwards the 6 standardized fields of\n * `GPUCompilationMessage` from `@webgpu/types` v0.1.69 (`message` / `type` /\n * `lineNum` / `linePos` / `offset` / `length`); research F-3 finding;\n * plan-decisions OQ-P2 locks full-field forwarding.\n *\n * @see {@link GPUCompilationMessage}\n */\nexport interface RhiShaderCompileDetail {\n readonly compilerMessages: readonly GPUCompilationMessage[];\n}\n\n/**\n * Detail structure exclusive to the `asset-not-registered` path (D-S6).\n *\n * `assetHandle` carries the offending u32 handle the caller passed via\n * `MeshFilter.assetHandle`; AI users access it through property access\n * (`err.detail.assetHandle`) rather than parsing the message string\n * (charter proposition 4 + F-3 contract surface).\n */\nexport interface RhiAssetNotRegisteredDetail {\n readonly assetHandle: number;\n}\n\n/**\n * Detail structure exclusive to the `webgpu-runtime-error` path (D-S8).\n *\n * `error` carries the underlying exception object so AI users can inspect the\n * root cause (`.code` / `.expected` / `.hint` for `RhiError` paths, or\n * `.code` + `.message` for non-RhiError falls) without parsing the\n * RhiError.message field. Optional: the K-9 silent-skip fan-out root path\n * may emit `webgpu-runtime-error` without `.detail` when the underlying\n * exception is unavailable.\n *\n * feat-20260608-mesh-ssbo-dynamic-grow-l1-lift-1024-entity-cap M4 / T-M4-02:\n * `error` field type widened from `string` to `RhiError | { code: string;\n * message: string }` so downstream `switch (err.code)` handlers can narrow\n * the inner error (`.code` / `.expected` / `.hint`) without an `as` cast.\n */\nexport interface RhiWebgpuRuntimeDetail {\n readonly error: RhiError | { code: string; message: string; name?: string };\n}\n\n/**\n * Detail structure exclusive to the `limit-exceeded` path.\n *\n * `maxStorageBufferBindingSize` carries the device-reported storage cap\n * (`device.limits.maxStorageBufferBindingSize`); `requestedBytes`\n * carries the byte count the caller attempted to allocate. AI users\n * access these through typed property access (`err.detail.maxStorageBufferBindingSize`\n * / `err.detail.requestedBytes`) rather than parsing the message string\n * — charter proposition 4 structured-error consumption path; `err.hint`\n * is for human eyeballs only.\n *\n * Single live emit point: the RenderSystem record stage per-entity\n * instance buffer upload path\n * (`packages/runtime/src/render-system-record.ts`). The 18-member\n * `RhiErrorCode` union is unchanged (`'limit-exceeded'` discriminant\n * preserved); evolution major rename + replace of the discriminated\n * `detail` shape per AGENTS.md Change stance + plan-strategy D-3.\n *\n * Migration history:\n * - feat-20260513-instanced-mesh M5: detail reshape from\n * `{ renderableCount, limit }` to `{ maxStorageBufferBindingSize,\n * requestedBytes }`. Emit point at the time was\n * `AssetRegistry.createInstancedBuffer`.\n * - feat-20260907-case01-case05-engine-convergence: explicit instance\n * matrices are supplied by the renderer-owned collection projection;\n * `requestedBytes` describes the resident record payload at the record\n * stage, independent of ECS managed-array capacity.\n */\nexport interface LimitExceededDetail {\n readonly maxStorageBufferBindingSize: number;\n readonly requestedBytes: number;\n}\n\n/**\n * Detail structure exclusive to the `'render-system-multi-light'` path.\n * The only remaining cardinality rule is one global DirectionalLight; all\n * PointLight, SpotLight, and RectArea lights are admitted through the shared\n * shared Cluster corpus and are admitted by the same local-light contract.\n */\nexport interface RhiMultiLightDetail {\n readonly type: 'directional';\n readonly got: number;\n}\n\n/**\n * Detail structure exclusive to the `'instancing-exceeds-uniform-cap'` path\n * (feat-20260622-chunk-gpu-instancing-sprite-tilemap M2 / w10 +\n * plan-strategy 2 D-2 + research N-1).\n *\n * Emitted by the record-stage fold dispatch loop\n * (`packages/runtime/src/render-system-record.ts`) when\n * `caps.storageBuffer === false` AND a fold bucket carries more than\n * `limit` instances. The engine fires the error AND falls the offending\n * bucket back to per-entity drawIndexed via the same exit the mode-gate\n * bypass uses (plan-strategy D-9 \"shared fallback exit\"), so the frame\n * is still visually correct (no identity-collapse / black screen) and\n * the cap event surfaces structurally for AI users to observe.\n *\n * Fields:\n * - `requested` — the offending bucket's instance count\n * (`FoldBucket.bucketSize`); always strictly greater than `limit` at\n * emit time (the cap-check helper guards `requested > limit`).\n * - `limit` — the literal 128. The value is locked at the type level\n * because the cap is structurally tied to the WebGL2 minimum 16384 B\n * UBO size (128 * 64 B mat4 stride = 8192 B leaves headroom for the\n * per-frame material UBO slice — research N-1). A future cap change\n * would be a major evolution, not a runtime knob.\n * - `scope` — closed `'sprite' | 'tilemap-chunk'` discriminator that\n * pinpoints the dispatch site (sprite-pass entry that came directly\n * from a user-spawned Sprite vs one derived by\n * `tilemap-chunk-extract-system`). AI users branch on `.scope` to\n * decide whether to shrink the sprite batch size or the tilemap\n * chunk size.\n *\n * AI-user consumption (charter P3 + plan-strategy 8.3):\n * ```ts\n * if (err.code === 'instancing-exceeds-uniform-cap') {\n * const d = err.detail as RhiInstancingExceedsUniformCapDetail;\n * if (d.scope === 'sprite') shrinkSpriteBatchSize(d.requested);\n * else if (d.scope === 'tilemap-chunk') shrinkTileChunkSize(d.requested);\n * }\n * ```\n * — never parse `err.message`. The discriminated `detail` field is the\n * surface; the human-readable `err.message` is for logs only.\n */\nexport interface RhiInstancingExceedsUniformCapDetail {\n readonly requested: number;\n readonly limit: 128;\n readonly scope: 'sprite' | 'tilemap-chunk';\n}\n\n/**\n * Detail structure exclusive to the `'render-system-owner-out-of-range'` path\n * (feat-20260708-composited-multi-world-rendering M3 / D-5).\n *\n * Emitted by `renderer.draw(worlds, { cameraOwner, resourceOwner })` when one\n * owner index is not valid for `worlds` (`owner < 0` or `owner >= worlds.length`).\n * An out-of-range index cannot resolve, so the frame is skipped before extract.\n *\n * Fields:\n * - `role` — WHICH of the two draw-owner indices was out of range\n * (feat-20260709-editor-world-partition M1 / w7). `draw(worlds, {\n * cameraOwner, resourceOwner })` carries two independent indices; `role`\n * tells the AI user whether the camera-source index (`'camera'`) or the\n * singleton-resource index (`'resource'`) is the offender, so the fix is\n * unambiguous from the text channel (no new error code — D-3 keeps 0 net\n * new codes; the discriminator lives in `.detail`). When both indices are\n * out of range the first offender is reported: `cameraOwner` is validated\n * before `resourceOwner`, so `role === 'camera'`.\n * - `owner` — the offending index the caller passed (the `role` index's\n * value).\n * - `worldCount` — `worlds.length` at call time (the valid range is\n * `0 .. worldCount - 1`).\n *\n * AI users branch via property access (`err.detail.role` / `err.detail.owner` /\n * `err.detail.worldCount`) after narrowing on `.code`, rather than parsing the\n * message string (charter P3 structured-failure surface).\n *\n * The sibling `'render-system-empty-worlds'` path carries no `.detail` — an\n * empty array is fully described by `.code`, and the entry check short-circuits\n * to that code before the owner-range check runs (the two codes are\n * non-exclusive).\n */\nexport interface RhiOwnerOutOfRangeDetail {\n readonly role: 'camera' | 'resource';\n readonly owner: number;\n readonly worldCount: number;\n}\n\n/** Detail for an incomplete device-owned texture-format profile probe. */\nexport interface RhiTextureFormatCapabilityUnavailableDetail {\n readonly stage: string;\n readonly deviceGeneration: number;\n readonly reason: string;\n}\n\n/**\n * Tagged union of `.detail` shapes carried by structured errors.\n *\n * Entries:\n * - `RhiShaderCompileDetail` (carries `compilerMessages`) - emitted on the\n * `'shader-compile-failed'` path.\n * - `RhiAssetNotRegisteredDetail` (carries `assetHandle`) - emitted on the\n * `'asset-not-registered'` path (D-S6).\n * - `RhiWebgpuRuntimeDetail` (carries `error: RhiError | { code, message }`) - optionally emitted\n * on the `'webgpu-runtime-error'` path when a captured `Error.message` is\n * available (D-S8).\n * - `LimitExceededDetail` (carries `maxStorageBufferBindingSize` +\n * `requestedBytes`) - emitted on the `'limit-exceeded'` path when\n * the RenderSystem record stage's per-entity Instances upload\n * exceeds `device.limits.maxStorageBufferBindingSize`\n * (feat-20260514-ecs-children-instances-managed-buffer-array M3 / w15;\n * emit point migrated from the deleted\n * `AssetRegistry.createInstancedBuffer` factory).\n *\n * The other 15 paths leave `.detail = undefined` (charter proposition 4\n * baseline).\n */\nexport type RhiErrorDetail =\n | RhiShaderCompileDetail\n | RhiAssetNotRegisteredDetail\n | RhiWebgpuRuntimeDetail\n | LimitExceededDetail\n | RhiMultiLightDetail\n | RhiInstancingExceedsUniformCapDetail\n | RhiOwnerOutOfRangeDetail\n | RhiTextureFormatCapabilityUnavailableDetail;\n\n/**\n * Structured RHI error.\n *\n * Three readonly fields aligned with AGENTS.md \"Errors are structured\":\n * - `.code` - closed union member (L1 key signal).\n * - `.expected` - expected-state description (L2 detail).\n * - `.hint` - actionable recovery guidance (L2 detail; charter proposition 3:\n * machine-readable hint > prose).\n *\n * `.detail` is populated on four paths:\n * - `code === 'shader-compile-failed'` -> `RhiShaderCompileDetail`\n * - `code === 'asset-not-registered'` -> `RhiAssetNotRegisteredDetail`\n * - `code === 'webgpu-runtime-error'` -> `RhiWebgpuRuntimeDetail` (optional)\n * - `code === 'limit-exceeded'` -> `LimitExceededDetail`\n * (feat-20260513-instanced-mesh M5 reshape; carries\n * `maxStorageBufferBindingSize` + `requestedBytes`)\n *\n * The other 15 paths leave `.detail = undefined` (charter proposition 4\n * baseline).\n *\n * Note: `RhiErrorDetail` is currently a flat tagged union without a\n * `code` discriminant field on each variant; AI users perform typed\n * narrowing via outer `switch (err.code)` then a one-time `as` cast on\n * `err.detail` per the documented variant. Full discriminated-union\n * refactor (each variant carrying its own `code` literal field) is left\n * to `feat-future-rhi-error-detail-discriminant` spinoff.\n */\nexport class RhiError extends Error {\n readonly code: RhiErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail: RhiErrorDetail | undefined;\n\n constructor(args: {\n code: RhiErrorCode;\n expected: string;\n hint: string;\n detail?: RhiErrorDetail | undefined;\n }) {\n super(`[RhiError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);\n this.name = 'RhiError';\n this.code = args.code;\n this.expected = args.expected;\n this.hint = args.hint;\n this.detail = args.detail;\n }\n}\n\n/**\n * The two split draw-owner indices carried by\n * `draw(worlds, { cameraOwner, resourceOwner })`\n * (feat-20260709-editor-world-partition M1 / w6). `cameraOwner` selects the\n * world whose cameras are surfaced; `resourceOwner` selects the world whose\n * skylight / skybox / postProcessParams are surfaced. Declared here (World-free\n * primitives) so the validator and the `RhiOwnerOutOfRangeDetail.role`\n * discriminator live in one SSOT package (architecture-principles §1).\n */\nexport interface DrawOwnerSplit {\n readonly cameraOwner: number;\n readonly resourceOwner: number;\n}\n\n/**\n * Validate `renderer.draw(worlds, { cameraOwner, resourceOwner })` arguments at\n * the draw entry (feat-20260708 M3 / D-5, extended by\n * feat-20260709-editor-world-partition M1 / w6-w7).\n *\n * The validator takes primitives (`worldCount = worlds.length`, plus the owner\n * index/indices) — no `World`, no math — so it lives in `@forgeax/engine-rhi`\n * alongside the `RhiErrorCode` members it emits (architecture-principles §1\n * SSOT). The runtime `createRenderer` draw entry calls it before any extract; a\n * non-`ok` result skips the frame with a structured error (charter P3), never a\n * silent no-op.\n *\n * Checks, in order (D-5 + w6):\n * 1. `worldCount === 0` -> `'render-system-empty-worlds'` (no `.detail`).\n * 2. `cameraOwner` is not a valid index -> `'render-system-owner-out-of-range'`\n * with `.detail = { role: 'camera', owner: cameraOwner, worldCount }`.\n * 3. `resourceOwner` is not a valid index -> `'render-system-owner-out-of-range'`\n * with `.detail = { role: 'resource', owner: resourceOwner, worldCount }`.\n * The `Number.isInteger` guard rejects a `NaN` / fractional / undefined-coerced\n * index a JS caller could pass despite the compile-time requirement. When both\n * indices are out of range the FIRST offender wins: `cameraOwner` is checked\n * before `resourceOwner`, so `role === 'camera'` (D-3 / w3 contract).\n *\n * The empty-worlds guard short-circuits before either owner-range check.\n */\nexport function validateDrawArgs(\n worldCount: number,\n owner: DrawOwnerSplit,\n): Result<void, RhiError> {\n if (worldCount === 0) {\n return err(\n new RhiError({\n code: 'render-system-empty-worlds',\n expected: 'worlds array has at least one world',\n hint: 'pass at least one world: draw([world], { cameraOwner: 0, resourceOwner: 0 })',\n }),\n );\n }\n const { cameraOwner, resourceOwner } = owner;\n const outOfRange = (index: number): boolean =>\n !Number.isInteger(index) || index < 0 || index >= worldCount;\n // cameraOwner is validated first: it is the first offender when both indices\n // are out of range (w3 contract). role names which index the AI user fixes.\n if (outOfRange(cameraOwner)) {\n return err(\n new RhiError({\n code: 'render-system-owner-out-of-range',\n expected: 'cameraOwner is an index into worlds (0 <= cameraOwner < worlds.length)',\n hint: 'cameraOwner must be in 0..worlds.length-1; the cameraOwner world supplies the surfaced cameras',\n detail: { role: 'camera', owner: cameraOwner, worldCount },\n }),\n );\n }\n if (outOfRange(resourceOwner)) {\n return err(\n new RhiError({\n code: 'render-system-owner-out-of-range',\n expected: 'resourceOwner is an index into worlds (0 <= resourceOwner < worlds.length)',\n hint: 'resourceOwner must be in 0..worlds.length-1; the resourceOwner world supplies skylight/skybox/postProcess',\n detail: { role: 'resource', owner: resourceOwner, worldCount },\n }),\n );\n }\n return ok(undefined);\n}\n\n// Result<T, E> + ok / err live in `@forgeax/engine-types` (tweak-20260612-result-\n// into-types). They were duplicated here (\"byte-for-byte aligned\" by prose) and\n// in packages/ecs/src/result.ts; SSOT consolidated upstream. The barrel here\n// re-exports them so existing `import { err, ok, Result, ResultOk, ResultErr }\n// from '@forgeax/engine-rhi'` consumers stay unchanged.\nexport {\n err,\n ok,\n type Result,\n type ResultErr,\n type ResultOk,\n} from '@forgeax/engine-types';\n","import { err, ok, type Result, RhiError } from '../errors';\n\n/** The only format profile currently admitted by the reflection fallback path. */\nexport const R32FLOAT_MIP_SAMPLED_STORAGE_PROFILE = 'r32float-mip-sampled-storage' as const;\n\nexport type RhiTextureFormatProfile = typeof R32FLOAT_MIP_SAMPLED_STORAGE_PROFILE;\nexport type RhiTextureFormatProbeVerdict = 'admitted' | 'unavailable' | 'structural-only';\nexport type RhiTextureFormatProbeEvidence = 'real' | 'structural';\nexport type RhiTextureFormatProbeStage =\n | 'texture-create'\n | 'mip-view'\n | 'sampled-storage-bind-group'\n | 'pipeline-bind'\n | 'finish'\n | 'submit'\n | 'completion'\n | 'readback';\n\nexport const R32FLOAT_PROBE_STAGES: readonly RhiTextureFormatProbeStage[] = [\n 'texture-create',\n 'mip-view',\n 'sampled-storage-bind-group',\n 'pipeline-bind',\n 'finish',\n 'submit',\n 'completion',\n 'readback',\n];\n\nexport interface RhiTextureFormatProbeStageReceipt {\n readonly stage: RhiTextureFormatProbeStage;\n readonly verdict: RhiTextureFormatProbeVerdict;\n readonly evidence: RhiTextureFormatProbeEvidence;\n readonly detail?: string | undefined;\n}\n\nexport interface RhiTextureFormatReadback {\n readonly byteLength: number;\n readonly values: readonly number[];\n}\n\nexport interface RhiTextureFormatCapabilityReceipt {\n readonly profile: RhiTextureFormatProfile;\n readonly verdict: RhiTextureFormatProbeVerdict;\n readonly evidence: RhiTextureFormatProbeEvidence;\n readonly deviceGeneration: number;\n readonly stages: readonly RhiTextureFormatProbeStageReceipt[];\n readonly sampleType: 'unfilterable-float';\n readonly usages: readonly ['texture-binding', 'storage-binding', 'copy-src'];\n readonly readback?: RhiTextureFormatReadback | undefined;\n readonly probeExecutions: number;\n}\n\nexport interface CreateUnavailableR32FloatReceiptOptions {\n readonly deviceGeneration: number;\n readonly failedStage: RhiTextureFormatProbeStage;\n readonly detail: string;\n readonly evidence?: RhiTextureFormatProbeEvidence | undefined;\n}\n\nexport function createUnavailableR32FloatReceipt(\n options: CreateUnavailableR32FloatReceiptOptions,\n): RhiTextureFormatCapabilityReceipt {\n const failureIndex = R32FLOAT_PROBE_STAGES.indexOf(options.failedStage);\n const evidence = options.evidence ?? 'real';\n return {\n profile: R32FLOAT_MIP_SAMPLED_STORAGE_PROFILE,\n verdict: 'unavailable',\n evidence,\n deviceGeneration: options.deviceGeneration,\n stages: R32FLOAT_PROBE_STAGES.map((stage, index) => ({\n stage,\n verdict: index < failureIndex ? 'admitted' : 'unavailable',\n evidence,\n ...(stage === options.failedStage ? { detail: options.detail } : {}),\n })),\n sampleType: 'unfilterable-float',\n usages: ['texture-binding', 'storage-binding', 'copy-src'],\n probeExecutions: 1,\n };\n}\n\nexport function validateR32FloatReceipt(\n receipt: RhiTextureFormatCapabilityReceipt,\n): Result<RhiTextureFormatCapabilityReceipt, RhiError> {\n const missing = R32FLOAT_PROBE_STAGES.find(\n (stage) => !receipt.stages.some((entry) => entry.stage === stage),\n );\n if (missing !== undefined) {\n return unavailable(receipt, missing, `required stage ${missing} is missing`);\n }\n if (receipt.profile !== R32FLOAT_MIP_SAMPLED_STORAGE_PROFILE) {\n return unavailable(receipt, 'texture-create', 'profile is not the closed r32float profile');\n }\n if (receipt.sampleType !== 'unfilterable-float') {\n return unavailable(\n receipt,\n 'sampled-storage-bind-group',\n 'sample type must be unfilterable-float',\n );\n }\n if (\n receipt.usages.length !== 3 ||\n receipt.usages[0] !== 'texture-binding' ||\n receipt.usages[1] !== 'storage-binding' ||\n receipt.usages[2] !== 'copy-src'\n ) {\n return unavailable(\n receipt,\n 'sampled-storage-bind-group',\n 'sampled, storage, and readback usages are required',\n );\n }\n if (receipt.verdict === 'admitted' && receipt.readback === undefined) {\n return unavailable(receipt, 'readback', 'admitted profiles require real readback evidence');\n }\n return ok(receipt);\n}\n\nfunction unavailable(\n receipt: RhiTextureFormatCapabilityReceipt,\n stage: RhiTextureFormatProbeStage,\n detail: string,\n): Result<never, RhiError> {\n return err(\n new RhiError({\n code: 'rhi-texture-format-capability-unavailable',\n expected: `r32float profile stage ${stage} to be complete`,\n hint: 'retain fallback-only rendering and retry the owner-owned device probe',\n detail: {\n stage,\n deviceGeneration: receipt.deviceGeneration,\n reason: detail,\n },\n }),\n );\n}\n","// @forgeax/engine-rhi - pure-interface RHI surface for forgeax-engine.\n//\n// Iron laws: spec-aligned (descriptor field names mirror Pick<GPUXxxDescriptor, ...>\n// byte-for-byte) / capability-gated / opaque handle / math-free. See README +\n// AGENTS.md \"## RHI / WebGPU\" section.\n//\n// This file is the complete entry for `import * as RHI from '@forgeax/engine-rhi'`\n// (charter proposition 1: progressive disclosure + plan-strategy 7.4\n// discoverability \"AI users see the full surface in one read\").\n//\n// =====================================================================\n// Async function form contract (D-P9 / requirements AC-12)\n// =====================================================================\n//\n// All async functions exposed by `@forgeax/engine-rhi` (and the rhi-webgpu /\n// rhi-wgpu shim packages that implement this interface) follow the\n// `Promise<Result<T, RhiError>>` shape — Promise NEVER rejects, failures\n// ride `Result.err` so AI users have a single error-handling idiom across\n// sync + async surfaces (charter proposition 4 explicit failure +\n// proposition 5 consistent abstraction).\n//\n// Three permitted whitelist categories may keep the bare `Promise<T>` shape;\n// each exemption must be marked with a `// forgeax-async-whitelist:\n// <category>` comment near the signature site so the grep gate\n// (scripts/check-async-form.mjs) can pair the violation count with the\n// whitelist count:\n//\n// (a) wasm-bindgen — outputs of wasm-pack JS shim that we cannot\n// restructure at the type layer (wasm-loader edge);\n// (b) dom-native — DOM native Promise passthrough such as\n// `GPUDevice.lost` re-exposed verbatim;\n// (c) render-loop — non-fallible internal drivers like\n// requestAnimationFrame wrappers.\n//\n// Anything else returning `Promise<T>` without the whitelist comment is a\n// CI gate red.\n//\n// Related: requirements AC AC-02 + MVP-1.1 / MVP-1.2 / MVP-1.3 / MVP-1.5 /\n// MVP-1.7 + AC-04 (RhiErrorCode 17 members) + AC-05 (RhiCaps 11\n// fields) + AC-10 (RhiBindingResource tagged union) + AC-11\n// (MappedBuffer brand) + AC-12 (Promise<Result<T,E>> + whitelist)\n// + hard-constraints 1 / 2 / 3 / 7 / 9; plan-strategy 1\n// architecture + 2 S-1 / S-3 / S-6 / S-7 + 6 M1 + D-P9 async form;\n// research F-1 (17 core descriptor surface) + F-7 (wgpu-hal 21\n// associated types);\n// feat-20260508-rhi-surface-completion w8 D-S5 (4 new descriptors\n// with `view` field tightened to TextureView);\n// feat-20260511-rhi-spec-realign-aggressive (Promise<Result<T,E>>\n// contract locked at the interface layer).\n\n/// <reference types=\"@webgpu/types\" />\n\nimport type {\n AddressMode,\n CompareFunction,\n FilterMode,\n TextureFormat,\n} from '@forgeax/engine-types';\nimport type { RhiTextureFormatCapabilityReceipt } from './capability/texture-format';\nimport type { Result, RhiError } from './errors';\n\n// ============================================================================\n// 14 opaque handles (MVP-1.3)\n// ============================================================================\n//\n// Shape: each handle = brand-only typed Id<T>; no runtime value; attempting to\n// access internal GPU fields is a tsc compile-time red signal (research R5;\n// charter proposition 4 explicit failure + proposition 5 consistent abstraction).\n//\n// Naming: no Rhi prefix (D-9); coexists with @webgpu/types.GPU* prefix +\n// wgpu::* Rust paths via module-path semantics (e.g.\n// `import { Buffer } from '@forgeax/engine-rhi'` vs `GPUBuffer`).\n\ndeclare const RhiBufferBrand: unique symbol;\ndeclare const RhiMappedBufferBrand: unique symbol;\n\n/**\n * GPU buffer opaque handle (vertex / index / uniform / storage / indirect).\n *\n * Spec anchor: W3C WebGPU §4 Buffers / [@webgpu/types.GPUBuffer]; research\n * §4.1 mapState 3-state enum + §4.2 mapAsync 8-item validation + §4.4 unmap\n * detach semantics.\n *\n * The buffer mapping surface is added in feat-20260510-rhi-resource-creation\n * M5 (K-1: raw GPUMapMode bitmask; K-2: alignment / mode-usage / detach\n * faults all ride 'webgpu-runtime-error' with structured .expected / .hint);\n * re-shaped in feat-20260511-rhi-spec-realign-aggressive M1 (D-P2 #6):\n * - `mapAsync` resolves to `Result<MappedBuffer, RhiError>` (success branch\n * carries a branded handle subsequently used for getMappedRange / unmap).\n * - `getMappedRange` / `unmap` are methods on `MappedBuffer` (not Buffer);\n * calling them on a plain Buffer is a TS2345 compile-time red.\n *\n * The forgeax form keeps the spec verb names but routes failures via Result\n * (charter proposition 4 explicit failure):\n * mapAsync(mode, offset?, size?): Promise<Result<MappedBuffer, RhiError>>\n * readonly mapState: 'unmapped' | 'pending' | 'mapped' - getter (research\n * §4.1; same closed union as GPUBufferMapState).\n */\nexport interface Buffer {\n readonly [RhiBufferBrand]: void;\n /**\n * Map the buffer for CPU access.\n *\n * Spec anchor: W3C WebGPU §gpubuffer-mapasync /\n * [@webgpu/types.GPUBuffer.mapAsync]. K-1 decision: `mode` is the raw\n * `GPUMapMode` bitmask (NOT a closed union 'read' | 'write') so the forgeax\n * form mirrors `GPUMapMode.READ` / `GPUMapMode.WRITE` literals.\n *\n * D-P2 #6 (feat-20260511-rhi-spec-realign-aggressive): the success branch\n * resolves to `MappedBuffer`, a brand on top of `Buffer`. AI users\n * subsequently call `mapped.getMappedRange(...)` / `mapped.unmap()` on the\n * branded handle; calling those methods on a plain `Buffer` is a TS2345\n * compile-time signal (charter proposition 4 explicit failure encoded at\n * the type layer).\n *\n * Failure paths (research §4.2 + plan-strategy §2 K-2):\n * - mapState !== 'unmapped' (F-8 row 1) -> 'webgpu-runtime-error'.\n * - offset % 8 != 0 (step 4) -> 'webgpu-runtime-error'.\n * - rangeSize % 4 != 0 (step 5) -> 'webgpu-runtime-error'.\n * - offset + rangeSize > size (step 6) -> 'webgpu-runtime-error'.\n * - mode contains foreign bits (step 7) -> 'webgpu-runtime-error'.\n * - mode is not exactly READ or WRITE (step 8) -> 'webgpu-runtime-error'.\n * - mode-usage mismatch (step 9 / F-8 row 3) -> 'webgpu-runtime-error'.\n *\n * @example\n * const r = await buffer.mapAsync(GPUMapMode.WRITE);\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * return;\n * }\n * const mapped: MappedBuffer = r.value;\n * const range = mapped.getMappedRange();\n * if (range.ok) new Uint32Array(range.value).set([1, 2, 3, 4]);\n * mapped.unmap();\n */\n mapAsync(\n mode: GPUMapModeFlags,\n offset?: number | undefined,\n size?: number | undefined,\n ): Promise<Result<MappedBuffer, RhiError>>;\n /**\n * Current mapping state (read-only getter).\n *\n * Spec anchor: research §4.1 mapState 3-state enum; mirrors\n * GPUBufferMapState. Transitions:\n * - createBuffer({mappedAtCreation:true}) sets mapState='mapped'.\n * - mapAsync moves 'unmapped' -> 'pending' -> 'mapped'.\n * - unmap moves 'mapped' -> 'unmapped'.\n */\n readonly mapState: 'unmapped' | 'pending' | 'mapped';\n}\n\n/**\n * Brand on top of `Buffer` indicating the mapping is currently open; only the\n * `MappedBuffer` exposes `getMappedRange` / `unmap` method forms so AI users\n * cannot accidentally call them on an unmapped `Buffer` (D-P2 #6).\n *\n * The brand is structural — runtime the `MappedBuffer` is the same JS object\n * as the underlying `Buffer`; TypeScript narrows access through the\n * `__mapped: void` private brand symbol.\n *\n * Spec anchor: W3C WebGPU §4 Buffers mapping lifecycle (research §4.1 /\n * §4.4); plan-strategy §7.1 + D-P2 break-point #6 (brand + method form\n * merged).\n *\n * @example\n * const r = await buffer.mapAsync(GPUMapMode.WRITE);\n * if (!r.ok) return;\n * const mapped: MappedBuffer = r.value;\n * mapped.getMappedRange(); // method form, this: MappedBuffer\n * mapped.unmap(); // method form, this: MappedBuffer\n */\nexport interface MappedBuffer extends Buffer {\n readonly [RhiMappedBufferBrand]: void;\n /**\n * Return an ArrayBuffer view of the mapped range. Method form on\n * `MappedBuffer` per D-P2 #6 — calling on a plain `Buffer` is TS2339.\n *\n * Spec anchor: W3C WebGPU §gpubuffer-getmappedrange /\n * [@webgpu/types.GPUBuffer.getMappedRange].\n *\n * Failure paths:\n * - mapState !== 'mapped' (incl after unmap, F-8 row 2 detach guard) ->\n * 'webgpu-runtime-error'.\n */\n getMappedRange(\n offset?: number | undefined,\n size?: number | undefined,\n ): Result<ArrayBuffer, RhiError>;\n /**\n * Unmap the buffer, detaching all ArrayBuffer views obtained from\n * getMappedRange. Method form on `MappedBuffer` per D-P2 #6.\n *\n * Spec anchor: W3C WebGPU §gpubuffer-unmap /\n * [@webgpu/types.GPUBuffer.unmap]. unmap() returns void per spec normative\n * silent no-op (research §4.4); calling unmap on an already-unmapped buffer\n * does NOT error. This is the ONE Result-shape exception in the buffer\n * surface (AI User Affordances explicit listing).\n *\n * After unmap, the JS object continues to exist but the brand narrows\n * away at the TS layer: AI users who hold a `MappedBuffer` after the\n * underlying state flipped should re-`mapAsync` to obtain a fresh branded\n * instance (OQ-5 plan-decisions: unmap returns void; subsequent mapAsync\n * returns a new MappedBuffer brand).\n */\n unmap(): void;\n}\n\ndeclare const RhiTextureBrand: unique symbol;\n/** GPU texture opaque handle (2D / 3D / cube / array). */\nexport interface Texture {\n readonly [RhiTextureBrand]: void;\n}\n\n/** RHI-safe source for a texture-to-buffer copy. */\nexport interface TextureCopySource {\n readonly texture: Texture;\n readonly mipLevel?: number | undefined;\n readonly origin?: GPUOrigin3D | undefined;\n readonly aspect?: GPUTextureAspect | undefined;\n}\n\n/** RHI-safe destination for a texture-to-buffer copy. */\nexport interface BufferCopyDestination {\n readonly buffer: Buffer;\n readonly offset?: number | undefined;\n readonly bytesPerRow: number;\n readonly rowsPerImage?: number | undefined;\n}\n\n/** RHI-owned destination for queue.writeTexture. The resource handle remains opaque. */\nexport interface TextureWriteDestination {\n readonly texture: Texture;\n readonly mipLevel?: number | undefined;\n readonly origin?: GPUOrigin3D | undefined;\n readonly aspect?: GPUTextureAspect | undefined;\n}\n\n/** RHI-owned destination for queue.copyExternalImageToTexture. */\nexport type ExternalImageTextureDestination = Omit<\n Pick<\n GPUCopyExternalImageDestInfo,\n 'texture' | 'mipLevel' | 'origin' | 'aspect' | 'colorSpace' | 'premultipliedAlpha'\n >,\n 'texture'\n> & {\n readonly texture: Texture;\n};\n\ndeclare const RhiTextureViewBrand: unique symbol;\n/** GPU texture view opaque handle. */\nexport interface TextureView {\n readonly [RhiTextureViewBrand]: void;\n}\n\ndeclare const RhiSamplerBrand: unique symbol;\n/** GPU sampler opaque handle. */\nexport interface Sampler {\n readonly [RhiSamplerBrand]: void;\n}\n\ndeclare const RhiBindGroupBrand: unique symbol;\n/** GPU bind group opaque handle (instantiated layout). */\nexport interface BindGroup {\n readonly [RhiBindGroupBrand]: void;\n}\n\ndeclare const RhiBindGroupLayoutBrand: unique symbol;\n/** GPU bind group layout opaque handle (declares binding shapes). */\nexport interface BindGroupLayout {\n readonly [RhiBindGroupLayoutBrand]: void;\n}\n\ndeclare const RhiPipelineLayoutBrand: unique symbol;\n/** GPU pipeline layout opaque handle (aggregates BindGroupLayouts). */\nexport interface PipelineLayout {\n readonly [RhiPipelineLayoutBrand]: void;\n}\n\ndeclare const RhiRenderPipelineBrand: unique symbol;\n/** GPU render pipeline opaque handle. */\nexport interface RenderPipeline {\n readonly [RhiRenderPipelineBrand]: void;\n}\n\ndeclare const RhiComputePipelineBrand: unique symbol;\n/** GPU compute pipeline opaque handle. */\nexport interface ComputePipeline {\n readonly [RhiComputePipelineBrand]: void;\n}\n\ndeclare const RhiShaderModuleBrand: unique symbol;\n/** GPU shader module opaque handle (WGSL / SPIR-V compile artifact). */\nexport interface ShaderModule {\n readonly [RhiShaderModuleBrand]: void;\n}\n\ndeclare const RhiQuerySetBrand: unique symbol;\n/** GPU query set opaque handle (occlusion / timestamp). */\nexport interface QuerySet {\n readonly [RhiQuerySetBrand]: void;\n}\n\ndeclare const RhiFenceBrand: unique symbol;\n/** GPU fence opaque handle (GPU/CPU sync barrier). */\nexport interface Fence {\n readonly [RhiFenceBrand]: void;\n}\n\ndeclare const RhiCommandEncoderBrand: unique symbol;\n/** GPU command encoder opaque handle (single-use). */\nexport interface CommandEncoder {\n readonly [RhiCommandEncoderBrand]: void;\n}\n\ndeclare const RhiCommandBufferBrand: unique symbol;\n/** GPU command buffer opaque handle (submitted to Queue). */\nexport interface CommandBuffer {\n readonly [RhiCommandBufferBrand]: void;\n}\n\n// ============================================================================\n// 5 core descriptors (MVP-1.1) - Pick<GPUXxxDescriptor, ...> field names\n// align byte-for-byte with @webgpu/types\n// ============================================================================\n//\n// Decision S-7 + research F-3: optional fields are uniformly `?: T | undefined`\n// (compatible with exactOptionalPropertyTypes; explicitly accepts writers\n// passing `{ x: undefined }`; charter proposition 4 explicit failure /\n// distinguish missing vs explicit-undefined).\n// R8 mitigation: Compatibility Mode field (textureBindingViewDimension) is\n// optional follow-on.\n//\n// Note: @webgpu/types v0.1.69 spec uses the `?: T` simplified form; forgeax\n// applies the ExplicitUndefined mapped type to `Pick<spec>` so the forgeax\n// side accepts `{ label: undefined }` writes (research F-3 finding;\n// ecosystem upgrade path = once upstream @webgpu/types v0.2.x ships\n// `?: T | undefined` uniformly, ExplicitUndefined can be removed).\n\n/**\n * Convert `?: T` optional fields to `?: T | undefined` (decision S-7).\n *\n * Compatible with exactOptionalPropertyTypes: writers may pass `undefined`\n * explicitly or omit the field; the M2 shim distinguishes the two via\n * `'x' in src` guards (research F-3 anti-pattern 2).\n */\ntype ExplicitUndefined<T> = { [K in keyof T]: T[K] | undefined };\n\n/** GPU buffer descriptor. Field set strictly matches GPUBufferDescriptor;\n * optional fields use `?: T | undefined`. */\nexport type BufferDescriptor = ExplicitUndefined<\n Pick<GPUBufferDescriptor, 'label' | 'size' | 'usage' | 'mappedAtCreation'>\n>;\n\n/** GPU texture descriptor. Field set strictly matches GPUTextureDescriptor\n * (incl R8 Compatibility Mode field). */\nexport type TextureDescriptor = ExplicitUndefined<\n Pick<\n GPUTextureDescriptor,\n | 'label'\n | 'size'\n | 'mipLevelCount'\n | 'sampleCount'\n | 'dimension'\n | 'format'\n | 'usage'\n | 'viewFormats'\n | 'textureBindingViewDimension'\n >\n>;\n\n/** GPU sampler descriptor. Field set strictly matches GPUSamplerDescriptor. */\nexport type SamplerDescriptor = ExplicitUndefined<\n Pick<\n GPUSamplerDescriptor,\n | 'label'\n | 'addressModeU'\n | 'addressModeV'\n | 'addressModeW'\n | 'magFilter'\n | 'minFilter'\n | 'mipmapFilter'\n | 'lodMinClamp'\n | 'lodMaxClamp'\n | 'compare'\n | 'maxAnisotropy'\n >\n>;\n\n/** GPU bind group layout descriptor. Field set strictly matches\n * GPUBindGroupLayoutDescriptor. */\nexport type BindGroupLayoutDescriptor = ExplicitUndefined<\n Pick<GPUBindGroupLayoutDescriptor, 'label' | 'entries'>\n>;\n\n/**\n * GPU texture view descriptor (Pick<GPUTextureViewDescriptor, 9 fields>).\n *\n * Spec anchor: W3C WebGPU §texture-view-creation /\n * [@webgpu/types.GPUTextureViewDescriptor]. Field NAMES align byte-for-byte;\n * field set excludes the feature-gated `swizzle` field (research §1.1 OOS-MVP;\n * a future closure can add it once `'texture-component-swizzle'` is enabled).\n *\n * Cross-resource validation (shim fast-path, research §1.1):\n * - `format` must equal source.format OR be in source.viewFormats; otherwise\n * the shim returns Result.err({ code: 'webgpu-runtime-error' }).\n * - `usage` must be a subset of source.usage (bitmask); otherwise the shim\n * returns the same code.\n *\n * @example\n * const r = device.createTextureView(tex, { format: 'rgba8unorm', dimension: '2d' });\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\nexport type TextureViewDescriptor = ExplicitUndefined<\n Pick<\n GPUTextureViewDescriptor,\n | 'label'\n | 'format'\n | 'dimension'\n | 'usage'\n | 'aspect'\n | 'baseMipLevel'\n | 'mipLevelCount'\n | 'baseArrayLayer'\n | 'arrayLayerCount'\n >\n>;\n\n/**\n * GPU compute pipeline descriptor (Pick<GPUComputePipelineDescriptor,\n * 'label' | 'layout' | 'compute'>).\n *\n * Spec anchor: W3C WebGPU §compute-pipeline-creation /\n * [@webgpu/types.GPUComputePipelineDescriptor]. Field NAMES align byte-for-byte\n * with spec.\n *\n * `layout` is the spec union `'auto' | GPUPipelineLayout`; forgeax tightens\n * the explicit form to the `PipelineLayout` opaque handle (D-S5 pattern):\n * layout: 'auto' | PipelineLayout\n *\n * `compute` mirrors `GPUProgrammableStage` verbatim — `module` (required\n * `ShaderModule` opaque handle), `entryPoint?` (optional string),\n * `constants?` (optional `Record<string, number>`).\n *\n * Capability gate (research §1.2 NOTE; plan-strategy §4.3 boundary case row 1):\n * - `caps.compute === false` -> shim returns Result.err({\n * code: 'feature-not-enabled', expected: 'caps.compute === true',\n * hint: 'check device.caps.compute before calling createComputePipeline'\n * }). MVP WebGPU path always has caps.compute=true (spec mandate); the gate\n * exists for potential future non-WebGPU backends.\n *\n * @example\n * const r = device.createComputePipeline({\n * label: 'cs',\n * layout: 'auto',\n * compute: { module: csModule, entryPoint: 'cs_main' },\n * });\n */\nexport type ComputePipelineDescriptor = ExplicitUndefined<\n Omit<Pick<GPUComputePipelineDescriptor, 'label' | 'layout' | 'compute'>, 'layout' | 'compute'>\n> & {\n /**\n * Either `'auto'` for user-agent BGL inference or a forgeax\n * `PipelineLayout` opaque handle (D-S5 pattern: forgeax handle replaces\n * spec polymorphism `(GPUAutoLayoutMode or GPUPipelineLayout)`).\n */\n layout: 'auto' | PipelineLayout;\n /**\n * The compute programmable stage. `module` is the forgeax `ShaderModule`\n * opaque handle (replacing spec `GPUShaderModule`); `entryPoint?` defaults\n * to the module's single compute entry; `constants?` is a record of\n * pipeline-overridable constants.\n */\n compute: {\n module: ShaderModule;\n entryPoint?: string | undefined;\n constants?: Record<string, number> | undefined;\n };\n};\n\n/**\n * GPU query set descriptor (Pick<GPUQuerySetDescriptor, 'label' | 'type' | 'count'>).\n *\n * Spec anchor: W3C WebGPU §queries / [@webgpu/types.GPUQuerySetDescriptor].\n * Field NAMES align byte-for-byte.\n *\n * Hard constraints (research §1.3):\n * - `count <= 4096` (spec normative). The shim fast-paths a violation to\n * Result.err({ code: 'limit-exceeded',\n * expected: 'count <= 4096 (spec normative)',\n * hint: 'create multiple QuerySet instances if more than 4096 queries needed' }).\n * - `type === 'timestamp'` requires `caps.timestampQuery === true` (the\n * 'timestamp-query' feature). Otherwise the shim fast-paths to\n * Result.err({ code: 'feature-not-enabled' }).\n * - `count = 0` is legal (lower bound; dawn end2end test fixture).\n *\n * @example\n * const r = device.createQuerySet({ type: 'occlusion', count: 4 });\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\nexport type QuerySetDescriptor = ExplicitUndefined<\n Pick<GPUQuerySetDescriptor, 'label' | 'type' | 'count'>\n>;\n\n/**\n * Discriminated union over the 4 BindGroup entry resource kinds (the spec\n * polymorphic `GPUBindingResource` collapsed to a tagged union — charter\n * proposition 4 closed-union exhaustive switch + proposition 5 consistent\n * abstraction over duck-typing).\n *\n * Introduced in feat-20260511-rhi-spec-realign-aggressive w9 per requirements\n * AC-10 + plan-strategy §7.1 + D-P2 break-point #5. AI users `switch\n * (resource.kind)` is exhaustive without a default fallback; construction-side\n * typos like `{ kind: 'samplre', ... }` trip TS2322 at the literal slot.\n *\n * Kind discriminator uses kebab-case for multi-word entries (`textureView` is\n * already single-word camelCase by convention; `externalTexture` is multi-word\n * camelCase for parity with the spec verb `GPUExternalTexture`).\n *\n * @example\n * const e: RhiBindingResource = { kind: 'sampler', value: linearSampler };\n * const e2: RhiBindingResource = {\n * kind: 'buffer',\n * value: { buffer: viewUniforms, offset: 0, size: 64 },\n * };\n */\nexport type RhiBindingResource =\n | { readonly kind: 'sampler'; readonly value: Sampler }\n | {\n readonly kind: 'buffer';\n readonly value: {\n readonly buffer: Buffer;\n readonly offset?: number;\n readonly size?: number;\n };\n }\n | { readonly kind: 'textureView'; readonly value: TextureView }\n | { readonly kind: 'externalTexture'; readonly value: GPUExternalTexture };\n\n/**\n * BindGroup entry — one slot in a BindGroup, identified by `binding` (the\n * shader binding number) and `resource` (the tagged-union `RhiBindingResource`\n * — replaces the spec polymorphic `GPUBindingResource`).\n *\n * Field set strictly mirrors `Pick<GPUBindGroupEntry, 'binding'>`; the\n * `resource` field is tightened to the forgeax `RhiBindingResource` tagged\n * union per D-P2 break-point #5 (charter proposition 5 consistent abstraction:\n * AI users see one canonical 4-kind switch rather than spec duck-typing).\n */\nexport type BindGroupEntry = Pick<GPUBindGroupEntry, 'binding'> & {\n resource: RhiBindingResource;\n};\n\n/**\n * GPU bind group descriptor (Pick<GPUBindGroupDescriptor, 'label' | 'layout' | 'entries'>).\n *\n * Spec anchor: W3C WebGPU 10 Resource binding /\n * [@webgpu/types.GPUBindGroupDescriptor].\n *\n * Introduced in feat-20260509-ecs-render-bridge-mvp (D-S1) so the RenderSystem\n * can record `pass.setBindGroup(0/1/2, bg, ...)` through a single RHI surface\n * (charter proposition 5 consistent abstraction; never via raw GPUDevice).\n *\n * The `layout` field references the forgeax `BindGroupLayout` opaque handle\n * (created via `RhiDevice.createBindGroupLayout`); the `entries` array uses\n * the forgeax `BindGroupEntry` shape (binding number + tagged-union\n * `RhiBindingResource`) per feat-20260511-rhi-spec-realign-aggressive D-P2\n * break-point #5 (was previously verbatim `GPUBindGroupEntry`).\n *\n * @example\n * const desc: BindGroupDescriptor = {\n * label: 'view-bg',\n * layout: bgl,\n * entries: [{ binding: 0, resource: { kind: 'buffer', value: { buffer: viewUniforms } } }],\n * };\n */\nexport type BindGroupDescriptor = ExplicitUndefined<\n Omit<Pick<GPUBindGroupDescriptor, 'label' | 'layout' | 'entries'>, 'layout' | 'entries'>\n> & {\n /**\n * BindGroupLayout opaque handle (forgeax tightening: `layout` is the\n * already-shipped `BindGroupLayout` brand, not the spec\n * `GPUBindGroupLayout`). Same D-S5 pattern as RenderPassColorAttachment.view\n * — AI users receive a forgeax-creatable handle, never a phantom spec type.\n */\n layout: BindGroupLayout;\n /**\n * Iterable of forgeax `BindGroupEntry` (binding + tagged-union\n * `RhiBindingResource`); replaces the spec polymorphic\n * `iterable<GPUBindGroupEntry>` per D-P2 break-point #5.\n */\n entries: Iterable<BindGroupEntry>;\n};\n\n/**\n * GPU pipeline layout descriptor (Pick<GPUPipelineLayoutDescriptor, 'label' | 'bindGroupLayouts'>).\n *\n * Spec anchor: W3C WebGPU 10.3 Pipeline layout /\n * [@webgpu/types.GPUPipelineLayoutDescriptor].\n *\n * Introduced in feat-20260509-ecs-render-bridge-mvp (D-S1) so the\n * `Renderer.ready` step 2 (PBR pipeline compile) can compose the 3\n * BindGroupLayouts (view / material / mesh-array) into a single\n * `PipelineLayout` for `RhiDevice.createRenderPipeline`.\n *\n * @example\n * const desc: PipelineLayoutDescriptor = {\n * label: 'pbr-pl',\n * bindGroupLayouts: [viewBgl, materialBgl, meshArrayBgl],\n * };\n */\nexport type PipelineLayoutDescriptor = ExplicitUndefined<\n Omit<Pick<GPUPipelineLayoutDescriptor, 'label' | 'bindGroupLayouts'>, 'bindGroupLayouts'>\n> & {\n /**\n * Iterable of BindGroupLayout opaque handles (forgeax tightening: the\n * iterable element type is the forgeax `BindGroupLayout` brand). Same D-S5\n * pattern as BindGroupDescriptor.layout.\n */\n bindGroupLayouts: Iterable<BindGroupLayout>;\n};\n\n/** GPU render pipeline vertex stage with an opaque forgeax shader module. */\nexport type RenderPipelineVertexState = ExplicitUndefined<\n Omit<GPUVertexState, 'module' | 'buffers'>\n> & {\n module: ShaderModule;\n buffers: NonNullable<GPUVertexState['buffers']>;\n};\n\n/** GPU render pipeline fragment stage with an opaque forgeax shader module. */\nexport type RenderPipelineFragmentState = ExplicitUndefined<\n Omit<GPUFragmentState, 'module' | 'targets'>\n> & {\n module: ShaderModule;\n targets: NonNullable<GPUFragmentState['targets']>;\n};\n\n/** GPU render pipeline descriptor with opaque forgeax layout and shader handles. */\nexport type RenderPipelineDescriptor = ExplicitUndefined<\n Omit<\n Pick<\n GPURenderPipelineDescriptor,\n 'label' | 'layout' | 'vertex' | 'primitive' | 'depthStencil' | 'multisample' | 'fragment'\n >,\n 'layout' | 'vertex' | 'fragment'\n >\n> & {\n layout: 'auto' | PipelineLayout;\n vertex: RenderPipelineVertexState;\n fragment?: RenderPipelineFragmentState | undefined;\n};\n\n// ============================================================================\n// 4 new descriptors (feat-20260508-rhi-surface-completion w8 / D-S5,\n// feat-20260510-rhi-resource-creation M2 view narrow Path X)\n// ============================================================================\n//\n// Field NAMES align byte-for-byte with @webgpu/types (Pick<GPUXxxDescriptor,\n// ...> shape preserved; R12 lint enforces this). Field TYPES for `view` are\n// SPEC-ALIGNED to the forgeax `TextureView` opaque handle (per\n// feat-20260510-rhi-resource-creation IN-2 / AC-02 view narrow Path X;\n// breakage point #1). The earlier D-S5 temporary tightening to `Texture` was\n// retired once M1 of feat-20260510-rhi-resource-creation shipped\n// `RhiDevice.createTextureView`, so AI users now follow the spec idiom:\n// const view = device.createTextureView(texture, desc).unwrap();\n// pass.beginRenderPass({ colorAttachments: [{ view, ... }] });\n//\n// Charter mapping: proposition 5 consistent abstraction (call site lines up\n// with what `createTextureView` returns) + proposition 4 explicit failure\n// (passing a Texture brand to `view` is a tsc red signal at the call site,\n// not a runtime swap). The breakage point is registered in the AGENTS.md\n// RHI / Shader error model contract section -> breakage point list (M7 of\n// this closure).\n\n/**\n * Command encoder descriptor (Pick<GPUCommandEncoderDescriptor, 'label'>).\n *\n * Spec anchor: W3C WebGPU 22 GPUCommandEncoder /\n * [@webgpu/types.GPUCommandEncoderDescriptor].\n *\n * @example\n * const desc: CommandEncoderDescriptor = { label: 'frame-encoder' };\n */\nexport type CommandEncoderDescriptor = ExplicitUndefined<\n Pick<GPUCommandEncoderDescriptor, 'label'>\n>;\n\n/**\n * Render-pass color attachment (Pick<GPURenderPassColorAttachment, ...> with\n * `view` field aligned to the forgeax `TextureView` opaque handle, per\n * feat-20260510-rhi-resource-creation M2 view narrow Path X / breakage point\n * #1).\n *\n * Spec anchor: W3C WebGPU 22.7 Render pass /\n * [@webgpu/types.GPURenderPassColorAttachment].\n *\n * v0.1.69 spec shape: `view: GPUTexture | GPUTextureView`. The forgeax RHI\n * tightens the union to the single `TextureView` brand (the only branch the\n * shim ever produces post-M1). Charter proposition 5 consistent abstraction\n * (the field type matches what `RhiDevice.createTextureView` returns) +\n * proposition 4 explicit failure (passing a `Texture` brand here is a tsc red\n * signal; the AI user is steered to the spec idiom).\n *\n * **Migration**: see AGENTS.md break-point list 2026-05-10 #1\n * \"view: Texture -> TextureView narrow (major breaking)\" for the call-site\n * upgrade diff (3 narrowed fields: this `view` + `resolveTarget` +\n * `RenderPassDepthStencilAttachment.view`).\n *\n * @example\n * const view = device.createTextureView(tex, {}).unwrap();\n * const att: RenderPassColorAttachment = {\n * view,\n * clearValue: { r: 0, g: 0, b: 0, a: 1 },\n * loadOp: 'clear',\n * storeOp: 'store',\n * };\n */\nexport type RenderPassColorAttachment = ExplicitUndefined<\n Omit<\n Pick<\n GPURenderPassColorAttachment,\n 'view' | 'depthSlice' | 'resolveTarget' | 'clearValue' | 'loadOp' | 'storeOp'\n >,\n 'view' | 'resolveTarget'\n >\n> & {\n /**\n * TextureView target of this color attachment (view narrow Path X: aligned\n * to the forgeax `TextureView` brand returned by `createTextureView`; not\n * the spec union `GPUTexture | GPUTextureView`).\n */\n view: TextureView;\n /**\n * Optional resolve target for multisample resolution. Same view narrow\n * alignment as `view`.\n */\n resolveTarget?: TextureView | undefined;\n};\n\n/**\n * Render-pass depth/stencil attachment (Pick<GPURenderPassDepthStencilAttachment,\n * ...> with `view` field aligned to the forgeax `TextureView` opaque handle,\n * per feat-20260510-rhi-resource-creation M2 view narrow Path X / breakage\n * point #1).\n *\n * Spec anchor: W3C WebGPU 22.7 Render pass /\n * [@webgpu/types.GPURenderPassDepthStencilAttachment].\n *\n * Same view narrow alignment as RenderPassColorAttachment.\n *\n * **Migration**: see AGENTS.md break-point list 2026-05-10 #1 for the\n * call-site upgrade diff covering this `view` field plus the two\n * `RenderPassColorAttachment` narrowed fields.\n *\n * @example\n * const view = device.createTextureView(depthTex, {}).unwrap();\n * const ds: RenderPassDepthStencilAttachment = {\n * view,\n * depthClearValue: 1,\n * depthLoadOp: 'clear',\n * depthStoreOp: 'store',\n * };\n */\nexport type RenderPassDepthStencilAttachment = ExplicitUndefined<\n Omit<\n Pick<\n GPURenderPassDepthStencilAttachment,\n | 'view'\n | 'depthClearValue'\n | 'depthLoadOp'\n | 'depthStoreOp'\n | 'depthReadOnly'\n | 'stencilClearValue'\n | 'stencilLoadOp'\n | 'stencilStoreOp'\n | 'stencilReadOnly'\n >,\n 'view'\n >\n> & {\n /**\n * TextureView target of this depth/stencil attachment (view narrow Path X:\n * aligned to the forgeax `TextureView` brand).\n */\n view: TextureView;\n};\n\n/**\n * Render-pass descriptor (Pick<GPURenderPassDescriptor, ...>).\n *\n * Spec anchor: W3C WebGPU 22.7 Render pass /\n * [@webgpu/types.GPURenderPassDescriptor].\n *\n * `colorAttachments` element type uses the forgeax narrow\n * `RenderPassColorAttachment` (with `view: TextureView`);\n * `depthStencilAttachment` uses `RenderPassDepthStencilAttachment`.\n *\n * @example\n * const view = device.createTextureView(tex, {}).unwrap();\n * const desc: RenderPassDescriptor = {\n * label: 'frame',\n * colorAttachments: [{ view, loadOp: 'clear', storeOp: 'store',\n * clearValue: { r: 0, g: 0, b: 0, a: 1 } }],\n * };\n */\nexport type RenderPassDescriptor = ExplicitUndefined<\n Omit<\n Pick<\n GPURenderPassDescriptor,\n | 'label'\n | 'colorAttachments'\n | 'depthStencilAttachment'\n | 'occlusionQuerySet'\n | 'timestampWrites'\n | 'maxDrawCount'\n >,\n 'colorAttachments' | 'depthStencilAttachment' | 'occlusionQuerySet' | 'timestampWrites'\n >\n> & {\n /**\n * Color attachments for this render pass (forgeax narrow element type per\n * view narrow Path X: each entry's `view` field is `TextureView`, not the\n * spec union `GPUTexture | GPUTextureView`).\n */\n colorAttachments: Iterable<RenderPassColorAttachment | null | undefined>;\n /** Optional depth/stencil attachment with the same view narrow alignment. */\n depthStencilAttachment?: RenderPassDepthStencilAttachment | undefined;\n /** Occlusion query set (capability-gated). The shim accepts a\n * `QuerySet` brand created via `device.createQuerySet({ type: 'occlusion',\n * count })` and pairs it with `pass.beginOcclusionQuery(idx) /\n * pass.endOcclusionQuery()`; both methods now have real implementations\n * (see `RhiRenderPassEncoder` below). Capability gate: read\n * `device.caps.timestampQuery` ahead of `'timestamp'` query sets;\n * occlusion sets are unconditionally available. */\n occlusionQuerySet?: QuerySet | undefined;\n /** Optional timestamp query set and the pass boundary write slots. */\n timestampWrites?: RenderPassTimestampWrites | undefined;\n};\n\n/** Timestamp writes attached to a render pass descriptor. */\nexport interface RenderPassTimestampWrites {\n querySet: QuerySet;\n beginningOfPassWriteIndex?: number | undefined;\n endOfPassWriteIndex?: number | undefined;\n}\n\n/** Compute-pass descriptor with forgeax-owned timestamp query handles. */\nexport type ComputePassDescriptor = ExplicitUndefined<\n Omit<Pick<GPUComputePassDescriptor, 'label' | 'timestampWrites'>, 'timestampWrites'>\n> & {\n timestampWrites?: ComputePassTimestampWrites | undefined;\n};\n\n/** Timestamp writes attached to a compute pass descriptor. */\nexport interface ComputePassTimestampWrites {\n querySet: QuerySet;\n beginningOfPassWriteIndex?: number | undefined;\n endOfPassWriteIndex?: number | undefined;\n}\n\n// ============================================================================\n// Capabilities trio (MVP-1.2) - readonly + independent fields\n// ============================================================================\n//\n// Charter proposition 5 (consistent abstraction / discoverable differences):\n// caps (hardware probe) / features (enabled set) / limits (numeric ceilings)\n// are three independent semantic layers; `caps.X = false` is an explicit\n// signal, never an exception (proposition 4).\n\n/** Hardware-probe layer: readonly boolean capability flags. */\nexport interface RhiCaps {\n /**\n * The rendering backend kind — single source of truth for backend-aware\n * logic (e.g. explicit barrier insertion vs. spec-managed / GL-implicit\n * sync). Closed 4-member union: every backend reports exactly one.\n *\n * - `'webgpu'`: browser WebGPU — spec-managed barriers, no explicit\n * barrier insertion needed.\n * - `'wgpu-native'`: wgpu native-desktop runtime (Tauri / native) —\n * requires explicit Vulkan/Metal/DX12 barrier commands.\n * - `'wgpu-webgl2'`: wgpu GLES3/WebGL2 backend — GL implicit sync, no\n * explicit barrier insertion needed (equivalence group with `'webgpu'`).\n * - `'null'`: headless no-op backend (`@forgeax/engine-rhi-null`) for\n * structural unit tests — no GPU / DOM; records command-stream shape into\n * a ledger instead of executing it. No barrier insertion needed (the\n * no-op backend executes nothing); falls into the same no-barrier branch\n * as `'webgpu'` / `'wgpu-webgl2'`.\n *\n * @note `exactOptionalPropertyTypes` requires every backend fill this\n * field; a backend that omits it produces a tsc compile error.\n */\n readonly backendKind: 'webgpu' | 'wgpu-native' | 'wgpu-webgl2' | 'null';\n /** Whether compute pipelines are supported. */\n readonly compute: boolean;\n /** Whether timestamp queries are supported. */\n readonly timestampQuery: boolean;\n /** Backend-owned nanoseconds represented by one timestamp tick, or null when unavailable. */\n readonly timestampPeriodNanoseconds: number | null;\n /** Whether indirect drawing is supported. */\n readonly indirectDrawing: boolean;\n /**\n * Whether BC texture compression (BC1-BC7) is available.\n *\n * Derived from `adapter.features.has('texture-compression-bc')`.\n * On rhi-null this is always `false` (headless has no compression hardware,\n * AC-06).\n */\n readonly textureCompressionBc: boolean;\n /**\n * Whether ETC2 texture compression is available.\n *\n * Derived from `adapter.features.has('texture-compression-etc2')`.\n * On rhi-null this is always `false` (headless has no compression hardware,\n * AC-06).\n */\n readonly textureCompressionEtc2: boolean;\n /**\n * Whether ASTC texture compression is available.\n *\n * Derived from `adapter.features.has('texture-compression-astc')`.\n * On rhi-null this is always `false` (headless has no compression hardware,\n * AC-06).\n */\n readonly textureCompressionAstc: boolean;\n /**\n * Whether multi-draw indirect is available (wgpu native extension).\n *\n * @reserved-for-wgpu-native-only always `false` on browser backends; only\n * available when the forgeax renderer runs against a wgpu native runtime\n * (Tauri / native runtime, not the wasm bundle). `caps.X = false` is an\n * explicit signal, never an exception (charter proposition 4 / AGENTS.md\n * `RHI / WebGPU` shape rule #2 capability-gated).\n */\n readonly multiDrawIndirect: boolean;\n /**\n * Whether push constants are available (wgpu native extension).\n *\n * @reserved-for-wgpu-native-only always `false` on browser backends; only\n * available when the forgeax renderer runs against a wgpu native runtime\n * (Tauri / native runtime, not the wasm bundle). `caps.X = false` is an\n * explicit signal, never an exception (charter proposition 4 / AGENTS.md\n * `RHI / WebGPU` shape rule #2 capability-gated).\n */\n readonly pushConstants: boolean;\n /**\n * Whether bindless texture array is available (wgpu native extension).\n *\n * @reserved-for-wgpu-native-only always `false` on browser backends; only\n * available when the forgeax renderer runs against a wgpu native runtime\n * (Tauri / native runtime, not the wasm bundle). `caps.X = false` is an\n * explicit signal, never an exception (charter proposition 4 / AGENTS.md\n * `RHI / WebGPU` shape rule #2 capability-gated).\n */\n readonly textureBindingArray: boolean;\n /**\n * Whether sampler binding aliasing is supported across pipelines.\n *\n * @spec-anchor W3C WebGPU §10.3 Bind group layout — spec mandates that a\n * sampler may alias multiple binding slots; both navigator.gpu and the\n * wgpu wasm bundle satisfy this so the field is always `true` on browser\n * backends.\n * @note Always `true` on shipped backends (WebGPU + wgpu wasm). The field\n * exists for potential future backends that lack sampler aliasing.\n * @hint AI users use `caps.samplerAliasing` to gate code that creates two\n * `BindGroupEntry`s pointing at the same `Sampler` across different\n * layouts; `caps.X = false` is an explicit signal, never an exception\n * (charter proposition 4).\n */\n readonly samplerAliasing: boolean;\n /**\n * Whether the renderer can issue indirect draws with a non-zero\n * `firstInstance`.\n *\n * @spec-anchor W3C WebGPU §22.4 drawIndirect — the `indirect-first-instance`\n * feature on `GPUAdapter.features` gates non-zero `firstInstance` in\n * indirect draws; rhi-webgpu maps this to `device.features.has(\n * 'indirect-first-instance')`.\n * @note `false` on backends without indirect drawing support.\n * @hint Most AI users never need this; the field surfaces so a renderer\n * author building instanced draw batchers can gate the fast path. With\n * `caps.firstInstanceIndirect === false` the renderer must pre-rebase\n * instance indices in the vertex shader (charter proposition 5\n * consistent abstraction over a discoverable cap difference).\n */\n readonly firstInstanceIndirect: boolean;\n /**\n * Whether storage buffer bindings are available\n * (`device.limits.maxStorageBuffersPerShaderStage > 0`).\n *\n * @spec-anchor W3C WebGPU §3.6.2 GPUSupportedLimits.\n * maxStorageBuffersPerShaderStage; `> 0` means the device supports the\n * `storage` / `read-only-storage` binding types.\n * @note `false` on backends without storage buffer support.\n * @hint AI users gate compute / large-buffer paths on\n * `caps.storageBuffer`; the per-stage numeric limit lives on\n * `device.limits.maxStorageBuffersPerShaderStage` for capacity planning\n * (charter proposition 4: `caps.X = false` is an explicit signal).\n */\n readonly storageBuffer: boolean;\n /**\n * Whether storage texture bindings are available\n * (`device.limits.maxStorageTexturesPerShaderStage > 0`).\n *\n * @spec-anchor W3C WebGPU §3.6.2 GPUSupportedLimits.\n * maxStorageTexturesPerShaderStage; `> 0` means the device supports the\n * `write-only` / `read-write` storage texture binding types.\n * @note `false` on backends without storage texture support.\n * @hint AI users gate image-effects compute / postprocess paths on\n * `caps.storageTexture`; the per-stage numeric limit lives on\n * `device.limits.maxStorageTexturesPerShaderStage` (charter proposition\n * 4: `caps.X = false` is an explicit signal).\n */\n readonly storageTexture: boolean;\n /**\n * Whether the device can create `rgba16float` textures with `RENDER_ATTACHMENT`\n * usage, enabling the HDR cubemap path for IBL irradiance / specular prefilter\n * and downstream HDR render-target chains.\n *\n * @spec-anchor W3C WebGPU $25.1 GPUTextureFormat — `rgba16float` is an\n * optional texture format whose `RENDER_ATTACHMENT` capability is probed by\n * attempting `createTexture({ format: 'rgba16float', usage:\n * GPUTextureUsage.RENDER_ATTACHMENT, size: [1, 1, 1] })` on the live\n * device; failure maps the cap to `false`.\n * @note Probed at device-creation time via a synchronous `createTexture`\n * call, not via `GPUAdapter.features`. The `rgba16float` format is widely\n * supported but `RENDER_ATTACHMENT` with float formats is optional per spec\n * so the cap reflects the concrete device, not the adapter feature list.\n * @hint AI users gate IBL / HDR post-processing paths on\n * `caps.rgba16floatRenderable`; when `false` the internal equirect-to-cubemap\n * IBL projection (driven by declaring `Skylight{equirect}`) degrades to the\n * white-cube fallback and fires `{ code: 'equirect-projection-failed' }` with\n * a machine-readable `expected` field naming this cap (charter P3 structured\n * failure).\n */\n readonly rgba16floatRenderable: boolean;\n /**\n * Whether the device can create `rg11b10ufloat` textures with\n * `RENDER_ATTACHMENT` usage, enabling the HDR swapchain / render-target path\n * with reduced bit-depth precision versus `rgba16float`.\n *\n * @spec-anchor W3C WebGPU $25.1 GPUTextureFormat — `rg11b10ufloat` is\n * `RENDER_ATTACHMENT`-capable only when the optional feature\n * `rg11b10ufloat-renderable` is enabled (W3C WebGPU $4.2). Probed by gating\n * on `device.features.has('rg11b10ufloat-renderable')` first; only then\n * confirmed by `createTexture({ format: 'rg11b10ufloat', usage:\n * GPUTextureUsage.RENDER_ATTACHMENT, size: [1, 1, 1] })`.\n * @note The format packs 11+11+10 unsigned float bits into 32 bits per pixel;\n * it is a popular HDR swapchain format for engines that trade precision\n * for bandwidth but its `RENDER_ATTACHMENT` capability is not universal.\n * The feature gate is the authoritative answer (avoiding fan-out via\n * `device.onuncapturederror` when the optional feature is absent); the\n * subsequent probe handles the rare case where the feature is reported\n * but the concrete device still rejects.\n * @hint AI users can select an HDR back-buffer format by reading\n * `caps.rg11b10ufloatRenderable` before creating a\n * `GPUTextureUsage.RENDER_ATTACHMENT` texture at that format; when `false`\n * fall back to `rgba16float` (if `caps.rgba16floatRenderable` is true)\n * or an SDR format.\n */\n readonly rg11b10ufloatRenderable: boolean;\n /**\n * Whether the device supports sampling `rgba32float` textures with a\n * `filtering` sampler (linear / mipmap filtering), NOT just with a\n * `non-filtering` sampler.\n *\n * @spec-anchor W3C WebGPU $10.3 Bind group layout — a bind group layout\n * entry pairing a `filtering` sampler type with `sampleType: 'float'`\n * (matching `rgba32float`) validates only when the\n * `float32-filterable` feature is enabled. The cap probes this via\n * `device.createBindGroupLayout({ entries: [{ sampler: { type:\n * 'filtering' } }, { texture: { sampleType: 'float' } }] })` and\n * `device.createSampler({ minFilter: 'linear', magFilter: 'linear' })`;\n * failure maps the cap to `false`.\n * @note Probed by gating on `device.features.has('float32-filterable')`\n * first (the authoritative answer per spec $4.2; avoids fan-out via\n * `device.onuncapturederror` when the optional feature is absent); only\n * then confirmed by exercising the bind-group-layout. The subsequent\n * probe handles the rare case where the feature is reported but the\n * concrete device still rejects (spec ambiguity, driver quirks).\n * @hint AI users gate float32-sampled compute / post-process paths on\n * `caps.float32Filterable`; when `false` use `sampleType: 'unfilterable-\n * float'` with a `non-filtering` sampler and compute the filter kernel\n * manually in the shader, or fall back to `rgba16float` with filtering.\n */\n readonly float32Filterable: boolean;\n /**\n * Maximum number of color attachments per render pass.\n *\n * @spec-anchor W3C WebGPU $3.6.2 GPUSupportedLimits.maxColorAttachments;\n * spec minimum = 4, defaults to 8 on mainstream backends.\n * HDRP deferred pipeline requires >= 4 (3 g-buffer RT + 1 depth);\n * installPipeline checks this cap at install time and throws\n * a structured Standard transport refusal on violation (charter P3).\n * @note add-only minor (feat-20260612-hdrp-deferred-shading-learn-render-5-8\n * M1 / w5); no existing field is modified.\n */\n readonly maxColorAttachments: number;\n}\n\n/**\n * Enabled feature set, opaque iteration only via `has()`.\n *\n * Aligned with `GPUSupportedFeatures` shape; this empty interface intentionally\n * adds no fields — the concrete enabled set is decided at `requestDevice` time\n * and is then probed by AI users via `device.features.has('feature-name')`\n * (charter proposition 5 consistent abstraction; no implementation-detail leak,\n * no enumeration helper that would tie callers to a fixed feature list).\n *\n * @see {@link GPUSupportedFeatures}\n */\nexport interface RhiFeatures extends ReadonlySet<GPUFeatureName> {\n /** Aligned with GPUSupportedFeatures shape; concrete enabled set is decided\n * at device creation time. */\n}\n\n/** Numeric-limits layer aligned with GPUSupportedLimits (incl Compatibility\n * Mode follow-on fields). */\nexport type RhiLimits = Readonly<GPUSupportedLimits>;\n\n// ============================================================================\n// 7 main interfaces: Device / Queue / CommandEncoder / RenderPassEncoder /\n// ComputePassEncoder / RenderPipeline / ComputePipeline\n// ============================================================================\n//\n// Interface signatures accept POD + ArrayBuffer / Float32Array (math-free /\n// MVP-1.5); all fallible operations return Result<T, RhiError>\n// (D-5 + AGENTS.md error baseline).\n//\n// Note: interface names RenderPipeline / ComputePipeline / CommandEncoder\n// match opaque handle names - spec-aligned choice (per plan-strategy 7.1)\n// matching GPURenderPipeline et al; module-path semantics distinguish them.\n// M1 interfaces express \"operation verb sets\"; opaque handles serve as\n// return-value types.\n\n// ============================================================================\n// RhiInstance + RhiAdapter (M3 break-point #2; K-5 / K-6)\n// ============================================================================\n//\n// Strict two-step path: `rhi.requestAdapter(opts) -> adapter.requestDevice(opts)`\n// mirrors wgpu (research §6.1) + Dawn (§6.2) source-level idiom. The legacy\n// top-level `rhi.requestDevice(opts)` factory is deprecated in favour of this\n// path; AGENTS.md break-point list registers the deprecation under\n// feat-20260510-rhi-resource-creation.\n//\n// K-5: `RhiAdapter.features: ReadonlySet<GPUFeatureName>` (Round 3 fix-up\n// F-P1-2: aligned with `RhiDevice.features: RhiFeatures extends\n// ReadonlySet<GPUFeatureName>` so the cross-tier surface is uniform —\n// AI users use `.has(name)` on both abstraction layers; previously a\n// `ReadonlyArray<string>` projection drifted from the spec\n// `GPUSupportedFeatures` Set shape and split the AI-user idiom).\n// `RhiAdapter.limits: Readonly<Record<string, number>>` aligns with\n// `GPUAdapter.limits` (`GPUSupportedLimits`). RhiDevice.caps stays\n// as the existing high-level boolean gate (caps.compute /\n// caps.timestampQuery etc.).\n//\n// K-6: `RhiAdapter.requestDevice` returns `Result<RhiDevice, RhiError>` (NOT a\n// `(Device, Queue)` tuple). The queue continues to be exposed via the\n// existing `RhiDevice.queue: RhiQueue` field (spec `device.queue` auto-\n// provisioned, packages/rhi/src/index.ts).\n\n/**\n * RhiAdapter request options.\n *\n * Spec anchor: W3C WebGPU §3.2 `GPURequestAdapterOptions` /\n * [@webgpu/types.GPURequestAdapterOptions]. Fields pass through to the\n * underlying `navigator.gpu.requestAdapter(opts)` call.\n */\nexport type RequestAdapterOptions = ExplicitUndefined<\n Pick<GPURequestAdapterOptions, 'powerPreference' | 'forceFallbackAdapter'>\n>;\n\n/**\n * RhiAdapter.requestDevice options.\n *\n * Spec anchor: W3C WebGPU §3.4 `GPUDeviceDescriptor` /\n * [@webgpu/types.GPUDeviceDescriptor]. Fields pass through to the underlying\n * `adapter.requestDevice(opts)` call.\n */\nexport type RequestDeviceOptions = ExplicitUndefined<\n Pick<GPUDeviceDescriptor, 'label' | 'requiredFeatures' | 'requiredLimits'>\n>;\n\n/**\n * RhiInstance — entry point for adapter discovery (K-6 strict two-step path).\n *\n * Spec anchor: W3C WebGPU §3.1 `GPU` interface / [@webgpu/types.GPU]; wgpu\n * `Instance::request_adapter` (research §6.1) + Dawn\n * `InstanceBase::APIRequestAdapter` (§6.2).\n *\n * Replaces the legacy top-level `rhi.requestDevice(opts)` factory (break-\n * point #2). AI users follow the spec idiom:\n * const a = (await rhi.requestAdapter()).unwrap();\n * const d = (await a.requestDevice(opts)).unwrap();\n *\n * @example\n * const adapterResult = await rhi.requestAdapter();\n * if (!adapterResult.ok) {\n * // route via switch (adapterResult.error.code)\n * }\n */\nexport interface RhiInstance {\n /**\n * Request a GPU adapter.\n *\n * Spec anchor: W3C WebGPU §3.1 `GPU.requestAdapter` /\n * [@webgpu/types.GPU.requestAdapter].\n *\n * @param opts — W3C-spec request adapter options (powerPreference,\n * forceFallbackAdapter).\n * @param compatibleSurface — non-W3C extension required by the wgpu GL\n * backend for adapter enumeration. Provided as a positional escape hatch\n * so the first parameter stays spec-aligned (plan-strategy D-5).\n * rhi-webgpu accepts and ignores this parameter (dual-impl symmetry);\n * rhi-wgpu routes it to `requestAdapterWithCanvas`.\n *\n * Failure paths (research §F-5):\n * - adapter null -> `Result.err({ code: 'adapter-unavailable' })`.\n */\n requestAdapter(\n opts?: RequestAdapterOptions | undefined,\n compatibleSurface?: HTMLCanvasElement | OffscreenCanvas | undefined,\n ): Promise<Result<RhiAdapter, RhiError>>;\n}\n\n/**\n * RhiAdapter — capability-probe layer + device-creation entry (K-5 + K-6).\n *\n * Spec anchor: W3C WebGPU §3.2 `GPUAdapter` interface /\n * [@webgpu/types.GPUAdapter]; wgpu `Adapter::request_device` (research §6.1)\n * + Dawn `AdapterBase::APIRequestDevice` (§6.2).\n *\n * The `features` / `limits` fields let AI users **pre-screen** device\n * capabilities before calling `requestDevice(opts)` (charter proposition 4\n * forward-reachable: features mismatch becomes visible before spec\n * validation surfaces it).\n *\n * @example\n * if (!adapter.features.has('timestamp-query')) {\n * // skip timestamp-related code paths\n * }\n * const deviceResult = await adapter.requestDevice({\n * requiredFeatures: ['timestamp-query'],\n * });\n */\nexport interface RhiAdapter {\n /**\n * Read-only feature-name set (K-5).\n *\n * Aligned with `GPUAdapter.features` projection of `GPUSupportedFeatures`\n * (a read-only Set) **and** with `RhiDevice.features` (Round 3 fix-up\n * F-P1-2: cross-tier shape uniformity — AI users use `.has(name)` on\n * both abstraction layers, no projection drift).\n *\n * F-1 ai-user-review: mutation of set entries (`features.add('x')` /\n * deletion / clear) is rejected at compile time via `ReadonlySet`;\n * charter proposition 4 explicit failure + proposition 5 consistent\n * abstraction.\n */\n readonly features: ReadonlySet<GPUFeatureName>;\n /**\n * Read-only numeric-limits map (K-5).\n *\n * Aligned with `GPUAdapter.limits` projection of `GPUSupportedLimits`. The\n * forgeax form flattens to a `Readonly<Record<string, number>>` so AI users\n * can do `adapter.limits.maxTextureDimension2D` lookups without holding the\n * spec object handle.\n *\n * F-1 ai-user-review: mutation of values (`limits.x = 0`) is rejected at\n * compile time.\n */\n readonly limits: Readonly<Record<string, number>>;\n /**\n * Request a GPU device.\n *\n * Spec anchor: W3C WebGPU §3.2 `GPUAdapter.requestDevice` /\n * [@webgpu/types.GPUAdapter.requestDevice].\n *\n * Returns `Result<RhiDevice, RhiError>` (K-6: NOT a `(Device, Queue)` tuple\n * — queue is exposed via `RhiDevice.queue`).\n *\n * Failure paths (research §F-5):\n * - feature not enabled -> `Result.err({ code: 'feature-not-enabled' })`.\n * - limit exceeded -> `Result.err({ code: 'limit-exceeded' })`.\n */\n requestDevice(opts?: RequestDeviceOptions | undefined): Promise<Result<RhiDevice, RhiError>>;\n}\n\n// ============================================================================\n// RhiSurface + RhiCanvasContext (M3 / K-4)\n// ============================================================================\n//\n// Spec anchor: W3C WebGPU §3.3 GPUCanvasContext / §3.3 GPUCanvasConfiguration.\n// 4 methods + 7 fields per research §3.1 + §3.2; 4-method algorithms per\n// research §3.3. K-4 decision: getCurrentTexture returns Result<Texture,\n// RhiError> (NOT TextureView) — spec literal alignment + AI users go two-step:\n// const tex = canvasContext.getCurrentTexture().unwrap();\n// const view = device.createTextureView(tex, {}).unwrap();\n\n/**\n * Canvas configuration descriptor (Pick<GPUCanvasConfiguration, 7 fields>).\n *\n * Spec anchor: W3C WebGPU §3.3 `GPUCanvasConfiguration` /\n * [@webgpu/types.GPUCanvasConfiguration].\n *\n * 7 fields (research §3.2):\n * - `device` (required): the GPUDevice for the configured context.\n * - `format` (required): one of `{'bgra8unorm', 'rgba8unorm', 'rgba16float'}`\n * (the spec normative supported context formats).\n * - `usage` (default `0x10` = RENDER_ATTACHMENT): bitmask of GPUTextureUsage\n * for the swap-chain textures.\n * - `viewFormats` (default `[]`): list of formats createView may yield;\n * **the spec sRGB-render-target idiom** uses `format='bgra8unorm'` +\n * `viewFormats=['bgra8unorm-srgb']` + `device.createTextureView` (research\n * §3.2 normative).\n * - `colorSpace` (default `'srgb'`): predefined color space for the canvas.\n * - `toneMapping` (default `{}` ≅ `{ mode: 'standard' }`): HDR tone-mapping\n * descriptor; the spec NOTE in research §3.2 says implementations\n * without tone-mapping support **omit** this from `getConfiguration()`.\n * - `alphaMode` (default `'opaque'`): canvas compositing mode.\n *\n * Field NAMES align byte-for-byte with the spec; the forgeax `?: T |\n * undefined` shape (S-7 / hard-constraint 10) lets writers omit or pass\n * `undefined` explicitly while the shim distinguishes via `'x' in src`.\n */\nexport type CanvasConfiguration = ExplicitUndefined<\n Omit<\n Pick<\n GPUCanvasConfiguration,\n 'device' | 'format' | 'usage' | 'viewFormats' | 'colorSpace' | 'toneMapping' | 'alphaMode'\n >,\n 'device'\n >\n> & {\n /**\n * The forgeax RhiDevice the configured context binds to (D-S5 pattern: spec\n * `device: GPUDevice` is replaced by the forgeax brand so AI users pass the\n * device they got from `rhi.requestAdapter().requestDevice()`).\n */\n device: RhiDevice;\n};\n\ndeclare const RhiSurfaceBrand: unique symbol;\n/**\n * RhiSurface — opaque abstraction over a canvas surface\n * (HTMLCanvasElement / OffscreenCanvas).\n *\n * Spec couples GPUCanvasContext to a canvas (research §3.1); the forgeax\n * abstraction wraps the raw GPUCanvasContext in an opaque brand. AI users\n * obtain the `RhiCanvasContext` via\n * `rhi.acquireCanvasContext(canvas)` (returns `Result<RhiCanvasContext, RhiError>`).\n *\n * Charter proposition 5 consistent abstraction: the surface brand decouples\n * AI-user code from the DOM canvas zoo (HTMLCanvasElement / OffscreenCanvas /\n * native Window).\n */\nexport interface RhiSurface {\n readonly [RhiSurfaceBrand]: void;\n}\n\n/**\n * RhiCanvasContext — forgeax canvas-context abstraction (M3 / K-4).\n *\n * Spec anchor: W3C WebGPU §3.3 `GPUCanvasContext` /\n * [@webgpu/types.GPUCanvasContext]. 4 methods (research §3.1) match the spec\n * names; the return types differ:\n * - `configure` returns `Result<void, RhiError>` (the spec returns void; the\n * forgeax form surfaces `webgpu-runtime-error` on format-gate / device-\n * lost paths via Result, charter proposition 4 explicit failure).\n * - `unconfigure` returns void (spec literal alignment).\n * - `getConfiguration` returns `CanvasConfiguration | undefined` (the spec\n * returns `GPUCanvasConfiguration?`; forgeax uses `undefined`).\n * - `getCurrentTexture` returns `Result<Texture, RhiError>` (K-4: Texture\n * brand, NOT TextureView; AI users go two-step\n * `device.createTextureView(canvasContext.getCurrentTexture().unwrap(), {})`).\n *\n * Lifecycle (research §3.3 [[Expire the current texture]]): currentTexture\n * **must NOT be cached across frames** — every frame must call\n * `getCurrentTexture()` afresh.\n */\n/** Configure-time proof that a storage surface can present through its endpoint. */\nexport interface RhiCanvasSurfaceDescriptorFacts {\n readonly format: string;\n readonly usage: number;\n readonly width: number;\n readonly height: number;\n readonly alphaMode: string;\n readonly presentMode: string;\n}\n\nexport interface RhiCanvasSurfacePresentationProof {\n readonly descriptor: boolean;\n readonly acquisition: boolean;\n readonly validation: boolean;\n /** Stable identity for the concrete surface that produced this proof. */\n readonly surfaceIdentity?: string;\n /** Descriptor requested by the owner at configure time. */\n readonly requested?: RhiCanvasSurfaceDescriptorFacts;\n /** Descriptor accepted and validated by the concrete surface. */\n readonly validated?: RhiCanvasSurfaceDescriptorFacts;\n}\n\nexport interface RhiCanvasContext {\n /** Backend-produced configure-time presentation proof; absent means fail closed. */\n readonly presentationProof?: RhiCanvasSurfacePresentationProof;\n /**\n * Configure the canvas context with a forgeax CanvasConfiguration.\n *\n * Returns `Result<void, RhiError>` (charter proposition 4 explicit failure).\n *\n * Failure paths (research §3.3):\n * - `format` not in supported context formats (`{'bgra8unorm',\n * 'rgba8unorm', 'rgba16float'}`) -> `'webgpu-runtime-error'` with\n * `.expected = 'one of bgra8unorm/rgba8unorm/rgba16float'`.\n * - `device` invalid | lost -> `'rhi-not-available'`.\n *\n * @example\n * const out = canvasContext.configure({\n * device,\n * format: 'bgra8unorm',\n * usage: GPUTextureUsage.RENDER_ATTACHMENT,\n * viewFormats: ['rgba8unorm-srgb'],\n * });\n * if (!out.ok) {\n * // route via switch (out.error.code)\n * }\n */\n configure(desc: CanvasConfiguration): Result<void, RhiError>;\n /**\n * Unconfigure the canvas context (spec literal void return).\n *\n * Idempotent (already-unconfigured contexts continue to be unconfigured;\n * Operation is silent).\n */\n unconfigure(): void;\n /**\n * Return the current canvas configuration, or `undefined` if the context is\n * unconfigured.\n *\n * Feature-detection entry (research §3.2 spec NOTE): when an implementation\n * does not support a configuration field (e.g. tone-mapping), the field is\n * **omitted** from the returned record (NOT defaulted) so AI users can use\n * `'toneMapping' in conf` to detect support.\n */\n getConfiguration(): CanvasConfiguration | undefined;\n /**\n * Get the current swap-chain texture (K-4: returns Texture brand, NOT\n * TextureView).\n *\n * Spec anchor: W3C WebGPU §3.3 `GPUCanvasContext.getCurrentTexture` /\n * [@webgpu/types.GPUCanvasContext.getCurrentTexture].\n *\n * Failure paths (research §3.3):\n * - context unconfigured -> `'webgpu-runtime-error'` (spec\n * `InvalidStateError` mapping).\n *\n * AI users typically pair this with `device.createTextureView` to get the\n * render-pass attachment view (charter proposition 5 consistent abstraction):\n * const tex = canvasContext.getCurrentTexture().unwrap();\n * const view = device.createTextureView(tex, {}).unwrap();\n * pass.beginRenderPass({ colorAttachments: [{ view, ... }] });\n *\n * Lifecycle (research §3.3 [[Expire the current texture]]): each frame\n * **must call this fresh**; the forgeax shim does NOT cache across frames.\n */\n getCurrentTexture(): Result<Texture, RhiError>;\n}\n\n/** GPU device - sole entry point for resource creation + capability probing. */\nexport interface RhiDevice {\n /** Hardware-probe layer (charter proposition 5). */\n readonly caps: RhiCaps;\n /** Enabled-features layer. */\n readonly features: RhiFeatures;\n /** Numeric-limits layer. */\n readonly limits: RhiLimits;\n\n /** Probe the complete r32float sampled/storage/readback profile once per device generation. */\n probeTextureFormatCapability(): Promise<Result<RhiTextureFormatCapabilityReceipt, RhiError>>;\n\n /** Create GPU buffer. */\n createBuffer(desc: BufferDescriptor): Result<Buffer, RhiError>;\n /** Create GPU texture. */\n createTexture(desc: TextureDescriptor): Result<Texture, RhiError>;\n /**\n * Destroy a GPU buffer obtained from `createBuffer`.\n *\n * Spec anchor: W3C WebGPU §gpubuffer-destroy /\n * [@webgpu/types.GPUBuffer.destroy]; wgpu wasm\n * `RhiWgpuBuffer::destroy` (research §F-1; both surfaces are idempotent\n * void at the underlying GPU).\n *\n * The forgeax form prefers fail-fast over the spec idempotent void:\n * the shim layer (rhi-webgpu / rhi-wgpu) tracks per-handle\n * `destroyed: boolean` and surfaces a second destroy as\n * `Result.err({ code: 'destroy-after-destroy' })` rather than silently\n * succeeding. Double destroy is almost always a lifecycle bug — caching\n * a stale handle, a forgotten registry slot, a race between dispose\n * paths — and surfacing it early at the call site is more useful than\n * swallowing it (plan-strategy D-7 + architecture-principles §5 Fail\n * Fast). Charter proposition 4 explicit failure.\n *\n * Failure paths:\n * - second destroy on the same handle ->\n * `Result.err({ code: 'destroy-after-destroy' })`.\n *\n * @example\n * const r = device.destroyBuffer(buf);\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\n destroyBuffer(buf: Buffer): Result<void, RhiError>;\n /**\n * Destroy a GPU query set obtained from `createQuerySet`.\n *\n * Query sets are device-owned resources even though the WebGPU surface does\n * not expose them through the Buffer/Texture families. The explicit RHI\n * seam lets Render release timestamp query sets exactly once after queue\n * completion, including failure and disposal paths.\n */\n destroyQuerySet(querySet: QuerySet): Result<void, RhiError>;\n /**\n * Destroy a GPU texture obtained from `createTexture`.\n *\n * Spec anchor: W3C WebGPU §gputexture-destroy /\n * [@webgpu/types.GPUTexture.destroy]; wgpu wasm idempotent void at the\n * underlying GPU.\n *\n * Same fail-fast contract as `destroyBuffer`: the shim layer tracks\n * per-handle `destroyed: boolean` and surfaces a second destroy as\n * `Result.err({ code: 'destroy-after-destroy' })`.\n *\n * @example\n * const r = device.destroyTexture(tex);\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\n destroyTexture(tex: Texture): Result<void, RhiError>;\n /**\n * Create a GPU texture view of an existing texture.\n *\n * Spec anchor: W3C WebGPU §texture-view-creation /\n * [@webgpu/types.GPUTexture.createView].\n *\n * Introduced in feat-20260510-rhi-resource-creation (M1). Cross-resource\n * validation is performed fast-path by the shim before forwarding to raw\n * GPUTexture.createView (research §1.1):\n * - `format` must be in `source.format ∪ source.viewFormats`; violation\n * returns Result.err({ code: 'webgpu-runtime-error' }).\n * - `usage` must be a subset of source.usage (bitmask); violation returns\n * the same code.\n *\n * @example\n * const r = device.createTextureView(tex, { format: 'rgba8unorm', dimension: '2d' });\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\n createTextureView(texture: Texture, desc: TextureViewDescriptor): Result<TextureView, RhiError>;\n /** Create sampler (spec defaults are applied by the shim). */\n createSampler(desc?: SamplerDescriptor | undefined): Result<Sampler, RhiError>;\n /** Create bind group layout. */\n createBindGroupLayout(desc: BindGroupLayoutDescriptor): Result<BindGroupLayout, RhiError>;\n /**\n * Create a bind group (instantiated layout + resource bindings).\n *\n * Spec anchor: W3C WebGPU 10 Resource binding /\n * [@webgpu/types.GPUDevice.createBindGroup].\n *\n * Introduced in feat-20260509-ecs-render-bridge-mvp (D-S1) — additive\n * extension; reuses the existing 17-member `RhiErrorCode` union\n * ('feature-not-enabled' / 'limit-exceeded' / 'webgpu-runtime-error').\n * No new error code is introduced (AGENTS.md evolution contract no-op,\n * breakage list stays empty).\n *\n * @example\n * const out = device.createBindGroup({ label: 'view-bg', layout: bgl, entries: [...] });\n * if (!out.ok) {\n * // route via switch (out.error.code)\n * }\n */\n createBindGroup(desc: BindGroupDescriptor): Result<BindGroup, RhiError>;\n /**\n * Create a pipeline layout (aggregates BindGroupLayouts).\n *\n * Spec anchor: W3C WebGPU 10.3 Pipeline layout /\n * [@webgpu/types.GPUDevice.createPipelineLayout].\n *\n * Introduced in feat-20260509-ecs-render-bridge-mvp (D-S1) — additive\n * extension; reuses the existing 17-member `RhiErrorCode` union.\n *\n * @example\n * const out = device.createPipelineLayout({ label: 'pbr-pl', bindGroupLayouts: [viewBgl, materialBgl, meshArrayBgl] });\n * if (!out.ok) {\n * // route via switch (out.error.code)\n * }\n */\n createPipelineLayout(desc: PipelineLayoutDescriptor): Result<PipelineLayout, RhiError>;\n /** Create render pipeline (synchronous path). */\n createRenderPipeline(desc: RenderPipelineDescriptor): Result<RenderPipeline, RhiError>;\n /**\n * Create a compute pipeline (synchronous path).\n *\n * Spec anchor: W3C WebGPU §compute-pipeline-creation /\n * [@webgpu/types.GPUDevice.createComputePipeline].\n *\n * Introduced in feat-20260510-rhi-resource-creation (M1). Capability gate\n * (research §1.2 + plan-strategy §4.3 boundary case row 1):\n * `caps.compute === false` -> Result.err({ code: 'feature-not-enabled' }).\n * The MVP WebGPU path always has caps.compute=true; the gate exists for\n * potential future backends that lack compute.\n *\n * @example\n * const r = device.createComputePipeline({\n * layout: 'auto',\n * compute: { module, entryPoint: 'cs_main' },\n * });\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\n createComputePipeline(desc: ComputePipelineDescriptor): Result<ComputePipeline, RhiError>;\n /**\n * Create a query set (occlusion or timestamp).\n *\n * Spec anchor: W3C WebGPU §queries / [@webgpu/types.GPUDevice.createQuerySet].\n *\n * Introduced in feat-20260510-rhi-resource-creation (M1). Hard constraints\n * (research §1.3):\n * - `count <= 4096` (spec normative); violation -> 'limit-exceeded'.\n * - `type === 'timestamp'` requires caps.timestampQuery; otherwise ->\n * 'feature-not-enabled'.\n * - `count = 0` is legal.\n *\n * @example\n * const r = device.createQuerySet({ type: 'occlusion', count: 4 });\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\n createQuerySet(desc: QuerySetDescriptor): Result<QuerySet, RhiError>;\n\n /**\n * Create a command encoder.\n *\n * Spec anchor: W3C WebGPU 21.2 createCommandEncoder /\n * [@webgpu/types.GPUDevice.createCommandEncoder].\n *\n * @example\n * const encResult = device.createCommandEncoder({ label: 'frame' });\n * if (!encResult.ok) {\n * // route via switch (encResult.error.code)\n * } else {\n * const enc = encResult.value;\n * // ... record commands ...\n * }\n */\n createCommandEncoder(\n desc?: CommandEncoderDescriptor | undefined,\n ): Result<RhiCommandEncoder, RhiError>;\n\n // fix-f3: synchronous createShaderModule placeholder removed - the\n // shader-compile-failed error path must go through the top-level async\n // factory `createShaderModule(device, desc)` exported from\n // `@forgeax/engine-rhi-webgpu`. A synchronous placeholder would render the\n // 'shader-compile-failed' branch unreachable in\n // `switch (err.code)` exhaustive consumers (charter proposition 5\n // consistent abstraction). See plan-strategy 7.3 error-info table\n // shader row + verify Round 1 finding F3.\n\n /** Queue for command submission. */\n readonly queue: RhiQueue;\n\n /**\n * Spec-style device.lost Promise (research F-4 / R2 mitigation). The engine\n * layer performs single-source subscription + dual-form fan-out without a\n * second cache. `reason` is a binary union ('destroyed' / 'unknown').\n */\n // forgeax-async-whitelist: dom-native — spec `GPUDevice.lost` Promise\n // passthrough; resolves (never rejects) per spec normative when the\n // underlying device transitions to the lost state.\n readonly lost: Promise<{ readonly reason: 'destroyed' | 'unknown'; readonly message: string }>;\n}\n\n/** GPU command queue - writeBuffer / submit + M5 writeTexture /\n * copyExternalImageToTexture / onSubmittedWorkDone. */\nexport interface RhiQueue {\n /** Direct write to a buffer (POD + ArrayBufferView, math-free). */\n writeBuffer(\n buffer: Buffer,\n bufferOffset: number,\n data: ArrayBufferView | ArrayBuffer,\n dataOffset?: number | undefined,\n size?: number | undefined,\n ): Result<void, RhiError>;\n /**\n * Direct write to a texture region.\n *\n * Spec anchor: W3C WebGPU §queue-writetexture /\n * [@webgpu/types.GPUQueue.writeTexture]. Field NAMES align byte-for-byte\n * with the spec; the forgeax form returns Result<void, RhiError> instead\n * of void so AI users can route alignment failures (research §1.3 +\n * plan-strategy 2 K-2: bytesPerRow % 256 != 0 maps to\n * 'queue-write-buffer-out-of-bounds').\n *\n * @example\n * const out = device.queue.writeTexture(\n * { texture: tex, mipLevel: 0, origin: [0, 0, 0] },\n * pixels,\n * { offset: 0, bytesPerRow: 256, rowsPerImage: H },\n * { width: W, height: H, depthOrArrayLayers: 1 },\n * );\n * if (!out.ok) {\n * // route via switch (out.error.code)\n * }\n */\n writeTexture(\n destination: TextureWriteDestination,\n data: ArrayBufferView | ArrayBuffer,\n dataLayout: Pick<GPUTexelCopyBufferLayout, 'offset' | 'bytesPerRow' | 'rowsPerImage'>,\n size: GPUExtent3DStrict,\n ): Result<void, RhiError>;\n /**\n * Copy an external image source (ImageBitmap / canvas / video) into a\n * GPUTexture region.\n *\n * Spec anchor: W3C WebGPU §queue-copyexternalimagetotexture /\n * [@webgpu/types.GPUQueue.copyExternalImageToTexture]. The forgeax form\n * returns Result<void, RhiError>.\n *\n * dawn-node note: dawn-node lacks HTMLCanvasElement / VideoFrame /\n * HTMLImageElement; only the ImageBitmap subset reachable from\n * createImageBitmap is exercised in dawn tests (research §7.1).\n */\n copyExternalImageToTexture(\n source: Pick<GPUCopyExternalImageSourceInfo, 'source' | 'origin' | 'flipY'>,\n destination: ExternalImageTextureDestination,\n copySize: GPUExtent3DStrict,\n ): Result<void, RhiError>;\n /** Submit command buffers (single-use). */\n submit(commandBuffers: readonly CommandBuffer[]): Result<void, RhiError>;\n /**\n * Resolve when all currently-enqueued operations have completed.\n *\n * Spec anchor: W3C WebGPU §queue-onsubmittedworkdone /\n * [@webgpu/types.GPUQueue.onSubmittedWorkDone]. Returns\n * `Promise<undefined>` per spec normative (research §5.1: no reject path;\n * device-lost flows through `RhiDevice.lost` instead). Ordering\n * constraints (research §5.2):\n * - constraint #1 (FIFO): if p1 = q.onSubmittedWorkDone() is called\n * before p2 = q.onSubmittedWorkDone(), p1 must settle before p2.\n * - constraint #2 (mapAsync vs onSubmittedWorkDone): if p1 =\n * b.mapAsync() is called before p2 = q.onSubmittedWorkDone(), p1 must\n * settle before p2.\n *\n * @example Pattern A read-back idiom:\n * const cb = enc.finish().value;\n * queue.submit([cb]);\n * await queue.onSubmittedWorkDone();\n * await readBuf.mapAsync(GPUMapMode.READ);\n * const range = readBuf.getMappedRange().value;\n */\n // forgeax-async-whitelist: dom-native — spec `GPUQueue.onSubmittedWorkDone`\n // never rejects (research §5.1 normative); failure surfaces via\n // `RhiDevice.lost` instead.\n onSubmittedWorkDone(): Promise<undefined>;\n}\n\n/** GPU command encoder - records render / compute passes + resource copies.\n *\n * Method NAMES align byte-for-byte with `@webgpu/types.GPUCommandEncoder` +\n * `GPUDebugCommandsMixin` (research F-1 / D-S4). 12 spec methods plus one\n * ForgeaX compound operation:\n * - 9 direct: beginRenderPass / beginComputePass / copyBufferToBuffer /\n * copyBufferToTexture / copyTextureToBuffer / copyTextureToTexture /\n * clearBuffer / resolveQuerySet / finish\n * - 3 mixin (GPUDebugCommandsMixin): pushDebugGroup / popDebugGroup /\n * insertDebugMarker\n *\n * Lifecycle: after `finish()`, all subsequent recording calls return\n * Result.err({ code: 'command-encoder-finished' }) per D-S3 template 1\n * (where the method returns Result; void-returning methods throw the\n * structured error so AI users observe the failure consistently).\n */\nexport interface RhiCommandEncoder {\n /** Begin render pass (auto-closes on end()).\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.beginRenderPass].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel: spec-aligned void return throws on finished state; AI users wrap call sites with `try / catch (e: unknown) { if (e instanceof RhiError && e.code === 'command-encoder-finished') ... }`).\n * @example\n * const pass = encoder.beginRenderPass({ colorAttachments: [{ ... }] });\n */\n beginRenderPass(desc: RenderPassDescriptor): RhiRenderPassEncoder;\n /** Begin compute pass.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.beginComputePass].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel: see beginRenderPass for the recovery pattern).\n * @example\n * const pass = encoder.beginComputePass();\n */\n beginComputePass(desc?: ComputePassDescriptor | undefined): RhiComputePassEncoder;\n /**\n * Record an empty timestamp-enabled compute pass and close it immediately.\n *\n * This is a ForgeaX compound recording operation equivalent to\n * `const pass = encoder.beginComputePass(desc); pass.end()`; it is not a\n * native `GPUCommandEncoder` method and does not write a timestamp directly.\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a\n * finished encoder.\n */\n encodeEmptyComputePass(desc: ComputePassDescriptor): void;\n /** Copy a sub-region of a Buffer to another Buffer (5-arg full form).\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.copyBufferToBuffer].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern). Both overloads share the same throw contract.\n * @example\n * encoder.copyBufferToBuffer(src, 0, dst, 0, 256);\n */\n copyBufferToBuffer(\n source: Buffer,\n sourceOffset: number,\n destination: Buffer,\n destinationOffset: number,\n size: number,\n ): void;\n /** Copy a Buffer to another Buffer (3-arg shorthand).\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.copyBufferToBuffer].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern). Both overloads share the same throw contract.\n * @example\n * encoder.copyBufferToBuffer(src, dst, 256);\n */\n copyBufferToBuffer(source: Buffer, destination: Buffer, size?: number | undefined): void;\n /** Copy a Buffer sub-region to a Texture sub-region.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.copyBufferToTexture].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern).\n * @example\n * encoder.copyBufferToTexture(srcInfo, dstInfo, [w, h, 1]);\n */\n copyBufferToTexture(\n source: GPUTexelCopyBufferInfo,\n destination: GPUTexelCopyTextureInfo,\n copySize: GPUExtent3DStrict,\n ): void;\n /** Copy a Texture sub-region to a Buffer sub-region.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.copyTextureToBuffer].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern).\n * @example\n * encoder.copyTextureToBuffer(srcInfo, dstInfo, [w, h, 1]);\n */\n copyTextureToBuffer(\n source: GPUTexelCopyTextureInfo,\n destination: GPUTexelCopyBufferInfo,\n copySize: GPUExtent3DStrict,\n ): void;\n /** Opaque RHI handle form for renderer-owned readback. */\n copyTextureToBuffer(\n source: TextureCopySource,\n destination: BufferCopyDestination,\n copySize: GPUExtent3DStrict,\n ): void;\n /** Union form for decorators that transparently forward either handle form. */\n copyTextureToBuffer(\n source: GPUTexelCopyTextureInfo | TextureCopySource,\n destination: GPUTexelCopyBufferInfo | BufferCopyDestination,\n copySize: GPUExtent3DStrict,\n ): void;\n /** Copy a Texture sub-region to a Texture sub-region.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.copyTextureToTexture].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern).\n * @example\n * encoder.copyTextureToTexture(srcInfo, dstInfo, [w, h, 1]);\n */\n copyTextureToTexture(\n source: GPUTexelCopyTextureInfo,\n destination: GPUTexelCopyTextureInfo,\n copySize: GPUExtent3DStrict,\n ): void;\n /** Fill a Buffer sub-region with zeros.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.clearBuffer].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern).\n * @example\n * encoder.clearBuffer(buf, 0, 256);\n */\n clearBuffer(buffer: Buffer, offset?: number | undefined, size?: number | undefined): void;\n /** Resolve query results from a QuerySet to a Buffer.\n *\n * Real implementation (M3 / w26): writes 8-byte query results in 256-byte\n * aligned strides into `destination` starting at `destinationOffset`.\n * Validates `destination.usage & GPUBufferUsage.QUERY_RESOLVE` and the\n * 256-byte alignment up front; on misuse returns\n * `Result.err({ code: 'webgpu-runtime-error', ... })` with a structured\n * .expected / .hint pair.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.resolveQuerySet].\n *\n * @example\n * const out = encoder.resolveQuerySet(qs, 0, 4, dstBuf, 0);\n * if (!out.ok) {\n * // switch (out.error.code) { case 'webgpu-runtime-error': ... }\n * }\n */\n resolveQuerySet(\n querySet: QuerySet,\n firstQuery: number,\n queryCount: number,\n destination: Buffer,\n destinationOffset: number,\n ): Result<void, RhiError>;\n /** Push a labelled debug group (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.pushDebugGroup].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (the debug-commands mixin permits a no-op pass-through after finish() so the signal stays real instead of forging a `@throws` contract; charter proposition 4).\n * @example\n * encoder.pushDebugGroup('frame-setup');\n */\n pushDebugGroup(groupLabel: string): void;\n /** Pop the most recent debug group (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.popDebugGroup].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (see pushDebugGroup JSDoc for the dual-channel rationale).\n * @example\n * encoder.popDebugGroup();\n */\n popDebugGroup(): void;\n /** Insert a labelled debug marker (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.insertDebugMarker].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (see pushDebugGroup JSDoc for the dual-channel rationale).\n * @example\n * encoder.insertDebugMarker('post-resolve');\n */\n insertDebugMarker(markerLabel: string): void;\n /** Finish recording -> CommandBuffer. After finish() any further recording\n * call returns Result.err({ code: 'command-encoder-finished' }).\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.finish].\n *\n * @example\n * const cb = encoder.finish();\n * if (cb.ok) device.queue.submit([cb.value]);\n */\n finish(): Result<CommandBuffer, RhiError>;\n}\n\n/** GPU render pass encoder - records draw calls + state changes.\n *\n * Method NAMES align byte-for-byte with @webgpu/types.GPURenderPassEncoder +\n * GPURenderCommandsMixin + GPUBindingCommandsMixin + GPUDebugCommandsMixin\n * (research F-2 / D-S4): 17 spec stable + 1 setBindGroup overload + 1\n * remaining capability-gated placeholder (`executeBundles` returns\n * Result.err({ code: 'rhi-not-available', hint: 'see\n * feat-future-rhi-render-bundle' })). The 2 occlusion-query methods\n * (`beginOcclusionQuery` / `endOcclusionQuery`) shipped real implementations\n * in M3 (w23) backed by `RenderPassDescriptor.occlusionQuerySet`.\n *\n * `setImmediates` (PROPOSED) is intentionally NOT exposed (charter\n * proposition 4: untested features hide behind caps, not surfaces).\n *\n * Lifecycle: encoder.finish() while a pass is unfinished returns\n * Result.err({ code: 'render-pass-not-ended' }) per D-S3 template 2.\n */\nexport interface RhiRenderPassEncoder {\n // ===== Existing 7 methods (Round 1 baseline) =====\n /** Set the bound render pipeline.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.setPipeline].\n *\n * @example pass.setPipeline(pipeline);\n */\n setPipeline(pipeline: RenderPipeline): void;\n /** Set a vertex buffer.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.setVertexBuffer].\n *\n * @example pass.setVertexBuffer(0, vbo);\n */\n setVertexBuffer(\n slot: number,\n buffer: Buffer,\n offset?: number | undefined,\n size?: number | undefined,\n ): void;\n /** Set the index buffer.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.setIndexBuffer].\n *\n * @example pass.setIndexBuffer(ibo, 'uint32');\n */\n setIndexBuffer(\n buffer: Buffer,\n format: 'uint16' | 'uint32',\n offset?: number | undefined,\n size?: number | undefined,\n ): void;\n /** Set a bind group with optional dynamic offsets array (overload (a)).\n *\n * Spec anchor: [@webgpu/types.GPUBindingCommandsMixin.setBindGroup].\n *\n * @example pass.setBindGroup(0, bg, [0, 256]);\n */\n setBindGroup(\n index: number,\n bindGroup: BindGroup,\n dynamicOffsets?: readonly number[] | undefined,\n ): void;\n /** Set a bind group with a Uint32Array slice for dynamic offsets (overload (b)).\n *\n * Spec anchor: [@webgpu/types.GPUBindingCommandsMixin.setBindGroup].\n *\n * @example\n * pass.setBindGroup(0, bg, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength);\n */\n setBindGroup(\n index: number,\n bindGroup: BindGroup,\n dynamicOffsetsData: Uint32Array,\n dynamicOffsetsDataStart: number,\n dynamicOffsetsDataLength: number,\n ): void;\n /** Issue a draw.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.draw].\n *\n * @example pass.draw(3);\n */\n draw(\n vertexCount: number,\n instanceCount?: number | undefined,\n firstVertex?: number | undefined,\n firstInstance?: number | undefined,\n ): void;\n /** Issue an indexed draw.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.drawIndexed].\n *\n * @example pass.drawIndexed(36);\n */\n drawIndexed(\n indexCount: number,\n instanceCount?: number | undefined,\n firstIndex?: number | undefined,\n baseVertex?: number | undefined,\n firstInstance?: number | undefined,\n ): void;\n /** End the render pass.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.end].\n *\n * @example pass.end();\n */\n end(): void;\n\n // ===== 10 new spec stable methods (D-S4) =====\n /** Set the viewport.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.setViewport].\n *\n * @example pass.setViewport(0, 0, 800, 600, 0, 1);\n */\n setViewport(x: number, y: number, w: number, h: number, minDepth: number, maxDepth: number): void;\n /** Set the scissor rect.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.setScissorRect].\n *\n * @example pass.setScissorRect(0, 0, 800, 600);\n */\n setScissorRect(x: number, y: number, w: number, h: number): void;\n /** Set the blend constant color.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.setBlendConstant].\n *\n * @example pass.setBlendConstant({ r: 1, g: 0, b: 0, a: 1 });\n */\n setBlendConstant(color: GPUColor): void;\n /** Set the stencil reference value.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.setStencilReference].\n *\n * @example pass.setStencilReference(0xff);\n */\n setStencilReference(reference: number): void;\n /** Issue an indirect draw.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.drawIndirect].\n *\n * @example pass.drawIndirect(indirectBuf, 0);\n */\n drawIndirect(indirectBuffer: Buffer, indirectOffset: number): void;\n /** Issue an indexed indirect draw.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.drawIndexedIndirect].\n *\n * @example pass.drawIndexedIndirect(indirectBuf, 0);\n */\n drawIndexedIndirect(indirectBuffer: Buffer, indirectOffset: number): void;\n /** Push a labelled debug group (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.pushDebugGroup].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (the debug-commands mixin permits a no-op pass-through after finish() so the signal stays real instead of forging a `@throws` contract; charter proposition 4).\n * @example pass.pushDebugGroup('lighting');\n */\n pushDebugGroup(groupLabel: string): void;\n /** Pop the most recent debug group (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.popDebugGroup].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (see pushDebugGroup JSDoc for the dual-channel rationale).\n * @example pass.popDebugGroup();\n */\n popDebugGroup(): void;\n /** Insert a labelled debug marker (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.insertDebugMarker].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (see pushDebugGroup JSDoc for the dual-channel rationale).\n * @example pass.insertDebugMarker('post-shadow');\n */\n insertDebugMarker(markerLabel: string): void;\n\n // ===== 1 remaining placeholder + 2 real impls (M3 / w23 + w26) =====\n /** Execute render bundles. Capability-gated placeholder per D-S4: returns\n * Result.err({ code: 'rhi-not-available', hint: 'see feat-future-rhi-render-bundle' })\n * until that closure lands RenderBundle creation.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.executeBundles].\n *\n * @example\n * const out = pass.executeBundles([bundle]);\n * if (!out.ok) { ... route via switch (out.error.code) ... }\n */\n executeBundles(bundles: Iterable<unknown>): Result<void, RhiError>;\n /** Begin an occlusion query. Real implementation (M3 / w23): pairs with\n * `endOcclusionQuery()` against the `RenderPassDescriptor.occlusionQuerySet`\n * and validates the spec [[occlusion_query_active]] state machine\n * (queries cannot nest; missing occlusionQuerySet returns\n * Result.err({ code: 'webgpu-runtime-error' }) with structured\n * .expected / .hint fields).\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.beginOcclusionQuery].\n *\n * @example\n * const out = pass.beginOcclusionQuery(0);\n * if (!out.ok) { ... route via switch (out.error.code) ... }\n */\n beginOcclusionQuery(queryIndex: number): Result<void, RhiError>;\n /** End an occlusion query. Real implementation (M3 / w23): finalizes the\n * matching `beginOcclusionQuery(idx)` slot; emits\n * Result.err({ code: 'render-pass-not-ended', ... }) if no active begin\n * is pending.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.endOcclusionQuery].\n *\n * @example\n * const out = pass.endOcclusionQuery();\n * if (!out.ok) { ... route via switch (out.error.code) ... }\n */\n endOcclusionQuery(): Result<void, RhiError>;\n}\n\n/** GPU compute pass encoder - records dispatch calls. */\nexport interface RhiComputePassEncoder {\n setPipeline(pipeline: ComputePipeline): void;\n setBindGroup(\n index: number,\n bindGroup: BindGroup,\n dynamicOffsets?: readonly number[] | undefined,\n ): void;\n dispatchWorkgroups(x: number, y?: number | undefined, z?: number | undefined): void;\n /** Dispatch dimensions read from three consecutive u32 values in an indirect buffer. */\n dispatchWorkgroupsIndirect(indirectBuffer: Buffer, indirectOffset: number): void;\n end(): void;\n}\n\n/** GPU render pipeline operations - returned by RhiDevice.createRenderPipeline. */\nexport interface RhiRenderPipelineOps {\n /** Get bind group layout (used for dynamic bind-group creation). */\n getBindGroupLayout(index: number): BindGroupLayout;\n}\n\n/** GPU compute pipeline operations. */\nexport interface RhiComputePipelineOps {\n /** Get bind group layout. */\n getBindGroupLayout(index: number): BindGroupLayout;\n}\n\n// ============================================================================\n// re-export errors (charter proposition 1: single entry shows the full surface)\n// ============================================================================\n\nexport {\n type CreateUnavailableR32FloatReceiptOptions,\n createUnavailableR32FloatReceipt,\n R32FLOAT_MIP_SAMPLED_STORAGE_PROFILE,\n R32FLOAT_PROBE_STAGES,\n type RhiTextureFormatCapabilityReceipt,\n type RhiTextureFormatProbeEvidence,\n type RhiTextureFormatProbeStage,\n type RhiTextureFormatProbeStageReceipt,\n type RhiTextureFormatProbeVerdict,\n type RhiTextureFormatReadback,\n validateR32FloatReceipt,\n} from './capability/texture-format';\nexport type {\n DrawOwnerSplit,\n LimitExceededDetail,\n Result,\n ResultErr,\n ResultOk,\n RhiAssetNotRegisteredDetail,\n RhiErrorCode,\n RhiErrorDetail,\n RhiOwnerOutOfRangeDetail,\n RhiShaderCompileDetail,\n RhiWebgpuRuntimeDetail,\n} from './errors';\nexport { err, ok, RhiError, validateDrawArgs } from './errors';\n\n// re-export common descriptor-related aliases for single-entry consumption.\nexport type { AddressMode, CompareFunction, FilterMode, TextureFormat };\n\n// ============================================================================\n// Descriptor builder helpers (feat-20260612-point-light-shadows-urp-hdrp M0)\n// ============================================================================\n//\n// Pure functions that assemble descriptor objects for cube_array depth\n// textures, comparison samplers, and cube-face texture views. These are\n// zero-side-effect descriptor factories — the caller passes the returned\n// descriptor to `device.createTexture(desc)` etc. Separating descriptor\n// assembly from GPU calls keeps tests concise and prevents copy-paste of\n// dimension/format/usage boilerplate across dawn + browser fixtures.\n\n/**\n * Build a TextureDescriptor for a cube-array depth texture suitable for\n * point-light shadow atlas (texture_depth_cube_array).\n *\n * Usage: `device.createTexture(cubeArrayDepthDescriptor(512, 4))`\n *\n * @param faceSize - width and height of each cube face in pixels (default 512)\n * @param layers - number of cube layers (= max shadow-casting point lights, default 4)\n * @param usage - texture usage flags (default RENDER_ATTACHMENT | TEXTURE_BINDING)\n */\nexport function cubeArrayDepthDescriptor(\n faceSize: number = 512,\n layers: number = 4,\n usage: number = GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,\n): TextureDescriptor {\n return {\n size: { width: faceSize, height: faceSize, depthOrArrayLayers: 6 * layers },\n format: 'depth32float',\n dimension: '2d',\n usage,\n };\n}\n\n/**\n * Build a SamplerDescriptor for a depth-comparison sampler used with\n * texture_depth_2d or texture_depth_cube_array.\n *\n * The returned descriptor uses clamp-to-edge addressing, linear filtering\n * (required for comparison sampling on some backends), and `compare: 'less'`.\n *\n * Usage: `device.createSampler(comparisonSamplerDescriptor())`\n */\nexport function comparisonSamplerDescriptor(): SamplerDescriptor {\n return {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n addressModeW: 'clamp-to-edge',\n magFilter: 'linear',\n minFilter: 'linear',\n compare: 'less',\n };\n}\n\n/**\n * Build a TextureViewDescriptor to view a single cube layer + face as a 2D\n * depth attachment during shadow-caster rendering.\n *\n * Each shadow-caster pass renders to one face of one cube layer. This helper\n * produces the view descriptor that selects `baseArrayLayer = layerIndex * 6 + faceIndex`\n * with `arrayLayerCount = 1` and `dimension = '2d'`, which satisfies WebGPU's\n * requirement that render pass attachments are 2D views (cube views cannot be\n * bound as render targets).\n *\n * Usage:\n * ```\n * const viewDesc = cubeArrayDepthFaceView(lightIndex, faceIndex);\n * const view = device.createTextureView(atlas, viewDesc).unwrap();\n * ```\n *\n * @param layerIndex - 0-based shadow-casting light index (0..3)\n * @param faceIndex - 0-based cube face index (0..5, +X/-X/+Y/-Y/+Z/-Z per §5.3)\n */\nexport function cubeArrayDepthFaceView(\n layerIndex: number,\n faceIndex: number,\n): TextureViewDescriptor {\n return {\n format: 'depth32float',\n dimension: '2d',\n aspect: 'depth-only',\n baseArrayLayer: layerIndex * 6 + faceIndex,\n arrayLayerCount: 1,\n baseMipLevel: 0,\n mipLevelCount: 1,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/capability/texture-format.ts","../src/index.ts"],"names":["ok","err"],"mappings":"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","file":"index.mjs","sourcesContent":["// @forgeax/engine-rhi/src/errors - RhiError + closed RhiErrorCode union + Result<T, E>.\n//\n// Shape:\n// - RhiErrorCode = closed union 23 members (charter P3: closed-union\n// exhaustive switch needs no default fallback; tsc strict mode guards\n// completeness). Extended from 6 to 10 in feat-20260508-rhi-surface-completion\n// w7 (D-S3): added 'command-encoder-finished' / 'render-pass-not-ended' /\n// 'queue-submit-failed' / 'queue-write-buffer-out-of-bounds'.\n// Extended from 10 to 14 in feat-20260509-ecs-render-bridge-mvp w6 (D-S7):\n// added 'render-system-no-camera' / 'render-system-multi-camera' /\n// 'render-system-multi-light' / 'asset-not-registered'.\n// Extended from 14 to 17 in feat-20260511-rhi-spec-realign-aggressive w6\n// (D-P4 + R-02 §2.1 W3C spec 22.2 subtypes): added 'device-lost' / 'oom' /\n// 'internal-error' so the onError fan-out can disambiguate spec error\n// subclasses without falling back to the bucket 'webgpu-runtime-error'.\n// Extended from 17 to 18 in feat-20260511-asset-system-v1 w4\n// (D-P2 + requirements §9 row 8 + AC-04 + AC-21): added\n// 'hierarchy-broken' for `propagateTransforms` stale ChildOf ref fail-fast\n// (ChildOf component references a destroyed entity); same\n// render-system / schedule semantic domain as\n// 'render-system-multi-camera' / 'render-system-no-camera'. Minor add-only\n// per AGENTS.md evolution contract (no reorder / rename / deprecate).\n// Extended from 18 to 19 in feat-20260612-rhi-destroy-renderer-dispose-gpu-\n// lifecycle M1 (D-6 + D-7 + AC-02 / AC-03): added 'destroy-after-destroy'\n// for second `destroyBuffer` / `destroyTexture` on the same handle. The\n// shim layer (rhi-webgpu + rhi-wgpu) tracks per-handle `destroyed: boolean`\n// in WeakMap-backed meta and fail-fasts the second call rather than\n// forwarding it to the underlying GPU (research F-1 wgpu wasm `destroy()`\n// is idempotent void; F-8 WebGPU spec is also idempotent void; D-7 prefers\n// fail-fast over silent idempotency because double-destroy is almost always\n// a lifecycle bug). Minor add-only per AGENTS.md evolution contract.\n// Extended from 19 to 20 in feat-20260619-wasm-fault-isolation M3 w7:\n// added 'rhi-descriptor-invalid' for `createRenderPipeline` (and other\n// create* entries) descriptor parse failures surfaced through the wgpu-wasm\n// backend (Rust `#[wasm_bindgen(catch)]` Err). The prefix-based\n// classification (D-1 / D-2) routes wasm exceptions with the stable marker\n// `[wgpu-wasm] failed to parse` to this code; exceptions without the prefix\n// remain in 'webgpu-runtime-error'. Semantics: descriptor parse failure =\n// caller bug (malformed descriptor data passed from TS), distinct from\n// 'webgpu-runtime-error' = runtime condition (valid descriptor rejected by\n// wgpu backend). Minor add-only per AGENTS.md evolution contract.\n// Extended from 20 to 21 in feat-20260622-chunk-gpu-instancing-sprite-\n// tilemap M2 w10 (D-2 + AC-05 + research N-1): added\n// 'instancing-exceeds-uniform-cap' for the WebGL2 uniform-fallback path\n// when a record-stage fold bucket carries more than 128 instances\n// (128 = MAX_UNIFORM_INSTANCES; 128 * 64B = 8192B comfortably fits the\n// WebGL2 minimum 16384B UBO size, leaving headroom for the per-frame\n// material UBO slice — research N-1 implements the locked value). The\n// record-stage dispatch site fires the error AND falls the offending\n// bucket back to per-entity drawIndexed (the same exit the mode-gate\n// bypass uses — plan-strategy D-9 \"shared fallback exit\"). Semantics:\n// distinct from 'limit-exceeded' (byte-cap against\n// maxStorageBufferBindingSize) — this code targets the per-bucket\n// instance-count cap, which is a backend-capability ceiling rather than\n// an allocation-size ceiling. AI users branch on .code first then read\n// detail.requested / .limit / .scope through property access (charter\n// P3 + plan-strategy 8.3 actionable hint). Minor add-only\n// per AGENTS.md evolution contract.\n// Extended from 21 to 23 in feat-20260708-composited-multi-world-rendering\n// M3 (D-5): added 'render-system-empty-worlds' + 'render-system-owner-out-of-\n// range' for draw(worlds, { cameraOwner, resourceOwner }) entry validation. The\n// owner-out-of-range path exposes .detail = RhiOwnerOutOfRangeDetail\n// ({ role, owner, worldCount } after feat-20260709-editor-world-partition\n// M1 / w7: role ∈ {'camera','resource'} names which of the two split draw\n// owners is out of range); empty-worlds carries no .detail. The pure\n// validateDrawArgs(worldCount, { cameraOwner, resourceOwner })\n// helper (World-free primitives) emits both and is consumed by the runtime\n// createRenderer draw entry (the codes' SSOT stays in rhi). Checks run\n// empty-worlds -> cameraOwner -> resourceOwner; the first out-of-range owner\n// wins (role='camera' when both offend). Add-only (no new code, 0 net Δ per\n// D-3) per AGENTS.md evolution contract.\n// - RhiError class has readonly .code / .expected / .hint three-field surface\n// (AGENTS.md \"Errors are structured\" / D-5); the 'shader-compile-failed' path\n// exposes .detail = RhiShaderCompileDetail (compilerMessages array);\n// the 'asset-not-registered' path exposes .detail = RhiAssetNotRegisteredDetail\n// ({ assetHandle: number }, D-S6); the 'webgpu-runtime-error' path optionally\n// exposes .detail = RhiWebgpuRuntimeDetail ({ error: RhiError | fallback }, D-S8) for\n// RenderSystem internal exception fan-out; the 'limit-exceeded' path\n// exposes .detail = LimitExceededDetail ({ maxStorageBufferBindingSize,\n// requestedBytes }, feat-20260513-instanced-mesh M5 reshape from legacy\n// { renderableCount, limit }); the other 15 paths leave\n// .detail = undefined per charter proposition 4 baseline.\n// - Result<T, E> = binary tag union ('ok' / 'err'), per AGENTS.md \"Errors are\n// structured\" convention.\n//\n// Related: requirements AC AC-10 + MVP-1.7 + AC-RSC-07 + hard-constraint 8 +\n// AI User Affordances; plan-strategy 2 S-6 (types/rhi single source) +\n// 7.3 error-info table; plan-decisions OQ-P2 (forward all 6 fields of\n// GPUCompilationMessage); D-S3 (4 command/queue members) + D-S6 / D-S7\n// / D-S8 (4 RenderSystem / AssetRegistry members + .detail structure).\n\n/// <reference types=\"@webgpu/types\" />\n\nimport { err, ok, type Result } from '@forgeax/engine-types';\n\n/**\n * Closed RhiErrorCode union. `switch` exhaustive checks need no default\n * fallback - tsc strict mode guards union completeness (charter proposition 4\n * + proposition 3: machine-readable union > prose).\n *\n *\n * The executable union below is the machine-readable source of truth for\n * the 23 members. The package README owns the AI-facing trigger and recovery\n * table; keeping that projection in one documentation owner avoids a second\n * member ledger drifting from the union.\n *\n * @example AI-user exhaustive switch on the 4 command/queue members (no default fallback)\n * ```ts\n * import type { RhiError, RhiErrorCode } from '@forgeax/engine-rhi';\n *\n * function recover(code: RhiErrorCode): string {\n * switch (code) {\n * // ... 6 baseline members elided ...\n * case 'command-encoder-finished': return 'recreate encoder via device.createCommandEncoder()';\n * case 'render-pass-not-ended': return 'call pass.end() before next beginRenderPass()';\n * case 'queue-submit-failed': return 'audit buffer/pipeline lifetimes before submit';\n * case 'queue-write-buffer-out-of-bounds': return 'realign offset and re-check buffer.size';\n * default: return 'baseline path';\n * }\n * }\n * ```\n */\nexport type RhiErrorCode =\n | 'adapter-unavailable'\n | 'feature-not-enabled'\n | 'limit-exceeded'\n | 'shader-compile-failed'\n | 'rhi-not-available'\n | 'webgpu-runtime-error'\n | 'command-encoder-finished'\n | 'render-pass-not-ended'\n | 'queue-submit-failed'\n | 'queue-write-buffer-out-of-bounds'\n | 'render-system-no-camera'\n | 'render-system-multi-camera'\n | 'render-system-multi-light'\n | 'asset-not-registered'\n | 'device-lost'\n | 'oom'\n | 'internal-error'\n | 'hierarchy-broken'\n | 'destroy-after-destroy'\n | 'rhi-descriptor-invalid'\n | 'instancing-exceeds-uniform-cap'\n | 'render-system-empty-worlds'\n | 'render-system-owner-out-of-range'\n | 'rhi-texture-format-capability-unavailable';\n\n/**\n * Detail structure exclusive to the `shader-compile-failed` path.\n *\n * `compilerMessages` directly forwards the 6 standardized fields of\n * `GPUCompilationMessage` from `@webgpu/types` v0.1.69 (`message` / `type` /\n * `lineNum` / `linePos` / `offset` / `length`); research F-3 finding;\n * plan-decisions OQ-P2 locks full-field forwarding.\n *\n * @see {@link GPUCompilationMessage}\n */\nexport interface RhiShaderCompileDetail {\n readonly compilerMessages: readonly GPUCompilationMessage[];\n}\n\n/**\n * Detail structure exclusive to the `asset-not-registered` path (D-S6).\n *\n * `assetHandle` carries the offending u32 handle the caller passed via\n * `MeshFilter.assetHandle`; AI users access it through property access\n * (`err.detail.assetHandle`) rather than parsing the message string\n * (charter proposition 4 + F-3 contract surface).\n */\nexport interface RhiAssetNotRegisteredDetail {\n readonly assetHandle: number;\n}\n\n/**\n * Detail structure exclusive to the `webgpu-runtime-error` path (D-S8).\n *\n * `error` carries the underlying exception object so AI users can inspect the\n * root cause (`.code` / `.expected` / `.hint` for `RhiError` paths, or\n * `.code` + `.message` for non-RhiError falls) without parsing the\n * RhiError.message field. Optional: the K-9 silent-skip fan-out root path\n * may emit `webgpu-runtime-error` without `.detail` when the underlying\n * exception is unavailable.\n *\n * feat-20260608-mesh-ssbo-dynamic-grow-l1-lift-1024-entity-cap M4 / T-M4-02:\n * `error` field type widened from `string` to `RhiError | { code: string;\n * message: string }` so downstream `switch (err.code)` handlers can narrow\n * the inner error (`.code` / `.expected` / `.hint`) without an `as` cast.\n */\n/**\n * Structured non-RHI causes carried by a `webgpu-runtime-error` wrapper.\n *\n * Pipeline-spec failures retain their own detail record here so callers can\n * reach the backend cause without parsing `Error.message` or losing the\n * producer-owned fields during initialization fan-out.\n */\nexport interface RhiWebgpuRuntimeCause {\n readonly code: string;\n readonly message: string;\n readonly name?: string;\n readonly detail?: object;\n}\n\nexport interface RhiWebgpuRuntimeDetail {\n readonly error: RhiError | RhiWebgpuRuntimeCause;\n}\n\n/**\n * Detail structure exclusive to the `limit-exceeded` path.\n *\n * `maxStorageBufferBindingSize` carries the device-reported storage cap\n * (`device.limits.maxStorageBufferBindingSize`); `requestedBytes`\n * carries the byte count the caller attempted to allocate. AI users\n * access these through typed property access (`err.detail.maxStorageBufferBindingSize`\n * / `err.detail.requestedBytes`) rather than parsing the message string\n * — charter proposition 4 structured-error consumption path; `err.hint`\n * is for human eyeballs only.\n *\n * Single live emit point: the RenderSystem record stage per-entity\n * instance buffer upload path\n * (`packages/runtime/src/render-system-record.ts`). The 18-member\n * `RhiErrorCode` union is unchanged (`'limit-exceeded'` discriminant\n * preserved); evolution major rename + replace of the discriminated\n * `detail` shape per AGENTS.md Change stance + plan-strategy D-3.\n *\n * Migration history:\n * - feat-20260513-instanced-mesh M5: detail reshape from\n * `{ renderableCount, limit }` to `{ maxStorageBufferBindingSize,\n * requestedBytes }`. Emit point at the time was\n * `AssetRegistry.createInstancedBuffer`.\n * - feat-20260907-case01-case05-engine-convergence: explicit instance\n * matrices are supplied by the renderer-owned collection projection;\n * `requestedBytes` describes the resident record payload at the record\n * stage, independent of ECS managed-array capacity.\n */\nexport interface LimitExceededDetail {\n readonly maxStorageBufferBindingSize: number;\n readonly requestedBytes: number;\n}\n\n/**\n * Detail structure exclusive to the `'render-system-multi-light'` path.\n * The only remaining cardinality rule is one global DirectionalLight; all\n * PointLight, SpotLight, and RectArea lights are admitted through the shared\n * shared Cluster corpus and are admitted by the same local-light contract.\n */\nexport interface RhiMultiLightDetail {\n readonly type: 'directional';\n readonly got: number;\n}\n\n/**\n * Detail structure exclusive to the `'instancing-exceeds-uniform-cap'` path\n * (feat-20260622-chunk-gpu-instancing-sprite-tilemap M2 / w10 +\n * plan-strategy 2 D-2 + research N-1).\n *\n * Emitted by the record-stage fold dispatch loop\n * (`packages/runtime/src/render-system-record.ts`) when\n * `caps.storageBuffer === false` AND a fold bucket carries more than\n * `limit` instances. The engine fires the error AND falls the offending\n * bucket back to per-entity drawIndexed via the same exit the mode-gate\n * bypass uses (plan-strategy D-9 \"shared fallback exit\"), so the frame\n * is still visually correct (no identity-collapse / black screen) and\n * the cap event surfaces structurally for AI users to observe.\n *\n * Fields:\n * - `requested` — the offending bucket's instance count\n * (`FoldBucket.bucketSize`); always strictly greater than `limit` at\n * emit time (the cap-check helper guards `requested > limit`).\n * - `limit` — the literal 128. The value is locked at the type level\n * because the cap is structurally tied to the WebGL2 minimum 16384 B\n * UBO size (128 * 64 B mat4 stride = 8192 B leaves headroom for the\n * per-frame material UBO slice — research N-1). A future cap change\n * would be a major evolution, not a runtime knob.\n * - `scope` — closed `'sprite' | 'tilemap-chunk'` discriminator that\n * pinpoints the dispatch site (sprite-pass entry that came directly\n * from a user-spawned Sprite vs one derived by\n * `tilemap-chunk-extract-system`). AI users branch on `.scope` to\n * decide whether to shrink the sprite batch size or the tilemap\n * chunk size.\n *\n * AI-user consumption (charter P3 + plan-strategy 8.3):\n * ```ts\n * if (err.code === 'instancing-exceeds-uniform-cap') {\n * const d = err.detail as RhiInstancingExceedsUniformCapDetail;\n * if (d.scope === 'sprite') shrinkSpriteBatchSize(d.requested);\n * else if (d.scope === 'tilemap-chunk') shrinkTileChunkSize(d.requested);\n * }\n * ```\n * — never parse `err.message`. The discriminated `detail` field is the\n * surface; the human-readable `err.message` is for logs only.\n */\nexport interface RhiInstancingExceedsUniformCapDetail {\n readonly requested: number;\n readonly limit: 128;\n readonly scope: 'sprite' | 'tilemap-chunk';\n}\n\n/**\n * Detail structure exclusive to the `'render-system-owner-out-of-range'` path\n * (feat-20260708-composited-multi-world-rendering M3 / D-5).\n *\n * Emitted by `renderer.draw(worlds, { cameraOwner, resourceOwner })` when one\n * owner index is not valid for `worlds` (`owner < 0` or `owner >= worlds.length`).\n * An out-of-range index cannot resolve, so the frame is skipped before extract.\n *\n * Fields:\n * - `role` — WHICH of the two draw-owner indices was out of range\n * (feat-20260709-editor-world-partition M1 / w7). `draw(worlds, {\n * cameraOwner, resourceOwner })` carries two independent indices; `role`\n * tells the AI user whether the camera-source index (`'camera'`) or the\n * singleton-resource index (`'resource'`) is the offender, so the fix is\n * unambiguous from the text channel (no new error code — D-3 keeps 0 net\n * new codes; the discriminator lives in `.detail`). When both indices are\n * out of range the first offender is reported: `cameraOwner` is validated\n * before `resourceOwner`, so `role === 'camera'`.\n * - `owner` — the offending index the caller passed (the `role` index's\n * value).\n * - `worldCount` — `worlds.length` at call time (the valid range is\n * `0 .. worldCount - 1`).\n *\n * AI users branch via property access (`err.detail.role` / `err.detail.owner` /\n * `err.detail.worldCount`) after narrowing on `.code`, rather than parsing the\n * message string (charter P3 structured-failure surface).\n *\n * The sibling `'render-system-empty-worlds'` path carries no `.detail` — an\n * empty array is fully described by `.code`, and the entry check short-circuits\n * to that code before the owner-range check runs (the two codes are\n * non-exclusive).\n */\nexport interface RhiOwnerOutOfRangeDetail {\n readonly role: 'camera' | 'resource';\n readonly owner: number;\n readonly worldCount: number;\n}\n\n/** Detail for an incomplete device-owned texture-format profile probe. */\nexport interface RhiTextureFormatCapabilityUnavailableDetail {\n readonly stage: string;\n readonly deviceGeneration: number;\n readonly reason: string;\n}\n\n/**\n * Tagged union of `.detail` shapes carried by structured errors.\n *\n * Entries:\n * - `RhiShaderCompileDetail` (carries `compilerMessages`) - emitted on the\n * `'shader-compile-failed'` path.\n * - `RhiAssetNotRegisteredDetail` (carries `assetHandle`) - emitted on the\n * `'asset-not-registered'` path (D-S6).\n * - `RhiWebgpuRuntimeDetail` (carries `error: RhiError | { code, message }`) - optionally emitted\n * on the `'webgpu-runtime-error'` path when a captured `Error.message` is\n * available (D-S8).\n * - `LimitExceededDetail` (carries `maxStorageBufferBindingSize` +\n * `requestedBytes`) - emitted on the `'limit-exceeded'` path when\n * the RenderSystem record stage's per-entity Instances upload\n * exceeds `device.limits.maxStorageBufferBindingSize`\n * (feat-20260514-ecs-children-instances-managed-buffer-array M3 / w15;\n * emit point migrated from the deleted\n * `AssetRegistry.createInstancedBuffer` factory).\n *\n * The other 15 paths leave `.detail = undefined` (charter proposition 4\n * baseline).\n */\nexport type RhiErrorDetail =\n | RhiShaderCompileDetail\n | RhiAssetNotRegisteredDetail\n | RhiWebgpuRuntimeDetail\n | LimitExceededDetail\n | RhiMultiLightDetail\n | RhiInstancingExceedsUniformCapDetail\n | RhiOwnerOutOfRangeDetail\n | RhiTextureFormatCapabilityUnavailableDetail;\n\n/**\n * Structured RHI error.\n *\n * Three readonly fields aligned with AGENTS.md \"Errors are structured\":\n * - `.code` - closed union member (L1 key signal).\n * - `.expected` - expected-state description (L2 detail).\n * - `.hint` - actionable recovery guidance (L2 detail; charter proposition 3:\n * machine-readable hint > prose).\n *\n * `.detail` is populated on four paths:\n * - `code === 'shader-compile-failed'` -> `RhiShaderCompileDetail`\n * - `code === 'asset-not-registered'` -> `RhiAssetNotRegisteredDetail`\n * - `code === 'webgpu-runtime-error'` -> `RhiWebgpuRuntimeDetail` (optional)\n * - `code === 'limit-exceeded'` -> `LimitExceededDetail`\n * (feat-20260513-instanced-mesh M5 reshape; carries\n * `maxStorageBufferBindingSize` + `requestedBytes`)\n *\n * The other 15 paths leave `.detail = undefined` (charter proposition 4\n * baseline).\n *\n * Note: `RhiErrorDetail` is currently a flat tagged union without a\n * `code` discriminant field on each variant; AI users perform typed\n * narrowing via outer `switch (err.code)` then a one-time `as` cast on\n * `err.detail` per the documented variant. Full discriminated-union\n * refactor (each variant carrying its own `code` literal field) is left\n * to `feat-future-rhi-error-detail-discriminant` spinoff.\n */\nexport class RhiError extends Error {\n readonly code: RhiErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail: RhiErrorDetail | undefined;\n\n constructor(args: {\n code: RhiErrorCode;\n expected: string;\n hint: string;\n detail?: RhiErrorDetail | undefined;\n }) {\n super(`[RhiError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);\n this.name = 'RhiError';\n this.code = args.code;\n this.expected = args.expected;\n this.hint = args.hint;\n this.detail = args.detail;\n }\n}\n\n/**\n * The two split draw-owner indices carried by\n * `draw(worlds, { cameraOwner, resourceOwner })`\n * (feat-20260709-editor-world-partition M1 / w6). `cameraOwner` selects the\n * world whose cameras are surfaced; `resourceOwner` selects the world whose\n * skylight / skybox / postProcessParams are surfaced. Declared here (World-free\n * primitives) so the validator and the `RhiOwnerOutOfRangeDetail.role`\n * discriminator live in one SSOT package (architecture-principles §1).\n */\nexport interface DrawOwnerSplit {\n readonly cameraOwner: number;\n readonly resourceOwner: number;\n}\n\n/**\n * Validate `renderer.draw(worlds, { cameraOwner, resourceOwner })` arguments at\n * the draw entry (feat-20260708 M3 / D-5, extended by\n * feat-20260709-editor-world-partition M1 / w6-w7).\n *\n * The validator takes primitives (`worldCount = worlds.length`, plus the owner\n * index/indices) — no `World`, no math — so it lives in `@forgeax/engine-rhi`\n * alongside the `RhiErrorCode` members it emits (architecture-principles §1\n * SSOT). The runtime `createRenderer` draw entry calls it before any extract; a\n * non-`ok` result skips the frame with a structured error (charter P3), never a\n * silent no-op.\n *\n * Checks, in order (D-5 + w6):\n * 1. `worldCount === 0` -> `'render-system-empty-worlds'` (no `.detail`).\n * 2. `cameraOwner` is not a valid index -> `'render-system-owner-out-of-range'`\n * with `.detail = { role: 'camera', owner: cameraOwner, worldCount }`.\n * 3. `resourceOwner` is not a valid index -> `'render-system-owner-out-of-range'`\n * with `.detail = { role: 'resource', owner: resourceOwner, worldCount }`.\n * The `Number.isInteger` guard rejects a `NaN` / fractional / undefined-coerced\n * index a JS caller could pass despite the compile-time requirement. When both\n * indices are out of range the FIRST offender wins: `cameraOwner` is checked\n * before `resourceOwner`, so `role === 'camera'` (D-3 / w3 contract).\n *\n * The empty-worlds guard short-circuits before either owner-range check.\n */\nexport function validateDrawArgs(\n worldCount: number,\n owner: DrawOwnerSplit,\n): Result<void, RhiError> {\n if (worldCount === 0) {\n return err(\n new RhiError({\n code: 'render-system-empty-worlds',\n expected: 'worlds array has at least one world',\n hint: 'pass at least one world: draw([world], { cameraOwner: 0, resourceOwner: 0 })',\n }),\n );\n }\n const { cameraOwner, resourceOwner } = owner;\n const outOfRange = (index: number): boolean =>\n !Number.isInteger(index) || index < 0 || index >= worldCount;\n // cameraOwner is validated first: it is the first offender when both indices\n // are out of range (w3 contract). role names which index the AI user fixes.\n if (outOfRange(cameraOwner)) {\n return err(\n new RhiError({\n code: 'render-system-owner-out-of-range',\n expected: 'cameraOwner is an index into worlds (0 <= cameraOwner < worlds.length)',\n hint: 'cameraOwner must be in 0..worlds.length-1; the cameraOwner world supplies the surfaced cameras',\n detail: { role: 'camera', owner: cameraOwner, worldCount },\n }),\n );\n }\n if (outOfRange(resourceOwner)) {\n return err(\n new RhiError({\n code: 'render-system-owner-out-of-range',\n expected: 'resourceOwner is an index into worlds (0 <= resourceOwner < worlds.length)',\n hint: 'resourceOwner must be in 0..worlds.length-1; the resourceOwner world supplies skylight/skybox/postProcess',\n detail: { role: 'resource', owner: resourceOwner, worldCount },\n }),\n );\n }\n return ok(undefined);\n}\n\n// Result<T, E> + ok / err live in `@forgeax/engine-types` (tweak-20260612-result-\n// into-types). They were duplicated here (\"byte-for-byte aligned\" by prose) and\n// in packages/ecs/src/result.ts; SSOT consolidated upstream. The barrel here\n// re-exports them so existing `import { err, ok, Result, ResultOk, ResultErr }\n// from '@forgeax/engine-rhi'` consumers stay unchanged.\nexport {\n err,\n ok,\n type Result,\n type ResultErr,\n type ResultOk,\n} from '@forgeax/engine-types';\n","import { err, ok, type Result, RhiError } from '../errors';\n\n/** The only format profile currently admitted by the reflection fallback path. */\nexport const R32FLOAT_MIP_SAMPLED_STORAGE_PROFILE = 'r32float-mip-sampled-storage' as const;\n\nexport type RhiTextureFormatProfile = typeof R32FLOAT_MIP_SAMPLED_STORAGE_PROFILE;\nexport type RhiTextureFormatProbeVerdict = 'admitted' | 'unavailable' | 'structural-only';\nexport type RhiTextureFormatProbeEvidence = 'real' | 'structural';\nexport type RhiTextureFormatProbeStage =\n | 'texture-create'\n | 'mip-view'\n | 'sampled-storage-bind-group'\n | 'pipeline-bind'\n | 'finish'\n | 'submit'\n | 'completion'\n | 'readback';\n\nexport const R32FLOAT_PROBE_STAGES: readonly RhiTextureFormatProbeStage[] = [\n 'texture-create',\n 'mip-view',\n 'sampled-storage-bind-group',\n 'pipeline-bind',\n 'finish',\n 'submit',\n 'completion',\n 'readback',\n];\n\nexport interface RhiTextureFormatProbeStageReceipt {\n readonly stage: RhiTextureFormatProbeStage;\n readonly verdict: RhiTextureFormatProbeVerdict;\n readonly evidence: RhiTextureFormatProbeEvidence;\n readonly detail?: string | undefined;\n}\n\nexport interface RhiTextureFormatReadback {\n readonly byteLength: number;\n readonly values: readonly number[];\n}\n\nexport interface RhiTextureFormatCapabilityReceipt {\n readonly profile: RhiTextureFormatProfile;\n readonly verdict: RhiTextureFormatProbeVerdict;\n readonly evidence: RhiTextureFormatProbeEvidence;\n readonly deviceGeneration: number;\n readonly stages: readonly RhiTextureFormatProbeStageReceipt[];\n readonly sampleType: 'unfilterable-float';\n readonly usages: readonly ['texture-binding', 'storage-binding', 'copy-src'];\n readonly readback?: RhiTextureFormatReadback | undefined;\n readonly probeExecutions: number;\n}\n\nexport interface CreateUnavailableR32FloatReceiptOptions {\n readonly deviceGeneration: number;\n readonly failedStage: RhiTextureFormatProbeStage;\n readonly detail: string;\n readonly evidence?: RhiTextureFormatProbeEvidence | undefined;\n}\n\nexport function createUnavailableR32FloatReceipt(\n options: CreateUnavailableR32FloatReceiptOptions,\n): RhiTextureFormatCapabilityReceipt {\n const failureIndex = R32FLOAT_PROBE_STAGES.indexOf(options.failedStage);\n const evidence = options.evidence ?? 'real';\n return {\n profile: R32FLOAT_MIP_SAMPLED_STORAGE_PROFILE,\n verdict: 'unavailable',\n evidence,\n deviceGeneration: options.deviceGeneration,\n stages: R32FLOAT_PROBE_STAGES.map((stage, index) => ({\n stage,\n verdict: index < failureIndex ? 'admitted' : 'unavailable',\n evidence,\n ...(stage === options.failedStage ? { detail: options.detail } : {}),\n })),\n sampleType: 'unfilterable-float',\n usages: ['texture-binding', 'storage-binding', 'copy-src'],\n probeExecutions: 1,\n };\n}\n\nexport function validateR32FloatReceipt(\n receipt: RhiTextureFormatCapabilityReceipt,\n): Result<RhiTextureFormatCapabilityReceipt, RhiError> {\n const missing = R32FLOAT_PROBE_STAGES.find(\n (stage) => !receipt.stages.some((entry) => entry.stage === stage),\n );\n if (missing !== undefined) {\n return unavailable(receipt, missing, `required stage ${missing} is missing`);\n }\n if (receipt.profile !== R32FLOAT_MIP_SAMPLED_STORAGE_PROFILE) {\n return unavailable(receipt, 'texture-create', 'profile is not the closed r32float profile');\n }\n if (receipt.sampleType !== 'unfilterable-float') {\n return unavailable(\n receipt,\n 'sampled-storage-bind-group',\n 'sample type must be unfilterable-float',\n );\n }\n if (\n receipt.usages.length !== 3 ||\n receipt.usages[0] !== 'texture-binding' ||\n receipt.usages[1] !== 'storage-binding' ||\n receipt.usages[2] !== 'copy-src'\n ) {\n return unavailable(\n receipt,\n 'sampled-storage-bind-group',\n 'sampled, storage, and readback usages are required',\n );\n }\n if (receipt.verdict === 'admitted' && receipt.readback === undefined) {\n return unavailable(receipt, 'readback', 'admitted profiles require real readback evidence');\n }\n return ok(receipt);\n}\n\nfunction unavailable(\n receipt: RhiTextureFormatCapabilityReceipt,\n stage: RhiTextureFormatProbeStage,\n detail: string,\n): Result<never, RhiError> {\n return err(\n new RhiError({\n code: 'rhi-texture-format-capability-unavailable',\n expected: `r32float profile stage ${stage} to be complete`,\n hint: 'retain fallback-only rendering and retry the owner-owned device probe',\n detail: {\n stage,\n deviceGeneration: receipt.deviceGeneration,\n reason: detail,\n },\n }),\n );\n}\n","// @forgeax/engine-rhi - pure-interface RHI surface for forgeax-engine.\n//\n// Iron laws: spec-aligned (descriptor field names mirror Pick<GPUXxxDescriptor, ...>\n// byte-for-byte) / capability-gated / opaque handle / math-free. See README +\n// AGENTS.md \"## RHI / WebGPU\" section.\n//\n// This file is the complete entry for `import * as RHI from '@forgeax/engine-rhi'`\n// (charter proposition 1: progressive disclosure + plan-strategy 7.4\n// discoverability \"AI users see the full surface in one read\").\n//\n// =====================================================================\n// Async function form contract (D-P9 / requirements AC-12)\n// =====================================================================\n//\n// All async functions exposed by `@forgeax/engine-rhi` (and the rhi-webgpu /\n// rhi-wgpu shim packages that implement this interface) follow the\n// `Promise<Result<T, RhiError>>` shape — Promise NEVER rejects, failures\n// ride `Result.err` so AI users have a single error-handling idiom across\n// sync + async surfaces (charter proposition 4 explicit failure +\n// proposition 5 consistent abstraction).\n//\n// Three permitted whitelist categories may keep the bare `Promise<T>` shape;\n// each exemption must be marked with a `// forgeax-async-whitelist:\n// <category>` comment near the signature site so the grep gate\n// (scripts/check-async-form.mjs) can pair the violation count with the\n// whitelist count:\n//\n// (a) wasm-bindgen — outputs of wasm-pack JS shim that we cannot\n// restructure at the type layer (wasm-loader edge);\n// (b) dom-native — DOM native Promise passthrough such as\n// `GPUDevice.lost` re-exposed verbatim;\n// (c) render-loop — non-fallible internal drivers like\n// requestAnimationFrame wrappers.\n//\n// Anything else returning `Promise<T>` without the whitelist comment is a\n// CI gate red.\n//\n// Related: requirements AC AC-02 + MVP-1.1 / MVP-1.2 / MVP-1.3 / MVP-1.5 /\n// MVP-1.7 + AC-04 (RhiErrorCode 17 members) + AC-05 (RhiCaps 11\n// fields) + AC-10 (RhiBindingResource tagged union) + AC-11\n// (MappedBuffer brand) + AC-12 (Promise<Result<T,E>> + whitelist)\n// + hard-constraints 1 / 2 / 3 / 7 / 9; plan-strategy 1\n// architecture + 2 S-1 / S-3 / S-6 / S-7 + 6 M1 + D-P9 async form;\n// research F-1 (17 core descriptor surface) + F-7 (wgpu-hal 21\n// associated types);\n// feat-20260508-rhi-surface-completion w8 D-S5 (4 new descriptors\n// with `view` field tightened to TextureView);\n// feat-20260511-rhi-spec-realign-aggressive (Promise<Result<T,E>>\n// contract locked at the interface layer).\n\n/// <reference types=\"@webgpu/types\" />\n\nimport type {\n AddressMode,\n CompareFunction,\n FilterMode,\n TextureFormat,\n} from '@forgeax/engine-types';\nimport type { RhiTextureFormatCapabilityReceipt } from './capability/texture-format';\nimport type { Result, RhiError } from './errors.js';\n\n// ============================================================================\n// 14 opaque handles (MVP-1.3)\n// ============================================================================\n//\n// Shape: each handle = brand-only typed Id<T>; no runtime value; attempting to\n// access internal GPU fields is a tsc compile-time red signal (research R5;\n// charter proposition 4 explicit failure + proposition 5 consistent abstraction).\n//\n// Naming: no Rhi prefix (D-9); coexists with @webgpu/types.GPU* prefix +\n// wgpu::* Rust paths via module-path semantics (e.g.\n// `import { Buffer } from '@forgeax/engine-rhi'` vs `GPUBuffer`).\n\ndeclare const RhiBufferBrand: unique symbol;\ndeclare const RhiMappedBufferBrand: unique symbol;\n\n/**\n * GPU buffer opaque handle (vertex / index / uniform / storage / indirect).\n *\n * Spec anchor: W3C WebGPU §4 Buffers / [@webgpu/types.GPUBuffer]; research\n * §4.1 mapState 3-state enum + §4.2 mapAsync 8-item validation + §4.4 unmap\n * detach semantics.\n *\n * The buffer mapping surface is added in feat-20260510-rhi-resource-creation\n * M5 (K-1: raw GPUMapMode bitmask; K-2: alignment / mode-usage / detach\n * faults all ride 'webgpu-runtime-error' with structured .expected / .hint);\n * re-shaped in feat-20260511-rhi-spec-realign-aggressive M1 (D-P2 #6):\n * - `mapAsync` resolves to `Result<MappedBuffer, RhiError>` (success branch\n * carries a branded handle subsequently used for getMappedRange / unmap).\n * - `getMappedRange` / `unmap` are methods on `MappedBuffer` (not Buffer);\n * calling them on a plain Buffer is a TS2345 compile-time red.\n *\n * The forgeax form keeps the spec verb names but routes failures via Result\n * (charter proposition 4 explicit failure):\n * mapAsync(mode, offset?, size?): Promise<Result<MappedBuffer, RhiError>>\n * readonly mapState: 'unmapped' | 'pending' | 'mapped' - getter (research\n * §4.1; same closed union as GPUBufferMapState).\n */\nexport interface Buffer {\n readonly [RhiBufferBrand]: void;\n /**\n * Map the buffer for CPU access.\n *\n * Spec anchor: W3C WebGPU §gpubuffer-mapasync /\n * [@webgpu/types.GPUBuffer.mapAsync]. K-1 decision: `mode` is the raw\n * `GPUMapMode` bitmask (NOT a closed union 'read' | 'write') so the forgeax\n * form mirrors `GPUMapMode.READ` / `GPUMapMode.WRITE` literals.\n *\n * D-P2 #6 (feat-20260511-rhi-spec-realign-aggressive): the success branch\n * resolves to `MappedBuffer`, a brand on top of `Buffer`. AI users\n * subsequently call `mapped.getMappedRange(...)` / `mapped.unmap()` on the\n * branded handle; calling those methods on a plain `Buffer` is a TS2345\n * compile-time signal (charter proposition 4 explicit failure encoded at\n * the type layer).\n *\n * Failure paths (research §4.2 + plan-strategy §2 K-2):\n * - mapState !== 'unmapped' (F-8 row 1) -> 'webgpu-runtime-error'.\n * - offset % 8 != 0 (step 4) -> 'webgpu-runtime-error'.\n * - rangeSize % 4 != 0 (step 5) -> 'webgpu-runtime-error'.\n * - offset + rangeSize > size (step 6) -> 'webgpu-runtime-error'.\n * - mode contains foreign bits (step 7) -> 'webgpu-runtime-error'.\n * - mode is not exactly READ or WRITE (step 8) -> 'webgpu-runtime-error'.\n * - mode-usage mismatch (step 9 / F-8 row 3) -> 'webgpu-runtime-error'.\n *\n * @example\n * const r = await buffer.mapAsync(GPUMapMode.WRITE);\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * return;\n * }\n * const mapped: MappedBuffer = r.value;\n * const range = mapped.getMappedRange();\n * if (range.ok) new Uint32Array(range.value).set([1, 2, 3, 4]);\n * mapped.unmap();\n */\n mapAsync(\n mode: GPUMapModeFlags,\n offset?: number | undefined,\n size?: number | undefined,\n ): Promise<Result<MappedBuffer, RhiError>>;\n /**\n * Current mapping state (read-only getter).\n *\n * Spec anchor: research §4.1 mapState 3-state enum; mirrors\n * GPUBufferMapState. Transitions:\n * - createBuffer({mappedAtCreation:true}) sets mapState='mapped'.\n * - mapAsync moves 'unmapped' -> 'pending' -> 'mapped'.\n * - unmap moves 'mapped' -> 'unmapped'.\n */\n readonly mapState: 'unmapped' | 'pending' | 'mapped';\n}\n\n/**\n * Brand on top of `Buffer` indicating the mapping is currently open; only the\n * `MappedBuffer` exposes `getMappedRange` / `unmap` method forms so AI users\n * cannot accidentally call them on an unmapped `Buffer` (D-P2 #6).\n *\n * The brand is structural — runtime the `MappedBuffer` is the same JS object\n * as the underlying `Buffer`; TypeScript narrows access through the\n * `__mapped: void` private brand symbol.\n *\n * Spec anchor: W3C WebGPU §4 Buffers mapping lifecycle (research §4.1 /\n * §4.4); plan-strategy §7.1 + D-P2 break-point #6 (brand + method form\n * merged).\n *\n * @example\n * const r = await buffer.mapAsync(GPUMapMode.WRITE);\n * if (!r.ok) return;\n * const mapped: MappedBuffer = r.value;\n * mapped.getMappedRange(); // method form, this: MappedBuffer\n * mapped.unmap(); // method form, this: MappedBuffer\n */\nexport interface MappedBuffer extends Buffer {\n readonly [RhiMappedBufferBrand]: void;\n /**\n * Return an ArrayBuffer view of the mapped range. Method form on\n * `MappedBuffer` per D-P2 #6 — calling on a plain `Buffer` is TS2339.\n *\n * Spec anchor: W3C WebGPU §gpubuffer-getmappedrange /\n * [@webgpu/types.GPUBuffer.getMappedRange].\n *\n * Failure paths:\n * - mapState !== 'mapped' (incl after unmap, F-8 row 2 detach guard) ->\n * 'webgpu-runtime-error'.\n */\n getMappedRange(\n offset?: number | undefined,\n size?: number | undefined,\n ): Result<ArrayBuffer, RhiError>;\n /**\n * Unmap the buffer, detaching all ArrayBuffer views obtained from\n * getMappedRange. Method form on `MappedBuffer` per D-P2 #6.\n *\n * Spec anchor: W3C WebGPU §gpubuffer-unmap /\n * [@webgpu/types.GPUBuffer.unmap]. unmap() returns void per spec normative\n * silent no-op (research §4.4); calling unmap on an already-unmapped buffer\n * does NOT error. This is the ONE Result-shape exception in the buffer\n * surface (AI User Affordances explicit listing).\n *\n * After unmap, the JS object continues to exist but the brand narrows\n * away at the TS layer: AI users who hold a `MappedBuffer` after the\n * underlying state flipped should re-`mapAsync` to obtain a fresh branded\n * instance (OQ-5 plan-decisions: unmap returns void; subsequent mapAsync\n * returns a new MappedBuffer brand).\n */\n unmap(): void;\n}\n\ndeclare const RhiTextureBrand: unique symbol;\n/** GPU texture opaque handle (2D / 3D / cube / array). */\nexport interface Texture {\n readonly [RhiTextureBrand]: void;\n}\n\n/** RHI-safe source for a texture-to-buffer copy. */\nexport interface TextureCopySource {\n readonly texture: Texture;\n readonly mipLevel?: number | undefined;\n readonly origin?: GPUOrigin3D | undefined;\n readonly aspect?: GPUTextureAspect | undefined;\n}\n\n/** RHI-safe destination for a texture-to-buffer copy. */\nexport interface BufferCopyDestination {\n readonly buffer: Buffer;\n readonly offset?: number | undefined;\n readonly bytesPerRow: number;\n readonly rowsPerImage?: number | undefined;\n}\n\n/** RHI-owned destination for queue.writeTexture. The resource handle remains opaque. */\nexport interface TextureWriteDestination {\n readonly texture: Texture;\n readonly mipLevel?: number | undefined;\n readonly origin?: GPUOrigin3D | undefined;\n readonly aspect?: GPUTextureAspect | undefined;\n}\n\n/** RHI-owned destination for queue.copyExternalImageToTexture. */\nexport type ExternalImageTextureDestination = Omit<\n Pick<\n GPUCopyExternalImageDestInfo,\n 'texture' | 'mipLevel' | 'origin' | 'aspect' | 'colorSpace' | 'premultipliedAlpha'\n >,\n 'texture'\n> & {\n readonly texture: Texture;\n};\n\ndeclare const RhiTextureViewBrand: unique symbol;\n/** GPU texture view opaque handle. */\nexport interface TextureView {\n readonly [RhiTextureViewBrand]: void;\n}\n\ndeclare const RhiSamplerBrand: unique symbol;\n/** GPU sampler opaque handle. */\nexport interface Sampler {\n readonly [RhiSamplerBrand]: void;\n}\n\ndeclare const RhiBindGroupBrand: unique symbol;\n/** GPU bind group opaque handle (instantiated layout). */\nexport interface BindGroup {\n readonly [RhiBindGroupBrand]: void;\n}\n\ndeclare const RhiBindGroupLayoutBrand: unique symbol;\n/** GPU bind group layout opaque handle (declares binding shapes). */\nexport interface BindGroupLayout {\n readonly [RhiBindGroupLayoutBrand]: void;\n}\n\ndeclare const RhiPipelineLayoutBrand: unique symbol;\n/** GPU pipeline layout opaque handle (aggregates BindGroupLayouts). */\nexport interface PipelineLayout {\n readonly [RhiPipelineLayoutBrand]: void;\n}\n\ndeclare const RhiRenderPipelineBrand: unique symbol;\n/** GPU render pipeline opaque handle. */\nexport interface RenderPipeline {\n readonly [RhiRenderPipelineBrand]: void;\n}\n\ndeclare const RhiComputePipelineBrand: unique symbol;\n/** GPU compute pipeline opaque handle. */\nexport interface ComputePipeline {\n readonly [RhiComputePipelineBrand]: void;\n}\n\ndeclare const RhiShaderModuleBrand: unique symbol;\n/** GPU shader module opaque handle (WGSL / SPIR-V compile artifact). */\nexport interface ShaderModule {\n readonly [RhiShaderModuleBrand]: void;\n}\n\ndeclare const RhiQuerySetBrand: unique symbol;\n/** GPU query set opaque handle (occlusion / timestamp). */\nexport interface QuerySet {\n readonly [RhiQuerySetBrand]: void;\n}\n\ndeclare const RhiFenceBrand: unique symbol;\n/** GPU fence opaque handle (GPU/CPU sync barrier). */\nexport interface Fence {\n readonly [RhiFenceBrand]: void;\n}\n\ndeclare const RhiCommandEncoderBrand: unique symbol;\n/** GPU command encoder opaque handle (single-use). */\nexport interface CommandEncoder {\n readonly [RhiCommandEncoderBrand]: void;\n}\n\ndeclare const RhiCommandBufferBrand: unique symbol;\n/** GPU command buffer opaque handle (submitted to Queue). */\nexport interface CommandBuffer {\n readonly [RhiCommandBufferBrand]: void;\n}\n\n// ============================================================================\n// 5 core descriptors (MVP-1.1) - Pick<GPUXxxDescriptor, ...> field names\n// align byte-for-byte with @webgpu/types\n// ============================================================================\n//\n// Decision S-7 + research F-3: optional fields are uniformly `?: T | undefined`\n// (compatible with exactOptionalPropertyTypes; explicitly accepts writers\n// passing `{ x: undefined }`; charter proposition 4 explicit failure /\n// distinguish missing vs explicit-undefined).\n// R8 mitigation: Compatibility Mode field (textureBindingViewDimension) is\n// optional follow-on.\n//\n// Note: @webgpu/types v0.1.69 spec uses the `?: T` simplified form; forgeax\n// applies the ExplicitUndefined mapped type to `Pick<spec>` so the forgeax\n// side accepts `{ label: undefined }` writes (research F-3 finding;\n// ecosystem upgrade path = once upstream @webgpu/types v0.2.x ships\n// `?: T | undefined` uniformly, ExplicitUndefined can be removed).\n\n/**\n * Convert `?: T` optional fields to `?: T | undefined` (decision S-7).\n *\n * Compatible with exactOptionalPropertyTypes: writers may pass `undefined`\n * explicitly or omit the field; the M2 shim distinguishes the two via\n * `'x' in src` guards (research F-3 anti-pattern 2).\n */\ntype ExplicitUndefined<T> = { [K in keyof T]: T[K] | undefined };\n\n/** GPU buffer descriptor. Field set strictly matches GPUBufferDescriptor;\n * optional fields use `?: T | undefined`. */\nexport type BufferDescriptor = ExplicitUndefined<\n Pick<GPUBufferDescriptor, 'label' | 'size' | 'usage' | 'mappedAtCreation'>\n>;\n\n/** GPU texture descriptor. Field set strictly matches GPUTextureDescriptor\n * (incl R8 Compatibility Mode field). */\nexport type TextureDescriptor = ExplicitUndefined<\n Pick<\n GPUTextureDescriptor,\n | 'label'\n | 'size'\n | 'mipLevelCount'\n | 'sampleCount'\n | 'dimension'\n | 'format'\n | 'usage'\n | 'viewFormats'\n | 'textureBindingViewDimension'\n >\n>;\n\n/** GPU sampler descriptor. Field set strictly matches GPUSamplerDescriptor. */\nexport type SamplerDescriptor = ExplicitUndefined<\n Pick<\n GPUSamplerDescriptor,\n | 'label'\n | 'addressModeU'\n | 'addressModeV'\n | 'addressModeW'\n | 'magFilter'\n | 'minFilter'\n | 'mipmapFilter'\n | 'lodMinClamp'\n | 'lodMaxClamp'\n | 'compare'\n | 'maxAnisotropy'\n >\n>;\n\n/** GPU bind group layout descriptor. Field set strictly matches\n * GPUBindGroupLayoutDescriptor. */\nexport type BindGroupLayoutDescriptor = ExplicitUndefined<\n Pick<GPUBindGroupLayoutDescriptor, 'label' | 'entries'>\n>;\n\n/**\n * GPU texture view descriptor (Pick<GPUTextureViewDescriptor, 9 fields>).\n *\n * Spec anchor: W3C WebGPU §texture-view-creation /\n * [@webgpu/types.GPUTextureViewDescriptor]. Field NAMES align byte-for-byte;\n * field set excludes the feature-gated `swizzle` field (research §1.1 OOS-MVP;\n * a future closure can add it once `'texture-component-swizzle'` is enabled).\n *\n * Cross-resource validation (shim fast-path, research §1.1):\n * - `format` must equal source.format OR be in source.viewFormats; otherwise\n * the shim returns Result.err({ code: 'webgpu-runtime-error' }).\n * - `usage` must be a subset of source.usage (bitmask); otherwise the shim\n * returns the same code.\n *\n * @example\n * const r = device.createTextureView(tex, { format: 'rgba8unorm', dimension: '2d' });\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\nexport type TextureViewDescriptor = ExplicitUndefined<\n Pick<\n GPUTextureViewDescriptor,\n | 'label'\n | 'format'\n | 'dimension'\n | 'usage'\n | 'aspect'\n | 'baseMipLevel'\n | 'mipLevelCount'\n | 'baseArrayLayer'\n | 'arrayLayerCount'\n >\n>;\n\n/**\n * GPU compute pipeline descriptor (Pick<GPUComputePipelineDescriptor,\n * 'label' | 'layout' | 'compute'>).\n *\n * Spec anchor: W3C WebGPU §compute-pipeline-creation /\n * [@webgpu/types.GPUComputePipelineDescriptor]. Field NAMES align byte-for-byte\n * with spec.\n *\n * `layout` is the spec union `'auto' | GPUPipelineLayout`; forgeax tightens\n * the explicit form to the `PipelineLayout` opaque handle (D-S5 pattern):\n * layout: 'auto' | PipelineLayout\n *\n * `compute` mirrors `GPUProgrammableStage` verbatim — `module` (required\n * `ShaderModule` opaque handle), `entryPoint?` (optional string),\n * `constants?` (optional `Record<string, number>`).\n *\n * Capability gate (research §1.2 NOTE; plan-strategy §4.3 boundary case row 1):\n * - `caps.compute === false` -> shim returns Result.err({\n * code: 'feature-not-enabled', expected: 'caps.compute === true',\n * hint: 'check device.caps.compute before calling createComputePipeline'\n * }). MVP WebGPU path always has caps.compute=true (spec mandate); the gate\n * exists for potential future non-WebGPU backends.\n *\n * @example\n * const r = device.createComputePipeline({\n * label: 'cs',\n * layout: 'auto',\n * compute: { module: csModule, entryPoint: 'cs_main' },\n * });\n */\nexport type ComputePipelineDescriptor = ExplicitUndefined<\n Omit<Pick<GPUComputePipelineDescriptor, 'label' | 'layout' | 'compute'>, 'layout' | 'compute'>\n> & {\n /**\n * Either `'auto'` for user-agent BGL inference or a forgeax\n * `PipelineLayout` opaque handle (D-S5 pattern: forgeax handle replaces\n * spec polymorphism `(GPUAutoLayoutMode or GPUPipelineLayout)`).\n */\n layout: 'auto' | PipelineLayout;\n /**\n * The compute programmable stage. `module` is the forgeax `ShaderModule`\n * opaque handle (replacing spec `GPUShaderModule`); `entryPoint?` defaults\n * to the module's single compute entry; `constants?` is a record of\n * pipeline-overridable constants.\n */\n compute: {\n module: ShaderModule;\n entryPoint?: string | undefined;\n constants?: Record<string, number> | undefined;\n };\n};\n\n/**\n * GPU query set descriptor (Pick<GPUQuerySetDescriptor, 'label' | 'type' | 'count'>).\n *\n * Spec anchor: W3C WebGPU §queries / [@webgpu/types.GPUQuerySetDescriptor].\n * Field NAMES align byte-for-byte.\n *\n * Hard constraints (research §1.3):\n * - `count <= 4096` (spec normative). The shim fast-paths a violation to\n * Result.err({ code: 'limit-exceeded',\n * expected: 'count <= 4096 (spec normative)',\n * hint: 'create multiple QuerySet instances if more than 4096 queries needed' }).\n * - `type === 'timestamp'` requires `caps.timestampQuery === true` (the\n * 'timestamp-query' feature). Otherwise the shim fast-paths to\n * Result.err({ code: 'feature-not-enabled' }).\n * - `count = 0` is legal (lower bound; dawn end2end test fixture).\n *\n * @example\n * const r = device.createQuerySet({ type: 'occlusion', count: 4 });\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\nexport type QuerySetDescriptor = ExplicitUndefined<\n Pick<GPUQuerySetDescriptor, 'label' | 'type' | 'count'>\n>;\n\n/**\n * Discriminated union over the 4 BindGroup entry resource kinds (the spec\n * polymorphic `GPUBindingResource` collapsed to a tagged union — charter\n * proposition 4 closed-union exhaustive switch + proposition 5 consistent\n * abstraction over duck-typing).\n *\n * Introduced in feat-20260511-rhi-spec-realign-aggressive w9 per requirements\n * AC-10 + plan-strategy §7.1 + D-P2 break-point #5. AI users `switch\n * (resource.kind)` is exhaustive without a default fallback; construction-side\n * typos like `{ kind: 'samplre', ... }` trip TS2322 at the literal slot.\n *\n * Kind discriminator uses kebab-case for multi-word entries (`textureView` is\n * already single-word camelCase by convention; `externalTexture` is multi-word\n * camelCase for parity with the spec verb `GPUExternalTexture`).\n *\n * @example\n * const e: RhiBindingResource = { kind: 'sampler', value: linearSampler };\n * const e2: RhiBindingResource = {\n * kind: 'buffer',\n * value: { buffer: viewUniforms, offset: 0, size: 64 },\n * };\n */\nexport type RhiBindingResource =\n | { readonly kind: 'sampler'; readonly value: Sampler }\n | {\n readonly kind: 'buffer';\n readonly value: {\n readonly buffer: Buffer;\n readonly offset?: number;\n readonly size?: number;\n };\n }\n | { readonly kind: 'textureView'; readonly value: TextureView }\n | { readonly kind: 'externalTexture'; readonly value: GPUExternalTexture };\n\n/**\n * BindGroup entry — one slot in a BindGroup, identified by `binding` (the\n * shader binding number) and `resource` (the tagged-union `RhiBindingResource`\n * — replaces the spec polymorphic `GPUBindingResource`).\n *\n * Field set strictly mirrors `Pick<GPUBindGroupEntry, 'binding'>`; the\n * `resource` field is tightened to the forgeax `RhiBindingResource` tagged\n * union per D-P2 break-point #5 (charter proposition 5 consistent abstraction:\n * AI users see one canonical 4-kind switch rather than spec duck-typing).\n */\nexport type BindGroupEntry = Pick<GPUBindGroupEntry, 'binding'> & {\n resource: RhiBindingResource;\n};\n\n/**\n * GPU bind group descriptor (Pick<GPUBindGroupDescriptor, 'label' | 'layout' | 'entries'>).\n *\n * Spec anchor: W3C WebGPU 10 Resource binding /\n * [@webgpu/types.GPUBindGroupDescriptor].\n *\n * Introduced in feat-20260509-ecs-render-bridge-mvp (D-S1) so the RenderSystem\n * can record `pass.setBindGroup(0/1/2, bg, ...)` through a single RHI surface\n * (charter proposition 5 consistent abstraction; never via raw GPUDevice).\n *\n * The `layout` field references the forgeax `BindGroupLayout` opaque handle\n * (created via `RhiDevice.createBindGroupLayout`); the `entries` array uses\n * the forgeax `BindGroupEntry` shape (binding number + tagged-union\n * `RhiBindingResource`) per feat-20260511-rhi-spec-realign-aggressive D-P2\n * break-point #5 (was previously verbatim `GPUBindGroupEntry`).\n *\n * @example\n * const desc: BindGroupDescriptor = {\n * label: 'view-bg',\n * layout: bgl,\n * entries: [{ binding: 0, resource: { kind: 'buffer', value: { buffer: viewUniforms } } }],\n * };\n */\nexport type BindGroupDescriptor = ExplicitUndefined<\n Omit<Pick<GPUBindGroupDescriptor, 'label' | 'layout' | 'entries'>, 'layout' | 'entries'>\n> & {\n /**\n * BindGroupLayout opaque handle (forgeax tightening: `layout` is the\n * already-shipped `BindGroupLayout` brand, not the spec\n * `GPUBindGroupLayout`). Same D-S5 pattern as RenderPassColorAttachment.view\n * — AI users receive a forgeax-creatable handle, never a phantom spec type.\n */\n layout: BindGroupLayout;\n /**\n * Iterable of forgeax `BindGroupEntry` (binding + tagged-union\n * `RhiBindingResource`); replaces the spec polymorphic\n * `iterable<GPUBindGroupEntry>` per D-P2 break-point #5.\n */\n entries: Iterable<BindGroupEntry>;\n};\n\n/**\n * GPU pipeline layout descriptor (Pick<GPUPipelineLayoutDescriptor, 'label' | 'bindGroupLayouts'>).\n *\n * Spec anchor: W3C WebGPU 10.3 Pipeline layout /\n * [@webgpu/types.GPUPipelineLayoutDescriptor].\n *\n * Introduced in feat-20260509-ecs-render-bridge-mvp (D-S1) so the\n * `Renderer.ready` step 2 (PBR pipeline compile) can compose the 3\n * BindGroupLayouts (view / material / mesh-array) into a single\n * `PipelineLayout` for `RhiDevice.createRenderPipeline`.\n *\n * @example\n * const desc: PipelineLayoutDescriptor = {\n * label: 'pbr-pl',\n * bindGroupLayouts: [viewBgl, materialBgl, meshArrayBgl],\n * };\n */\nexport type PipelineLayoutDescriptor = ExplicitUndefined<\n Omit<Pick<GPUPipelineLayoutDescriptor, 'label' | 'bindGroupLayouts'>, 'bindGroupLayouts'>\n> & {\n /**\n * Iterable of BindGroupLayout opaque handles (forgeax tightening: the\n * iterable element type is the forgeax `BindGroupLayout` brand). Same D-S5\n * pattern as BindGroupDescriptor.layout.\n */\n bindGroupLayouts: Iterable<BindGroupLayout>;\n};\n\n/** GPU render pipeline vertex stage with an opaque forgeax shader module. */\nexport type RenderPipelineVertexState = ExplicitUndefined<\n Omit<GPUVertexState, 'module' | 'buffers'>\n> & {\n module: ShaderModule;\n buffers: NonNullable<GPUVertexState['buffers']>;\n};\n\n/** GPU render pipeline fragment stage with an opaque forgeax shader module. */\nexport type RenderPipelineFragmentState = ExplicitUndefined<\n Omit<GPUFragmentState, 'module' | 'targets'>\n> & {\n module: ShaderModule;\n targets: NonNullable<GPUFragmentState['targets']>;\n};\n\n/** GPU render pipeline descriptor with opaque forgeax layout and shader handles. */\nexport type RenderPipelineDescriptor = ExplicitUndefined<\n Omit<\n Pick<\n GPURenderPipelineDescriptor,\n 'label' | 'layout' | 'vertex' | 'primitive' | 'depthStencil' | 'multisample' | 'fragment'\n >,\n 'layout' | 'vertex' | 'fragment'\n >\n> & {\n layout: 'auto' | PipelineLayout;\n vertex: RenderPipelineVertexState;\n fragment?: RenderPipelineFragmentState | undefined;\n};\n\n// ============================================================================\n// 4 new descriptors (feat-20260508-rhi-surface-completion w8 / D-S5,\n// feat-20260510-rhi-resource-creation M2 view narrow Path X)\n// ============================================================================\n//\n// Field NAMES align byte-for-byte with @webgpu/types (Pick<GPUXxxDescriptor,\n// ...> shape preserved; R12 lint enforces this). Field TYPES for `view` are\n// SPEC-ALIGNED to the forgeax `TextureView` opaque handle (per\n// feat-20260510-rhi-resource-creation IN-2 / AC-02 view narrow Path X;\n// breakage point #1). The earlier D-S5 temporary tightening to `Texture` was\n// retired once M1 of feat-20260510-rhi-resource-creation shipped\n// `RhiDevice.createTextureView`, so AI users now follow the spec idiom:\n// const view = device.createTextureView(texture, desc).unwrap();\n// pass.beginRenderPass({ colorAttachments: [{ view, ... }] });\n//\n// Charter mapping: proposition 5 consistent abstraction (call site lines up\n// with what `createTextureView` returns) + proposition 4 explicit failure\n// (passing a Texture brand to `view` is a tsc red signal at the call site,\n// not a runtime swap). The breakage point is registered in the AGENTS.md\n// RHI / Shader error model contract section -> breakage point list (M7 of\n// this closure).\n\n/**\n * Command encoder descriptor (Pick<GPUCommandEncoderDescriptor, 'label'>).\n *\n * Spec anchor: W3C WebGPU 22 GPUCommandEncoder /\n * [@webgpu/types.GPUCommandEncoderDescriptor].\n *\n * @example\n * const desc: CommandEncoderDescriptor = { label: 'frame-encoder' };\n */\nexport type CommandEncoderDescriptor = ExplicitUndefined<\n Pick<GPUCommandEncoderDescriptor, 'label'>\n>;\n\n/**\n * Render-pass color attachment (Pick<GPURenderPassColorAttachment, ...> with\n * `view` field aligned to the forgeax `TextureView` opaque handle, per\n * feat-20260510-rhi-resource-creation M2 view narrow Path X / breakage point\n * #1).\n *\n * Spec anchor: W3C WebGPU 22.7 Render pass /\n * [@webgpu/types.GPURenderPassColorAttachment].\n *\n * v0.1.69 spec shape: `view: GPUTexture | GPUTextureView`. The forgeax RHI\n * tightens the union to the single `TextureView` brand (the only branch the\n * shim ever produces post-M1). Charter proposition 5 consistent abstraction\n * (the field type matches what `RhiDevice.createTextureView` returns) +\n * proposition 4 explicit failure (passing a `Texture` brand here is a tsc red\n * signal; the AI user is steered to the spec idiom).\n *\n * **Migration**: see AGENTS.md break-point list 2026-05-10 #1\n * \"view: Texture -> TextureView narrow (major breaking)\" for the call-site\n * upgrade diff (3 narrowed fields: this `view` + `resolveTarget` +\n * `RenderPassDepthStencilAttachment.view`).\n *\n * @example\n * const view = device.createTextureView(tex, {}).unwrap();\n * const att: RenderPassColorAttachment = {\n * view,\n * clearValue: { r: 0, g: 0, b: 0, a: 1 },\n * loadOp: 'clear',\n * storeOp: 'store',\n * };\n */\nexport type RenderPassColorAttachment = ExplicitUndefined<\n Omit<\n Pick<\n GPURenderPassColorAttachment,\n 'view' | 'depthSlice' | 'resolveTarget' | 'clearValue' | 'loadOp' | 'storeOp'\n >,\n 'view' | 'resolveTarget'\n >\n> & {\n /**\n * TextureView target of this color attachment (view narrow Path X: aligned\n * to the forgeax `TextureView` brand returned by `createTextureView`; not\n * the spec union `GPUTexture | GPUTextureView`).\n */\n view: TextureView;\n /**\n * Optional resolve target for multisample resolution. Same view narrow\n * alignment as `view`.\n */\n resolveTarget?: TextureView | undefined;\n};\n\n/**\n * Render-pass depth/stencil attachment (Pick<GPURenderPassDepthStencilAttachment,\n * ...> with `view` field aligned to the forgeax `TextureView` opaque handle,\n * per feat-20260510-rhi-resource-creation M2 view narrow Path X / breakage\n * point #1).\n *\n * Spec anchor: W3C WebGPU 22.7 Render pass /\n * [@webgpu/types.GPURenderPassDepthStencilAttachment].\n *\n * Same view narrow alignment as RenderPassColorAttachment.\n *\n * **Migration**: see AGENTS.md break-point list 2026-05-10 #1 for the\n * call-site upgrade diff covering this `view` field plus the two\n * `RenderPassColorAttachment` narrowed fields.\n *\n * @example\n * const view = device.createTextureView(depthTex, {}).unwrap();\n * const ds: RenderPassDepthStencilAttachment = {\n * view,\n * depthClearValue: 1,\n * depthLoadOp: 'clear',\n * depthStoreOp: 'store',\n * };\n */\nexport type RenderPassDepthStencilAttachment = ExplicitUndefined<\n Omit<\n Pick<\n GPURenderPassDepthStencilAttachment,\n | 'view'\n | 'depthClearValue'\n | 'depthLoadOp'\n | 'depthStoreOp'\n | 'depthReadOnly'\n | 'stencilClearValue'\n | 'stencilLoadOp'\n | 'stencilStoreOp'\n | 'stencilReadOnly'\n >,\n 'view'\n >\n> & {\n /**\n * TextureView target of this depth/stencil attachment (view narrow Path X:\n * aligned to the forgeax `TextureView` brand).\n */\n view: TextureView;\n};\n\n/**\n * Render-pass descriptor (Pick<GPURenderPassDescriptor, ...>).\n *\n * Spec anchor: W3C WebGPU 22.7 Render pass /\n * [@webgpu/types.GPURenderPassDescriptor].\n *\n * `colorAttachments` element type uses the forgeax narrow\n * `RenderPassColorAttachment` (with `view: TextureView`);\n * `depthStencilAttachment` uses `RenderPassDepthStencilAttachment`.\n *\n * @example\n * const view = device.createTextureView(tex, {}).unwrap();\n * const desc: RenderPassDescriptor = {\n * label: 'frame',\n * colorAttachments: [{ view, loadOp: 'clear', storeOp: 'store',\n * clearValue: { r: 0, g: 0, b: 0, a: 1 } }],\n * };\n */\nexport type RenderPassDescriptor = ExplicitUndefined<\n Omit<\n Pick<\n GPURenderPassDescriptor,\n | 'label'\n | 'colorAttachments'\n | 'depthStencilAttachment'\n | 'occlusionQuerySet'\n | 'timestampWrites'\n | 'maxDrawCount'\n >,\n 'colorAttachments' | 'depthStencilAttachment' | 'occlusionQuerySet' | 'timestampWrites'\n >\n> & {\n /**\n * Color attachments for this render pass (forgeax narrow element type per\n * view narrow Path X: each entry's `view` field is `TextureView`, not the\n * spec union `GPUTexture | GPUTextureView`).\n */\n colorAttachments: Iterable<RenderPassColorAttachment | null | undefined>;\n /** Optional depth/stencil attachment with the same view narrow alignment. */\n depthStencilAttachment?: RenderPassDepthStencilAttachment | undefined;\n /** Occlusion query set (capability-gated). The shim accepts a\n * `QuerySet` brand created via `device.createQuerySet({ type: 'occlusion',\n * count })` and pairs it with `pass.beginOcclusionQuery(idx) /\n * pass.endOcclusionQuery()`; both methods now have real implementations\n * (see `RhiRenderPassEncoder` below). Capability gate: read\n * `device.caps.timestampQuery` ahead of `'timestamp'` query sets;\n * occlusion sets are unconditionally available. */\n occlusionQuerySet?: QuerySet | undefined;\n /** Optional timestamp query set and the pass boundary write slots. */\n timestampWrites?: RenderPassTimestampWrites | undefined;\n};\n\n/** Timestamp writes attached to a render pass descriptor. */\nexport interface RenderPassTimestampWrites {\n querySet: QuerySet;\n beginningOfPassWriteIndex?: number | undefined;\n endOfPassWriteIndex?: number | undefined;\n}\n\n/** Compute-pass descriptor with forgeax-owned timestamp query handles. */\nexport type ComputePassDescriptor = ExplicitUndefined<\n Omit<Pick<GPUComputePassDescriptor, 'label' | 'timestampWrites'>, 'timestampWrites'>\n> & {\n timestampWrites?: ComputePassTimestampWrites | undefined;\n};\n\n/** Timestamp writes attached to a compute pass descriptor. */\nexport interface ComputePassTimestampWrites {\n querySet: QuerySet;\n beginningOfPassWriteIndex?: number | undefined;\n endOfPassWriteIndex?: number | undefined;\n}\n\n// ============================================================================\n// Capabilities trio (MVP-1.2) - readonly + independent fields\n// ============================================================================\n//\n// Charter proposition 5 (consistent abstraction / discoverable differences):\n// caps (hardware probe) / features (enabled set) / limits (numeric ceilings)\n// are three independent semantic layers; `caps.X = false` is an explicit\n// signal, never an exception (proposition 4).\n\n/** Hardware-probe layer: readonly boolean capability flags. */\nexport interface RhiCaps {\n /**\n * The rendering backend kind — single source of truth for backend-aware\n * logic (e.g. explicit barrier insertion vs. spec-managed / GL-implicit\n * sync). Closed 4-member union: every backend reports exactly one.\n *\n * - `'webgpu'`: browser WebGPU — spec-managed barriers, no explicit\n * barrier insertion needed.\n * - `'wgpu-native'`: wgpu native-desktop runtime (Tauri / native) —\n * requires explicit Vulkan/Metal/DX12 barrier commands.\n * - `'wgpu-webgl2'`: wgpu GLES3/WebGL2 backend — GL implicit sync, no\n * explicit barrier insertion needed (equivalence group with `'webgpu'`).\n * - `'null'`: headless no-op backend (`@forgeax/engine-rhi-null`) for\n * structural unit tests — no GPU / DOM; records command-stream shape into\n * a ledger instead of executing it. No barrier insertion needed (the\n * no-op backend executes nothing); falls into the same no-barrier branch\n * as `'webgpu'` / `'wgpu-webgl2'`.\n *\n * @note `exactOptionalPropertyTypes` requires every backend fill this\n * field; a backend that omits it produces a tsc compile error.\n */\n readonly backendKind: 'webgpu' | 'wgpu-native' | 'wgpu-webgl2' | 'null';\n /** Whether compute pipelines are supported. */\n readonly compute: boolean;\n /** Whether timestamp queries are supported. */\n readonly timestampQuery: boolean;\n /** Backend-owned nanoseconds represented by one timestamp tick, or null when unavailable. */\n readonly timestampPeriodNanoseconds: number | null;\n /** Whether indirect drawing is supported. */\n readonly indirectDrawing: boolean;\n /**\n * Whether BC texture compression (BC1-BC7) is available.\n *\n * Derived from `adapter.features.has('texture-compression-bc')`.\n * On rhi-null this is always `false` (headless has no compression hardware,\n * AC-06).\n */\n readonly textureCompressionBc: boolean;\n /**\n * Whether ETC2 texture compression is available.\n *\n * Derived from `adapter.features.has('texture-compression-etc2')`.\n * On rhi-null this is always `false` (headless has no compression hardware,\n * AC-06).\n */\n readonly textureCompressionEtc2: boolean;\n /**\n * Whether ASTC texture compression is available.\n *\n * Derived from `adapter.features.has('texture-compression-astc')`.\n * On rhi-null this is always `false` (headless has no compression hardware,\n * AC-06).\n */\n readonly textureCompressionAstc: boolean;\n /**\n * Whether multi-draw indirect is available (wgpu native extension).\n *\n * @reserved-for-wgpu-native-only always `false` on browser backends; only\n * available when the forgeax renderer runs against a wgpu native runtime\n * (Tauri / native runtime, not the wasm bundle). `caps.X = false` is an\n * explicit signal, never an exception (charter proposition 4 / AGENTS.md\n * `RHI / WebGPU` shape rule #2 capability-gated).\n */\n readonly multiDrawIndirect: boolean;\n /**\n * Whether push constants are available (wgpu native extension).\n *\n * @reserved-for-wgpu-native-only always `false` on browser backends; only\n * available when the forgeax renderer runs against a wgpu native runtime\n * (Tauri / native runtime, not the wasm bundle). `caps.X = false` is an\n * explicit signal, never an exception (charter proposition 4 / AGENTS.md\n * `RHI / WebGPU` shape rule #2 capability-gated).\n */\n readonly pushConstants: boolean;\n /**\n * Whether bindless texture array is available (wgpu native extension).\n *\n * @reserved-for-wgpu-native-only always `false` on browser backends; only\n * available when the forgeax renderer runs against a wgpu native runtime\n * (Tauri / native runtime, not the wasm bundle). `caps.X = false` is an\n * explicit signal, never an exception (charter proposition 4 / AGENTS.md\n * `RHI / WebGPU` shape rule #2 capability-gated).\n */\n readonly textureBindingArray: boolean;\n /**\n * Whether sampler binding aliasing is supported across pipelines.\n *\n * @spec-anchor W3C WebGPU §10.3 Bind group layout — spec mandates that a\n * sampler may alias multiple binding slots; both navigator.gpu and the\n * wgpu wasm bundle satisfy this so the field is always `true` on browser\n * backends.\n * @note Always `true` on shipped backends (WebGPU + wgpu wasm). The field\n * exists for potential future backends that lack sampler aliasing.\n * @hint AI users use `caps.samplerAliasing` to gate code that creates two\n * `BindGroupEntry`s pointing at the same `Sampler` across different\n * layouts; `caps.X = false` is an explicit signal, never an exception\n * (charter proposition 4).\n */\n readonly samplerAliasing: boolean;\n /**\n * Whether the renderer can issue indirect draws with a non-zero\n * `firstInstance`.\n *\n * @spec-anchor W3C WebGPU §22.4 drawIndirect — the `indirect-first-instance`\n * feature on `GPUAdapter.features` gates non-zero `firstInstance` in\n * indirect draws; rhi-webgpu maps this to `device.features.has(\n * 'indirect-first-instance')`.\n * @note `false` on backends without indirect drawing support.\n * @hint Most AI users never need this; the field surfaces so a renderer\n * author building instanced draw batchers can gate the fast path. With\n * `caps.firstInstanceIndirect === false` the renderer must pre-rebase\n * instance indices in the vertex shader (charter proposition 5\n * consistent abstraction over a discoverable cap difference).\n */\n readonly firstInstanceIndirect: boolean;\n /**\n * Whether storage buffer bindings are available\n * (`device.limits.maxStorageBuffersPerShaderStage > 0`).\n *\n * @spec-anchor W3C WebGPU §3.6.2 GPUSupportedLimits.\n * maxStorageBuffersPerShaderStage; `> 0` means the device supports the\n * `storage` / `read-only-storage` binding types.\n * @note `false` on backends without storage buffer support.\n * @hint AI users gate compute / large-buffer paths on\n * `caps.storageBuffer`; the per-stage numeric limit lives on\n * `device.limits.maxStorageBuffersPerShaderStage` for capacity planning\n * (charter proposition 4: `caps.X = false` is an explicit signal).\n */\n readonly storageBuffer: boolean;\n /**\n * Whether storage texture bindings are available\n * (`device.limits.maxStorageTexturesPerShaderStage > 0`).\n *\n * @spec-anchor W3C WebGPU §3.6.2 GPUSupportedLimits.\n * maxStorageTexturesPerShaderStage; `> 0` means the device supports the\n * `write-only` / `read-write` storage texture binding types.\n * @note `false` on backends without storage texture support.\n * @hint AI users gate image-effects compute / postprocess paths on\n * `caps.storageTexture`; the per-stage numeric limit lives on\n * `device.limits.maxStorageTexturesPerShaderStage` (charter proposition\n * 4: `caps.X = false` is an explicit signal).\n */\n readonly storageTexture: boolean;\n /**\n * Whether the device can create `rgba16float` textures with `RENDER_ATTACHMENT`\n * usage, enabling the HDR cubemap path for IBL irradiance / specular prefilter\n * and downstream HDR render-target chains.\n *\n * @spec-anchor W3C WebGPU $25.1 GPUTextureFormat — `rgba16float` is an\n * optional texture format whose `RENDER_ATTACHMENT` capability is probed by\n * attempting `createTexture({ format: 'rgba16float', usage:\n * GPUTextureUsage.RENDER_ATTACHMENT, size: [1, 1, 1] })` on the live\n * device; failure maps the cap to `false`.\n * @note Probed at device-creation time via a synchronous `createTexture`\n * call, not via `GPUAdapter.features`. The `rgba16float` format is widely\n * supported but `RENDER_ATTACHMENT` with float formats is optional per spec\n * so the cap reflects the concrete device, not the adapter feature list.\n * @hint AI users gate IBL / HDR post-processing paths on\n * `caps.rgba16floatRenderable`; when `false` the internal equirect-to-cubemap\n * IBL projection (driven by declaring `Skylight{equirect}`) degrades to the\n * white-cube fallback and fires `{ code: 'equirect-projection-failed' }` with\n * a machine-readable `expected` field naming this cap (charter P3 structured\n * failure).\n */\n readonly rgba16floatRenderable: boolean;\n /**\n * Whether the device can create `rg11b10ufloat` textures with\n * `RENDER_ATTACHMENT` usage, enabling the HDR swapchain / render-target path\n * with reduced bit-depth precision versus `rgba16float`.\n *\n * @spec-anchor W3C WebGPU $25.1 GPUTextureFormat — `rg11b10ufloat` is\n * `RENDER_ATTACHMENT`-capable only when the optional feature\n * `rg11b10ufloat-renderable` is enabled (W3C WebGPU $4.2). Probed by gating\n * on `device.features.has('rg11b10ufloat-renderable')` first; only then\n * confirmed by `createTexture({ format: 'rg11b10ufloat', usage:\n * GPUTextureUsage.RENDER_ATTACHMENT, size: [1, 1, 1] })`.\n * @note The format packs 11+11+10 unsigned float bits into 32 bits per pixel;\n * it is a popular HDR swapchain format for engines that trade precision\n * for bandwidth but its `RENDER_ATTACHMENT` capability is not universal.\n * The feature gate is the authoritative answer (avoiding fan-out via\n * `device.onuncapturederror` when the optional feature is absent); the\n * subsequent probe handles the rare case where the feature is reported\n * but the concrete device still rejects.\n * @hint AI users can select an HDR back-buffer format by reading\n * `caps.rg11b10ufloatRenderable` before creating a\n * `GPUTextureUsage.RENDER_ATTACHMENT` texture at that format; when `false`\n * fall back to `rgba16float` (if `caps.rgba16floatRenderable` is true)\n * or an SDR format.\n */\n readonly rg11b10ufloatRenderable: boolean;\n /**\n * Whether the device supports sampling `rgba32float` textures with a\n * `filtering` sampler (linear / mipmap filtering), NOT just with a\n * `non-filtering` sampler.\n *\n * @spec-anchor W3C WebGPU $10.3 Bind group layout — a bind group layout\n * entry pairing a `filtering` sampler type with `sampleType: 'float'`\n * (matching `rgba32float`) validates only when the\n * `float32-filterable` feature is enabled. The cap probes this via\n * `device.createBindGroupLayout({ entries: [{ sampler: { type:\n * 'filtering' } }, { texture: { sampleType: 'float' } }] })` and\n * `device.createSampler({ minFilter: 'linear', magFilter: 'linear' })`;\n * failure maps the cap to `false`.\n * @note Probed by gating on `device.features.has('float32-filterable')`\n * first (the authoritative answer per spec $4.2; avoids fan-out via\n * `device.onuncapturederror` when the optional feature is absent); only\n * then confirmed by exercising the bind-group-layout. The subsequent\n * probe handles the rare case where the feature is reported but the\n * concrete device still rejects (spec ambiguity, driver quirks).\n * @hint AI users gate float32-sampled compute / post-process paths on\n * `caps.float32Filterable`; when `false` use `sampleType: 'unfilterable-\n * float'` with a `non-filtering` sampler and compute the filter kernel\n * manually in the shader, or fall back to `rgba16float` with filtering.\n */\n readonly float32Filterable: boolean;\n /**\n * Maximum number of color attachments per render pass.\n *\n * @spec-anchor W3C WebGPU $3.6.2 GPUSupportedLimits.maxColorAttachments;\n * spec minimum = 4, defaults to 8 on mainstream backends.\n * HDRP deferred pipeline requires >= 4 (3 g-buffer RT + 1 depth);\n * installPipeline checks this cap at install time and throws\n * a structured Standard transport refusal on violation (charter P3).\n * @note add-only minor (feat-20260612-hdrp-deferred-shading-learn-render-5-8\n * M1 / w5); no existing field is modified.\n */\n readonly maxColorAttachments: number;\n}\n\n/**\n * Enabled feature set, opaque iteration only via `has()`.\n *\n * Aligned with `GPUSupportedFeatures` shape; this empty interface intentionally\n * adds no fields — the concrete enabled set is decided at `requestDevice` time\n * and is then probed by AI users via `device.features.has('feature-name')`\n * (charter proposition 5 consistent abstraction; no implementation-detail leak,\n * no enumeration helper that would tie callers to a fixed feature list).\n *\n * @see {@link GPUSupportedFeatures}\n */\nexport interface RhiFeatures extends ReadonlySet<GPUFeatureName> {\n /** Aligned with GPUSupportedFeatures shape; concrete enabled set is decided\n * at device creation time. */\n}\n\n/** Numeric-limits layer aligned with GPUSupportedLimits (incl Compatibility\n * Mode follow-on fields). */\nexport type RhiLimits = Readonly<GPUSupportedLimits>;\n\n// ============================================================================\n// 7 main interfaces: Device / Queue / CommandEncoder / RenderPassEncoder /\n// ComputePassEncoder / RenderPipeline / ComputePipeline\n// ============================================================================\n//\n// Interface signatures accept POD + ArrayBuffer / Float32Array (math-free /\n// MVP-1.5); all fallible operations return Result<T, RhiError>\n// (D-5 + AGENTS.md error baseline).\n//\n// Note: interface names RenderPipeline / ComputePipeline / CommandEncoder\n// match opaque handle names - spec-aligned choice (per plan-strategy 7.1)\n// matching GPURenderPipeline et al; module-path semantics distinguish them.\n// M1 interfaces express \"operation verb sets\"; opaque handles serve as\n// return-value types.\n\n// ============================================================================\n// RhiInstance + RhiAdapter (M3 break-point #2; K-5 / K-6)\n// ============================================================================\n//\n// Strict two-step path: `rhi.requestAdapter(opts) -> adapter.requestDevice(opts)`\n// mirrors wgpu (research §6.1) + Dawn (§6.2) source-level idiom. The legacy\n// top-level `rhi.requestDevice(opts)` factory is deprecated in favour of this\n// path; AGENTS.md break-point list registers the deprecation under\n// feat-20260510-rhi-resource-creation.\n//\n// K-5: `RhiAdapter.features: ReadonlySet<GPUFeatureName>` (Round 3 fix-up\n// F-P1-2: aligned with `RhiDevice.features: RhiFeatures extends\n// ReadonlySet<GPUFeatureName>` so the cross-tier surface is uniform —\n// AI users use `.has(name)` on both abstraction layers; previously a\n// `ReadonlyArray<string>` projection drifted from the spec\n// `GPUSupportedFeatures` Set shape and split the AI-user idiom).\n// `RhiAdapter.limits: Readonly<Record<string, number>>` aligns with\n// `GPUAdapter.limits` (`GPUSupportedLimits`). RhiDevice.caps stays\n// as the existing high-level boolean gate (caps.compute /\n// caps.timestampQuery etc.).\n//\n// K-6: `RhiAdapter.requestDevice` returns `Result<RhiDevice, RhiError>` (NOT a\n// `(Device, Queue)` tuple). The queue continues to be exposed via the\n// existing `RhiDevice.queue: RhiQueue` field (spec `device.queue` auto-\n// provisioned, packages/rhi/src/index.ts).\n\n/**\n * RhiAdapter request options.\n *\n * Spec anchor: W3C WebGPU §3.2 `GPURequestAdapterOptions` /\n * [@webgpu/types.GPURequestAdapterOptions]. Fields pass through to the\n * underlying `navigator.gpu.requestAdapter(opts)` call.\n */\nexport type RequestAdapterOptions = ExplicitUndefined<\n Pick<GPURequestAdapterOptions, 'powerPreference' | 'forceFallbackAdapter'>\n>;\n\n/**\n * RhiAdapter.requestDevice options.\n *\n * Spec anchor: W3C WebGPU §3.4 `GPUDeviceDescriptor` /\n * [@webgpu/types.GPUDeviceDescriptor]. Fields pass through to the underlying\n * `adapter.requestDevice(opts)` call.\n */\nexport type RequestDeviceOptions = ExplicitUndefined<\n Pick<GPUDeviceDescriptor, 'label' | 'requiredFeatures' | 'requiredLimits'>\n>;\n\n/**\n * RhiInstance — entry point for adapter discovery (K-6 strict two-step path).\n *\n * Spec anchor: W3C WebGPU §3.1 `GPU` interface / [@webgpu/types.GPU]; wgpu\n * `Instance::request_adapter` (research §6.1) + Dawn\n * `InstanceBase::APIRequestAdapter` (§6.2).\n *\n * Replaces the legacy top-level `rhi.requestDevice(opts)` factory (break-\n * point #2). AI users follow the spec idiom:\n * const a = (await rhi.requestAdapter()).unwrap();\n * const d = (await a.requestDevice(opts)).unwrap();\n *\n * @example\n * const adapterResult = await rhi.requestAdapter();\n * if (!adapterResult.ok) {\n * // route via switch (adapterResult.error.code)\n * }\n */\nexport interface RhiInstance {\n /**\n * Request a GPU adapter.\n *\n * Spec anchor: W3C WebGPU §3.1 `GPU.requestAdapter` /\n * [@webgpu/types.GPU.requestAdapter].\n *\n * @param opts — W3C-spec request adapter options (powerPreference,\n * forceFallbackAdapter).\n * @param compatibleSurface — non-W3C extension required by the wgpu GL\n * backend for adapter enumeration. Provided as a positional escape hatch\n * so the first parameter stays spec-aligned (plan-strategy D-5).\n * rhi-webgpu accepts and ignores this parameter (dual-impl symmetry);\n * rhi-wgpu routes it to `requestAdapterWithCanvas`.\n *\n * Failure paths (research §F-5):\n * - adapter null -> `Result.err({ code: 'adapter-unavailable' })`.\n */\n requestAdapter(\n opts?: RequestAdapterOptions | undefined,\n compatibleSurface?: HTMLCanvasElement | OffscreenCanvas | undefined,\n ): Promise<Result<RhiAdapter, RhiError>>;\n}\n\n/**\n * RhiAdapter — capability-probe layer + device-creation entry (K-5 + K-6).\n *\n * Spec anchor: W3C WebGPU §3.2 `GPUAdapter` interface /\n * [@webgpu/types.GPUAdapter]; wgpu `Adapter::request_device` (research §6.1)\n * + Dawn `AdapterBase::APIRequestDevice` (§6.2).\n *\n * The `features` / `limits` fields let AI users **pre-screen** device\n * capabilities before calling `requestDevice(opts)` (charter proposition 4\n * forward-reachable: features mismatch becomes visible before spec\n * validation surfaces it).\n *\n * @example\n * if (!adapter.features.has('timestamp-query')) {\n * // skip timestamp-related code paths\n * }\n * const deviceResult = await adapter.requestDevice({\n * requiredFeatures: ['timestamp-query'],\n * });\n */\nexport interface RhiAdapter {\n /**\n * Read-only feature-name set (K-5).\n *\n * Aligned with `GPUAdapter.features` projection of `GPUSupportedFeatures`\n * (a read-only Set) **and** with `RhiDevice.features` (Round 3 fix-up\n * F-P1-2: cross-tier shape uniformity — AI users use `.has(name)` on\n * both abstraction layers, no projection drift).\n *\n * F-1 ai-user-review: mutation of set entries (`features.add('x')` /\n * deletion / clear) is rejected at compile time via `ReadonlySet`;\n * charter proposition 4 explicit failure + proposition 5 consistent\n * abstraction.\n */\n readonly features: ReadonlySet<GPUFeatureName>;\n /**\n * Read-only numeric-limits map (K-5).\n *\n * Aligned with `GPUAdapter.limits` projection of `GPUSupportedLimits`. The\n * forgeax form flattens to a `Readonly<Record<string, number>>` so AI users\n * can do `adapter.limits.maxTextureDimension2D` lookups without holding the\n * spec object handle.\n *\n * F-1 ai-user-review: mutation of values (`limits.x = 0`) is rejected at\n * compile time.\n */\n readonly limits: Readonly<Record<string, number>>;\n /**\n * Request a GPU device.\n *\n * Spec anchor: W3C WebGPU §3.2 `GPUAdapter.requestDevice` /\n * [@webgpu/types.GPUAdapter.requestDevice].\n *\n * Returns `Result<RhiDevice, RhiError>` (K-6: NOT a `(Device, Queue)` tuple\n * — queue is exposed via `RhiDevice.queue`).\n *\n * Failure paths (research §F-5):\n * - feature not enabled -> `Result.err({ code: 'feature-not-enabled' })`.\n * - limit exceeded -> `Result.err({ code: 'limit-exceeded' })`.\n */\n requestDevice(opts?: RequestDeviceOptions | undefined): Promise<Result<RhiDevice, RhiError>>;\n}\n\n// ============================================================================\n// RhiSurface + RhiCanvasContext (M3 / K-4)\n// ============================================================================\n//\n// Spec anchor: W3C WebGPU §3.3 GPUCanvasContext / §3.3 GPUCanvasConfiguration.\n// 4 methods + 7 fields per research §3.1 + §3.2; 4-method algorithms per\n// research §3.3. K-4 decision: getCurrentTexture returns Result<Texture,\n// RhiError> (NOT TextureView) — spec literal alignment + AI users go two-step:\n// const tex = canvasContext.getCurrentTexture().unwrap();\n// const view = device.createTextureView(tex, {}).unwrap();\n\n/**\n * Canvas configuration descriptor (Pick<GPUCanvasConfiguration, 7 fields>).\n *\n * Spec anchor: W3C WebGPU §3.3 `GPUCanvasConfiguration` /\n * [@webgpu/types.GPUCanvasConfiguration].\n *\n * 7 fields (research §3.2):\n * - `device` (required): the GPUDevice for the configured context.\n * - `format` (required): one of `{'bgra8unorm', 'rgba8unorm', 'rgba16float'}`\n * (the spec normative supported context formats).\n * - `usage` (default `0x10` = RENDER_ATTACHMENT): bitmask of GPUTextureUsage\n * for the swap-chain textures.\n * - `viewFormats` (default `[]`): list of formats createView may yield;\n * **the spec sRGB-render-target idiom** uses `format='bgra8unorm'` +\n * `viewFormats=['bgra8unorm-srgb']` + `device.createTextureView` (research\n * §3.2 normative).\n * - `colorSpace` (default `'srgb'`): predefined color space for the canvas.\n * - `toneMapping` (default `{}` ≅ `{ mode: 'standard' }`): HDR tone-mapping\n * descriptor; the spec NOTE in research §3.2 says implementations\n * without tone-mapping support **omit** this from `getConfiguration()`.\n * - `alphaMode` (default `'opaque'`): canvas compositing mode.\n *\n * Field NAMES align byte-for-byte with the spec; the forgeax `?: T |\n * undefined` shape (S-7 / hard-constraint 10) lets writers omit or pass\n * `undefined` explicitly while the shim distinguishes via `'x' in src`.\n */\nexport type CanvasConfiguration = ExplicitUndefined<\n Omit<\n Pick<\n GPUCanvasConfiguration,\n 'device' | 'format' | 'usage' | 'viewFormats' | 'colorSpace' | 'toneMapping' | 'alphaMode'\n >,\n 'device'\n >\n> & {\n /**\n * The forgeax RhiDevice the configured context binds to (D-S5 pattern: spec\n * `device: GPUDevice` is replaced by the forgeax brand so AI users pass the\n * device they got from `rhi.requestAdapter().requestDevice()`).\n */\n device: RhiDevice;\n};\n\ndeclare const RhiSurfaceBrand: unique symbol;\n/**\n * RhiSurface — opaque abstraction over a canvas surface\n * (HTMLCanvasElement / OffscreenCanvas).\n *\n * Spec couples GPUCanvasContext to a canvas (research §3.1); the forgeax\n * abstraction wraps the raw GPUCanvasContext in an opaque brand. AI users\n * obtain the `RhiCanvasContext` via\n * `rhi.acquireCanvasContext(canvas)` (returns `Result<RhiCanvasContext, RhiError>`).\n *\n * Charter proposition 5 consistent abstraction: the surface brand decouples\n * AI-user code from the DOM canvas zoo (HTMLCanvasElement / OffscreenCanvas /\n * native Window).\n */\nexport interface RhiSurface {\n readonly [RhiSurfaceBrand]: void;\n}\n\n/**\n * RhiCanvasContext — forgeax canvas-context abstraction (M3 / K-4).\n *\n * Spec anchor: W3C WebGPU §3.3 `GPUCanvasContext` /\n * [@webgpu/types.GPUCanvasContext]. 4 methods (research §3.1) match the spec\n * names; the return types differ:\n * - `configure` returns `Result<void, RhiError>` (the spec returns void; the\n * forgeax form surfaces `webgpu-runtime-error` on format-gate / device-\n * lost paths via Result, charter proposition 4 explicit failure).\n * - `unconfigure` returns void (spec literal alignment).\n * - `getConfiguration` returns `CanvasConfiguration | undefined` (the spec\n * returns `GPUCanvasConfiguration?`; forgeax uses `undefined`).\n * - `getCurrentTexture` returns `Result<Texture, RhiError>` (K-4: Texture\n * brand, NOT TextureView; AI users go two-step\n * `device.createTextureView(canvasContext.getCurrentTexture().unwrap(), {})`).\n *\n * Lifecycle (research §3.3 [[Expire the current texture]]): currentTexture\n * **must NOT be cached across frames** — every frame must call\n * `getCurrentTexture()` afresh.\n */\n/** Configure-time proof that a storage surface can present through its endpoint. */\nexport interface RhiCanvasSurfaceDescriptorFacts {\n readonly format: string;\n readonly usage: number;\n readonly width: number;\n readonly height: number;\n readonly alphaMode: string;\n readonly presentMode: string;\n}\n\nexport interface RhiCanvasSurfacePresentationProof {\n readonly descriptor: boolean;\n readonly acquisition: boolean;\n readonly validation: boolean;\n /** Stable identity for the concrete surface that produced this proof. */\n readonly surfaceIdentity?: string;\n /** Descriptor requested by the owner at configure time. */\n readonly requested?: RhiCanvasSurfaceDescriptorFacts;\n /** Descriptor accepted and validated by the concrete surface. */\n readonly validated?: RhiCanvasSurfaceDescriptorFacts;\n}\n\nexport interface RhiCanvasContext {\n /** Backend-produced configure-time presentation proof; absent means fail closed. */\n readonly presentationProof?: RhiCanvasSurfacePresentationProof;\n /**\n * Configure the canvas context with a forgeax CanvasConfiguration.\n *\n * Returns `Result<void, RhiError>` (charter proposition 4 explicit failure).\n *\n * Failure paths (research §3.3):\n * - `format` not in supported context formats (`{'bgra8unorm',\n * 'rgba8unorm', 'rgba16float'}`) -> `'webgpu-runtime-error'` with\n * `.expected = 'one of bgra8unorm/rgba8unorm/rgba16float'`.\n * - `device` invalid | lost -> `'rhi-not-available'`.\n *\n * @example\n * const out = canvasContext.configure({\n * device,\n * format: 'bgra8unorm',\n * usage: GPUTextureUsage.RENDER_ATTACHMENT,\n * viewFormats: ['rgba8unorm-srgb'],\n * });\n * if (!out.ok) {\n * // route via switch (out.error.code)\n * }\n */\n configure(desc: CanvasConfiguration): Result<void, RhiError>;\n /**\n * Unconfigure the canvas context (spec literal void return).\n *\n * Idempotent (already-unconfigured contexts continue to be unconfigured;\n * Operation is silent).\n */\n unconfigure(): void;\n /**\n * Return the current canvas configuration, or `undefined` if the context is\n * unconfigured.\n *\n * Feature-detection entry (research §3.2 spec NOTE): when an implementation\n * does not support a configuration field (e.g. tone-mapping), the field is\n * **omitted** from the returned record (NOT defaulted) so AI users can use\n * `'toneMapping' in conf` to detect support.\n */\n getConfiguration(): CanvasConfiguration | undefined;\n /**\n * Get the current swap-chain texture (K-4: returns Texture brand, NOT\n * TextureView).\n *\n * Spec anchor: W3C WebGPU §3.3 `GPUCanvasContext.getCurrentTexture` /\n * [@webgpu/types.GPUCanvasContext.getCurrentTexture].\n *\n * Failure paths (research §3.3):\n * - context unconfigured -> `'webgpu-runtime-error'` (spec\n * `InvalidStateError` mapping).\n *\n * AI users typically pair this with `device.createTextureView` to get the\n * render-pass attachment view (charter proposition 5 consistent abstraction):\n * const tex = canvasContext.getCurrentTexture().unwrap();\n * const view = device.createTextureView(tex, {}).unwrap();\n * pass.beginRenderPass({ colorAttachments: [{ view, ... }] });\n *\n * Lifecycle (research §3.3 [[Expire the current texture]]): each frame\n * **must call this fresh**; the forgeax shim does NOT cache across frames.\n */\n getCurrentTexture(): Result<Texture, RhiError>;\n}\n\n/** GPU device - sole entry point for resource creation + capability probing. */\nexport interface RhiDevice {\n /** Hardware-probe layer (charter proposition 5). */\n readonly caps: RhiCaps;\n /** Enabled-features layer. */\n readonly features: RhiFeatures;\n /** Numeric-limits layer. */\n readonly limits: RhiLimits;\n\n /** Probe the complete r32float sampled/storage/readback profile once per device generation. */\n probeTextureFormatCapability(): Promise<Result<RhiTextureFormatCapabilityReceipt, RhiError>>;\n\n /** Create GPU buffer. */\n createBuffer(desc: BufferDescriptor): Result<Buffer, RhiError>;\n /** Create GPU texture. */\n createTexture(desc: TextureDescriptor): Result<Texture, RhiError>;\n /**\n * Destroy a GPU buffer obtained from `createBuffer`.\n *\n * Spec anchor: W3C WebGPU §gpubuffer-destroy /\n * [@webgpu/types.GPUBuffer.destroy]; wgpu wasm\n * `RhiWgpuBuffer::destroy` (research §F-1; both surfaces are idempotent\n * void at the underlying GPU).\n *\n * The forgeax form prefers fail-fast over the spec idempotent void:\n * the shim layer (rhi-webgpu / rhi-wgpu) tracks per-handle\n * `destroyed: boolean` and surfaces a second destroy as\n * `Result.err({ code: 'destroy-after-destroy' })` rather than silently\n * succeeding. Double destroy is almost always a lifecycle bug — caching\n * a stale handle, a forgotten registry slot, a race between dispose\n * paths — and surfacing it early at the call site is more useful than\n * swallowing it (plan-strategy D-7 + architecture-principles §5 Fail\n * Fast). Charter proposition 4 explicit failure.\n *\n * Failure paths:\n * - second destroy on the same handle ->\n * `Result.err({ code: 'destroy-after-destroy' })`.\n *\n * @example\n * const r = device.destroyBuffer(buf);\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\n destroyBuffer(buf: Buffer): Result<void, RhiError>;\n /**\n * Destroy a GPU query set obtained from `createQuerySet`.\n *\n * Query sets are device-owned resources even though the WebGPU surface does\n * not expose them through the Buffer/Texture families. The explicit RHI\n * seam lets Render release timestamp query sets exactly once after queue\n * completion, including failure and disposal paths.\n */\n destroyQuerySet(querySet: QuerySet): Result<void, RhiError>;\n /**\n * Destroy a GPU texture obtained from `createTexture`.\n *\n * Spec anchor: W3C WebGPU §gputexture-destroy /\n * [@webgpu/types.GPUTexture.destroy]; wgpu wasm idempotent void at the\n * underlying GPU.\n *\n * Same fail-fast contract as `destroyBuffer`: the shim layer tracks\n * per-handle `destroyed: boolean` and surfaces a second destroy as\n * `Result.err({ code: 'destroy-after-destroy' })`.\n *\n * @example\n * const r = device.destroyTexture(tex);\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\n destroyTexture(tex: Texture): Result<void, RhiError>;\n /**\n * Create a GPU texture view of an existing texture.\n *\n * Spec anchor: W3C WebGPU §texture-view-creation /\n * [@webgpu/types.GPUTexture.createView].\n *\n * Introduced in feat-20260510-rhi-resource-creation (M1). Cross-resource\n * validation is performed fast-path by the shim before forwarding to raw\n * GPUTexture.createView (research §1.1):\n * - `format` must be in `source.format ∪ source.viewFormats`; violation\n * returns Result.err({ code: 'webgpu-runtime-error' }).\n * - `usage` must be a subset of source.usage (bitmask); violation returns\n * the same code.\n *\n * @example\n * const r = device.createTextureView(tex, { format: 'rgba8unorm', dimension: '2d' });\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\n createTextureView(texture: Texture, desc: TextureViewDescriptor): Result<TextureView, RhiError>;\n /** Create sampler (spec defaults are applied by the shim). */\n createSampler(desc?: SamplerDescriptor | undefined): Result<Sampler, RhiError>;\n /** Create bind group layout. */\n createBindGroupLayout(desc: BindGroupLayoutDescriptor): Result<BindGroupLayout, RhiError>;\n /**\n * Create a bind group (instantiated layout + resource bindings).\n *\n * Spec anchor: W3C WebGPU 10 Resource binding /\n * [@webgpu/types.GPUDevice.createBindGroup].\n *\n * Introduced in feat-20260509-ecs-render-bridge-mvp (D-S1) — additive\n * extension; reuses the existing 17-member `RhiErrorCode` union\n * ('feature-not-enabled' / 'limit-exceeded' / 'webgpu-runtime-error').\n * No new error code is introduced (AGENTS.md evolution contract no-op,\n * breakage list stays empty).\n *\n * @example\n * const out = device.createBindGroup({ label: 'view-bg', layout: bgl, entries: [...] });\n * if (!out.ok) {\n * // route via switch (out.error.code)\n * }\n */\n createBindGroup(desc: BindGroupDescriptor): Result<BindGroup, RhiError>;\n /**\n * Create a pipeline layout (aggregates BindGroupLayouts).\n *\n * Spec anchor: W3C WebGPU 10.3 Pipeline layout /\n * [@webgpu/types.GPUDevice.createPipelineLayout].\n *\n * Introduced in feat-20260509-ecs-render-bridge-mvp (D-S1) — additive\n * extension; reuses the existing 17-member `RhiErrorCode` union.\n *\n * @example\n * const out = device.createPipelineLayout({ label: 'pbr-pl', bindGroupLayouts: [viewBgl, materialBgl, meshArrayBgl] });\n * if (!out.ok) {\n * // route via switch (out.error.code)\n * }\n */\n createPipelineLayout(desc: PipelineLayoutDescriptor): Result<PipelineLayout, RhiError>;\n /** Create render pipeline (synchronous path). */\n createRenderPipeline(desc: RenderPipelineDescriptor): Result<RenderPipeline, RhiError>;\n /**\n * Create a compute pipeline (synchronous path).\n *\n * Spec anchor: W3C WebGPU §compute-pipeline-creation /\n * [@webgpu/types.GPUDevice.createComputePipeline].\n *\n * Introduced in feat-20260510-rhi-resource-creation (M1). Capability gate\n * (research §1.2 + plan-strategy §4.3 boundary case row 1):\n * `caps.compute === false` -> Result.err({ code: 'feature-not-enabled' }).\n * The MVP WebGPU path always has caps.compute=true; the gate exists for\n * potential future backends that lack compute.\n *\n * @example\n * const r = device.createComputePipeline({\n * layout: 'auto',\n * compute: { module, entryPoint: 'cs_main' },\n * });\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\n createComputePipeline(desc: ComputePipelineDescriptor): Result<ComputePipeline, RhiError>;\n /**\n * Create a query set (occlusion or timestamp).\n *\n * Spec anchor: W3C WebGPU §queries / [@webgpu/types.GPUDevice.createQuerySet].\n *\n * Introduced in feat-20260510-rhi-resource-creation (M1). Hard constraints\n * (research §1.3):\n * - `count <= 4096` (spec normative); violation -> 'limit-exceeded'.\n * - `type === 'timestamp'` requires caps.timestampQuery; otherwise ->\n * 'feature-not-enabled'.\n * - `count = 0` is legal.\n *\n * @example\n * const r = device.createQuerySet({ type: 'occlusion', count: 4 });\n * if (!r.ok) {\n * // route via switch (r.error.code)\n * }\n */\n createQuerySet(desc: QuerySetDescriptor): Result<QuerySet, RhiError>;\n\n /**\n * Create a command encoder.\n *\n * Spec anchor: W3C WebGPU 21.2 createCommandEncoder /\n * [@webgpu/types.GPUDevice.createCommandEncoder].\n *\n * @example\n * const encResult = device.createCommandEncoder({ label: 'frame' });\n * if (!encResult.ok) {\n * // route via switch (encResult.error.code)\n * } else {\n * const enc = encResult.value;\n * // ... record commands ...\n * }\n */\n createCommandEncoder(\n desc?: CommandEncoderDescriptor | undefined,\n ): Result<RhiCommandEncoder, RhiError>;\n\n // fix-f3: synchronous createShaderModule placeholder removed - the\n // shader-compile-failed error path must go through the top-level async\n // factory `createShaderModule(device, desc)` exported from\n // `@forgeax/engine-rhi-webgpu`. A synchronous placeholder would render the\n // 'shader-compile-failed' branch unreachable in\n // `switch (err.code)` exhaustive consumers (charter proposition 5\n // consistent abstraction). See plan-strategy 7.3 error-info table\n // shader row + verify Round 1 finding F3.\n\n /** Queue for command submission. */\n readonly queue: RhiQueue;\n\n /**\n * Spec-style device.lost Promise (research F-4 / R2 mitigation). The engine\n * layer performs single-source subscription + dual-form fan-out without a\n * second cache. `reason` is a binary union ('destroyed' / 'unknown').\n */\n // forgeax-async-whitelist: dom-native — spec `GPUDevice.lost` Promise\n // passthrough; resolves (never rejects) per spec normative when the\n // underlying device transitions to the lost state.\n readonly lost: Promise<{ readonly reason: 'destroyed' | 'unknown'; readonly message: string }>;\n}\n\n/** GPU command queue - writeBuffer / submit + M5 writeTexture /\n * copyExternalImageToTexture / onSubmittedWorkDone. */\nexport interface RhiQueue {\n /** Direct write to a buffer (POD + ArrayBufferView, math-free). */\n writeBuffer(\n buffer: Buffer,\n bufferOffset: number,\n data: ArrayBufferView | ArrayBuffer,\n dataOffset?: number | undefined,\n size?: number | undefined,\n ): Result<void, RhiError>;\n /**\n * Direct write to a texture region.\n *\n * Spec anchor: W3C WebGPU §queue-writetexture /\n * [@webgpu/types.GPUQueue.writeTexture]. Field NAMES align byte-for-byte\n * with the spec; the forgeax form returns Result<void, RhiError> instead\n * of void so AI users can route alignment failures (research §1.3 +\n * plan-strategy 2 K-2: bytesPerRow % 256 != 0 maps to\n * 'queue-write-buffer-out-of-bounds').\n *\n * @example\n * const out = device.queue.writeTexture(\n * { texture: tex, mipLevel: 0, origin: [0, 0, 0] },\n * pixels,\n * { offset: 0, bytesPerRow: 256, rowsPerImage: H },\n * { width: W, height: H, depthOrArrayLayers: 1 },\n * );\n * if (!out.ok) {\n * // route via switch (out.error.code)\n * }\n */\n writeTexture(\n destination: TextureWriteDestination,\n data: ArrayBufferView | ArrayBuffer,\n dataLayout: Pick<GPUTexelCopyBufferLayout, 'offset' | 'bytesPerRow' | 'rowsPerImage'>,\n size: GPUExtent3DStrict,\n ): Result<void, RhiError>;\n /**\n * Copy an external image source (ImageBitmap / canvas / video) into a\n * GPUTexture region.\n *\n * Spec anchor: W3C WebGPU §queue-copyexternalimagetotexture /\n * [@webgpu/types.GPUQueue.copyExternalImageToTexture]. The forgeax form\n * returns Result<void, RhiError>.\n *\n * dawn-node note: dawn-node lacks HTMLCanvasElement / VideoFrame /\n * HTMLImageElement; only the ImageBitmap subset reachable from\n * createImageBitmap is exercised in dawn tests (research §7.1).\n */\n copyExternalImageToTexture(\n source: Pick<GPUCopyExternalImageSourceInfo, 'source' | 'origin' | 'flipY'>,\n destination: ExternalImageTextureDestination,\n copySize: GPUExtent3DStrict,\n ): Result<void, RhiError>;\n /** Submit command buffers (single-use). */\n submit(commandBuffers: readonly CommandBuffer[]): Result<void, RhiError>;\n /**\n * Resolve when all currently-enqueued operations have completed.\n *\n * Spec anchor: W3C WebGPU §queue-onsubmittedworkdone /\n * [@webgpu/types.GPUQueue.onSubmittedWorkDone]. Returns\n * `Promise<undefined>` per spec normative (research §5.1: no reject path;\n * device-lost flows through `RhiDevice.lost` instead). Ordering\n * constraints (research §5.2):\n * - constraint #1 (FIFO): if p1 = q.onSubmittedWorkDone() is called\n * before p2 = q.onSubmittedWorkDone(), p1 must settle before p2.\n * - constraint #2 (mapAsync vs onSubmittedWorkDone): if p1 =\n * b.mapAsync() is called before p2 = q.onSubmittedWorkDone(), p1 must\n * settle before p2.\n *\n * @example Pattern A read-back idiom:\n * const cb = enc.finish().value;\n * queue.submit([cb]);\n * await queue.onSubmittedWorkDone();\n * await readBuf.mapAsync(GPUMapMode.READ);\n * const range = readBuf.getMappedRange().value;\n */\n // forgeax-async-whitelist: dom-native — spec `GPUQueue.onSubmittedWorkDone`\n // never rejects (research §5.1 normative); failure surfaces via\n // `RhiDevice.lost` instead.\n onSubmittedWorkDone(): Promise<undefined>;\n}\n\n/** GPU command encoder - records render / compute passes + resource copies.\n *\n * Method NAMES align byte-for-byte with `@webgpu/types.GPUCommandEncoder` +\n * `GPUDebugCommandsMixin` (research F-1 / D-S4). 12 spec methods plus one\n * ForgeaX compound operation:\n * - 9 direct: beginRenderPass / beginComputePass / copyBufferToBuffer /\n * copyBufferToTexture / copyTextureToBuffer / copyTextureToTexture /\n * clearBuffer / resolveQuerySet / finish\n * - 3 mixin (GPUDebugCommandsMixin): pushDebugGroup / popDebugGroup /\n * insertDebugMarker\n *\n * Lifecycle: after `finish()`, all subsequent recording calls return\n * Result.err({ code: 'command-encoder-finished' }) per D-S3 template 1\n * (where the method returns Result; void-returning methods throw the\n * structured error so AI users observe the failure consistently).\n */\nexport interface RhiCommandEncoder {\n /** Begin render pass (auto-closes on end()).\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.beginRenderPass].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel: spec-aligned void return throws on finished state; AI users wrap call sites with `try / catch (e: unknown) { if (e instanceof RhiError && e.code === 'command-encoder-finished') ... }`).\n * @example\n * const pass = encoder.beginRenderPass({ colorAttachments: [{ ... }] });\n */\n beginRenderPass(desc: RenderPassDescriptor): RhiRenderPassEncoder;\n /** Begin compute pass.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.beginComputePass].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel: see beginRenderPass for the recovery pattern).\n * @example\n * const pass = encoder.beginComputePass();\n */\n beginComputePass(desc?: ComputePassDescriptor | undefined): RhiComputePassEncoder;\n /**\n * Record an empty timestamp-enabled compute pass and close it immediately.\n *\n * This is a ForgeaX compound recording operation equivalent to\n * `const pass = encoder.beginComputePass(desc); pass.end()`; it is not a\n * native `GPUCommandEncoder` method and does not write a timestamp directly.\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a\n * finished encoder.\n */\n encodeEmptyComputePass(desc: ComputePassDescriptor): void;\n /** Copy a sub-region of a Buffer to another Buffer (5-arg full form).\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.copyBufferToBuffer].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern). Both overloads share the same throw contract.\n * @example\n * encoder.copyBufferToBuffer(src, 0, dst, 0, 256);\n */\n copyBufferToBuffer(\n source: Buffer,\n sourceOffset: number,\n destination: Buffer,\n destinationOffset: number,\n size: number,\n ): void;\n /** Copy a Buffer to another Buffer (3-arg shorthand).\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.copyBufferToBuffer].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern). Both overloads share the same throw contract.\n * @example\n * encoder.copyBufferToBuffer(src, dst, 256);\n */\n copyBufferToBuffer(source: Buffer, destination: Buffer, size?: number | undefined): void;\n /** Copy a Buffer sub-region to a Texture sub-region.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.copyBufferToTexture].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern).\n * @example\n * encoder.copyBufferToTexture(srcInfo, dstInfo, [w, h, 1]);\n */\n copyBufferToTexture(\n source: GPUTexelCopyBufferInfo,\n destination: GPUTexelCopyTextureInfo,\n copySize: GPUExtent3DStrict,\n ): void;\n /** Copy a Texture sub-region to a Buffer sub-region.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.copyTextureToBuffer].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern).\n * @example\n * encoder.copyTextureToBuffer(srcInfo, dstInfo, [w, h, 1]);\n */\n copyTextureToBuffer(\n source: GPUTexelCopyTextureInfo,\n destination: GPUTexelCopyBufferInfo,\n copySize: GPUExtent3DStrict,\n ): void;\n /** Opaque RHI handle form for renderer-owned readback. */\n copyTextureToBuffer(\n source: TextureCopySource,\n destination: BufferCopyDestination,\n copySize: GPUExtent3DStrict,\n ): void;\n /** Union form for decorators that transparently forward either handle form. */\n copyTextureToBuffer(\n source: GPUTexelCopyTextureInfo | TextureCopySource,\n destination: GPUTexelCopyBufferInfo | BufferCopyDestination,\n copySize: GPUExtent3DStrict,\n ): void;\n /** Copy a Texture sub-region to a Texture sub-region.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.copyTextureToTexture].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern).\n * @example\n * encoder.copyTextureToTexture(srcInfo, dstInfo, [w, h, 1]);\n */\n copyTextureToTexture(\n source: GPUTexelCopyTextureInfo,\n destination: GPUTexelCopyTextureInfo,\n copySize: GPUExtent3DStrict,\n ): void;\n /** Fill a Buffer sub-region with zeros.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.clearBuffer].\n *\n * @throws RhiError code === 'command-encoder-finished' when invoked on a finished encoder (dual-channel; see beginRenderPass JSDoc for the recovery pattern).\n * @example\n * encoder.clearBuffer(buf, 0, 256);\n */\n clearBuffer(buffer: Buffer, offset?: number | undefined, size?: number | undefined): void;\n /** Resolve query results from a QuerySet to a Buffer.\n *\n * Real implementation (M3 / w26): writes 8-byte query results in 256-byte\n * aligned strides into `destination` starting at `destinationOffset`.\n * Validates `destination.usage & GPUBufferUsage.QUERY_RESOLVE` and the\n * 256-byte alignment up front; on misuse returns\n * `Result.err({ code: 'webgpu-runtime-error', ... })` with a structured\n * .expected / .hint pair.\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.resolveQuerySet].\n *\n * @example\n * const out = encoder.resolveQuerySet(qs, 0, 4, dstBuf, 0);\n * if (!out.ok) {\n * // switch (out.error.code) { case 'webgpu-runtime-error': ... }\n * }\n */\n resolveQuerySet(\n querySet: QuerySet,\n firstQuery: number,\n queryCount: number,\n destination: Buffer,\n destinationOffset: number,\n ): Result<void, RhiError>;\n /** Push a labelled debug group (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.pushDebugGroup].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (the debug-commands mixin permits a no-op pass-through after finish() so the signal stays real instead of forging a `@throws` contract; charter proposition 4).\n * @example\n * encoder.pushDebugGroup('frame-setup');\n */\n pushDebugGroup(groupLabel: string): void;\n /** Pop the most recent debug group (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.popDebugGroup].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (see pushDebugGroup JSDoc for the dual-channel rationale).\n * @example\n * encoder.popDebugGroup();\n */\n popDebugGroup(): void;\n /** Insert a labelled debug marker (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.insertDebugMarker].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (see pushDebugGroup JSDoc for the dual-channel rationale).\n * @example\n * encoder.insertDebugMarker('post-resolve');\n */\n insertDebugMarker(markerLabel: string): void;\n /** Finish recording -> CommandBuffer. After finish() any further recording\n * call returns Result.err({ code: 'command-encoder-finished' }).\n *\n * Spec anchor: [@webgpu/types.GPUCommandEncoder.finish].\n *\n * @example\n * const cb = encoder.finish();\n * if (cb.ok) device.queue.submit([cb.value]);\n */\n finish(): Result<CommandBuffer, RhiError>;\n}\n\n/** GPU render pass encoder - records draw calls + state changes.\n *\n * Method NAMES align byte-for-byte with @webgpu/types.GPURenderPassEncoder +\n * GPURenderCommandsMixin + GPUBindingCommandsMixin + GPUDebugCommandsMixin\n * (research F-2 / D-S4): 17 spec stable + 1 setBindGroup overload + 1\n * remaining capability-gated placeholder (`executeBundles` returns\n * Result.err({ code: 'rhi-not-available', hint: 'see\n * feat-future-rhi-render-bundle' })). The 2 occlusion-query methods\n * (`beginOcclusionQuery` / `endOcclusionQuery`) shipped real implementations\n * in M3 (w23) backed by `RenderPassDescriptor.occlusionQuerySet`.\n *\n * `setImmediates` (PROPOSED) is intentionally NOT exposed (charter\n * proposition 4: untested features hide behind caps, not surfaces).\n *\n * Lifecycle: encoder.finish() while a pass is unfinished returns\n * Result.err({ code: 'render-pass-not-ended' }) per D-S3 template 2.\n */\nexport interface RhiRenderPassEncoder {\n // ===== Existing 7 methods (Round 1 baseline) =====\n /** Set the bound render pipeline.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.setPipeline].\n *\n * @example pass.setPipeline(pipeline);\n */\n setPipeline(pipeline: RenderPipeline): void;\n /** Set a vertex buffer.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.setVertexBuffer].\n *\n * @example pass.setVertexBuffer(0, vbo);\n */\n setVertexBuffer(\n slot: number,\n buffer: Buffer,\n offset?: number | undefined,\n size?: number | undefined,\n ): void;\n /** Set the index buffer.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.setIndexBuffer].\n *\n * @example pass.setIndexBuffer(ibo, 'uint32');\n */\n setIndexBuffer(\n buffer: Buffer,\n format: 'uint16' | 'uint32',\n offset?: number | undefined,\n size?: number | undefined,\n ): void;\n /** Set a bind group with optional dynamic offsets array (overload (a)).\n *\n * Spec anchor: [@webgpu/types.GPUBindingCommandsMixin.setBindGroup].\n *\n * @example pass.setBindGroup(0, bg, [0, 256]);\n */\n setBindGroup(\n index: number,\n bindGroup: BindGroup,\n dynamicOffsets?: readonly number[] | undefined,\n ): void;\n /** Set a bind group with a Uint32Array slice for dynamic offsets (overload (b)).\n *\n * Spec anchor: [@webgpu/types.GPUBindingCommandsMixin.setBindGroup].\n *\n * @example\n * pass.setBindGroup(0, bg, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength);\n */\n setBindGroup(\n index: number,\n bindGroup: BindGroup,\n dynamicOffsetsData: Uint32Array,\n dynamicOffsetsDataStart: number,\n dynamicOffsetsDataLength: number,\n ): void;\n /** Issue a draw.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.draw].\n *\n * @example pass.draw(3);\n */\n draw(\n vertexCount: number,\n instanceCount?: number | undefined,\n firstVertex?: number | undefined,\n firstInstance?: number | undefined,\n ): void;\n /** Issue an indexed draw.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.drawIndexed].\n *\n * @example pass.drawIndexed(36);\n */\n drawIndexed(\n indexCount: number,\n instanceCount?: number | undefined,\n firstIndex?: number | undefined,\n baseVertex?: number | undefined,\n firstInstance?: number | undefined,\n ): void;\n /** End the render pass.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.end].\n *\n * @example pass.end();\n */\n end(): void;\n\n // ===== 10 new spec stable methods (D-S4) =====\n /** Set the viewport.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.setViewport].\n *\n * @example pass.setViewport(0, 0, 800, 600, 0, 1);\n */\n setViewport(x: number, y: number, w: number, h: number, minDepth: number, maxDepth: number): void;\n /** Set the scissor rect.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.setScissorRect].\n *\n * @example pass.setScissorRect(0, 0, 800, 600);\n */\n setScissorRect(x: number, y: number, w: number, h: number): void;\n /** Set the blend constant color.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.setBlendConstant].\n *\n * @example pass.setBlendConstant({ r: 1, g: 0, b: 0, a: 1 });\n */\n setBlendConstant(color: GPUColor): void;\n /** Set the stencil reference value.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.setStencilReference].\n *\n * @example pass.setStencilReference(0xff);\n */\n setStencilReference(reference: number): void;\n /** Issue an indirect draw.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.drawIndirect].\n *\n * @example pass.drawIndirect(indirectBuf, 0);\n */\n drawIndirect(indirectBuffer: Buffer, indirectOffset: number): void;\n /** Issue an indexed indirect draw.\n *\n * Spec anchor: [@webgpu/types.GPURenderCommandsMixin.drawIndexedIndirect].\n *\n * @example pass.drawIndexedIndirect(indirectBuf, 0);\n */\n drawIndexedIndirect(indirectBuffer: Buffer, indirectOffset: number): void;\n /** Push a labelled debug group (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.pushDebugGroup].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (the debug-commands mixin permits a no-op pass-through after finish() so the signal stays real instead of forging a `@throws` contract; charter proposition 4).\n * @example pass.pushDebugGroup('lighting');\n */\n pushDebugGroup(groupLabel: string): void;\n /** Pop the most recent debug group (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.popDebugGroup].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (see pushDebugGroup JSDoc for the dual-channel rationale).\n * @example pass.popDebugGroup();\n */\n popDebugGroup(): void;\n /** Insert a labelled debug marker (GPUDebugCommandsMixin).\n *\n * Spec anchor: [@webgpu/types.GPUDebugCommandsMixin.insertDebugMarker].\n *\n * @note silent delegate to raw GPU encoder on finished encoder; matches W3C spec lenience (see pushDebugGroup JSDoc for the dual-channel rationale).\n * @example pass.insertDebugMarker('post-shadow');\n */\n insertDebugMarker(markerLabel: string): void;\n\n // ===== 1 remaining placeholder + 2 real impls (M3 / w23 + w26) =====\n /** Execute render bundles. Capability-gated placeholder per D-S4: returns\n * Result.err({ code: 'rhi-not-available', hint: 'see feat-future-rhi-render-bundle' })\n * until that closure lands RenderBundle creation.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.executeBundles].\n *\n * @example\n * const out = pass.executeBundles([bundle]);\n * if (!out.ok) { ... route via switch (out.error.code) ... }\n */\n executeBundles(bundles: Iterable<unknown>): Result<void, RhiError>;\n /** Begin an occlusion query. Real implementation (M3 / w23): pairs with\n * `endOcclusionQuery()` against the `RenderPassDescriptor.occlusionQuerySet`\n * and validates the spec [[occlusion_query_active]] state machine\n * (queries cannot nest; missing occlusionQuerySet returns\n * Result.err({ code: 'webgpu-runtime-error' }) with structured\n * .expected / .hint fields).\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.beginOcclusionQuery].\n *\n * @example\n * const out = pass.beginOcclusionQuery(0);\n * if (!out.ok) { ... route via switch (out.error.code) ... }\n */\n beginOcclusionQuery(queryIndex: number): Result<void, RhiError>;\n /** End an occlusion query. Real implementation (M3 / w23): finalizes the\n * matching `beginOcclusionQuery(idx)` slot; emits\n * Result.err({ code: 'render-pass-not-ended', ... }) if no active begin\n * is pending.\n *\n * Spec anchor: [@webgpu/types.GPURenderPassEncoder.endOcclusionQuery].\n *\n * @example\n * const out = pass.endOcclusionQuery();\n * if (!out.ok) { ... route via switch (out.error.code) ... }\n */\n endOcclusionQuery(): Result<void, RhiError>;\n}\n\n/** GPU compute pass encoder - records dispatch calls. */\nexport interface RhiComputePassEncoder {\n setPipeline(pipeline: ComputePipeline): void;\n setBindGroup(\n index: number,\n bindGroup: BindGroup,\n dynamicOffsets?: readonly number[] | undefined,\n ): void;\n dispatchWorkgroups(x: number, y?: number | undefined, z?: number | undefined): void;\n /** Dispatch dimensions read from three consecutive u32 values in an indirect buffer. */\n dispatchWorkgroupsIndirect(indirectBuffer: Buffer, indirectOffset: number): void;\n end(): void;\n}\n\n/** GPU render pipeline operations - returned by RhiDevice.createRenderPipeline. */\nexport interface RhiRenderPipelineOps {\n /** Get bind group layout (used for dynamic bind-group creation). */\n getBindGroupLayout(index: number): BindGroupLayout;\n}\n\n/** GPU compute pipeline operations. */\nexport interface RhiComputePipelineOps {\n /** Get bind group layout. */\n getBindGroupLayout(index: number): BindGroupLayout;\n}\n\n// ============================================================================\n// re-export errors (charter proposition 1: single entry shows the full surface)\n// ============================================================================\n\nexport {\n type CreateUnavailableR32FloatReceiptOptions,\n createUnavailableR32FloatReceipt,\n R32FLOAT_MIP_SAMPLED_STORAGE_PROFILE,\n R32FLOAT_PROBE_STAGES,\n type RhiTextureFormatCapabilityReceipt,\n type RhiTextureFormatProbeEvidence,\n type RhiTextureFormatProbeStage,\n type RhiTextureFormatProbeStageReceipt,\n type RhiTextureFormatProbeVerdict,\n type RhiTextureFormatReadback,\n validateR32FloatReceipt,\n} from './capability/texture-format';\nexport type {\n DrawOwnerSplit,\n LimitExceededDetail,\n Result,\n ResultErr,\n ResultOk,\n RhiAssetNotRegisteredDetail,\n RhiErrorCode,\n RhiErrorDetail,\n RhiOwnerOutOfRangeDetail,\n RhiShaderCompileDetail,\n RhiWebgpuRuntimeCause,\n RhiWebgpuRuntimeDetail,\n} from './errors.js';\nexport { err, ok, RhiError, validateDrawArgs } from './errors.js';\n\n// re-export common descriptor-related aliases for single-entry consumption.\nexport type { AddressMode, CompareFunction, FilterMode, TextureFormat };\n\n// ============================================================================\n// Descriptor builder helpers (feat-20260612-point-light-shadows-urp-hdrp M0)\n// ============================================================================\n//\n// Pure functions that assemble descriptor objects for cube_array depth\n// textures, comparison samplers, and cube-face texture views. These are\n// zero-side-effect descriptor factories — the caller passes the returned\n// descriptor to `device.createTexture(desc)` etc. Separating descriptor\n// assembly from GPU calls keeps tests concise and prevents copy-paste of\n// dimension/format/usage boilerplate across dawn + browser fixtures.\n\n/**\n * Build a TextureDescriptor for a cube-array depth texture suitable for\n * point-light shadow atlas (texture_depth_cube_array).\n *\n * Usage: `device.createTexture(cubeArrayDepthDescriptor(512, 4))`\n *\n * @param faceSize - width and height of each cube face in pixels (default 512)\n * @param layers - number of cube layers (= max shadow-casting point lights, default 4)\n * @param usage - texture usage flags (default RENDER_ATTACHMENT | TEXTURE_BINDING)\n */\nexport function cubeArrayDepthDescriptor(\n faceSize: number = 512,\n layers: number = 4,\n usage: number = GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,\n): TextureDescriptor {\n return {\n size: { width: faceSize, height: faceSize, depthOrArrayLayers: 6 * layers },\n format: 'depth32float',\n dimension: '2d',\n usage,\n };\n}\n\n/**\n * Build a SamplerDescriptor for a depth-comparison sampler used with\n * texture_depth_2d or texture_depth_cube_array.\n *\n * The returned descriptor uses clamp-to-edge addressing, linear filtering\n * (required for comparison sampling on some backends), and `compare: 'less'`.\n *\n * Usage: `device.createSampler(comparisonSamplerDescriptor())`\n */\nexport function comparisonSamplerDescriptor(): SamplerDescriptor {\n return {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n addressModeW: 'clamp-to-edge',\n magFilter: 'linear',\n minFilter: 'linear',\n compare: 'less',\n };\n}\n\n/**\n * Build a TextureViewDescriptor to view a single cube layer + face as a 2D\n * depth attachment during shadow-caster rendering.\n *\n * Each shadow-caster pass renders to one face of one cube layer. This helper\n * produces the view descriptor that selects `baseArrayLayer = layerIndex * 6 + faceIndex`\n * with `arrayLayerCount = 1` and `dimension = '2d'`, which satisfies WebGPU's\n * requirement that render pass attachments are 2D views (cube views cannot be\n * bound as render targets).\n *\n * Usage:\n * ```\n * const viewDesc = cubeArrayDepthFaceView(lightIndex, faceIndex);\n * const view = device.createTextureView(atlas, viewDesc).unwrap();\n * ```\n *\n * @param layerIndex - 0-based shadow-casting light index (0..3)\n * @param faceIndex - 0-based cube face index (0..5, +X/-X/+Y/-Y/+Z/-Z per §5.3)\n */\nexport function cubeArrayDepthFaceView(\n layerIndex: number,\n faceIndex: number,\n): TextureViewDescriptor {\n return {\n format: 'depth32float',\n dimension: '2d',\n aspect: 'depth-only',\n baseArrayLayer: layerIndex * 6 + faceIndex,\n arrayLayerCount: 1,\n baseMipLevel: 0,\n mipLevelCount: 1,\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeax/engine-rhi",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -26,7 +26,7 @@
26
26
  "LICENSE"
27
27
  ],
28
28
  "dependencies": {
29
- "@forgeax/engine-types": "0.1.28",
29
+ "@forgeax/engine-types": "0.1.30",
30
30
  "@webgpu/types": "^0.1.71"
31
31
  },
32
32
  "forgeax": {
package/src/errors.ts CHANGED
@@ -187,8 +187,22 @@ export interface RhiAssetNotRegisteredDetail {
187
187
  * message: string }` so downstream `switch (err.code)` handlers can narrow
188
188
  * the inner error (`.code` / `.expected` / `.hint`) without an `as` cast.
189
189
  */
190
+ /**
191
+ * Structured non-RHI causes carried by a `webgpu-runtime-error` wrapper.
192
+ *
193
+ * Pipeline-spec failures retain their own detail record here so callers can
194
+ * reach the backend cause without parsing `Error.message` or losing the
195
+ * producer-owned fields during initialization fan-out.
196
+ */
197
+ export interface RhiWebgpuRuntimeCause {
198
+ readonly code: string;
199
+ readonly message: string;
200
+ readonly name?: string;
201
+ readonly detail?: object;
202
+ }
203
+
190
204
  export interface RhiWebgpuRuntimeDetail {
191
- readonly error: RhiError | { code: string; message: string; name?: string };
205
+ readonly error: RhiError | RhiWebgpuRuntimeCause;
192
206
  }
193
207
 
194
208
  /**
package/src/index.ts CHANGED
@@ -57,7 +57,7 @@ import type {
57
57
  TextureFormat,
58
58
  } from '@forgeax/engine-types';
59
59
  import type { RhiTextureFormatCapabilityReceipt } from './capability/texture-format';
60
- import type { Result, RhiError } from './errors';
60
+ import type { Result, RhiError } from './errors.js';
61
61
 
62
62
  // ============================================================================
63
63
  // 14 opaque handles (MVP-1.3)
@@ -2235,9 +2235,10 @@ export type {
2235
2235
  RhiErrorDetail,
2236
2236
  RhiOwnerOutOfRangeDetail,
2237
2237
  RhiShaderCompileDetail,
2238
+ RhiWebgpuRuntimeCause,
2238
2239
  RhiWebgpuRuntimeDetail,
2239
- } from './errors';
2240
- export { err, ok, RhiError, validateDrawArgs } from './errors';
2240
+ } from './errors.js';
2241
+ export { err, ok, RhiError, validateDrawArgs } from './errors.js';
2241
2242
 
2242
2243
  // re-export common descriptor-related aliases for single-entry consumption.
2243
2244
  export type { AddressMode, CompareFunction, FilterMode, TextureFormat };