@kya-os/checkpoint-nextjs 1.2.0 → 1.7.1

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 (52) hide show
  1. package/CHANGELOG.md +159 -0
  2. package/EDGE_RUNTIME_WASM_SETUP.md +1 -1
  3. package/bin/setup-edge-wasm.js +1 -1
  4. package/dist/api-middleware.d.mts +9 -1
  5. package/dist/api-middleware.d.ts +9 -1
  6. package/dist/api-middleware.js +14 -4
  7. package/dist/api-middleware.mjs +15 -5
  8. package/dist/composed-policy.d.mts +115 -0
  9. package/dist/composed-policy.d.ts +115 -0
  10. package/dist/composed-policy.js +102 -0
  11. package/dist/composed-policy.mjs +96 -0
  12. package/dist/config-DAwIA4DB.d.mts +214 -0
  13. package/dist/config-DyU4l5er.d.ts +214 -0
  14. package/dist/create-middleware.js +0 -2
  15. package/dist/create-middleware.mjs +0 -2
  16. package/dist/edge-runtime-loader.js +3 -1
  17. package/dist/edge-runtime-loader.mjs +3 -1
  18. package/dist/edge-wasm-middleware.d.mts +6 -6
  19. package/dist/edge-wasm-middleware.d.ts +6 -6
  20. package/dist/index.d.mts +6 -14
  21. package/dist/index.d.ts +6 -14
  22. package/dist/index.js +191 -13
  23. package/dist/index.mjs +192 -14
  24. package/dist/middleware-edge.d.mts +7 -3
  25. package/dist/middleware-edge.d.ts +7 -3
  26. package/dist/middleware-edge.js +174 -4
  27. package/dist/middleware-edge.mjs +171 -4
  28. package/dist/middleware-node.d.mts +39 -116
  29. package/dist/middleware-node.d.ts +39 -116
  30. package/dist/middleware-node.js +181 -4
  31. package/dist/middleware-node.mjs +178 -5
  32. package/dist/middleware.d.mts +10 -1
  33. package/dist/middleware.d.ts +10 -1
  34. package/dist/middleware.js +6 -0
  35. package/dist/middleware.mjs +6 -1
  36. package/dist/nodejs-wasm-loader.d.mts +3 -4
  37. package/dist/nodejs-wasm-loader.d.ts +3 -4
  38. package/dist/nodejs-wasm-loader.js +1 -1
  39. package/dist/nodejs-wasm-loader.mjs +1 -1
  40. package/dist/wasm-setup.js +1 -1
  41. package/dist/wasm-setup.mjs +1 -1
  42. package/package.json +4 -9
  43. package/dist/.tsbuildinfo +0 -1
  44. package/dist/signature-verifier.d.mts +0 -33
  45. package/dist/signature-verifier.d.ts +0 -33
  46. package/dist/signature-verifier.js +0 -384
  47. package/dist/signature-verifier.mjs +0 -360
  48. package/dist/wasm-middleware.d.mts +0 -98
  49. package/dist/wasm-middleware.d.ts +0 -98
  50. package/dist/wasm-middleware.js +0 -125
  51. package/dist/wasm-middleware.mjs +0 -121
  52. package/templates/middleware-wasm-100.ts +0 -161
@@ -0,0 +1,96 @@
1
+ import { makeComposedPolicyCache, evaluateComposedPolicy, verifyResultToAuthorizeInput } from '@kya-os/checkpoint-wasm-runtime/composed-policy';
2
+ import { requestCarriesDelegationProof } from '@kya-os/checkpoint-shared';
3
+
4
+ // src/composed-policy.ts
5
+ var DEFAULT_DASHBOARD_URL = "https://kya.vouched.id";
6
+ var NOOP_LOGGER = {
7
+ shadowDivergence: () => {
8
+ },
9
+ evaluationError: () => {
10
+ }
11
+ };
12
+ function makeComposedPolicyContext(opts) {
13
+ const { projectId, fetcher } = opts;
14
+ const cache = makeComposedPolicyCache({ compile: opts.compile, cacheMax: opts.cacheMax });
15
+ const logger = opts.logger ?? NOOP_LOGGER;
16
+ return {
17
+ async apply(result, path) {
18
+ const structured = { decision: result.decision, acted: false };
19
+ const policy = await fetcher.getPolicy(projectId);
20
+ const outcome = await evaluateComposedPolicy({
21
+ cache,
22
+ projectId,
23
+ flags: {
24
+ policyLanguage: policy.policyLanguage,
25
+ policySourceText: policy.policySourceText,
26
+ engineEnforcementEnabled: policy.engineEnforcementEnabled,
27
+ enabled: policy.enabled
28
+ },
29
+ authorizeInput: verifyResultToAuthorizeInput(result, { tenantId: projectId, path }),
30
+ baselineDecisionKind: result.decision.kind
31
+ });
32
+ if ((outcome.status === "acting" || outcome.status === "shadow") && outcome.diverged) {
33
+ logger.shadowDivergence({
34
+ projectId,
35
+ path,
36
+ engineDecision: outcome.engineDecision.kind,
37
+ structuredDecision: result.decision.kind,
38
+ detectionClass: result.detectionDetail.detectionClass.type,
39
+ verificationMethod: result.detectionDetail.verificationMethod,
40
+ confidence: result.detectionDetail.confidence,
41
+ agentName: result.detectionDetail.detectedAgent?.name
42
+ });
43
+ }
44
+ if (outcome.status === "error") {
45
+ logger.evaluationError(projectId, outcome.error);
46
+ return structured;
47
+ }
48
+ if (outcome.status === "acting") {
49
+ return {
50
+ decision: outcome.engineDecision,
51
+ acted: true,
52
+ // Echo the SSOT revision pin with the decision it produced (#3246
53
+ // PR5). Conditional spread: absent upstream stays absent here.
54
+ ...policy.policySourceHash ? { composedBlobHash: policy.policySourceHash } : {}
55
+ };
56
+ }
57
+ return structured;
58
+ },
59
+ async trustedDelegationRoots() {
60
+ const policy = await fetcher.getPolicy(projectId);
61
+ return policy.trustedDelegationRoots ?? [];
62
+ }
63
+ };
64
+ }
65
+ async function resolveTrustedDelegationRootsForRequest(resolver, headers) {
66
+ if (!resolver) return void 0;
67
+ if (!requestCarriesDelegationProof(headers)) return void 0;
68
+ const roots = await resolver();
69
+ return roots.length > 0 ? roots : void 0;
70
+ }
71
+ async function applyComposedPolicy(context, result, path) {
72
+ if (!context) return;
73
+ try {
74
+ const outcome = await context.apply(result, path);
75
+ if (outcome.acted) {
76
+ result.decision = outcome.decision;
77
+ if (outcome.composedBlobHash) {
78
+ result.composedBlobHash = outcome.composedBlobHash;
79
+ }
80
+ }
81
+ } catch {
82
+ }
83
+ }
84
+ var consoleComposedPolicyLogger = {
85
+ shadowDivergence(info) {
86
+ console.warn("[checkpoint/composed-policy] shadow-divergence", info);
87
+ },
88
+ evaluationError(projectId, error) {
89
+ console.error(
90
+ `[checkpoint/composed-policy] evaluation failed for ${projectId}; using structured decision:`,
91
+ error
92
+ );
93
+ }
94
+ };
95
+
96
+ export { DEFAULT_DASHBOARD_URL, applyComposedPolicy, consoleComposedPolicyLogger, makeComposedPolicyContext, resolveTrustedDelegationRootsForRequest };
@@ -0,0 +1,214 @@
1
+ import { NextRequest } from 'next/server';
2
+ import { DidResolverAdapter, StatusListCacheAdapter, ReputationOracleAdapter, PolicyEvaluatorAdapter } from '@kya-os/checkpoint-wasm-runtime/adapters';
3
+ import { EnforcementMode, VerifyResult, EngineConfig } from '@kya-os/checkpoint-wasm-runtime/engine';
4
+ import { ChallengeEnvelopeMode } from '@kya-os/checkpoint-shared';
5
+ import { ComposedPolicyContext } from './composed-policy.mjs';
6
+
7
+ /**
8
+ * `CheckpointConfig` — the `withCheckpoint` config contract for both the Node
9
+ * (`./node`) and Edge (`./edge`) middleware entries. Extracted from
10
+ * `middleware-node.ts` (a 190-line documented contract); both entries import it
11
+ * from here and re-export it so the public import paths
12
+ * (`@kya-os/checkpoint-nextjs`, `/node`, `/edge`) are unchanged.
13
+ */
14
+
15
+ /**
16
+ * Configuration for `withCheckpoint`.
17
+ *
18
+ * The new minimal shape Phase D's middleware needs. Legacy
19
+ * `AgentShieldMiddlewareConfig` (from `./api-middleware`) remains
20
+ * exported during the deprecation window — see D.4 cutover.
21
+ */
22
+ interface CheckpointConfig {
23
+ /**
24
+ * Tenant identifier — typically the customer's dashboard hostname
25
+ * (e.g. `acme.checkpoint.example`). The PolicyEvaluator uses this
26
+ * to look up tenant policy from the dashboard.
27
+ */
28
+ tenantHost: string;
29
+ /**
30
+ * `'enforce'` (default) blocks; `'observe'` passes everything
31
+ * through with `X-Checkpoint-Would-Have-Been` headers. Per Phase 0.2.
32
+ */
33
+ enforcementMode?: EnforcementMode;
34
+ /**
35
+ * Challenge-emission envelope mode (draft-kya-http-02 §8.1 fetcher-200).
36
+ * `negotiated` serves a body-readable HTTP 200 step-up response to
37
+ * cooperative agents (fetchers that drop 4xx/5xx bodies), keeping the spec
38
+ * 401/422 for everyone else. Defaults to `spec-401`. A cooperative-UX
39
+ * bridge, NOT an access control.
40
+ */
41
+ delegationChallengeMode?: ChallengeEnvelopeMode;
42
+ /**
43
+ * Argus reputation oracle base URL. Omit to use the trust-by-default
44
+ * baseline (reputation defaults to 1.0; orchestrator logs a one-shot
45
+ * warning at first request).
46
+ */
47
+ argusUrl?: string;
48
+ /**
49
+ * Dashboard base URL for the PolicyEvaluator to fetch tenant policy
50
+ * from. Omit to use the open-by-default tenant policy.
51
+ */
52
+ dashboardUrl?: string;
53
+ /**
54
+ * Returned to the PolicyEvaluator for anonymous requests (no agent
55
+ * DID). Default 1.0 (trust-by-default).
56
+ */
57
+ reputationBaseline?: number;
58
+ /**
59
+ * Pre-built adapter instances. Production deployments use the
60
+ * factory-built defaults from `@kya-os/checkpoint-wasm-runtime/adapters`;
61
+ * tests use stubs. The factory composes any provided overrides over
62
+ * defaults — partial overrides are supported.
63
+ */
64
+ adapters?: Partial<{
65
+ didResolver: DidResolverAdapter;
66
+ statusListCache: StatusListCacheAdapter;
67
+ reputationOracle: ReputationOracleAdapter;
68
+ policyEvaluator: PolicyEvaluatorAdapter;
69
+ }>;
70
+ /**
71
+ * Optional callback for the post-verdict path — fires after every
72
+ * verification, regardless of permit/block, with the full
73
+ * `VerifyResult`. Use for logging, dashboards, telemetry. Errors
74
+ * thrown here are swallowed so user code can't break the middleware
75
+ * response.
76
+ */
77
+ onResult?: (result: VerifyResult, req: NextRequest) => void | Promise<void>;
78
+ /**
79
+ * Accept legacy `KYA-Delegation`-header envelope form alongside the
80
+ * canonical `_meta.proof.jws` body form. Default `false`.
81
+ *
82
+ * **When to enable** — customers whose agents pre-date Envelope-1
83
+ * (#2537) and ship MCP-I proofs as `{protected,payload,signature}`
84
+ * JSON in a `KYA-Delegation` HTTP header. Post-Envelope-1 agents
85
+ * ship compact JWS in the request body's `_meta.proof.jws` field;
86
+ * those don't need this flag.
87
+ *
88
+ * Forwarded to the orchestrator's `VerifyRequestOpts.legacyEnvelopeFallback`.
89
+ * Both transports (header + body) are honored when this is `true`;
90
+ * the orchestrator's detection order is body first, then header
91
+ * (`packages/checkpoint-wasm-runtime/src/engine/orchestrator/build-agent-request.ts`).
92
+ *
93
+ * SDK-Envelope-Plumbing-1 (#2594). Added in `@kya-os/checkpoint-nextjs@1.1.0`.
94
+ */
95
+ legacyEnvelopeFallback?: boolean;
96
+ /**
97
+ * Read the request body when `content-type` is `application/json` so
98
+ * the orchestrator can extract an MCP-I envelope from
99
+ * `_meta.proof.jws`. Default `true`.
100
+ *
101
+ * **When to disable** — streaming middlewares that can't tolerate
102
+ * the `req.clone()` memory overhead (one full-body copy is buffered
103
+ * during the read). For those, set `false` and route MCP-I
104
+ * envelopes through the `KYA-Delegation` header transport instead
105
+ * (requires `legacyEnvelopeFallback: true`).
106
+ *
107
+ * The clone preserves `req.body` for downstream handlers — disabling
108
+ * is a performance optimization, not a correctness fix.
109
+ *
110
+ * SDK-Envelope-Plumbing-1 (#2594). Added in `@kya-os/checkpoint-nextjs@1.1.0`.
111
+ */
112
+ drainJsonBody?: boolean;
113
+ /**
114
+ * Engine-default behaviour knobs forwarded to every composed
115
+ * `ContextSpec`. Defaults to `{ tier3Action: 'monitor' }` —
116
+ * customer-onboarding-safe (tenant policy decides; engine doesn't
117
+ * short-circuit known-agent UAs with an engine-default Block).
118
+ *
119
+ * Opt into `{ tier3Action: 'block' }` when the host wants the
120
+ * calibrated engine-default block for KnownAiAgent / AiCrawler /
121
+ * HeadlessBrowser classifications BEFORE the tenant policy seam.
122
+ *
123
+ * Added in `@kya-os/checkpoint-nextjs@1.2.0` (Engine-Tier3-Monitor-
124
+ * Default, #2653 + this PR's plumbing follow-up).
125
+ */
126
+ engineConfig?: EngineConfig;
127
+ /**
128
+ * Project API key. Required for detections to land in the dashboard
129
+ * — the engine verifies in-process via WASM, but the resulting
130
+ * `VerifyResult` only reaches the dashboard's `detections` table
131
+ * when this reporter is configured. Without it the verdict path
132
+ * works locally but the onboarding "Verify connection" check fails
133
+ * forever because no rows are ever written.
134
+ *
135
+ * Resolve from `process.env.CHECKPOINT_API_KEY` in the host app.
136
+ *
137
+ * Added in `@kya-os/checkpoint-nextjs@1.4.0`
138
+ * (SDK-Detection-Reporter-1).
139
+ */
140
+ apiKey?: string;
141
+ /**
142
+ * Dashboard base URL. Defaults to `https://kya.vouched.id`.
143
+ * Override for staging or self-hosted dashboards.
144
+ */
145
+ baseUrl?: string;
146
+ /**
147
+ * Surface reporter errors via `console.warn`. Defaults to `false`.
148
+ * The reporter is fire-and-forget; enable during development to
149
+ * confirm `apiKey` / `baseUrl` are routed correctly.
150
+ *
151
+ * Also wires the composed-policy shadow-divergence + fail-open
152
+ * telemetry to `console.warn`/`console.error` (otherwise silent).
153
+ */
154
+ debug?: boolean;
155
+ /**
156
+ * Project id whose composed (/policy-compose) policy this middleware
157
+ * enforces. When set, the project's policy is fetched from the dashboard
158
+ * (`<dashboardUrl ?? baseUrl ?? default>/api/internal/policies/${projectId}`)
159
+ * and — if it carries a deployed Cedar bundle with `engineEnforcementEnabled`
160
+ * on — the kya-os-engine decision is enforced IN-PROCESS, byte-for-byte the
161
+ * same as the DNS Gateway. Omit to run detection + the structured policy only
162
+ * (fully back-compatible; purely additive).
163
+ *
164
+ * SHADOW-FIRST: with a deployed bundle but `engineEnforcementEnabled` off, the
165
+ * engine decision is computed + logged on divergence but does NOT act.
166
+ *
167
+ * **Node vs Edge:** composed enforcement is default-on under the Node runtime
168
+ * (`./node`). Under the Edge runtime (`./edge`) it additionally requires
169
+ * `cedarWasmModule` to be wired (see below) — otherwise the seam stays inert.
170
+ *
171
+ * Added in `@kya-os/checkpoint-nextjs@1.5.0` (@Policy middleware-Cedar, #3076).
172
+ */
173
+ projectId?: string;
174
+ /**
175
+ * Policy-fetch cache TTL in seconds. Defaults to 300 (5 minutes). How long
176
+ * a fetched project policy is reused before the middleware refetches from
177
+ * the dashboard — i.e. the worst-case delay before a dashboard policy
178
+ * change takes effect on this host.
179
+ *
180
+ * `0` disables reuse entirely: every request fetches the policy (one
181
+ * origin round-trip per request). Use for demo/example sites where instant
182
+ * policy propagation matters more than latency; keep the default (or a
183
+ * small positive value like 5) for production and benchmark hosts.
184
+ */
185
+ policyCacheTtlSeconds?: number;
186
+ /**
187
+ * Advanced / testing: inject a pre-built composed-policy context instead of
188
+ * letting `withCheckpoint` construct one from `projectId` + `baseUrl` +
189
+ * `apiKey`. Mirrors the `adapters` injection philosophy — production omits
190
+ * this. When set, it takes precedence over `projectId`.
191
+ */
192
+ composedPolicyEnforcer?: ComposedPolicyContext;
193
+ /**
194
+ * EDGE runtime only. The cedar-web `WebAssembly.Module`, statically imported
195
+ * by the host so composed-policy Cedar can compile at the edge:
196
+ *
197
+ * ```ts
198
+ * import cedarWasmModule from
199
+ * '@kya-os/checkpoint-wasm-runtime/wasm/kya-os-engine-cedar-web/kya_os_engine_bg.wasm?module';
200
+ * export default withCheckpoint({ projectId, cedarWasmModule });
201
+ * ```
202
+ *
203
+ * The ~2 MB cedar binary is deliberately NOT bundled into the SDK — wiring it
204
+ * is the consumer's explicit opt-in for edge composed enforcement (requires
205
+ * `experiments.asyncWebAssembly` + a `.wasm` asset rule in `next.config`).
206
+ * Without it the Edge seam stays inert (behaves exactly as 1.4.0); the Node
207
+ * runtime ignores this field (it loads cedar via `createPolicyEvaluator`).
208
+ *
209
+ * Added in `@kya-os/checkpoint-nextjs@1.5.0` (@Policy middleware-Cedar, #3076).
210
+ */
211
+ cedarWasmModule?: WebAssembly.Module;
212
+ }
213
+
214
+ export type { CheckpointConfig as C };
@@ -0,0 +1,214 @@
1
+ import { NextRequest } from 'next/server';
2
+ import { DidResolverAdapter, StatusListCacheAdapter, ReputationOracleAdapter, PolicyEvaluatorAdapter } from '@kya-os/checkpoint-wasm-runtime/adapters';
3
+ import { EnforcementMode, VerifyResult, EngineConfig } from '@kya-os/checkpoint-wasm-runtime/engine';
4
+ import { ChallengeEnvelopeMode } from '@kya-os/checkpoint-shared';
5
+ import { ComposedPolicyContext } from './composed-policy.js';
6
+
7
+ /**
8
+ * `CheckpointConfig` — the `withCheckpoint` config contract for both the Node
9
+ * (`./node`) and Edge (`./edge`) middleware entries. Extracted from
10
+ * `middleware-node.ts` (a 190-line documented contract); both entries import it
11
+ * from here and re-export it so the public import paths
12
+ * (`@kya-os/checkpoint-nextjs`, `/node`, `/edge`) are unchanged.
13
+ */
14
+
15
+ /**
16
+ * Configuration for `withCheckpoint`.
17
+ *
18
+ * The new minimal shape Phase D's middleware needs. Legacy
19
+ * `AgentShieldMiddlewareConfig` (from `./api-middleware`) remains
20
+ * exported during the deprecation window — see D.4 cutover.
21
+ */
22
+ interface CheckpointConfig {
23
+ /**
24
+ * Tenant identifier — typically the customer's dashboard hostname
25
+ * (e.g. `acme.checkpoint.example`). The PolicyEvaluator uses this
26
+ * to look up tenant policy from the dashboard.
27
+ */
28
+ tenantHost: string;
29
+ /**
30
+ * `'enforce'` (default) blocks; `'observe'` passes everything
31
+ * through with `X-Checkpoint-Would-Have-Been` headers. Per Phase 0.2.
32
+ */
33
+ enforcementMode?: EnforcementMode;
34
+ /**
35
+ * Challenge-emission envelope mode (draft-kya-http-02 §8.1 fetcher-200).
36
+ * `negotiated` serves a body-readable HTTP 200 step-up response to
37
+ * cooperative agents (fetchers that drop 4xx/5xx bodies), keeping the spec
38
+ * 401/422 for everyone else. Defaults to `spec-401`. A cooperative-UX
39
+ * bridge, NOT an access control.
40
+ */
41
+ delegationChallengeMode?: ChallengeEnvelopeMode;
42
+ /**
43
+ * Argus reputation oracle base URL. Omit to use the trust-by-default
44
+ * baseline (reputation defaults to 1.0; orchestrator logs a one-shot
45
+ * warning at first request).
46
+ */
47
+ argusUrl?: string;
48
+ /**
49
+ * Dashboard base URL for the PolicyEvaluator to fetch tenant policy
50
+ * from. Omit to use the open-by-default tenant policy.
51
+ */
52
+ dashboardUrl?: string;
53
+ /**
54
+ * Returned to the PolicyEvaluator for anonymous requests (no agent
55
+ * DID). Default 1.0 (trust-by-default).
56
+ */
57
+ reputationBaseline?: number;
58
+ /**
59
+ * Pre-built adapter instances. Production deployments use the
60
+ * factory-built defaults from `@kya-os/checkpoint-wasm-runtime/adapters`;
61
+ * tests use stubs. The factory composes any provided overrides over
62
+ * defaults — partial overrides are supported.
63
+ */
64
+ adapters?: Partial<{
65
+ didResolver: DidResolverAdapter;
66
+ statusListCache: StatusListCacheAdapter;
67
+ reputationOracle: ReputationOracleAdapter;
68
+ policyEvaluator: PolicyEvaluatorAdapter;
69
+ }>;
70
+ /**
71
+ * Optional callback for the post-verdict path — fires after every
72
+ * verification, regardless of permit/block, with the full
73
+ * `VerifyResult`. Use for logging, dashboards, telemetry. Errors
74
+ * thrown here are swallowed so user code can't break the middleware
75
+ * response.
76
+ */
77
+ onResult?: (result: VerifyResult, req: NextRequest) => void | Promise<void>;
78
+ /**
79
+ * Accept legacy `KYA-Delegation`-header envelope form alongside the
80
+ * canonical `_meta.proof.jws` body form. Default `false`.
81
+ *
82
+ * **When to enable** — customers whose agents pre-date Envelope-1
83
+ * (#2537) and ship MCP-I proofs as `{protected,payload,signature}`
84
+ * JSON in a `KYA-Delegation` HTTP header. Post-Envelope-1 agents
85
+ * ship compact JWS in the request body's `_meta.proof.jws` field;
86
+ * those don't need this flag.
87
+ *
88
+ * Forwarded to the orchestrator's `VerifyRequestOpts.legacyEnvelopeFallback`.
89
+ * Both transports (header + body) are honored when this is `true`;
90
+ * the orchestrator's detection order is body first, then header
91
+ * (`packages/checkpoint-wasm-runtime/src/engine/orchestrator/build-agent-request.ts`).
92
+ *
93
+ * SDK-Envelope-Plumbing-1 (#2594). Added in `@kya-os/checkpoint-nextjs@1.1.0`.
94
+ */
95
+ legacyEnvelopeFallback?: boolean;
96
+ /**
97
+ * Read the request body when `content-type` is `application/json` so
98
+ * the orchestrator can extract an MCP-I envelope from
99
+ * `_meta.proof.jws`. Default `true`.
100
+ *
101
+ * **When to disable** — streaming middlewares that can't tolerate
102
+ * the `req.clone()` memory overhead (one full-body copy is buffered
103
+ * during the read). For those, set `false` and route MCP-I
104
+ * envelopes through the `KYA-Delegation` header transport instead
105
+ * (requires `legacyEnvelopeFallback: true`).
106
+ *
107
+ * The clone preserves `req.body` for downstream handlers — disabling
108
+ * is a performance optimization, not a correctness fix.
109
+ *
110
+ * SDK-Envelope-Plumbing-1 (#2594). Added in `@kya-os/checkpoint-nextjs@1.1.0`.
111
+ */
112
+ drainJsonBody?: boolean;
113
+ /**
114
+ * Engine-default behaviour knobs forwarded to every composed
115
+ * `ContextSpec`. Defaults to `{ tier3Action: 'monitor' }` —
116
+ * customer-onboarding-safe (tenant policy decides; engine doesn't
117
+ * short-circuit known-agent UAs with an engine-default Block).
118
+ *
119
+ * Opt into `{ tier3Action: 'block' }` when the host wants the
120
+ * calibrated engine-default block for KnownAiAgent / AiCrawler /
121
+ * HeadlessBrowser classifications BEFORE the tenant policy seam.
122
+ *
123
+ * Added in `@kya-os/checkpoint-nextjs@1.2.0` (Engine-Tier3-Monitor-
124
+ * Default, #2653 + this PR's plumbing follow-up).
125
+ */
126
+ engineConfig?: EngineConfig;
127
+ /**
128
+ * Project API key. Required for detections to land in the dashboard
129
+ * — the engine verifies in-process via WASM, but the resulting
130
+ * `VerifyResult` only reaches the dashboard's `detections` table
131
+ * when this reporter is configured. Without it the verdict path
132
+ * works locally but the onboarding "Verify connection" check fails
133
+ * forever because no rows are ever written.
134
+ *
135
+ * Resolve from `process.env.CHECKPOINT_API_KEY` in the host app.
136
+ *
137
+ * Added in `@kya-os/checkpoint-nextjs@1.4.0`
138
+ * (SDK-Detection-Reporter-1).
139
+ */
140
+ apiKey?: string;
141
+ /**
142
+ * Dashboard base URL. Defaults to `https://kya.vouched.id`.
143
+ * Override for staging or self-hosted dashboards.
144
+ */
145
+ baseUrl?: string;
146
+ /**
147
+ * Surface reporter errors via `console.warn`. Defaults to `false`.
148
+ * The reporter is fire-and-forget; enable during development to
149
+ * confirm `apiKey` / `baseUrl` are routed correctly.
150
+ *
151
+ * Also wires the composed-policy shadow-divergence + fail-open
152
+ * telemetry to `console.warn`/`console.error` (otherwise silent).
153
+ */
154
+ debug?: boolean;
155
+ /**
156
+ * Project id whose composed (/policy-compose) policy this middleware
157
+ * enforces. When set, the project's policy is fetched from the dashboard
158
+ * (`<dashboardUrl ?? baseUrl ?? default>/api/internal/policies/${projectId}`)
159
+ * and — if it carries a deployed Cedar bundle with `engineEnforcementEnabled`
160
+ * on — the kya-os-engine decision is enforced IN-PROCESS, byte-for-byte the
161
+ * same as the DNS Gateway. Omit to run detection + the structured policy only
162
+ * (fully back-compatible; purely additive).
163
+ *
164
+ * SHADOW-FIRST: with a deployed bundle but `engineEnforcementEnabled` off, the
165
+ * engine decision is computed + logged on divergence but does NOT act.
166
+ *
167
+ * **Node vs Edge:** composed enforcement is default-on under the Node runtime
168
+ * (`./node`). Under the Edge runtime (`./edge`) it additionally requires
169
+ * `cedarWasmModule` to be wired (see below) — otherwise the seam stays inert.
170
+ *
171
+ * Added in `@kya-os/checkpoint-nextjs@1.5.0` (@Policy middleware-Cedar, #3076).
172
+ */
173
+ projectId?: string;
174
+ /**
175
+ * Policy-fetch cache TTL in seconds. Defaults to 300 (5 minutes). How long
176
+ * a fetched project policy is reused before the middleware refetches from
177
+ * the dashboard — i.e. the worst-case delay before a dashboard policy
178
+ * change takes effect on this host.
179
+ *
180
+ * `0` disables reuse entirely: every request fetches the policy (one
181
+ * origin round-trip per request). Use for demo/example sites where instant
182
+ * policy propagation matters more than latency; keep the default (or a
183
+ * small positive value like 5) for production and benchmark hosts.
184
+ */
185
+ policyCacheTtlSeconds?: number;
186
+ /**
187
+ * Advanced / testing: inject a pre-built composed-policy context instead of
188
+ * letting `withCheckpoint` construct one from `projectId` + `baseUrl` +
189
+ * `apiKey`. Mirrors the `adapters` injection philosophy — production omits
190
+ * this. When set, it takes precedence over `projectId`.
191
+ */
192
+ composedPolicyEnforcer?: ComposedPolicyContext;
193
+ /**
194
+ * EDGE runtime only. The cedar-web `WebAssembly.Module`, statically imported
195
+ * by the host so composed-policy Cedar can compile at the edge:
196
+ *
197
+ * ```ts
198
+ * import cedarWasmModule from
199
+ * '@kya-os/checkpoint-wasm-runtime/wasm/kya-os-engine-cedar-web/kya_os_engine_bg.wasm?module';
200
+ * export default withCheckpoint({ projectId, cedarWasmModule });
201
+ * ```
202
+ *
203
+ * The ~2 MB cedar binary is deliberately NOT bundled into the SDK — wiring it
204
+ * is the consumer's explicit opt-in for edge composed enforcement (requires
205
+ * `experiments.asyncWebAssembly` + a `.wasm` asset rule in `next.config`).
206
+ * Without it the Edge seam stays inert (behaves exactly as 1.4.0); the Node
207
+ * runtime ignores this field (it loads cedar via `createPolicyEvaluator`).
208
+ *
209
+ * Added in `@kya-os/checkpoint-nextjs@1.5.0` (@Policy middleware-Cedar, #3076).
210
+ */
211
+ cedarWasmModule?: WebAssembly.Module;
212
+ }
213
+
214
+ export type { CheckpointConfig as C };
@@ -3,8 +3,6 @@
3
3
  var server = require('next/server');
4
4
 
5
5
  // src/create-middleware.ts
6
-
7
- // src/middleware.ts
8
6
  var MIGRATION_ERROR = "@kya-os/checkpoint-nextjs's `createAgentShieldMiddleware` / `agentShield` were deleted in Phase D (engine consolidation). The 600-line TS pattern matcher that backed them is gone. Migrate to `withCheckpoint` from `@kya-os/checkpoint-nextjs` (Node runtime) or `@kya-os/checkpoint-nextjs/edge` (Edge runtime). See packages/checkpoint-nextjs/CHANGELOG.md (1.0.0) for the recipe.";
9
7
  function createAgentShieldMiddleware(_config = {}) {
10
8
  throw new Error(MIGRATION_ERROR);
@@ -1,8 +1,6 @@
1
1
  import { NextResponse } from 'next/server';
2
2
 
3
3
  // src/create-middleware.ts
4
-
5
- // src/middleware.ts
6
4
  var MIGRATION_ERROR = "@kya-os/checkpoint-nextjs's `createAgentShieldMiddleware` / `agentShield` were deleted in Phase D (engine consolidation). The 600-line TS pattern matcher that backed them is gone. Migrate to `withCheckpoint` from `@kya-os/checkpoint-nextjs` (Node runtime) or `@kya-os/checkpoint-nextjs/edge` (Edge runtime). See packages/checkpoint-nextjs/CHANGELOG.md (1.0.0) for the recipe.";
7
5
  function createAgentShieldMiddleware(_config = {}) {
8
6
  throw new Error(MIGRATION_ERROR);
@@ -25,11 +25,13 @@ var SUSPICIOUS_HEADER_PREFIXES = ["x-openai-", "x-anthropic-", "x-ai-", "x-llm-"
25
25
  function escapeRegex(s) {
26
26
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
27
27
  }
28
+ var REGEX_SYNTAX_PATTERN = /(?:\\.|[()[\]{}|^$]|\.\*|\.\+|\.\?)/;
28
29
  var TOKEN_REGEX_CACHE = /* @__PURE__ */ new Map();
29
30
  function tokenRegex(token) {
30
31
  const cached = TOKEN_REGEX_CACHE.get(token);
31
32
  if (cached) return cached;
32
- const regex = new RegExp(`\\b${escapeRegex(token)}\\b`, "i");
33
+ const source = REGEX_SYNTAX_PATTERN.test(token) ? token : escapeRegex(token);
34
+ const regex = new RegExp(`(^|[^a-z0-9])${source}($|[^a-z0-9])`, "i");
33
35
  TOKEN_REGEX_CACHE.set(token, regex);
34
36
  return regex;
35
37
  }
@@ -23,11 +23,13 @@ var SUSPICIOUS_HEADER_PREFIXES = ["x-openai-", "x-anthropic-", "x-ai-", "x-llm-"
23
23
  function escapeRegex(s) {
24
24
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
25
25
  }
26
+ var REGEX_SYNTAX_PATTERN = /(?:\\.|[()[\]{}|^$]|\.\*|\.\+|\.\?)/;
26
27
  var TOKEN_REGEX_CACHE = /* @__PURE__ */ new Map();
27
28
  function tokenRegex(token) {
28
29
  const cached = TOKEN_REGEX_CACHE.get(token);
29
30
  if (cached) return cached;
30
- const regex = new RegExp(`\\b${escapeRegex(token)}\\b`, "i");
31
+ const source = REGEX_SYNTAX_PATTERN.test(token) ? token : escapeRegex(token);
32
+ const regex = new RegExp(`(^|[^a-z0-9])${source}($|[^a-z0-9])`, "i");
31
33
  TOKEN_REGEX_CACHE.set(token, regex);
32
34
  return regex;
33
35
  }
@@ -5,13 +5,13 @@ import { NextRequest, NextResponse } from 'next/server';
5
5
  * the retired `agentshield-wasm` Rust crate. This file shipped hand-
6
6
  * written wasm-bindgen glue code that loaded the legacy detector's
7
7
  * WASM binary; PR #2599's SSOT consolidation + PDM-1 #2560's engine
8
- * move + AgentDetector-Deletion-1 PR #2610's class-deprecation made
9
- * it structural dead weight.
8
+ * move + AgentDetector-Deletion-1 PR #2610's class-deprecation +
9
+ * AgentDetector-Deletion-2's class removal made it structural dead weight.
10
10
  *
11
- * Phase-D.9a converts the exports to throw-stubs (same precedent as
12
- * PR #2610's `createWasmAgentShieldMiddleware` deprecation). Phase-D.9b
13
- * (follow-up) deletes the underlying `agentshield-wasm` Rust crate
14
- * after migrating the production Cloudflare gateway worker.
11
+ * Phase-D.9a converts the exports to throw-stubs (same precedent the
12
+ * `createWasmAgentShieldMiddleware` removal used). Phase-D.9b (follow-up)
13
+ * deletes the underlying `agentshield-wasm` Rust crate after migrating
14
+ * the production Cloudflare gateway worker.
15
15
  *
16
16
  * Migrate to `withCheckpoint` from `@kya-os/checkpoint-nextjs/edge` —
17
17
  * engine-backed, runs the full kya-os-engine orchestrator including
@@ -5,13 +5,13 @@ import { NextRequest, NextResponse } from 'next/server';
5
5
  * the retired `agentshield-wasm` Rust crate. This file shipped hand-
6
6
  * written wasm-bindgen glue code that loaded the legacy detector's
7
7
  * WASM binary; PR #2599's SSOT consolidation + PDM-1 #2560's engine
8
- * move + AgentDetector-Deletion-1 PR #2610's class-deprecation made
9
- * it structural dead weight.
8
+ * move + AgentDetector-Deletion-1 PR #2610's class-deprecation +
9
+ * AgentDetector-Deletion-2's class removal made it structural dead weight.
10
10
  *
11
- * Phase-D.9a converts the exports to throw-stubs (same precedent as
12
- * PR #2610's `createWasmAgentShieldMiddleware` deprecation). Phase-D.9b
13
- * (follow-up) deletes the underlying `agentshield-wasm` Rust crate
14
- * after migrating the production Cloudflare gateway worker.
11
+ * Phase-D.9a converts the exports to throw-stubs (same precedent the
12
+ * `createWasmAgentShieldMiddleware` removal used). Phase-D.9b (follow-up)
13
+ * deletes the underlying `agentshield-wasm` Rust crate after migrating
14
+ * the production Cloudflare gateway worker.
15
15
  *
16
16
  * Migrate to `withCheckpoint` from `@kya-os/checkpoint-nextjs/edge` —
17
17
  * engine-backed, runs the full kya-os-engine orchestrator including
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { CheckpointConfig, withCheckpoint } from './middleware-node.mjs';
1
+ export { VERSION, withCheckpoint } from './middleware-node.mjs';
2
2
  export { createAgentShieldMiddleware, createAgentShieldMiddleware as createMiddleware } from './create-middleware.mjs';
3
3
  export { AgentDetectionEvent, AgentSession, AgentShieldMiddlewareConfig, CheckpointApiMiddlewareConfig, EnhancedMiddlewareConfig, StorageAdapter, StorageConfig, agentShieldMiddleware, createEnhancedAgentShieldMiddleware, withAgentShield, withCheckpointApi } from './api-middleware.mjs';
4
4
  export { createAgentShieldMiddleware as createAgentShieldMiddlewareBase } from './middleware.mjs';
@@ -6,20 +6,12 @@ export { EdgeSessionTracker, SessionData, SessionTrackingConfig, StatelessSessio
6
6
  export { AgentShieldClient, AgentShieldClientConfig, CheckpointApiClient, CheckpointApiClientConfig, EnforceInput, EnforceResponse, EnforcementDecision, LogDetectionInput, getAgentShieldClient, getCheckpointApiClient, resetAgentShieldClient, resetCheckpointApiClient } from './api-client.mjs';
7
7
  export { A as AgentShieldRequest, D as DetectionContext, N as NextJSMiddlewareConfig } from './types-D9RQvPNy.mjs';
8
8
  export { NextJSPolicyMiddlewareConfig, PolicyMiddlewareConfig, applyPolicy, buildBlockedResponse as buildPolicyBlockedResponse, buildRedirectResponse as buildPolicyRedirectResponse, createContextFromDetection, evaluatePolicyForDetection, getPolicy, handlePolicyDecision } from './policy.mjs';
9
+ export { C as CheckpointConfig } from './config-DAwIA4DB.mjs';
9
10
  export { DEFAULT_POLICY, ENFORCEMENT_ACTIONS, EnforcementAction, PolicyConfig, PolicyEvaluationContext, PolicyEvaluationResult, createEvaluationContext, evaluatePolicy } from '@kya-os/checkpoint-shared';
11
+ import '@kya-os/checkpoint-wasm-runtime/engine';
10
12
  import '@kya-os/checkpoint-wasm-runtime/adapters';
11
13
  import 'next/server';
12
- import '@kya-os/checkpoint-wasm-runtime/engine';
14
+ import '@kya-os/checkpoint-wasm-runtime/reporter';
15
+ import './composed-policy.mjs';
16
+ import '@kya-os/checkpoint-wasm-runtime/composed-policy';
13
17
  import '@kya-os/checkpoint';
14
-
15
- /**
16
- * @fileoverview Checkpoint Next.js Integration
17
- * @license MIT OR Apache-2.0
18
- */
19
-
20
- /**
21
- * Library version
22
- */
23
- declare const VERSION = "0.1.0";
24
-
25
- export { VERSION };