@kya-os/checkpoint-wasm-runtime 1.0.0 → 1.1.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 (44) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/adapters.js +0 -2
  3. package/dist/adapters.mjs +0 -2
  4. package/dist/edge.js +0 -2
  5. package/dist/edge.mjs +0 -2
  6. package/dist/engine-edge.js +0 -2
  7. package/dist/engine-edge.mjs +0 -2
  8. package/dist/engine.js +0 -2
  9. package/dist/engine.mjs +0 -2
  10. package/dist/index.js +0 -2
  11. package/dist/index.mjs +0 -2
  12. package/dist/node.js +0 -2
  13. package/dist/node.mjs +0 -2
  14. package/dist/orchestrator-edge.d.mts +5 -199
  15. package/dist/orchestrator-edge.d.ts +5 -199
  16. package/dist/orchestrator-edge.js +0 -2
  17. package/dist/orchestrator-edge.mjs +0 -2
  18. package/dist/orchestrator-node.d.mts +49 -0
  19. package/dist/orchestrator-node.d.ts +49 -0
  20. package/dist/orchestrator-node.js +547 -0
  21. package/dist/orchestrator-node.mjs +538 -0
  22. package/dist/orchestrator.d.mts +4 -47
  23. package/dist/orchestrator.d.ts +4 -47
  24. package/dist/orchestrator.js +0 -2
  25. package/dist/orchestrator.mjs +0 -2
  26. package/dist/render-decision-C1a-iuiW.d.mts +200 -0
  27. package/dist/render-decision-Dsjwt96g.d.ts +200 -0
  28. package/package.json +11 -1
  29. package/dist/adapters.js.map +0 -1
  30. package/dist/adapters.mjs.map +0 -1
  31. package/dist/edge.js.map +0 -1
  32. package/dist/edge.mjs.map +0 -1
  33. package/dist/engine-edge.js.map +0 -1
  34. package/dist/engine-edge.mjs.map +0 -1
  35. package/dist/engine.js.map +0 -1
  36. package/dist/engine.mjs.map +0 -1
  37. package/dist/index.js.map +0 -1
  38. package/dist/index.mjs.map +0 -1
  39. package/dist/node.js.map +0 -1
  40. package/dist/node.mjs.map +0 -1
  41. package/dist/orchestrator-edge.js.map +0 -1
  42. package/dist/orchestrator-edge.mjs.map +0 -1
  43. package/dist/orchestrator.js.map +0 -1
  44. package/dist/orchestrator.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,75 @@
1
1
  # @kya-os/checkpoint-wasm-runtime
2
2
 
3
+ ## 1.1.0 — 2026-05-17
4
+
5
+ **SDK-WASM-Bundler-Loader-1 fix.** Surfaced during Bench-Before-After-1
6
+ sub-phase 3 follow-up: the `./orchestrator` barrel bundled both the
7
+ Node-target and Web-target wasm-bindgen outputs, and the Web-target's
8
+ `new URL("kya_os_engine_bg.wasm", import.meta.url)` browser-style
9
+ fallback failed static analysis in Next.js 16's Turbopack (and
10
+ webpack ≥5) even when the runtime branch was unreachable. Net result:
11
+ `@kya-os/checkpoint-nextjs`'s `withCheckpoint` couldn't be deployed
12
+ under Next.js's Node runtime at all — middleware imports died at
13
+ build time.
14
+
15
+ ### New (additive, zero customer-visible change)
16
+
17
+ - **`./orchestrator/node` subpath export** — Node-only orchestrator
18
+ entry that omits the Edge-variant import chain. Re-exports the same
19
+ `verifyRequest`, `buildAgentRequest`, `renderDecisionAsResponse`,
20
+ and types as the main barrel. No URL trick in the bundle.
21
+ - **`"node"` export condition** on the `./orchestrator` entry — routes
22
+ Node-runtime bundlers (Next.js Node runtime, Express, AWS Lambda,
23
+ long-lived Node servers) to `orchestrator-node.mjs` automatically.
24
+ Edge consumers continue routing to `orchestrator-edge.mjs` via
25
+ the pre-existing `"edge-runtime"` and `"browser"` conditions.
26
+
27
+ ### What this means for consumers
28
+
29
+ **Zero migration required.** Existing imports of
30
+ `@kya-os/checkpoint-wasm-runtime/orchestrator` route to the correct
31
+ per-runtime variant via the package's `exports` map. The runtime
32
+ selection is invisible at the call site:
33
+
34
+ ```typescript
35
+ // Unchanged — runtime-conditional resolution happens at bundle time
36
+ import { verifyRequest } from '@kya-os/checkpoint-wasm-runtime/orchestrator';
37
+ ```
38
+
39
+ Power users who want to lock to a specific variant can import
40
+ explicitly:
41
+
42
+ ```typescript
43
+ import { verifyRequest } from '@kya-os/checkpoint-wasm-runtime/orchestrator/node';
44
+ // or
45
+ import { verifyRequestEdge } from '@kya-os/checkpoint-wasm-runtime/orchestrator/edge';
46
+ ```
47
+
48
+ ### Bundle verification
49
+
50
+ ```
51
+ $ grep -c 'kya_os_engine_bg.wasm' dist/orchestrator-node.mjs # 0
52
+ $ grep -c 'kya_os_engine_bg.wasm' dist/orchestrator.mjs # 1 (barrel — unchanged for back-compat)
53
+ $ grep -c 'kya_os_engine_bg.wasm' dist/orchestrator-edge.mjs # 1 (Edge — expected, runtime handles URL)
54
+ ```
55
+
56
+ ### Coordinated release
57
+
58
+ Shipped alongside `@kya-os/checkpoint-{nextjs,express}@1.1.x` to
59
+ unblock the `withCheckpoint` factory's Next.js Node-runtime deploy
60
+ path. See `docs/benchmarks/bench-before-after-1.md` §3.7 + the
61
+ SDK-Envelope-Plumbing-1 ticket (#2594) for the surfacing context.
62
+
63
+ ### Why this wasn't caught earlier
64
+
65
+ No Next.js end-to-end CI for `withCheckpoint` — the package's unit
66
+ tests mock `verifyRequest`, so the wasm-runtime import chain never
67
+ actually loads in the test harness. The factory contract is tested;
68
+ the bundled artifact's bundler behavior isn't. Adding a sites-driven
69
+ build-CI gate is filed as a follow-up.
70
+
71
+ ---
72
+
3
73
  ## 1.0.0 — 2026-05-15
4
74
 
5
75
  E-tracks Phase D — package rename + orchestrator edge variant. **BREAKING.**
package/dist/adapters.js CHANGED
@@ -599,5 +599,3 @@ exports.makePolicyEvaluator = makePolicyEvaluator;
599
599
  exports.makeReputationOracle = makeReputationOracle;
600
600
  exports.makeStatusListCache = makeStatusListCache;
601
601
  exports.makeSystemClock = makeSystemClock;
602
- //# sourceMappingURL=adapters.js.map
603
- //# sourceMappingURL=adapters.js.map
package/dist/adapters.mjs CHANGED
@@ -582,5 +582,3 @@ function makeFixedClock(unixSeconds) {
582
582
  }
583
583
 
584
584
  export { DidNotFound, DidResolverError, DidResolverTimeout, MalformedDid, MalformedStatusList, StatusListTimeout, StatusListUnavailable, UnsupportedDidMethod, UnsupportedKeyType, decodeDidKey, makeDidResolver, makeFixedClock, makePolicyEvaluator, makeReputationOracle, makeStatusListCache, makeSystemClock };
585
- //# sourceMappingURL=adapters.mjs.map
586
- //# sourceMappingURL=adapters.mjs.map
package/dist/edge.js CHANGED
@@ -1399,5 +1399,3 @@ exports.createPolicyLoader = createPolicyLoader;
1399
1399
  exports.createRulesDetector = createRulesDetector;
1400
1400
  exports.createStaticLoader = createStaticLoader;
1401
1401
  exports.extractInputFromRequest = extractInputFromRequest;
1402
- //# sourceMappingURL=edge.js.map
1403
- //# sourceMappingURL=edge.js.map
package/dist/edge.mjs CHANGED
@@ -1387,5 +1387,3 @@ function extractInputFromRequest(request) {
1387
1387
  }
1388
1388
 
1389
1389
  export { CONFIDENCE, PolicyLoader, RulesDetector, StaticWasmLoader, WasmDetector, createEdgeDetector, createFallbackDetector, createPolicyLoader, createRulesDetector, createStaticLoader, extractInputFromRequest };
1390
- //# sourceMappingURL=edge.mjs.map
1391
- //# sourceMappingURL=edge.mjs.map
@@ -533,5 +533,3 @@ async function engineVerifyEdge(input, ctx) {
533
533
 
534
534
  exports.engineVerifyEdge = engineVerifyEdge;
535
535
  exports.initEngineEdge = initEngineEdge;
536
- //# sourceMappingURL=engine-edge.js.map
537
- //# sourceMappingURL=engine-edge.js.map
@@ -529,5 +529,3 @@ async function engineVerifyEdge(input, ctx) {
529
529
  }
530
530
 
531
531
  export { engineVerifyEdge, initEngineEdge };
532
- //# sourceMappingURL=engine-edge.mjs.map
533
- //# sourceMappingURL=engine-edge.mjs.map
package/dist/engine.js CHANGED
@@ -7,5 +7,3 @@ function engineVerify(input, ctx) {
7
7
  }
8
8
 
9
9
  exports.engineVerify = engineVerify;
10
- //# sourceMappingURL=engine.js.map
11
- //# sourceMappingURL=engine.js.map
package/dist/engine.mjs CHANGED
@@ -5,5 +5,3 @@ function engineVerify(input, ctx) {
5
5
  }
6
6
 
7
7
  export { engineVerify };
8
- //# sourceMappingURL=engine.mjs.map
9
- //# sourceMappingURL=engine.mjs.map
package/dist/index.js CHANGED
@@ -1648,5 +1648,3 @@ exports.createFallbackDetector = createFallbackDetector;
1648
1648
  exports.createPolicyLoader = createPolicyLoader;
1649
1649
  exports.createRulesDetector = createRulesDetector;
1650
1650
  exports.createStaticLoader = createStaticLoader;
1651
- //# sourceMappingURL=index.js.map
1652
- //# sourceMappingURL=index.js.map
package/dist/index.mjs CHANGED
@@ -1633,5 +1633,3 @@ function createFallbackDetector() {
1633
1633
  }
1634
1634
 
1635
1635
  export { CONFIDENCE, DynamicWasmLoader, PolicyLoadError, PolicyLoader, RulesDetector, StaticWasmLoader, WasmDetector, createDetector, createDynamicLoader, createEdgeDetector, createFallbackDetector, createPolicyLoader, createRulesDetector, createStaticLoader };
1636
- //# sourceMappingURL=index.mjs.map
1637
- //# sourceMappingURL=index.mjs.map
package/dist/node.js CHANGED
@@ -968,5 +968,3 @@ exports.createNodeDetector = createNodeDetector;
968
968
  exports.createPolicyLoader = createPolicyLoader;
969
969
  exports.createRulesDetector = createRulesDetector;
970
970
  exports.extractInputFromExpressRequest = extractInputFromExpressRequest;
971
- //# sourceMappingURL=node.js.map
972
- //# sourceMappingURL=node.js.map
package/dist/node.mjs CHANGED
@@ -956,5 +956,3 @@ function extractInputFromExpressRequest(req) {
956
956
  }
957
957
 
958
958
  export { CONFIDENCE, DynamicWasmLoader, PolicyLoader, RulesDetector, WasmDetector, createDynamicLoader, createFallbackDetector, createNodeDetector, createPolicyLoader, createRulesDetector, extractInputFromExpressRequest };
959
- //# sourceMappingURL=node.mjs.map
960
- //# sourceMappingURL=node.mjs.map
@@ -1,203 +1,9 @@
1
1
  export { initEngineEdge } from './engine-edge.mjs';
2
- import { E as EnforcementMode, A as AgentRequest, V as VerifyResult } from './types-D0j85fF0.mjs';
3
- import { DidResolverAdapter, StatusListCacheAdapter, ReputationOracleAdapter, PolicyEvaluatorAdapter, ClockAdapter } from './adapters.mjs';
2
+ import { V as VerifyResult } from './types-D0j85fF0.mjs';
3
+ import { V as VerifyRequestOpts, I as IncomingHttpLike } from './render-decision-C1a-iuiW.mjs';
4
+ export { B as BuildAgentRequestOpts, R as RenderedResponse, b as buildAgentRequest, e as extractAgentDid, a as extractCredentialStatusUrl, c as extractIssuer, h as hasMalformedJwsBody, r as renderDecisionAsResponse } from './render-decision-C1a-iuiW.mjs';
4
5
  import '@kya-os/checkpoint-shared';
5
-
6
- /**
7
- * Orchestrator-layer types — Phase C, host-side only.
8
- *
9
- * Nothing here crosses the WASM boundary. The engine ABI types live
10
- * in `../types.ts`; the adapter interfaces live in
11
- * `../adapters/index.ts`. This file is the host-wrapper-facing
12
- * surface — what Phase D (Next.js) and Phase E (Express) import.
13
- */
14
-
15
- /**
16
- * Framework-agnostic HTTP request shape.
17
- *
18
- * Next.js / Express / Cloudflare Workers / Hono adapters marshal
19
- * their native request type into this shape before calling
20
- * `verifyRequest`. The shape is intentionally minimal — only what
21
- * the engine needs to make a verdict.
22
- */
23
- interface IncomingHttpLike {
24
- method: string;
25
- /** Path + query string (no scheme + host). */
26
- url: string;
27
- headers: Record<string, string | string[] | undefined>;
28
- /**
29
- * Parsed body if the framework has already parsed it (Next.js
30
- * with `await req.json()`, Express with `body-parser`). Falsy if
31
- * the caller hasn't materialised the body — the orchestrator
32
- * treats that as "no MCP-I envelope present" and routes to
33
- * PlainHttp.
34
- */
35
- body?: Buffer | string | object | null;
36
- /** Client IP if the framework surfaces one (Express `req.ip`). */
37
- remoteAddress?: string;
38
- }
39
- /**
40
- * Options the host wrapper passes per-`verifyRequest`-construction.
41
- * The five adapters + clock + tenant identifier + enforcement mode.
42
- */
43
- interface VerifyRequestOpts {
44
- didResolver: DidResolverAdapter;
45
- statusListCache: StatusListCacheAdapter;
46
- reputationOracle: ReputationOracleAdapter;
47
- policyEvaluator: PolicyEvaluatorAdapter;
48
- clock: ClockAdapter;
49
- /** Tenant identifier — the host customer this request targets. */
50
- tenantHost: string;
51
- enforcementMode: EnforcementMode;
52
- /** Returned to the PolicyEvaluator when the request has no agent DID. Default 1.0. */
53
- reputationBaseline?: number;
54
- /**
55
- * **Envelope-1 (#2537) coordination flag.** Pre-Envelope-1 the TS
56
- * bouncer ships MCP-I proofs as `{protected,payload,signature}` JSON
57
- * in a `KYA-Delegation` header. Post-Envelope-1 they ship compact
58
- * JWS in `_meta.proof.jws` of the body. When this flag is true the
59
- * orchestrator also accepts the legacy header form. **Default off.**
60
- * Delete this flag once Envelope-1 ships end-to-end.
61
- */
62
- legacyEnvelopeFallback?: boolean;
63
- /**
64
- * Argus URL — passed only so the orchestrator can detect "Argus
65
- * not configured" at construction time and log the one-shot
66
- * warning. The actual reputation fetch goes through `reputationOracle`.
67
- */
68
- argusUrl?: string;
69
- /** Injectable for the once-only Argus configuration warning. */
70
- logger?: (msg: string) => void;
71
- }
72
- /**
73
- * Transport-agnostic response shape `renderDecisionAsResponse`
74
- * produces. Host wrappers adapt this to their framework's response
75
- * type (NextResponse / Express `res` / Cloudflare Response).
76
- *
77
- * `status === null` means "pass through" — the request continues to
78
- * the next handler. Happens in two cases:
79
- * 1. `Decision::Permit` (no block in Enforce mode).
80
- * 2. **Any verdict in Observe mode** — Observe never blocks, but
81
- * the response headers still carry the would-have-been verdict.
82
- */
83
- interface RenderedResponse {
84
- status: number | null;
85
- headers: Record<string, string>;
86
- body?: string | object;
87
- }
88
-
89
- /**
90
- * HTTP-to-`AgentRequest` translator — Phase C.1.
91
- *
92
- * Detects which engine protocol the request belongs to and builds
93
- * the typed `AgentRequest` the WASM consumes. Conservative
94
- * detection: never escalates an ambiguous request into a higher
95
- * verification tier. Anonymous PlainHttp is the default.
96
- *
97
- * **What this layer parses and what it doesn't.** It parses *only
98
- * what's needed to drive conditional pre-fetch* — header presence,
99
- * the MCP-I envelope's payload segment (to extract `iss` + `sub` +
100
- * optional credentialStatus URL). It does **not** verify
101
- * signatures, decode VC chains for revocation bits, or evaluate
102
- * scope. Those live in the engine (H-1's parser + Stages 2-5).
103
- *
104
- * **Buffer-portability note.** This module uses `Buffer.from(...)` and
105
- * `Buffer.isBuffer(...)` at multiple call sites (the JWS preflight
106
- * `hasMalformedJwsBody`, both `tryBuildMcpIFromBody` variants, the
107
- * legacy-header reconstitution path, and `bodyAsBytes`). All of these
108
- * assume the Node `Buffer` global is available — provided natively by
109
- * the Node runtime, polyfilled on Vercel Edge, and gated behind
110
- * `nodejs_compat` on Cloudflare Workers. Bare-Edge and pure-browser
111
- * embedders would need a `Buffer` polyfill or a refactor to
112
- * `TextEncoder` / `Uint8Array.from`. Tracked as a follow-up since
113
- * Phase D's Vercel Node + Vercel Edge targets are both covered today.
114
- */
115
-
116
- interface BuildAgentRequestOpts {
117
- /** See `VerifyRequestOpts.legacyEnvelopeFallback`. */
118
- legacyEnvelopeFallback?: boolean;
119
- }
120
- /**
121
- * Translate an HTTP-like request into the engine's `AgentRequest`.
122
- *
123
- * Detection order (conservative — never escalate ambiguous input):
124
- * 1. MCP-I L2 detached proof in `_meta.proof.jws` (spec form).
125
- * 2. (Legacy, opt-in) MCP-I in `KYA-Delegation` header
126
- * (Envelope-1 #2537 transition window only).
127
- * 3. RFC 9421 HTTP Message Signatures (`Signature-Input` header).
128
- * 4. PlainHttp (default — anonymous traffic).
129
- */
130
- declare function buildAgentRequest(req: IncomingHttpLike, opts?: BuildAgentRequestOpts): AgentRequest;
131
- /**
132
- * Preflight check — does the request body carry a `_meta.proof.jws`
133
- * string that `parseJwsPayloadStruct` cannot project into a typed
134
- * `McpIPayload`?
135
- *
136
- * The caller declared intent (an MCP-I envelope) by including the
137
- * JWS field; structural failure to extract the payload means the
138
- * envelope is malformed, not absent. Without this preflight, the
139
- * orchestrator would silently fall through to PlainHttp — pre-#2560
140
- * that happened to also Block (engine returned `Block(ParseError)`
141
- * for every PlainHttp), so the regression was invisible; post-#2560
142
- * the engine's Stage 1 + stub policy returns `Permit` for anonymous
143
- * PlainHttp and tampered envelopes would be silently accepted.
144
- *
145
- * Returns `true` when the orchestrator should synthesize
146
- * `Block(ParseError)` BEFORE calling `buildAgentRequest`.
147
- */
148
- declare function hasMalformedJwsBody(req: IncomingHttpLike): boolean;
149
- /**
150
- * Issuer DID — Stage 1 (identity resolution) targets this. `null`
151
- * for PlainHttp (anonymous → no DID to resolve).
152
- */
153
- declare function extractIssuer(request: AgentRequest): string | null;
154
- /**
155
- * Agent DID — used by ReputationOracle. Defaults to `payload.sub`
156
- * for MCP-I (subject = the agent the proof is *about*).
157
- */
158
- declare function extractAgentDid(request: AgentRequest): string | null;
159
- /**
160
- * Status-list URL for revocation pre-fetch. Pulled from the JWS
161
- * payload's `vc.credentialStatus.id` (W3C VC Data Model 1.1).
162
- * `null` when the envelope is L1 (no VC chain) — Stage 3 will skip.
163
- */
164
- declare function extractCredentialStatusUrl(request: AgentRequest): string | null;
165
-
166
- /**
167
- * Transport-agnostic `Decision` → HTTP renderer — Phase C.3.
168
- *
169
- * Translates a `VerifyResult` into a framework-neutral
170
- * `{ status, headers, body }` shape. Phase D (Next.js) adapts this
171
- * to `NextResponse`; Phase E (Express) adapts it to `res.status().set().send()`.
172
- * One source of truth for the verdict→HTTP mapping.
173
- *
174
- * Mapping table (§ 4.5 of Phase C kickoff):
175
- *
176
- * | Decision | HTTP | Notes |
177
- * |-----------------------------------|------|-----------------------------------------|
178
- * | Permit | null | Pass through to next handler |
179
- * | Block(Unauthenticated) | 401 | WWW-Authenticate header |
180
- * | Block(InvalidSignature) | 403 | |
181
- * | Block(Revoked) | 403 | |
182
- * | Block(Expired) | 401 | Refresh-the-credential semantics |
183
- * | Block(OutOfScope) | 403 | Body carries requested + granted |
184
- * | Block(LowReputation) | 403 | Body carries score + threshold |
185
- * | Block(PolicyDenied) | 403 | Body carries detail |
186
- * | Block(ParseError) | 400 | Body carries detail |
187
- * | Challenge | 401 | Body carries ChallengeParams |
188
- * | Redirect | 302 | Location header |
189
- * | Instruct | 422 | application/problem+json body |
190
- *
191
- * Observe mode overrides: every verdict renders as `status: null`
192
- * (pass through) with an `X-Checkpoint-Would-Have-Been` header
193
- * carrying the verdict kind, plus the standard attribution headers.
194
- *
195
- * Every response carries the Phase 0.1 attribution headers:
196
- * `X-Checkpoint-Engine`, `X-Checkpoint-Engine-Version`, and
197
- * (when present) `X-Checkpoint-Ruleset-Hash`.
198
- */
199
-
200
- declare function renderDecisionAsResponse(result: VerifyResult): RenderedResponse;
6
+ import './adapters.mjs';
201
7
 
202
8
  /**
203
9
  * `verifyRequestEdge` async-init orchestrator — Edge-WASM-2 (folded into
@@ -240,4 +46,4 @@ declare function makeVerifyRequestEdge(opts: VerifyRequestOpts): (req: IncomingH
240
46
  */
241
47
  declare function verifyRequestEdge(req: IncomingHttpLike, opts: VerifyRequestOpts): Promise<VerifyResult>;
242
48
 
243
- export { type BuildAgentRequestOpts, type IncomingHttpLike, type RenderedResponse, type VerifyRequestOpts, buildAgentRequest, extractAgentDid, extractCredentialStatusUrl, extractIssuer, hasMalformedJwsBody, makeVerifyRequestEdge, renderDecisionAsResponse, verifyRequestEdge };
49
+ export { IncomingHttpLike, VerifyRequestOpts, makeVerifyRequestEdge, verifyRequestEdge };
@@ -1,203 +1,9 @@
1
1
  export { initEngineEdge } from './engine-edge.js';
2
- import { E as EnforcementMode, A as AgentRequest, V as VerifyResult } from './types-D0j85fF0.js';
3
- import { DidResolverAdapter, StatusListCacheAdapter, ReputationOracleAdapter, PolicyEvaluatorAdapter, ClockAdapter } from './adapters.js';
2
+ import { V as VerifyResult } from './types-D0j85fF0.js';
3
+ import { V as VerifyRequestOpts, I as IncomingHttpLike } from './render-decision-Dsjwt96g.js';
4
+ export { B as BuildAgentRequestOpts, R as RenderedResponse, b as buildAgentRequest, e as extractAgentDid, a as extractCredentialStatusUrl, c as extractIssuer, h as hasMalformedJwsBody, r as renderDecisionAsResponse } from './render-decision-Dsjwt96g.js';
4
5
  import '@kya-os/checkpoint-shared';
5
-
6
- /**
7
- * Orchestrator-layer types — Phase C, host-side only.
8
- *
9
- * Nothing here crosses the WASM boundary. The engine ABI types live
10
- * in `../types.ts`; the adapter interfaces live in
11
- * `../adapters/index.ts`. This file is the host-wrapper-facing
12
- * surface — what Phase D (Next.js) and Phase E (Express) import.
13
- */
14
-
15
- /**
16
- * Framework-agnostic HTTP request shape.
17
- *
18
- * Next.js / Express / Cloudflare Workers / Hono adapters marshal
19
- * their native request type into this shape before calling
20
- * `verifyRequest`. The shape is intentionally minimal — only what
21
- * the engine needs to make a verdict.
22
- */
23
- interface IncomingHttpLike {
24
- method: string;
25
- /** Path + query string (no scheme + host). */
26
- url: string;
27
- headers: Record<string, string | string[] | undefined>;
28
- /**
29
- * Parsed body if the framework has already parsed it (Next.js
30
- * with `await req.json()`, Express with `body-parser`). Falsy if
31
- * the caller hasn't materialised the body — the orchestrator
32
- * treats that as "no MCP-I envelope present" and routes to
33
- * PlainHttp.
34
- */
35
- body?: Buffer | string | object | null;
36
- /** Client IP if the framework surfaces one (Express `req.ip`). */
37
- remoteAddress?: string;
38
- }
39
- /**
40
- * Options the host wrapper passes per-`verifyRequest`-construction.
41
- * The five adapters + clock + tenant identifier + enforcement mode.
42
- */
43
- interface VerifyRequestOpts {
44
- didResolver: DidResolverAdapter;
45
- statusListCache: StatusListCacheAdapter;
46
- reputationOracle: ReputationOracleAdapter;
47
- policyEvaluator: PolicyEvaluatorAdapter;
48
- clock: ClockAdapter;
49
- /** Tenant identifier — the host customer this request targets. */
50
- tenantHost: string;
51
- enforcementMode: EnforcementMode;
52
- /** Returned to the PolicyEvaluator when the request has no agent DID. Default 1.0. */
53
- reputationBaseline?: number;
54
- /**
55
- * **Envelope-1 (#2537) coordination flag.** Pre-Envelope-1 the TS
56
- * bouncer ships MCP-I proofs as `{protected,payload,signature}` JSON
57
- * in a `KYA-Delegation` header. Post-Envelope-1 they ship compact
58
- * JWS in `_meta.proof.jws` of the body. When this flag is true the
59
- * orchestrator also accepts the legacy header form. **Default off.**
60
- * Delete this flag once Envelope-1 ships end-to-end.
61
- */
62
- legacyEnvelopeFallback?: boolean;
63
- /**
64
- * Argus URL — passed only so the orchestrator can detect "Argus
65
- * not configured" at construction time and log the one-shot
66
- * warning. The actual reputation fetch goes through `reputationOracle`.
67
- */
68
- argusUrl?: string;
69
- /** Injectable for the once-only Argus configuration warning. */
70
- logger?: (msg: string) => void;
71
- }
72
- /**
73
- * Transport-agnostic response shape `renderDecisionAsResponse`
74
- * produces. Host wrappers adapt this to their framework's response
75
- * type (NextResponse / Express `res` / Cloudflare Response).
76
- *
77
- * `status === null` means "pass through" — the request continues to
78
- * the next handler. Happens in two cases:
79
- * 1. `Decision::Permit` (no block in Enforce mode).
80
- * 2. **Any verdict in Observe mode** — Observe never blocks, but
81
- * the response headers still carry the would-have-been verdict.
82
- */
83
- interface RenderedResponse {
84
- status: number | null;
85
- headers: Record<string, string>;
86
- body?: string | object;
87
- }
88
-
89
- /**
90
- * HTTP-to-`AgentRequest` translator — Phase C.1.
91
- *
92
- * Detects which engine protocol the request belongs to and builds
93
- * the typed `AgentRequest` the WASM consumes. Conservative
94
- * detection: never escalates an ambiguous request into a higher
95
- * verification tier. Anonymous PlainHttp is the default.
96
- *
97
- * **What this layer parses and what it doesn't.** It parses *only
98
- * what's needed to drive conditional pre-fetch* — header presence,
99
- * the MCP-I envelope's payload segment (to extract `iss` + `sub` +
100
- * optional credentialStatus URL). It does **not** verify
101
- * signatures, decode VC chains for revocation bits, or evaluate
102
- * scope. Those live in the engine (H-1's parser + Stages 2-5).
103
- *
104
- * **Buffer-portability note.** This module uses `Buffer.from(...)` and
105
- * `Buffer.isBuffer(...)` at multiple call sites (the JWS preflight
106
- * `hasMalformedJwsBody`, both `tryBuildMcpIFromBody` variants, the
107
- * legacy-header reconstitution path, and `bodyAsBytes`). All of these
108
- * assume the Node `Buffer` global is available — provided natively by
109
- * the Node runtime, polyfilled on Vercel Edge, and gated behind
110
- * `nodejs_compat` on Cloudflare Workers. Bare-Edge and pure-browser
111
- * embedders would need a `Buffer` polyfill or a refactor to
112
- * `TextEncoder` / `Uint8Array.from`. Tracked as a follow-up since
113
- * Phase D's Vercel Node + Vercel Edge targets are both covered today.
114
- */
115
-
116
- interface BuildAgentRequestOpts {
117
- /** See `VerifyRequestOpts.legacyEnvelopeFallback`. */
118
- legacyEnvelopeFallback?: boolean;
119
- }
120
- /**
121
- * Translate an HTTP-like request into the engine's `AgentRequest`.
122
- *
123
- * Detection order (conservative — never escalate ambiguous input):
124
- * 1. MCP-I L2 detached proof in `_meta.proof.jws` (spec form).
125
- * 2. (Legacy, opt-in) MCP-I in `KYA-Delegation` header
126
- * (Envelope-1 #2537 transition window only).
127
- * 3. RFC 9421 HTTP Message Signatures (`Signature-Input` header).
128
- * 4. PlainHttp (default — anonymous traffic).
129
- */
130
- declare function buildAgentRequest(req: IncomingHttpLike, opts?: BuildAgentRequestOpts): AgentRequest;
131
- /**
132
- * Preflight check — does the request body carry a `_meta.proof.jws`
133
- * string that `parseJwsPayloadStruct` cannot project into a typed
134
- * `McpIPayload`?
135
- *
136
- * The caller declared intent (an MCP-I envelope) by including the
137
- * JWS field; structural failure to extract the payload means the
138
- * envelope is malformed, not absent. Without this preflight, the
139
- * orchestrator would silently fall through to PlainHttp — pre-#2560
140
- * that happened to also Block (engine returned `Block(ParseError)`
141
- * for every PlainHttp), so the regression was invisible; post-#2560
142
- * the engine's Stage 1 + stub policy returns `Permit` for anonymous
143
- * PlainHttp and tampered envelopes would be silently accepted.
144
- *
145
- * Returns `true` when the orchestrator should synthesize
146
- * `Block(ParseError)` BEFORE calling `buildAgentRequest`.
147
- */
148
- declare function hasMalformedJwsBody(req: IncomingHttpLike): boolean;
149
- /**
150
- * Issuer DID — Stage 1 (identity resolution) targets this. `null`
151
- * for PlainHttp (anonymous → no DID to resolve).
152
- */
153
- declare function extractIssuer(request: AgentRequest): string | null;
154
- /**
155
- * Agent DID — used by ReputationOracle. Defaults to `payload.sub`
156
- * for MCP-I (subject = the agent the proof is *about*).
157
- */
158
- declare function extractAgentDid(request: AgentRequest): string | null;
159
- /**
160
- * Status-list URL for revocation pre-fetch. Pulled from the JWS
161
- * payload's `vc.credentialStatus.id` (W3C VC Data Model 1.1).
162
- * `null` when the envelope is L1 (no VC chain) — Stage 3 will skip.
163
- */
164
- declare function extractCredentialStatusUrl(request: AgentRequest): string | null;
165
-
166
- /**
167
- * Transport-agnostic `Decision` → HTTP renderer — Phase C.3.
168
- *
169
- * Translates a `VerifyResult` into a framework-neutral
170
- * `{ status, headers, body }` shape. Phase D (Next.js) adapts this
171
- * to `NextResponse`; Phase E (Express) adapts it to `res.status().set().send()`.
172
- * One source of truth for the verdict→HTTP mapping.
173
- *
174
- * Mapping table (§ 4.5 of Phase C kickoff):
175
- *
176
- * | Decision | HTTP | Notes |
177
- * |-----------------------------------|------|-----------------------------------------|
178
- * | Permit | null | Pass through to next handler |
179
- * | Block(Unauthenticated) | 401 | WWW-Authenticate header |
180
- * | Block(InvalidSignature) | 403 | |
181
- * | Block(Revoked) | 403 | |
182
- * | Block(Expired) | 401 | Refresh-the-credential semantics |
183
- * | Block(OutOfScope) | 403 | Body carries requested + granted |
184
- * | Block(LowReputation) | 403 | Body carries score + threshold |
185
- * | Block(PolicyDenied) | 403 | Body carries detail |
186
- * | Block(ParseError) | 400 | Body carries detail |
187
- * | Challenge | 401 | Body carries ChallengeParams |
188
- * | Redirect | 302 | Location header |
189
- * | Instruct | 422 | application/problem+json body |
190
- *
191
- * Observe mode overrides: every verdict renders as `status: null`
192
- * (pass through) with an `X-Checkpoint-Would-Have-Been` header
193
- * carrying the verdict kind, plus the standard attribution headers.
194
- *
195
- * Every response carries the Phase 0.1 attribution headers:
196
- * `X-Checkpoint-Engine`, `X-Checkpoint-Engine-Version`, and
197
- * (when present) `X-Checkpoint-Ruleset-Hash`.
198
- */
199
-
200
- declare function renderDecisionAsResponse(result: VerifyResult): RenderedResponse;
6
+ import './adapters.js';
201
7
 
202
8
  /**
203
9
  * `verifyRequestEdge` async-init orchestrator — Edge-WASM-2 (folded into
@@ -240,4 +46,4 @@ declare function makeVerifyRequestEdge(opts: VerifyRequestOpts): (req: IncomingH
240
46
  */
241
47
  declare function verifyRequestEdge(req: IncomingHttpLike, opts: VerifyRequestOpts): Promise<VerifyResult>;
242
48
 
243
- export { type BuildAgentRequestOpts, type IncomingHttpLike, type RenderedResponse, type VerifyRequestOpts, buildAgentRequest, extractAgentDid, extractCredentialStatusUrl, extractIssuer, hasMalformedJwsBody, makeVerifyRequestEdge, renderDecisionAsResponse, verifyRequestEdge };
49
+ export { IncomingHttpLike, VerifyRequestOpts, makeVerifyRequestEdge, verifyRequestEdge };
@@ -1072,5 +1072,3 @@ exports.initEngineEdge = initEngineEdge;
1072
1072
  exports.makeVerifyRequestEdge = makeVerifyRequestEdge;
1073
1073
  exports.renderDecisionAsResponse = renderDecisionAsResponse;
1074
1074
  exports.verifyRequestEdge = verifyRequestEdge;
1075
- //# sourceMappingURL=orchestrator-edge.js.map
1076
- //# sourceMappingURL=orchestrator-edge.js.map
@@ -1061,5 +1061,3 @@ function defaultLogger(msg) {
1061
1061
  }
1062
1062
 
1063
1063
  export { buildAgentRequest, extractAgentDid, extractCredentialStatusUrl, extractIssuer, hasMalformedJwsBody, initEngineEdge, makeVerifyRequestEdge, renderDecisionAsResponse, verifyRequestEdge };
1064
- //# sourceMappingURL=orchestrator-edge.mjs.map
1065
- //# sourceMappingURL=orchestrator-edge.mjs.map
@@ -0,0 +1,49 @@
1
+ import { V as VerifyResult } from './types-D0j85fF0.mjs';
2
+ import { V as VerifyRequestOpts, I as IncomingHttpLike } from './render-decision-C1a-iuiW.mjs';
3
+ export { B as BuildAgentRequestOpts, R as RenderedResponse, b as buildAgentRequest, e as extractAgentDid, a as extractCredentialStatusUrl, c as extractIssuer, h as hasMalformedJwsBody, r as renderDecisionAsResponse } from './render-decision-C1a-iuiW.mjs';
4
+ import '@kya-os/checkpoint-shared';
5
+ import './adapters.mjs';
6
+
7
+ /**
8
+ * `verifyRequest` async orchestrator — Phase C.2.
9
+ *
10
+ * The single entry point Phase D (Next.js) and Phase E (Express)
11
+ * compose. Async pre-fetch on the host side; one sync `engineVerify`
12
+ * call across the WASM boundary. Sync-engine / async-host invariant
13
+ * (H-1 § 4.5) preserved.
14
+ *
15
+ * Orchestration:
16
+ * 1. Translate HTTP → AgentRequest (no engine I/O).
17
+ * 2. Extract identifiers (issuer DID, agent DID, status-list URL).
18
+ * 3. Conditional Promise.all over the *applicable* adapters —
19
+ * anonymous PlainHttp gets no network calls; signed MCP-I gets
20
+ * DID + status-list + reputation in parallel.
21
+ * 4. Translate adapter errors to verdicts where the architect-
22
+ * ratified posture says so:
23
+ * - DidResolver throw → Block(ParseError) verdict
24
+ * - StatusListCache throw → re-throw (host renders 503)
25
+ * - Reputation throw → impossible (Phase B § 4.5)
26
+ * 5. Compute the tenant Decision via PolicyEvaluator over the
27
+ * resolved reputation.
28
+ * 6. Build ContextSpec, call `engineVerify`, return VerifyResult.
29
+ *
30
+ * Cedar-1 forward-compat: step (5) is the only place the
31
+ * PolicyEvaluator interface gets exercised. When Cedar-1 swaps
32
+ * implementations, this orchestrator does not change.
33
+ */
34
+
35
+ /**
36
+ * Factory — constructs a `verifyRequest` closure that remembers the
37
+ * one-shot Argus-not-configured warning state. Use this when the
38
+ * host wrapper wants the startup log; call `verifyRequest` directly
39
+ * (the loose function below) if you don't.
40
+ */
41
+ declare function makeVerifyRequest(opts: VerifyRequestOpts): (req: IncomingHttpLike) => Promise<VerifyResult>;
42
+ /**
43
+ * Single-shot async entry. Use [`makeVerifyRequest`] in long-lived
44
+ * hosts (so the Argus warning is one-shot per process); use this
45
+ * loose form in tests + one-off invocations.
46
+ */
47
+ declare function verifyRequest(req: IncomingHttpLike, opts: VerifyRequestOpts): Promise<VerifyResult>;
48
+
49
+ export { IncomingHttpLike, VerifyRequestOpts, makeVerifyRequest, verifyRequest };