@nextera.one/axis-server-sdk 2.3.10 → 2.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -122,6 +122,31 @@ var init_capsule_policy_decorator = __esm({
122
122
  });
123
123
 
124
124
  // src/decorators/intent-policy.decorator.ts
125
+ function appendRequiredProof(target, propertyKey, proof) {
126
+ const existing = propertyKey !== void 0 ? Reflect.getMetadata(
127
+ REQUIRED_PROOF_METADATA_KEY,
128
+ target,
129
+ propertyKey
130
+ ) ?? [] : Reflect.getMetadata(
131
+ REQUIRED_PROOF_METADATA_KEY,
132
+ target
133
+ ) ?? [];
134
+ const merged = existing.includes(proof) ? existing : [...existing, proof];
135
+ if (propertyKey !== void 0) {
136
+ Reflect.defineMetadata(
137
+ REQUIRED_PROOF_METADATA_KEY,
138
+ merged,
139
+ target,
140
+ propertyKey
141
+ );
142
+ return;
143
+ }
144
+ Reflect.defineMetadata(
145
+ REQUIRED_PROOF_METADATA_KEY,
146
+ merged,
147
+ target
148
+ );
149
+ }
125
150
  function Sensitivity(level) {
126
151
  return ((target, propertyKey) => {
127
152
  if (propertyKey !== void 0) {
@@ -170,56 +195,12 @@ function RequiredProof(proofs) {
170
195
  }
171
196
  function Capsule() {
172
197
  return ((target, propertyKey) => {
173
- const existing = propertyKey !== void 0 ? Reflect.getMetadata(
174
- REQUIRED_PROOF_METADATA_KEY,
175
- target,
176
- propertyKey
177
- ) ?? [] : Reflect.getMetadata(
178
- REQUIRED_PROOF_METADATA_KEY,
179
- target
180
- ) ?? [];
181
- const merged = existing.includes("CAPSULE") ? existing : [...existing, "CAPSULE"];
182
- if (propertyKey !== void 0) {
183
- Reflect.defineMetadata(
184
- REQUIRED_PROOF_METADATA_KEY,
185
- merged,
186
- target,
187
- propertyKey
188
- );
189
- } else {
190
- Reflect.defineMetadata(
191
- REQUIRED_PROOF_METADATA_KEY,
192
- merged,
193
- target
194
- );
195
- }
198
+ appendRequiredProof(target, propertyKey, "CAPSULE");
196
199
  });
197
200
  }
198
201
  function Witness() {
199
202
  return ((target, propertyKey) => {
200
- const existing = propertyKey !== void 0 ? Reflect.getMetadata(
201
- REQUIRED_PROOF_METADATA_KEY,
202
- target,
203
- propertyKey
204
- ) ?? [] : Reflect.getMetadata(
205
- REQUIRED_PROOF_METADATA_KEY,
206
- target
207
- ) ?? [];
208
- const merged = existing.includes("WITNESS") ? existing : [...existing, "WITNESS"];
209
- if (propertyKey !== void 0) {
210
- Reflect.defineMetadata(
211
- REQUIRED_PROOF_METADATA_KEY,
212
- merged,
213
- target,
214
- propertyKey
215
- );
216
- } else {
217
- Reflect.defineMetadata(
218
- REQUIRED_PROOF_METADATA_KEY,
219
- merged,
220
- target
221
- );
222
- }
203
+ appendRequiredProof(target, propertyKey, "WITNESS");
223
204
  });
224
205
  }
225
206
  function Axis() {
@@ -229,31 +210,37 @@ function Axis() {
229
210
  }
230
211
  function AxisPublic() {
231
212
  return (target, propertyKey, descriptor) => {
232
- if (descriptor) {
213
+ if (propertyKey !== void 0) {
233
214
  Reflect.defineMetadata(AXIS_PUBLIC_KEY, true, target, propertyKey);
215
+ appendRequiredProof(target, propertyKey, "NONE");
234
216
  return descriptor;
235
217
  }
236
218
  Reflect.defineMetadata(AXIS_PUBLIC_KEY, true, target);
219
+ appendRequiredProof(target, void 0, "NONE");
237
220
  return target;
238
221
  };
239
222
  }
240
223
  function AxisAuthorized() {
241
224
  return (target, propertyKey, descriptor) => {
242
- if (descriptor) {
225
+ if (propertyKey !== void 0) {
243
226
  Reflect.defineMetadata(AXIS_AUTHORIZED_KEY, true, target, propertyKey);
227
+ appendRequiredProof(target, propertyKey, "AUTHORIZED");
244
228
  return descriptor;
245
229
  }
246
230
  Reflect.defineMetadata(AXIS_AUTHORIZED_KEY, true, target);
231
+ appendRequiredProof(target, void 0, "AUTHORIZED");
247
232
  return target;
248
233
  };
249
234
  }
250
235
  function AxisAnonymous() {
251
236
  return (target, propertyKey, descriptor) => {
252
- if (descriptor) {
237
+ if (propertyKey !== void 0) {
253
238
  Reflect.defineMetadata(AXIS_ANONYMOUS_KEY, true, target, propertyKey);
239
+ appendRequiredProof(target, propertyKey, "ANONYMOUS");
254
240
  return descriptor;
255
241
  }
256
242
  Reflect.defineMetadata(AXIS_ANONYMOUS_KEY, true, target);
243
+ appendRequiredProof(target, void 0, "ANONYMOUS");
257
244
  return target;
258
245
  };
259
246
  }
@@ -2306,6 +2293,147 @@ var init_axis_error = __esm({
2306
2293
  }
2307
2294
  });
2308
2295
 
2296
+ // src/engine/intent-builtins.ts
2297
+ function isBuiltinIntent(intent) {
2298
+ return BUILTIN_INTENTS.has(intent);
2299
+ }
2300
+ function isChainExecIntent(intent) {
2301
+ return intent === "CHAIN.EXEC" || intent === "axis.chain.exec";
2302
+ }
2303
+ function isIntentExecIntent(intent) {
2304
+ return intent === "INTENT.EXEC" || intent === "axis.intent.exec";
2305
+ }
2306
+ function routeSystemBuiltinIntent(intent, body, encoder) {
2307
+ if (intent === "system.ping" || intent === "public.ping") {
2308
+ return {
2309
+ ok: true,
2310
+ effect: "pong",
2311
+ headers: /* @__PURE__ */ new Map([[100, encoder.encode("AXIS_BACKEND_V1")]]),
2312
+ body: encoder.encode(
2313
+ JSON.stringify({
2314
+ status: "ok",
2315
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2316
+ version: "1.0.0"
2317
+ })
2318
+ )
2319
+ };
2320
+ }
2321
+ if (intent === "system.time") {
2322
+ const ts = Date.now().toString();
2323
+ return {
2324
+ ok: true,
2325
+ effect: "time",
2326
+ body: encoder.encode(
2327
+ JSON.stringify({
2328
+ ts,
2329
+ iso: (/* @__PURE__ */ new Date()).toISOString()
2330
+ })
2331
+ )
2332
+ };
2333
+ }
2334
+ if (intent === "system.echo") {
2335
+ return {
2336
+ ok: true,
2337
+ effect: "echo",
2338
+ body
2339
+ };
2340
+ }
2341
+ return void 0;
2342
+ }
2343
+ var BUILTIN_INTENTS;
2344
+ var init_intent_builtins = __esm({
2345
+ "src/engine/intent-builtins.ts"() {
2346
+ BUILTIN_INTENTS = /* @__PURE__ */ new Set([
2347
+ "system.ping",
2348
+ "public.ping",
2349
+ "system.time",
2350
+ "system.echo",
2351
+ "CHAIN.EXEC",
2352
+ "axis.chain.exec",
2353
+ "INTENT.EXEC",
2354
+ "axis.intent.exec"
2355
+ ]);
2356
+ }
2357
+ });
2358
+
2359
+ // src/engine/intent-proof-policy.ts
2360
+ function mergeProofKinds(...proofGroups) {
2361
+ const merged = /* @__PURE__ */ new Set();
2362
+ for (const proofs of proofGroups) {
2363
+ for (const proof of proofs ?? []) {
2364
+ merged.add(proof);
2365
+ }
2366
+ }
2367
+ return Array.from(merged);
2368
+ }
2369
+ function accessProofKinds(isPublic, isAnonymous, isAuthorized) {
2370
+ const proofs = [];
2371
+ if (isPublic) proofs.push("NONE");
2372
+ if (isAnonymous) proofs.push("ANONYMOUS");
2373
+ if (isAuthorized) proofs.push("AUTHORIZED");
2374
+ return proofs;
2375
+ }
2376
+ function resolveIntentProofPolicy(proto, methodName) {
2377
+ const methodProof = Reflect.getMetadata(
2378
+ REQUIRED_PROOF_METADATA_KEY,
2379
+ proto,
2380
+ methodName
2381
+ );
2382
+ const classProof = Reflect.getMetadata(
2383
+ REQUIRED_PROOF_METADATA_KEY,
2384
+ proto.constructor
2385
+ );
2386
+ const isPublicMethod = Reflect.getMetadata(
2387
+ AXIS_PUBLIC_KEY,
2388
+ proto,
2389
+ methodName
2390
+ );
2391
+ const isPublicClass = Reflect.getMetadata(
2392
+ AXIS_PUBLIC_KEY,
2393
+ proto.constructor
2394
+ );
2395
+ const isAnonymousMethod = Reflect.getMetadata(
2396
+ AXIS_ANONYMOUS_KEY,
2397
+ proto,
2398
+ methodName
2399
+ );
2400
+ const isAnonymousClass = Reflect.getMetadata(
2401
+ AXIS_ANONYMOUS_KEY,
2402
+ proto.constructor
2403
+ );
2404
+ const isAuthorizedMethod = Reflect.getMetadata(
2405
+ AXIS_AUTHORIZED_KEY,
2406
+ proto,
2407
+ methodName
2408
+ );
2409
+ const isAuthorizedClass = Reflect.getMetadata(
2410
+ AXIS_AUTHORIZED_KEY,
2411
+ proto.constructor
2412
+ );
2413
+ const methodPolicyProof = mergeProofKinds(
2414
+ methodProof,
2415
+ accessProofKinds(isPublicMethod, isAnonymousMethod, isAuthorizedMethod)
2416
+ );
2417
+ const classPolicyProof = mergeProofKinds(
2418
+ classProof,
2419
+ accessProofKinds(isPublicClass, isAnonymousClass, isAuthorizedClass)
2420
+ );
2421
+ const requiredProof = methodPolicyProof.length ? methodPolicyProof : classPolicyProof;
2422
+ return {
2423
+ requiredProof,
2424
+ isPublic: requiredProof.includes("NONE"),
2425
+ isAnonymous: requiredProof.includes("ANONYMOUS"),
2426
+ isAuthorized: requiredProof.includes("AUTHORIZED")
2427
+ };
2428
+ }
2429
+ var import_reflect_metadata12;
2430
+ var init_intent_proof_policy = __esm({
2431
+ "src/engine/intent-proof-policy.ts"() {
2432
+ import_reflect_metadata12 = require("reflect-metadata");
2433
+ init_intent_policy_decorator();
2434
+ }
2435
+ });
2436
+
2309
2437
  // src/engine/intent.router.ts
2310
2438
  var intent_router_exports = {};
2311
2439
  __export(intent_router_exports, {
@@ -2375,7 +2503,7 @@ function normalizeChainConfig(decoratorConfig, intentConfig) {
2375
2503
  ...intentConfig
2376
2504
  };
2377
2505
  }
2378
- var import_axis_protocol3, import_dto_schema, _IntentRouter, IntentRouter;
2506
+ var import_axis_protocol3, import_dto_schema, IntentRouter;
2379
2507
  var init_intent_router = __esm({
2380
2508
  "src/engine/intent.router.ts"() {
2381
2509
  import_axis_protocol3 = require("@nextera.one/axis-protocol");
@@ -2396,7 +2524,9 @@ var init_intent_router = __esm({
2396
2524
  init_cce_pipeline();
2397
2525
  init_axis_error();
2398
2526
  init_constants();
2399
- _IntentRouter = class _IntentRouter {
2527
+ init_intent_builtins();
2528
+ init_intent_proof_policy();
2529
+ IntentRouter = class _IntentRouter {
2400
2530
  constructor(dependencyResolver, observerDispatcher, sensorRegistry) {
2401
2531
  this.logger = createAxisLogger(_IntentRouter.name);
2402
2532
  this.decoder = new TextDecoder();
@@ -2427,12 +2557,6 @@ var init_intent_router = __esm({
2427
2557
  this.intentContracts = /* @__PURE__ */ new Map();
2428
2558
  /** Per-intent required proof kinds */
2429
2559
  this.intentRequiredProof = /* @__PURE__ */ new Map();
2430
- /** Intents flagged as public (no auth required) */
2431
- this.publicIntents = /* @__PURE__ */ new Set();
2432
- /** Intents flagged as anonymous-session accessible */
2433
- this.anonymousIntents = /* @__PURE__ */ new Set();
2434
- /** Intents flagged as authorized-session accessible */
2435
- this.authorizedIntents = /* @__PURE__ */ new Set();
2436
2560
  /** Per-intent rate limit config */
2437
2561
  this.intentRateLimits = /* @__PURE__ */ new Map();
2438
2562
  /** CCE handler registry */
@@ -2463,10 +2587,10 @@ var init_intent_router = __esm({
2463
2587
  }
2464
2588
  has(intent) {
2465
2589
  const resolved = this.resolveIntentAlias(intent);
2466
- return this.handlers.has(resolved) || _IntentRouter.BUILTIN_INTENTS.has(resolved);
2590
+ return this.handlers.has(resolved) || isBuiltinIntent(resolved);
2467
2591
  }
2468
2592
  getRegisteredIntents() {
2469
- return [..._IntentRouter.BUILTIN_INTENTS, ...this.handlers.keys()];
2593
+ return [...BUILTIN_INTENTS, ...this.handlers.keys()];
2470
2594
  }
2471
2595
  getIntentEntry(intent) {
2472
2596
  const resolved = this.resolveIntentAlias(intent);
@@ -2475,7 +2599,7 @@ var init_intent_router = __esm({
2475
2599
  schema: this.intentSchemas.get(resolved),
2476
2600
  validators: this.intentValidators.get(resolved),
2477
2601
  hasSensors: this.intentSensors.has(resolved),
2478
- builtin: _IntentRouter.BUILTIN_INTENTS.has(resolved),
2602
+ builtin: isBuiltinIntent(resolved),
2479
2603
  kind: this.intentKinds.get(resolved),
2480
2604
  chain: this.intentChains.get(resolved),
2481
2605
  capsulePolicy: this.intentCapsulePolicies.get(resolved),
@@ -2497,6 +2621,9 @@ var init_intent_router = __esm({
2497
2621
  * @param {any} handler - The handler function or object
2498
2622
  */
2499
2623
  register(intent, handler) {
2624
+ if (this.handlers.has(intent)) {
2625
+ this.logger.warn(`Intent ${intent} is already registered; replacing handler`);
2626
+ }
2500
2627
  this.handlers.set(intent, handler);
2501
2628
  if (typeof handler === "function" && handler.name) {
2502
2629
  this.intentHandlerRefs.set(intent, handler.name);
@@ -2607,128 +2734,7 @@ var init_intent_router = __esm({
2607
2734
  frame
2608
2735
  });
2609
2736
  let effect;
2610
- if (intent === "system.ping" || intent === "public.ping") {
2611
- this.logger.debug("PING received");
2612
- effect = {
2613
- ok: true,
2614
- effect: "pong",
2615
- headers: /* @__PURE__ */ new Map([
2616
- [100, new TextEncoder().encode("AXIS_BACKEND_V1")]
2617
- ]),
2618
- body: new TextEncoder().encode(
2619
- JSON.stringify({
2620
- status: "ok",
2621
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2622
- version: "1.0.0"
2623
- })
2624
- )
2625
- };
2626
- } else if (intent === "system.time") {
2627
- const ts = Date.now().toString();
2628
- effect = {
2629
- ok: true,
2630
- effect: "time",
2631
- body: new TextEncoder().encode(
2632
- JSON.stringify({
2633
- ts,
2634
- iso: (/* @__PURE__ */ new Date()).toISOString()
2635
- })
2636
- )
2637
- };
2638
- } else if (intent === "system.echo") {
2639
- effect = {
2640
- ok: true,
2641
- effect: "echo",
2642
- body: frame.body
2643
- };
2644
- } else if (intent === "CHAIN.EXEC" || intent === "axis.chain.exec") {
2645
- const chainRequest = this.parseChainRequestBody(frame.body);
2646
- effect = await this.executeChainRequest(frame, chainRequest);
2647
- } else if (intent === "INTENT.EXEC" || intent === "axis.intent.exec") {
2648
- const execBody = this.parseIntentExecBody(frame.body);
2649
- const innerIntent = execBody.intent;
2650
- const innerArgs = execBody.args || {};
2651
- if (!innerIntent) {
2652
- throw new Error("INTENT.EXEC missing inner intent");
2653
- }
2654
- this.logger.debug(`EXEC: routing to inner intent '${innerIntent}'`);
2655
- const innerHeaders = new Map(frame.headers);
2656
- innerHeaders.set(import_axis_protocol2.TLV_INTENT, this.encoder.encode(innerIntent));
2657
- const inlineCapsule = this.toInlineCapsuleRecord(execBody.capsule);
2658
- const capsuleId = this.extractInlineCapsuleId(inlineCapsule);
2659
- if (capsuleId) {
2660
- innerHeaders.set(import_axis_protocol2.TLV_CAPSULE, this.encoder.encode(capsuleId));
2661
- innerHeaders.set(import_axis_protocol2.TLV_PROOF_REF, this.encoder.encode(capsuleId));
2662
- }
2663
- const innerFrame = withAxisExecutionContext(
2664
- {
2665
- ...frame,
2666
- headers: innerHeaders,
2667
- body: this.encodeJson(innerArgs)
2668
- },
2669
- mergeAxisExecutionContext(getAxisExecutionContext(frame), {
2670
- metaIntent: "INTENT.EXEC",
2671
- actorId: this.getActorIdFromFrame(frame),
2672
- inlineCapsule
2673
- }) || {}
2674
- );
2675
- effect = await this.route(innerFrame);
2676
- } else {
2677
- const handler = this.handlers.get(intent);
2678
- if (!handler) {
2679
- throw new Error(`Intent not found: ${intent}`);
2680
- }
2681
- const sensorBindings = this.intentSensors.get(intent);
2682
- if (sensorBindings && sensorBindings.length > 0) {
2683
- await this.runIntentSensors(sensorBindings, intent, frame, "before");
2684
- }
2685
- const decoder = this.intentDecoders.get(intent);
2686
- let decodedBody = frame.body;
2687
- if (decoder) {
2688
- try {
2689
- decodedBody = decoder(Buffer.from(frame.body));
2690
- } catch (decodeErr) {
2691
- throw new Error(
2692
- `IntentBody decode failed for ${intent}: ${decodeErr.message}`
2693
- );
2694
- }
2695
- }
2696
- this.enforceCapsulePolicy(
2697
- intent,
2698
- frame,
2699
- decodedBody,
2700
- this.getEffectiveCapsulePolicy(intent, frame)
2701
- );
2702
- if (typeof handler === "function") {
2703
- const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
2704
- effect = {
2705
- ok: true,
2706
- effect: "complete",
2707
- body: resultBody
2708
- };
2709
- } else {
2710
- if (typeof handler.handle === "function") {
2711
- effect = await handler.handle(frame);
2712
- } else if (typeof handler.execute === "function") {
2713
- const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
2714
- effect = {
2715
- ok: true,
2716
- effect: "complete",
2717
- body: bodyRes
2718
- };
2719
- } else {
2720
- throw new Error(
2721
- `Handler for ${intent} does not implement handle or execute`
2722
- );
2723
- }
2724
- }
2725
- if (sensorBindings && sensorBindings.length > 0) {
2726
- await this.runIntentSensors(sensorBindings, intent, frame, "after", {
2727
- decodedBody,
2728
- effect
2729
- });
2730
- }
2731
- }
2737
+ effect = await this.routeResolvedIntent(intent, frame);
2732
2738
  await this.emitIntentObservers(observerBindings, {
2733
2739
  event: "intent.completed",
2734
2740
  timestamp: Date.now(),
@@ -2753,6 +2759,134 @@ var init_intent_router = __esm({
2753
2759
  throw e;
2754
2760
  }
2755
2761
  }
2762
+ /**
2763
+ * Dispatches a resolved canonical intent to the correct execution path.
2764
+ * This keeps route() focused on observer/error lifecycle concerns.
2765
+ */
2766
+ async routeResolvedIntent(intent, frame) {
2767
+ const builtinEffect = routeSystemBuiltinIntent(
2768
+ intent,
2769
+ frame.body,
2770
+ this.encoder
2771
+ );
2772
+ if (builtinEffect) {
2773
+ if (intent === "system.ping" || intent === "public.ping") {
2774
+ this.logger.debug("PING received");
2775
+ }
2776
+ return builtinEffect;
2777
+ }
2778
+ if (isChainExecIntent(intent)) {
2779
+ const chainRequest = this.parseChainRequestBody(frame.body);
2780
+ return this.executeChainRequest(frame, chainRequest);
2781
+ }
2782
+ if (isIntentExecIntent(intent)) {
2783
+ return this.routeIntentExec(frame);
2784
+ }
2785
+ return this.routeRegisteredIntent(intent, frame);
2786
+ }
2787
+ /**
2788
+ * Handles INTENT.EXEC by building an inner frame and routing it normally.
2789
+ * The recursive route call is intentional so sensors/observers/policies for
2790
+ * the inner intent stay identical to a direct request.
2791
+ */
2792
+ async routeIntentExec(frame) {
2793
+ const execBody = this.parseIntentExecBody(frame.body);
2794
+ const innerIntent = execBody.intent;
2795
+ const innerArgs = execBody.args || {};
2796
+ if (!innerIntent) {
2797
+ throw new Error("INTENT.EXEC missing inner intent");
2798
+ }
2799
+ this.logger.debug(`EXEC: routing to inner intent '${innerIntent}'`);
2800
+ const innerHeaders = new Map(frame.headers);
2801
+ innerHeaders.set(import_axis_protocol2.TLV_INTENT, this.encoder.encode(innerIntent));
2802
+ const inlineCapsule = this.toInlineCapsuleRecord(execBody.capsule);
2803
+ const capsuleId = this.extractInlineCapsuleId(inlineCapsule);
2804
+ if (capsuleId) {
2805
+ innerHeaders.set(import_axis_protocol2.TLV_CAPSULE, this.encoder.encode(capsuleId));
2806
+ innerHeaders.set(import_axis_protocol2.TLV_PROOF_REF, this.encoder.encode(capsuleId));
2807
+ }
2808
+ const innerFrame = withAxisExecutionContext(
2809
+ {
2810
+ ...frame,
2811
+ headers: innerHeaders,
2812
+ body: this.encodeJson(innerArgs)
2813
+ },
2814
+ mergeAxisExecutionContext(getAxisExecutionContext(frame), {
2815
+ metaIntent: "INTENT.EXEC",
2816
+ actorId: this.getActorIdFromFrame(frame),
2817
+ inlineCapsule
2818
+ }) || {}
2819
+ );
2820
+ return this.route(innerFrame);
2821
+ }
2822
+ /**
2823
+ * Executes an app-registered intent: before sensors, body decode, capsule
2824
+ * policy, handler invocation, then after sensors.
2825
+ */
2826
+ async routeRegisteredIntent(intent, frame) {
2827
+ const handler = this.handlers.get(intent);
2828
+ if (!handler) {
2829
+ throw new Error(`Intent not found: ${intent}`);
2830
+ }
2831
+ const sensorBindings = this.intentSensors.get(intent);
2832
+ if (sensorBindings && sensorBindings.length > 0) {
2833
+ await this.runIntentSensors(sensorBindings, intent, frame, "before");
2834
+ }
2835
+ const decoder = this.intentDecoders.get(intent);
2836
+ const decodedBody = this.decodeIntentBody(intent, frame, decoder);
2837
+ this.enforceCapsulePolicy(
2838
+ intent,
2839
+ frame,
2840
+ decodedBody,
2841
+ this.getEffectiveCapsulePolicy(intent, frame)
2842
+ );
2843
+ const effect = await this.invokeRegisteredHandler(
2844
+ intent,
2845
+ handler,
2846
+ frame,
2847
+ decoder,
2848
+ decodedBody
2849
+ );
2850
+ if (sensorBindings && sensorBindings.length > 0) {
2851
+ await this.runIntentSensors(sensorBindings, intent, frame, "after", {
2852
+ decodedBody,
2853
+ effect
2854
+ });
2855
+ }
2856
+ return effect;
2857
+ }
2858
+ decodeIntentBody(intent, frame, decoder) {
2859
+ if (!decoder) return frame.body;
2860
+ try {
2861
+ return decoder(Buffer.from(frame.body));
2862
+ } catch (decodeErr) {
2863
+ throw new Error(
2864
+ `IntentBody decode failed for ${intent}: ${decodeErr.message}`
2865
+ );
2866
+ }
2867
+ }
2868
+ async invokeRegisteredHandler(intent, handler, frame, decoder, decodedBody) {
2869
+ if (typeof handler === "function") {
2870
+ const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
2871
+ return {
2872
+ ok: true,
2873
+ effect: "complete",
2874
+ body: resultBody
2875
+ };
2876
+ }
2877
+ if (typeof handler.handle === "function") {
2878
+ return handler.handle(frame);
2879
+ }
2880
+ if (typeof handler.execute === "function") {
2881
+ const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
2882
+ return {
2883
+ ok: true,
2884
+ effect: "complete",
2885
+ body: bodyRes
2886
+ };
2887
+ }
2888
+ throw new Error(`Handler for ${intent} does not implement handle or execute`);
2889
+ }
2756
2890
  logIntent(intent, start, ok, error) {
2757
2891
  const diff = process.hrtime(start);
2758
2892
  const ms = (diff[0] * 1e3 + diff[1] / 1e6).toFixed(2);
@@ -2846,54 +2980,9 @@ var init_intent_router = __esm({
2846
2980
  if (contract) {
2847
2981
  this.intentContracts.set(intent, contract);
2848
2982
  }
2849
- const methodProof = Reflect.getMetadata(
2850
- REQUIRED_PROOF_METADATA_KEY,
2851
- proto,
2852
- methodName
2853
- );
2854
- const classProof = Reflect.getMetadata(
2855
- REQUIRED_PROOF_METADATA_KEY,
2856
- proto.constructor
2857
- );
2858
- const requiredProof = methodProof ?? classProof;
2859
- if (requiredProof && requiredProof.length > 0) {
2860
- this.intentRequiredProof.set(intent, requiredProof);
2861
- }
2862
- const isPublicMethod = Reflect.getMetadata(
2863
- AXIS_PUBLIC_KEY,
2864
- proto,
2865
- methodName
2866
- );
2867
- const isPublicClass = Reflect.getMetadata(
2868
- AXIS_PUBLIC_KEY,
2869
- proto.constructor
2870
- );
2871
- if (isPublicMethod || isPublicClass) {
2872
- this.publicIntents.add(intent);
2873
- }
2874
- const isAnonMethod = Reflect.getMetadata(
2875
- AXIS_ANONYMOUS_KEY,
2876
- proto,
2877
- methodName
2878
- );
2879
- const isAnonClass = Reflect.getMetadata(
2880
- AXIS_ANONYMOUS_KEY,
2881
- proto.constructor
2882
- );
2883
- if (isAnonMethod || isAnonClass) {
2884
- this.anonymousIntents.add(intent);
2885
- }
2886
- const isAuthorizedMethod = Reflect.getMetadata(
2887
- AXIS_AUTHORIZED_KEY,
2888
- proto,
2889
- methodName
2890
- );
2891
- const isAuthorizedClass = Reflect.getMetadata(
2892
- AXIS_AUTHORIZED_KEY,
2893
- proto.constructor
2894
- );
2895
- if (isAuthorizedMethod || isAuthorizedClass) {
2896
- this.authorizedIntents.add(intent);
2983
+ const proofPolicy = resolveIntentProofPolicy(proto, methodName);
2984
+ if (proofPolicy.requiredProof.length > 0) {
2985
+ this.intentRequiredProof.set(intent, proofPolicy.requiredProof);
2897
2986
  }
2898
2987
  const rateLimit = Reflect.getMetadata(
2899
2988
  AXIS_RATE_LIMIT_KEY,
@@ -2915,13 +3004,13 @@ var init_intent_router = __esm({
2915
3004
  return this.intentRequiredProof.get(this.resolveIntentAlias(intent));
2916
3005
  }
2917
3006
  isPublic(intent) {
2918
- return this.publicIntents.has(this.resolveIntentAlias(intent));
3007
+ return this.getRequiredProof(intent)?.includes("NONE") ?? false;
2919
3008
  }
2920
3009
  isAnonymous(intent) {
2921
- return this.anonymousIntents.has(this.resolveIntentAlias(intent));
3010
+ return this.getRequiredProof(intent)?.includes("ANONYMOUS") ?? false;
2922
3011
  }
2923
3012
  isAuthorized(intent) {
2924
- return this.authorizedIntents.has(this.resolveIntentAlias(intent));
3013
+ return this.getRequiredProof(intent)?.includes("AUTHORIZED") ?? false;
2925
3014
  }
2926
3015
  getRateLimit(intent) {
2927
3016
  return this.intentRateLimits.get(this.resolveIntentAlias(intent));
@@ -2942,7 +3031,7 @@ var init_intent_router = __esm({
2942
3031
  }
2943
3032
  /** The system/builtin intents (ping, time, echo, chain, intent.exec). */
2944
3033
  getSystemIntents() {
2945
- return [..._IntentRouter.BUILTIN_INTENTS];
3034
+ return [...BUILTIN_INTENTS];
2946
3035
  }
2947
3036
  /** True if every intent in the handler is public, or any one is public — returns true if ANY intent is @AxisPublic. */
2948
3037
  isHandlerPublic(handlerName) {
@@ -3015,7 +3104,7 @@ var init_intent_router = __esm({
3015
3104
  * canonical intent. Existing exact intent names always win.
3016
3105
  */
3017
3106
  resolveIntentAlias(intent) {
3018
- if (this.handlers.has(intent) || _IntentRouter.BUILTIN_INTENTS.has(intent)) {
3107
+ if (this.handlers.has(intent) || isBuiltinIntent(intent)) {
3019
3108
  return intent;
3020
3109
  }
3021
3110
  const separator = "...";
@@ -3539,18 +3628,6 @@ var init_intent_router = __esm({
3539
3628
  this.intentSchemas.set(meta.intent, schema);
3540
3629
  }
3541
3630
  };
3542
- /** Intents handled inline in route() — not in `handlers` map */
3543
- _IntentRouter.BUILTIN_INTENTS = /* @__PURE__ */ new Set([
3544
- "system.ping",
3545
- "public.ping",
3546
- "system.time",
3547
- "system.echo",
3548
- "CHAIN.EXEC",
3549
- "axis.chain.exec",
3550
- "INTENT.EXEC",
3551
- "axis.intent.exec"
3552
- ]);
3553
- IntentRouter = _IntentRouter;
3554
3631
  }
3555
3632
  });
3556
3633