@kya-os/checkpoint-wasm-runtime 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/dist/engine-edge.d.mts +52 -16
  3. package/dist/engine-edge.d.ts +52 -16
  4. package/dist/engine-edge.js +11 -4
  5. package/dist/engine-edge.mjs +11 -4
  6. package/dist/index.d.mts +118 -1
  7. package/dist/index.d.ts +118 -1
  8. package/dist/orchestrator-edge.js +29 -13
  9. package/dist/orchestrator-edge.mjs +29 -13
  10. package/dist/orchestrator-node.js +18 -9
  11. package/dist/orchestrator-node.mjs +18 -9
  12. package/dist/orchestrator.d.mts +52 -16
  13. package/dist/orchestrator.d.ts +52 -16
  14. package/dist/orchestrator.js +29 -13
  15. package/dist/orchestrator.mjs +29 -13
  16. package/dist/policy.d.mts +148 -0
  17. package/dist/policy.d.ts +148 -0
  18. package/dist/policy.js +52 -0
  19. package/dist/policy.mjs +53 -0
  20. package/dist/reporter.d.mts +102 -0
  21. package/dist/reporter.d.ts +102 -0
  22. package/dist/reporter.js +125 -0
  23. package/dist/reporter.mjs +122 -0
  24. package/package.json +15 -5
  25. package/wasm/kya-os-engine/kya_os_engine_bg.wasm +0 -0
  26. package/wasm/kya-os-engine-bundler/kya_os_engine_bg.wasm +0 -0
  27. package/wasm/kya-os-engine-cedar/README.md +26 -0
  28. package/wasm/kya-os-engine-cedar/kya_os_engine.d.ts +77 -0
  29. package/wasm/kya-os-engine-cedar/kya_os_engine.js +636 -0
  30. package/wasm/kya-os-engine-cedar/kya_os_engine_bg.wasm +0 -0
  31. package/wasm/kya-os-engine-cedar/kya_os_engine_bg.wasm.d.ts +11 -0
  32. package/wasm/kya-os-engine-cedar/package.json +29 -0
  33. package/wasm/kya-os-engine-cedar-web/README.md +26 -0
  34. package/wasm/kya-os-engine-cedar-web/kya_os_engine.d.ts +117 -0
  35. package/wasm/kya-os-engine-cedar-web/kya_os_engine.js +694 -0
  36. package/wasm/kya-os-engine-cedar-web/kya_os_engine_bg.wasm +0 -0
  37. package/wasm/kya-os-engine-cedar-web/kya_os_engine_bg.wasm.d.ts +11 -0
  38. package/wasm/kya-os-engine-cedar-web/package.json +31 -0
  39. package/wasm/kya-os-engine-web/kya_os_engine_bg.wasm +0 -0
  40. package/wasm/agentshield_wasm.d.ts +0 -485
  41. package/wasm/agentshield_wasm.js +0 -1551
  42. package/wasm/agentshield_wasm_bg.wasm +0 -0
  43. package/wasm/agentshield_wasm_bg.wasm.d.ts +0 -97
package/CHANGELOG.md CHANGED
@@ -1,5 +1,132 @@
1
1
  # @kya-os/checkpoint-wasm-runtime
2
2
 
3
+ ## 1.6.0 — 2026-05-26 — `./reporter` subpath
4
+
5
+ **Minor release** — adds the detection reporter consumed by the
6
+ engine-backed host wrappers in `@kya-os/checkpoint-express@1.4.0` and
7
+ `@kya-os/checkpoint-nextjs@1.4.0`.
8
+
9
+ ### Added
10
+
11
+ - **`./reporter` subpath** exports `makeDetectionReporter(config)` and
12
+ `buildLogDetectionPayload(result, ctx)`. The reporter is a
13
+ fire-and-forget POST to `${baseUrl}/api/v1/log-detection` (default
14
+ `https://kya.vouched.id`) with `Authorization: Bearer ${apiKey}`.
15
+ Maps the engine's `VerifyResult` into the dashboard's
16
+ `LogDetectionRequestSchema` (detection + context + source=middleware
17
+ - enforcement + engine). Errors are swallowed unless `debug: true`.
18
+ - Runtime-agnostic (uses global `fetch` + `AbortController`); works
19
+ under Node 18+ and the Edge runtime without polyfills.
20
+
21
+ ### Why
22
+
23
+ The two engine-backed host wrappers (`withCheckpoint` in express +
24
+ nextjs) ran verification locally via WASM but had no path to ship the
25
+ `VerifyResult` back to the dashboard. Customers installed the SDK,
26
+ deployed, and the onboarding "Verify connection" check failed forever
27
+ because the `detections` table never received a row. The reporter
28
+ closes that loop without re-introducing the legacy gateway round-trip.
29
+
30
+ ## Unreleased — Phase-D.9b.1 — `initEngineEdge` switched to `--target bundler`
31
+
32
+ **Production-incident hotfix (2026-05-24).** `initEngineEdge()` previously
33
+ loaded the `wasm-pack --target web` artifact, which falls back to
34
+ `new URL('<wasm>', import.meta.url)` when no `moduleOrPath` is passed.
35
+ Cloudflare Workers don't materialise `import.meta.url` the way browsers do,
36
+ so the URL construction threw `TypeError: Invalid URL string` at engine
37
+ init — taking down the post-D.9b production gateway deploy twice in ~1h
38
+ (rolled back via `wrangler rollback` both times; captured in dev tail
39
+ run 26352287112).
40
+
41
+ Fix: switch `engine/edge.ts` to import the `--target bundler` artifact
42
+ (`@kya-os/checkpoint-wasm-runtime/wasm/kya-os-engine-bundler/kya_os_engine.js`).
43
+ The bundler target embeds the WASM inline via the host bundler's `.wasm`
44
+ import mechanism + initialises synchronously on module load. No URL
45
+ construction, no `import.meta.url` dependency, no `default()` init call.
46
+
47
+ ### Behaviour change (no API surface change)
48
+
49
+ - `moduleOrPath` parameter is now reserved/ignored. The bundler target
50
+ loads the WASM at module-load time via the host bundler, so the
51
+ caller has no opportunity to inject a pre-fetched `WebAssembly.Module`.
52
+ Parameter retained in the signature for type-compat; the value is
53
+ intentionally unused.
54
+ - The `engine-edge.smoke.test.ts` "failed init recovery" regression
55
+ test was skipped (with a TODO for re-expressing the rejection-
56
+ caching guard via a dynamic-import mock) since the bundler target
57
+ can't be made to fail on caller input. The cache-clearing logic in
58
+ `ensureReady` is unchanged + still protects the same shape for OTHER
59
+ failure modes (e.g., dynamic import errors).
60
+
61
+ ### Consumer compatibility
62
+
63
+ All known `initEngineEdge` consumers run inside a bundler that supports
64
+ `.wasm` imports — `@kya-os/gateway-worker` (wrangler), `@kya-os/checkpoint-
65
+ nextjs/middleware-edge` (webpack), `@kya-os/checkpoint-wasm-runtime/src/
66
+ engine/orchestrator/verify-request-edge` (consumed by both above). No
67
+ browser-direct consumer exists, so switching off the web target is safe.
68
+
69
+ ### Version
70
+
71
+ Workspace-internal change; npm publish deferred until the next
72
+ coordinated cut. Workspace consumers (gateway worker, checkpoint-nextjs)
73
+ pick up the fix immediately via `pnpm` symlinks.
74
+
75
+ ## Unreleased — Phase-D.9b — engine-only publish path
76
+
77
+ Internal-only change (no consumer-visible API removal). The
78
+ `rust/crates/agentshield-wasm` Rust crate was deleted as part of
79
+ Phase-D.9b after the Cloudflare gateway worker migrated onto
80
+ `./orchestrator/edge`. Build/publish plumbing follows:
81
+
82
+ - **Removed `copy-wasm` script** from `package.json`. The
83
+ `prepublishOnly` chain no longer copies the legacy
84
+ `agentshield_wasm_bg.wasm` artifact from the now-deleted crate —
85
+ publishing 1.4.4 against this tree would have failed at that step.
86
+ - **Removed `./wasm/agentshield_wasm_bg.wasm` subpath export.** The
87
+ legacy artifact is no longer shipped with the npm package.
88
+ - **Removed `wasm/agentshield_wasm*` files** from the package's `wasm/`
89
+ directory. Only the three `kya-os-engine*` artifact directories
90
+ (Node, web, bundler targets) remain.
91
+
92
+ ### Orchestrator legacy header parser — compact-JWS shape accepted
93
+
94
+ `tryBuildMcpIFromLegacyHeader` (`engine/orchestrator/build-agent-request.ts`)
95
+ now accepts **two** wire shapes in the `KYA-Delegation` header when
96
+ `legacyEnvelopeFallback: true`:
97
+
98
+ 1. JSON envelope `{"protected":"…","payload":"…","signature":"…"}`
99
+ (the pre-Envelope-1 TS bouncer form). Unchanged behavior.
100
+ 2. Compact JWS `<protected>.<payload>.<signature>` (the form
101
+ consumed by the legacy `agentshield-wasm` `verify_mcp_i_proof`
102
+ function on the gateway worker). New in this release.
103
+
104
+ Why: the gateway-worker cutover in Phase-D.9b moves MCP-I parsing
105
+ from `verify_mcp_i_proof` (compact-JWS only) onto the orchestrator
106
+ (JSON-envelope only pre-this-release). Third-party agents or custom
107
+ integrations shipping compact JWS in the header would have silently
108
+ fallen through to PlainHttp post-cutover; this extension preserves
109
+ the parse path so they keep producing `McpI` agent requests.
110
+
111
+ JSON parse runs first because a compact JWS is never valid JSON.
112
+ A JSON object that's not envelope-shaped does NOT fall through to
113
+ the compact-JWS branch — it's unambiguously a malformed envelope
114
+ attempt, returns null. Coverage: 4 new fixtures in
115
+ `build-agent-request.test.ts` (19/19 pass).
116
+
117
+ The package's runtime API surface is unchanged. The legacy
118
+ `./edge` entry (`StaticWasmLoader`, `WasmDetector`,
119
+ `src/wasm-bindgen/agentshield_wasm.{js,d.ts}`) is still present in
120
+ source — its upstream consumers (`@kya-os/checkpoint-nextjs/edge`,
121
+ `@kya-os/checkpoint/wasm/loader-factory`) are throw-stubbed at the
122
+ public API layer, so the legacy WASM glue never executes at runtime.
123
+ A future cleanup will delete those source files; this release just
124
+ unblocks deleting the underlying Rust crate.
125
+
126
+ Phase-D.9b PR adds a structural deletion gate
127
+ (`packages/checkpoint-nextjs/src/__tests__/d9b-deletion-gate.test.ts`)
128
+ that re-asserts these conditions on every test run.
129
+
3
130
  ## 1.5.1 — 2026-05-20
4
131
 
5
132
  **Tier 1 verification is now observable from the wire.** Closes the
@@ -11,11 +11,44 @@ export { DetectionDetail, McpIPayload } from '@kya-os/checkpoint-shared';
11
11
  * no sync wasm load).
12
12
  *
13
13
  * This module loads the `wasm-pack --target web` artifact via the
14
- * async `__wbg_init` default export, then exposes the same typed
15
- * `engineVerifyEdge(input, ctx) Promise<VerifyResult>` shape with
16
- * a small lazy-init wrapper. First call awaits initialisation;
17
- * subsequent calls resolve synchronously on the JS side (the
18
- * underlying wasm `verify` is sync).
14
+ * async `__wbg_init` default export. The web target's `init()`
15
+ * accepts a pre-instantiated `WebAssembly.Module` argument — the
16
+ * canonical Cloudflare-Workers + wasm-bindgen pattern.
17
+ *
18
+ * # Why the caller MUST pass `wasmModule` on Cloudflare Workers
19
+ *
20
+ * Both `--target web` (URL fetch) and `--target bundler` (auto-
21
+ * instantiated `__wbg_set_wasm(wasm)`) have failure modes on wrangler:
22
+ *
23
+ * - `--target web` falls back to `new URL('<wasm>', import.meta.url)`
24
+ * when `init()` is called with no arg. Cloudflare Workers don't
25
+ * materialise `import.meta.url` the way browsers do → throws
26
+ * `TypeError: Invalid URL string`. (Broke production 2026-05-23,
27
+ * captured via dev tail in run 26352287112.)
28
+ *
29
+ * - `--target bundler` expects the host bundler to AUTO-INSTANTIATE
30
+ * `import * as wasm from './foo.wasm'` so `wasm` is the
31
+ * `Instance.exports` object. Webpack does this. **Wrangler does
32
+ * NOT** — wrangler gives you a raw `WebAssembly.Module`, and the
33
+ * bundler-target shim's `__wbg_set_wasm(rawModule)` happily
34
+ * accepts it, then every export lookup (`wasm.__wbindgen_add_
35
+ * to_stack_pointer`, etc.) returns undefined → throws
36
+ * `TypeError: wasm.__wbindgen_add_to_stack_pointer is not a function`.
37
+ * (Broke production 2026-05-24 after switching to bundler target
38
+ * in PR #2785; captured via prod tail.)
39
+ *
40
+ * The fix is the standard Cloudflare-Workers + wasm-bindgen pattern:
41
+ * the consumer statically imports the `.wasm` file (wrangler then
42
+ * bundles it + hands the worker a `WebAssembly.Module`), then passes
43
+ * it to `init(wasmModule)`. The web target's init detects the Module
44
+ * input + calls `WebAssembly.instantiate(Module, imports)` internally
45
+ * to produce a real `Instance` whose exports populate the JS shim's
46
+ * `wasm` binding correctly.
47
+ *
48
+ * Vercel Edge / webpack consumers MAY omit the argument — webpack's
49
+ * async-WASM support handles the URL fetch correctly. But the typed
50
+ * signature here marks `wasmModule` optional for backward compat;
51
+ * Cloudflare-Workers consumers MUST pass it.
19
52
  *
20
53
  * **Why this matters for the consolidation narrative.** Phase A
21
54
  * shipped Node-only. Without an edge build, the first Vercel-edge
@@ -29,18 +62,21 @@ export { DetectionDetail, McpIPayload } from '@kya-os/checkpoint-shared';
29
62
 
30
63
  /**
31
64
  * Initialise the edge wasm module. Idempotent — subsequent calls
32
- * return the same in-flight or resolved promise. Host wrappers can
33
- * call this at startup to eagerly load the wasm and avoid first-
34
- * request latency, but it's not required: `engineVerifyEdge`
35
- * lazily initialises on first call.
36
- *
37
- * @param moduleOrPath Optional pre-fetched `WebAssembly.Module` or
38
- * a URL / Request the wasm-bindgen loader will
39
- * fetch. Defaults to the bundled artifact via
40
- * `import.meta.url`. Cloudflare Workers / Vercel
41
- * Edge typically pass a pre-bundled `Module`.
65
+ * return the same in-flight or resolved promise. Host wrappers
66
+ * should call this once at startup with the `wasmModule` they
67
+ * statically imported from the package's `./wasm/kya-os-engine-web/`
68
+ * subpath (see CLAUDE.md for the wrangler/webpack import pattern).
69
+ *
70
+ * @param wasmModule REQUIRED on Cloudflare Workers (wrangler hands
71
+ * the consumer a `WebAssembly.Module` from the
72
+ * static `.wasm` import; pass it here so the
73
+ * web-target's `init()` instantiates it). OPTIONAL
74
+ * on Vercel Edge / webpack webpack's async-WASM
75
+ * support resolves the URL fetch correctly, but
76
+ * passing the module explicitly is recommended
77
+ * for cross-runtime consistency.
42
78
  */
43
- declare function initEngineEdge(moduleOrPath?: WebAssembly.Module | URL | string | Request | BufferSource): Promise<void>;
79
+ declare function initEngineEdge(wasmModule?: WebAssembly.Module | URL | string | Request | BufferSource): Promise<void>;
44
80
  /**
45
81
  * Edge-runtime async equivalent of `engineVerify`.
46
82
  *
@@ -11,11 +11,44 @@ export { DetectionDetail, McpIPayload } from '@kya-os/checkpoint-shared';
11
11
  * no sync wasm load).
12
12
  *
13
13
  * This module loads the `wasm-pack --target web` artifact via the
14
- * async `__wbg_init` default export, then exposes the same typed
15
- * `engineVerifyEdge(input, ctx) Promise<VerifyResult>` shape with
16
- * a small lazy-init wrapper. First call awaits initialisation;
17
- * subsequent calls resolve synchronously on the JS side (the
18
- * underlying wasm `verify` is sync).
14
+ * async `__wbg_init` default export. The web target's `init()`
15
+ * accepts a pre-instantiated `WebAssembly.Module` argument — the
16
+ * canonical Cloudflare-Workers + wasm-bindgen pattern.
17
+ *
18
+ * # Why the caller MUST pass `wasmModule` on Cloudflare Workers
19
+ *
20
+ * Both `--target web` (URL fetch) and `--target bundler` (auto-
21
+ * instantiated `__wbg_set_wasm(wasm)`) have failure modes on wrangler:
22
+ *
23
+ * - `--target web` falls back to `new URL('<wasm>', import.meta.url)`
24
+ * when `init()` is called with no arg. Cloudflare Workers don't
25
+ * materialise `import.meta.url` the way browsers do → throws
26
+ * `TypeError: Invalid URL string`. (Broke production 2026-05-23,
27
+ * captured via dev tail in run 26352287112.)
28
+ *
29
+ * - `--target bundler` expects the host bundler to AUTO-INSTANTIATE
30
+ * `import * as wasm from './foo.wasm'` so `wasm` is the
31
+ * `Instance.exports` object. Webpack does this. **Wrangler does
32
+ * NOT** — wrangler gives you a raw `WebAssembly.Module`, and the
33
+ * bundler-target shim's `__wbg_set_wasm(rawModule)` happily
34
+ * accepts it, then every export lookup (`wasm.__wbindgen_add_
35
+ * to_stack_pointer`, etc.) returns undefined → throws
36
+ * `TypeError: wasm.__wbindgen_add_to_stack_pointer is not a function`.
37
+ * (Broke production 2026-05-24 after switching to bundler target
38
+ * in PR #2785; captured via prod tail.)
39
+ *
40
+ * The fix is the standard Cloudflare-Workers + wasm-bindgen pattern:
41
+ * the consumer statically imports the `.wasm` file (wrangler then
42
+ * bundles it + hands the worker a `WebAssembly.Module`), then passes
43
+ * it to `init(wasmModule)`. The web target's init detects the Module
44
+ * input + calls `WebAssembly.instantiate(Module, imports)` internally
45
+ * to produce a real `Instance` whose exports populate the JS shim's
46
+ * `wasm` binding correctly.
47
+ *
48
+ * Vercel Edge / webpack consumers MAY omit the argument — webpack's
49
+ * async-WASM support handles the URL fetch correctly. But the typed
50
+ * signature here marks `wasmModule` optional for backward compat;
51
+ * Cloudflare-Workers consumers MUST pass it.
19
52
  *
20
53
  * **Why this matters for the consolidation narrative.** Phase A
21
54
  * shipped Node-only. Without an edge build, the first Vercel-edge
@@ -29,18 +62,21 @@ export { DetectionDetail, McpIPayload } from '@kya-os/checkpoint-shared';
29
62
 
30
63
  /**
31
64
  * Initialise the edge wasm module. Idempotent — subsequent calls
32
- * return the same in-flight or resolved promise. Host wrappers can
33
- * call this at startup to eagerly load the wasm and avoid first-
34
- * request latency, but it's not required: `engineVerifyEdge`
35
- * lazily initialises on first call.
36
- *
37
- * @param moduleOrPath Optional pre-fetched `WebAssembly.Module` or
38
- * a URL / Request the wasm-bindgen loader will
39
- * fetch. Defaults to the bundled artifact via
40
- * `import.meta.url`. Cloudflare Workers / Vercel
41
- * Edge typically pass a pre-bundled `Module`.
65
+ * return the same in-flight or resolved promise. Host wrappers
66
+ * should call this once at startup with the `wasmModule` they
67
+ * statically imported from the package's `./wasm/kya-os-engine-web/`
68
+ * subpath (see CLAUDE.md for the wrangler/webpack import pattern).
69
+ *
70
+ * @param wasmModule REQUIRED on Cloudflare Workers (wrangler hands
71
+ * the consumer a `WebAssembly.Module` from the
72
+ * static `.wasm` import; pass it here so the
73
+ * web-target's `init()` instantiates it). OPTIONAL
74
+ * on Vercel Edge / webpack webpack's async-WASM
75
+ * support resolves the URL fetch correctly, but
76
+ * passing the module explicitly is recommended
77
+ * for cross-runtime consistency.
42
78
  */
43
- declare function initEngineEdge(moduleOrPath?: WebAssembly.Module | URL | string | Request | BufferSource): Promise<void>;
79
+ declare function initEngineEdge(wasmModule?: WebAssembly.Module | URL | string | Request | BufferSource): Promise<void>;
44
80
  /**
45
81
  * Edge-runtime async equivalent of `engineVerify`.
46
82
  *
@@ -2,20 +2,27 @@
2
2
 
3
3
  // src/engine/edge.ts
4
4
  var initialised = null;
5
- function initEngineEdge(moduleOrPath) {
6
- return ensureReady(moduleOrPath).then(() => void 0);
5
+ var providedModule;
6
+ function initEngineEdge(wasmModule) {
7
+ if (wasmModule !== void 0 && providedModule === void 0) {
8
+ providedModule = wasmModule;
9
+ }
10
+ return ensureReady().then(() => void 0);
7
11
  }
8
- function ensureReady(moduleOrPath) {
12
+ function ensureReady() {
9
13
  if (initialised) return initialised;
10
14
  const pending = (async () => {
11
15
  const mod = await import('@kya-os/checkpoint-wasm-runtime/wasm/kya-os-engine-web/kya_os_engine.js');
12
- await mod.default(moduleOrPath !== void 0 ? { module_or_path: moduleOrPath } : void 0);
16
+ await mod.default(
17
+ providedModule !== void 0 ? { module_or_path: providedModule } : void 0
18
+ );
13
19
  return mod.verify;
14
20
  })();
15
21
  initialised = pending;
16
22
  pending.catch(() => {
17
23
  if (initialised === pending) {
18
24
  initialised = null;
25
+ providedModule = void 0;
19
26
  }
20
27
  });
21
28
  return initialised;
@@ -1,19 +1,26 @@
1
1
  // src/engine/edge.ts
2
2
  var initialised = null;
3
- function initEngineEdge(moduleOrPath) {
4
- return ensureReady(moduleOrPath).then(() => void 0);
3
+ var providedModule;
4
+ function initEngineEdge(wasmModule) {
5
+ if (wasmModule !== void 0 && providedModule === void 0) {
6
+ providedModule = wasmModule;
7
+ }
8
+ return ensureReady().then(() => void 0);
5
9
  }
6
- function ensureReady(moduleOrPath) {
10
+ function ensureReady() {
7
11
  if (initialised) return initialised;
8
12
  const pending = (async () => {
9
13
  const mod = await import('@kya-os/checkpoint-wasm-runtime/wasm/kya-os-engine-web/kya_os_engine.js');
10
- await mod.default(moduleOrPath !== void 0 ? { module_or_path: moduleOrPath } : void 0);
14
+ await mod.default(
15
+ providedModule !== void 0 ? { module_or_path: providedModule } : void 0
16
+ );
11
17
  return mod.verify;
12
18
  })();
13
19
  initialised = pending;
14
20
  pending.catch(() => {
15
21
  if (initialised === pending) {
16
22
  initialised = null;
23
+ providedModule = void 0;
17
24
  }
18
25
  });
19
26
  return initialised;
package/dist/index.d.mts CHANGED
@@ -1,3 +1,7 @@
1
+ import { D as Decision } from './types-C3RniIOM.mjs';
2
+ export { B as BlockReason } from './types-C3RniIOM.mjs';
3
+ import '@kya-os/checkpoint-shared';
4
+
1
5
  /**
2
6
  * AgentShield WASM Runtime Types
3
7
  *
@@ -598,6 +602,119 @@ declare class RulesDetector implements IDetector {
598
602
  */
599
603
  declare function createRulesDetector(): RulesDetector;
600
604
 
605
+ /**
606
+ * Cedar policy-evaluator bridge — Node fallback.
607
+ *
608
+ * Surfaces the `PolicyEvaluator` class exported by the cedar-enabled
609
+ * `kya-os-engine` WASM artifact (built by
610
+ * `rust/scripts/build-engine-cedar-wasm.sh`, gated on the Rust
611
+ * `wasm,cedar` features). A JS host (the gateway) compiles a tenant
612
+ * policy bundle once and authorizes many requests against it in-process,
613
+ * with no round-trip to a separate policy service.
614
+ *
615
+ * The cedar artifact is a SEPARATE, larger binary than the lean
616
+ * detection artifact — it pulls in `cedar-policy`. Detection-only
617
+ * consumers load `./engine` (the lean `verify()` glue); only callers that
618
+ * need in-process authorization reach for this bridge.
619
+ *
620
+ * ## Lazy loading
621
+ *
622
+ * The cedar `--target nodejs` glue instantiates the ~2 MB cedar WASM the
623
+ * moment it is `require`d (it `fs.readFileSync`s its `.wasm` sibling at
624
+ * module load). To keep the separate-artifact promise — detection-only
625
+ * consumers must NOT pay cedar's memory/startup — the glue is loaded
626
+ * LAZILY: nothing happens on `import`; the artifact is `require`d (and
627
+ * memoised) only on the first {@link createPolicyEvaluator} call. This is
628
+ * also why cedar lives behind the dedicated `./policy` subpath and is NOT
629
+ * re-exported from the `./node` barrel.
630
+ *
631
+ * `createRequire(__filename)` resolves the glue at call time in both
632
+ * builds — native `require` under CJS, the tsup `shims` / `createRequire`
633
+ * banner under ESM. The glue stays external (regex
634
+ * `wasm/kya-os-engine-cedar/` in tsup's `commonOpts.external`), so its
635
+ * `__dirname` resolves against `node_modules/.../wasm/kya-os-engine-cedar/`
636
+ * where the `.wasm` lives, and `"type": "commonjs"` on the artifact's
637
+ * package.json keeps Node from throwing `ERR_REQUIRE_ESM`.
638
+ *
639
+ * Direct .wasm path (for callers building their own loaders):
640
+ * `@kya-os/checkpoint-wasm-runtime/wasm/kya-os-engine-cedar/kya_os_engine_bg.wasm`
641
+ */
642
+
643
+ /**
644
+ * Owned, plain-data request the host hands to
645
+ * {@link PolicyEvaluatorRuntime.authorize}. Mirrors the Rust
646
+ * `AuthorizeInput` (`rust/crates/kya-os-engine/src/policy/authorize.rs`);
647
+ * keys are camelCase across the wasm-bindgen boundary, matching every
648
+ * other engine wire type.
649
+ *
650
+ * The evaluator is **synchronous over pre-resolved facts** (H-1 Kickoff
651
+ * § 4.5): the host pre-fetches the agent's delegation chain, reputation,
652
+ * etc. and ships the results here — no JS callbacks cross the boundary.
653
+ *
654
+ * `agentDid` and `reputation` are optional (omit or pass `undefined` for
655
+ * an anonymous or reputation-less request); `grantedScopes` defaults to an
656
+ * empty list when omitted.
657
+ */
658
+ interface AuthorizeInput {
659
+ /** Agent DID if identity has been established, otherwise omitted. */
660
+ agentDid?: string;
661
+ /** The action being requested (e.g., `"book_flight"`). */
662
+ action: string;
663
+ /** The resource being acted on (e.g., `"travel_api"`). */
664
+ resource: string;
665
+ /** Scopes granted by the agent's delegation chain. Defaults to `[]`. */
666
+ grantedScopes?: string[];
667
+ /** Agent's reputation score in `[0.0, 1.0]`, if computed. */
668
+ reputation?: number;
669
+ /** Tenant identifier. */
670
+ tenantId: string;
671
+ }
672
+ /**
673
+ * Structural type of the WASM `PolicyEvaluator` class the cedar glue
674
+ * exports. Pinned here so this bridge type-checks against the artifact's
675
+ * `.d.ts` (`constructor(policy_text: string)`, `authorize(input): any`,
676
+ * `free()`).
677
+ */
678
+ interface WasmPolicyEvaluator {
679
+ authorize(input: AuthorizeInput): unknown;
680
+ free(): void;
681
+ }
682
+ /**
683
+ * Host-facing wrapper around one compiled Cedar policy bundle.
684
+ *
685
+ * Construction compiles the bundle once; every {@link authorize} call
686
+ * evaluates a single owned request against it without re-parsing policy
687
+ * text (the compile-once / evaluate-many contract the engine upholds,
688
+ * carried across the boundary).
689
+ */
690
+ declare class PolicyEvaluatorRuntime {
691
+ private readonly inner;
692
+ /**
693
+ * @param inner - The compiled WASM `PolicyEvaluator` handle. Built in
694
+ * {@link createPolicyEvaluator}; reused by every {@link authorize}
695
+ * call for the lifetime of this wrapper.
696
+ */
697
+ constructor(inner: WasmPolicyEvaluator);
698
+ /**
699
+ * Authorize one owned request against the compiled policy bundle.
700
+ *
701
+ * The evaluator owns the fail-closed posture — a request it cannot
702
+ * marshal into Cedar, or one matching no `permit`, comes back as a
703
+ * {@link Decision} `Block` (not a thrown error). Authorization
704
+ * *verdicts* never throw; they surface inside the returned value.
705
+ *
706
+ * @throws {Error} only for boundary faults the WASM glue rejects: a
707
+ * malformed `input` that fails `AuthorizeInput` deserialisation, or a
708
+ * failure serialising the resulting `Decision`.
709
+ */
710
+ authorize(input: AuthorizeInput): Decision;
711
+ /**
712
+ * Release the compiled bundle's WASM memory. Call when the evaluator is
713
+ * no longer needed; after this the wrapper must not be reused.
714
+ */
715
+ free(): void;
716
+ }
717
+
601
718
  /**
602
719
  * Create a detector with automatic runtime selection
603
720
  *
@@ -650,4 +767,4 @@ declare function createEdgeDetector(wasmModule: WebAssembly.Module, options?: ID
650
767
  */
651
768
  declare function createFallbackDetector(): IDetector;
652
769
 
653
- export { CONFIDENCE, type DetectionClass, DynamicWasmLoader, type ForgeabilityRisk, type ICustomerPolicy, type IDetectedAgent, type IDetectionInput, type IDetectionResult, type IDetector, type IDetectorOptions, type IPathRule, type IPolicyLoader, type IWasmBindings, type IWasmLoader, PolicyLoadError, PolicyLoader, type PolicyLoaderConfig, RulesDetector, StaticWasmLoader, type VerificationMethod, WasmDetector, createDetector, createDynamicLoader, createEdgeDetector, createFallbackDetector, createPolicyLoader, createRulesDetector, createStaticLoader };
770
+ export { type AuthorizeInput, CONFIDENCE, Decision, type DetectionClass, DynamicWasmLoader, type ForgeabilityRisk, type ICustomerPolicy, type IDetectedAgent, type IDetectionInput, type IDetectionResult, type IDetector, type IDetectorOptions, type IPathRule, type IPolicyLoader, type IWasmBindings, type IWasmLoader, PolicyEvaluatorRuntime, PolicyLoadError, PolicyLoader, type PolicyLoaderConfig, RulesDetector, StaticWasmLoader, type VerificationMethod, WasmDetector, createDetector, createDynamicLoader, createEdgeDetector, createFallbackDetector, createPolicyLoader, createRulesDetector, createStaticLoader };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ import { D as Decision } from './types-C3RniIOM.js';
2
+ export { B as BlockReason } from './types-C3RniIOM.js';
3
+ import '@kya-os/checkpoint-shared';
4
+
1
5
  /**
2
6
  * AgentShield WASM Runtime Types
3
7
  *
@@ -598,6 +602,119 @@ declare class RulesDetector implements IDetector {
598
602
  */
599
603
  declare function createRulesDetector(): RulesDetector;
600
604
 
605
+ /**
606
+ * Cedar policy-evaluator bridge — Node fallback.
607
+ *
608
+ * Surfaces the `PolicyEvaluator` class exported by the cedar-enabled
609
+ * `kya-os-engine` WASM artifact (built by
610
+ * `rust/scripts/build-engine-cedar-wasm.sh`, gated on the Rust
611
+ * `wasm,cedar` features). A JS host (the gateway) compiles a tenant
612
+ * policy bundle once and authorizes many requests against it in-process,
613
+ * with no round-trip to a separate policy service.
614
+ *
615
+ * The cedar artifact is a SEPARATE, larger binary than the lean
616
+ * detection artifact — it pulls in `cedar-policy`. Detection-only
617
+ * consumers load `./engine` (the lean `verify()` glue); only callers that
618
+ * need in-process authorization reach for this bridge.
619
+ *
620
+ * ## Lazy loading
621
+ *
622
+ * The cedar `--target nodejs` glue instantiates the ~2 MB cedar WASM the
623
+ * moment it is `require`d (it `fs.readFileSync`s its `.wasm` sibling at
624
+ * module load). To keep the separate-artifact promise — detection-only
625
+ * consumers must NOT pay cedar's memory/startup — the glue is loaded
626
+ * LAZILY: nothing happens on `import`; the artifact is `require`d (and
627
+ * memoised) only on the first {@link createPolicyEvaluator} call. This is
628
+ * also why cedar lives behind the dedicated `./policy` subpath and is NOT
629
+ * re-exported from the `./node` barrel.
630
+ *
631
+ * `createRequire(__filename)` resolves the glue at call time in both
632
+ * builds — native `require` under CJS, the tsup `shims` / `createRequire`
633
+ * banner under ESM. The glue stays external (regex
634
+ * `wasm/kya-os-engine-cedar/` in tsup's `commonOpts.external`), so its
635
+ * `__dirname` resolves against `node_modules/.../wasm/kya-os-engine-cedar/`
636
+ * where the `.wasm` lives, and `"type": "commonjs"` on the artifact's
637
+ * package.json keeps Node from throwing `ERR_REQUIRE_ESM`.
638
+ *
639
+ * Direct .wasm path (for callers building their own loaders):
640
+ * `@kya-os/checkpoint-wasm-runtime/wasm/kya-os-engine-cedar/kya_os_engine_bg.wasm`
641
+ */
642
+
643
+ /**
644
+ * Owned, plain-data request the host hands to
645
+ * {@link PolicyEvaluatorRuntime.authorize}. Mirrors the Rust
646
+ * `AuthorizeInput` (`rust/crates/kya-os-engine/src/policy/authorize.rs`);
647
+ * keys are camelCase across the wasm-bindgen boundary, matching every
648
+ * other engine wire type.
649
+ *
650
+ * The evaluator is **synchronous over pre-resolved facts** (H-1 Kickoff
651
+ * § 4.5): the host pre-fetches the agent's delegation chain, reputation,
652
+ * etc. and ships the results here — no JS callbacks cross the boundary.
653
+ *
654
+ * `agentDid` and `reputation` are optional (omit or pass `undefined` for
655
+ * an anonymous or reputation-less request); `grantedScopes` defaults to an
656
+ * empty list when omitted.
657
+ */
658
+ interface AuthorizeInput {
659
+ /** Agent DID if identity has been established, otherwise omitted. */
660
+ agentDid?: string;
661
+ /** The action being requested (e.g., `"book_flight"`). */
662
+ action: string;
663
+ /** The resource being acted on (e.g., `"travel_api"`). */
664
+ resource: string;
665
+ /** Scopes granted by the agent's delegation chain. Defaults to `[]`. */
666
+ grantedScopes?: string[];
667
+ /** Agent's reputation score in `[0.0, 1.0]`, if computed. */
668
+ reputation?: number;
669
+ /** Tenant identifier. */
670
+ tenantId: string;
671
+ }
672
+ /**
673
+ * Structural type of the WASM `PolicyEvaluator` class the cedar glue
674
+ * exports. Pinned here so this bridge type-checks against the artifact's
675
+ * `.d.ts` (`constructor(policy_text: string)`, `authorize(input): any`,
676
+ * `free()`).
677
+ */
678
+ interface WasmPolicyEvaluator {
679
+ authorize(input: AuthorizeInput): unknown;
680
+ free(): void;
681
+ }
682
+ /**
683
+ * Host-facing wrapper around one compiled Cedar policy bundle.
684
+ *
685
+ * Construction compiles the bundle once; every {@link authorize} call
686
+ * evaluates a single owned request against it without re-parsing policy
687
+ * text (the compile-once / evaluate-many contract the engine upholds,
688
+ * carried across the boundary).
689
+ */
690
+ declare class PolicyEvaluatorRuntime {
691
+ private readonly inner;
692
+ /**
693
+ * @param inner - The compiled WASM `PolicyEvaluator` handle. Built in
694
+ * {@link createPolicyEvaluator}; reused by every {@link authorize}
695
+ * call for the lifetime of this wrapper.
696
+ */
697
+ constructor(inner: WasmPolicyEvaluator);
698
+ /**
699
+ * Authorize one owned request against the compiled policy bundle.
700
+ *
701
+ * The evaluator owns the fail-closed posture — a request it cannot
702
+ * marshal into Cedar, or one matching no `permit`, comes back as a
703
+ * {@link Decision} `Block` (not a thrown error). Authorization
704
+ * *verdicts* never throw; they surface inside the returned value.
705
+ *
706
+ * @throws {Error} only for boundary faults the WASM glue rejects: a
707
+ * malformed `input` that fails `AuthorizeInput` deserialisation, or a
708
+ * failure serialising the resulting `Decision`.
709
+ */
710
+ authorize(input: AuthorizeInput): Decision;
711
+ /**
712
+ * Release the compiled bundle's WASM memory. Call when the evaluator is
713
+ * no longer needed; after this the wrapper must not be reused.
714
+ */
715
+ free(): void;
716
+ }
717
+
601
718
  /**
602
719
  * Create a detector with automatic runtime selection
603
720
  *
@@ -650,4 +767,4 @@ declare function createEdgeDetector(wasmModule: WebAssembly.Module, options?: ID
650
767
  */
651
768
  declare function createFallbackDetector(): IDetector;
652
769
 
653
- export { CONFIDENCE, type DetectionClass, DynamicWasmLoader, type ForgeabilityRisk, type ICustomerPolicy, type IDetectedAgent, type IDetectionInput, type IDetectionResult, type IDetector, type IDetectorOptions, type IPathRule, type IPolicyLoader, type IWasmBindings, type IWasmLoader, PolicyLoadError, PolicyLoader, type PolicyLoaderConfig, RulesDetector, StaticWasmLoader, type VerificationMethod, WasmDetector, createDetector, createDynamicLoader, createEdgeDetector, createFallbackDetector, createPolicyLoader, createRulesDetector, createStaticLoader };
770
+ export { type AuthorizeInput, CONFIDENCE, Decision, type DetectionClass, DynamicWasmLoader, type ForgeabilityRisk, type ICustomerPolicy, type IDetectedAgent, type IDetectionInput, type IDetectionResult, type IDetector, type IDetectorOptions, type IPathRule, type IPolicyLoader, type IWasmBindings, type IWasmLoader, PolicyEvaluatorRuntime, PolicyLoadError, PolicyLoader, type PolicyLoaderConfig, RulesDetector, StaticWasmLoader, type VerificationMethod, WasmDetector, createDetector, createDynamicLoader, createEdgeDetector, createFallbackDetector, createPolicyLoader, createRulesDetector, createStaticLoader };