@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.
@@ -381,6 +381,31 @@ var init_capsule_policy_decorator = __esm({
381
381
  });
382
382
 
383
383
  // src/decorators/intent-policy.decorator.ts
384
+ function appendRequiredProof(target, propertyKey, proof) {
385
+ const existing = propertyKey !== void 0 ? Reflect.getMetadata(
386
+ REQUIRED_PROOF_METADATA_KEY,
387
+ target,
388
+ propertyKey
389
+ ) ?? [] : Reflect.getMetadata(
390
+ REQUIRED_PROOF_METADATA_KEY,
391
+ target
392
+ ) ?? [];
393
+ const merged = existing.includes(proof) ? existing : [...existing, proof];
394
+ if (propertyKey !== void 0) {
395
+ Reflect.defineMetadata(
396
+ REQUIRED_PROOF_METADATA_KEY,
397
+ merged,
398
+ target,
399
+ propertyKey
400
+ );
401
+ return;
402
+ }
403
+ Reflect.defineMetadata(
404
+ REQUIRED_PROOF_METADATA_KEY,
405
+ merged,
406
+ target
407
+ );
408
+ }
384
409
  function Sensitivity(level) {
385
410
  return ((target, propertyKey) => {
386
411
  if (propertyKey !== void 0) {
@@ -429,56 +454,12 @@ function RequiredProof(proofs) {
429
454
  }
430
455
  function Capsule() {
431
456
  return ((target, propertyKey) => {
432
- const existing = propertyKey !== void 0 ? Reflect.getMetadata(
433
- REQUIRED_PROOF_METADATA_KEY,
434
- target,
435
- propertyKey
436
- ) ?? [] : Reflect.getMetadata(
437
- REQUIRED_PROOF_METADATA_KEY,
438
- target
439
- ) ?? [];
440
- const merged = existing.includes("CAPSULE") ? existing : [...existing, "CAPSULE"];
441
- if (propertyKey !== void 0) {
442
- Reflect.defineMetadata(
443
- REQUIRED_PROOF_METADATA_KEY,
444
- merged,
445
- target,
446
- propertyKey
447
- );
448
- } else {
449
- Reflect.defineMetadata(
450
- REQUIRED_PROOF_METADATA_KEY,
451
- merged,
452
- target
453
- );
454
- }
457
+ appendRequiredProof(target, propertyKey, "CAPSULE");
455
458
  });
456
459
  }
457
460
  function Witness() {
458
461
  return ((target, propertyKey) => {
459
- const existing = propertyKey !== void 0 ? Reflect.getMetadata(
460
- REQUIRED_PROOF_METADATA_KEY,
461
- target,
462
- propertyKey
463
- ) ?? [] : Reflect.getMetadata(
464
- REQUIRED_PROOF_METADATA_KEY,
465
- target
466
- ) ?? [];
467
- const merged = existing.includes("WITNESS") ? existing : [...existing, "WITNESS"];
468
- if (propertyKey !== void 0) {
469
- Reflect.defineMetadata(
470
- REQUIRED_PROOF_METADATA_KEY,
471
- merged,
472
- target,
473
- propertyKey
474
- );
475
- } else {
476
- Reflect.defineMetadata(
477
- REQUIRED_PROOF_METADATA_KEY,
478
- merged,
479
- target
480
- );
481
- }
462
+ appendRequiredProof(target, propertyKey, "WITNESS");
482
463
  });
483
464
  }
484
465
  function Axis() {
@@ -488,31 +469,37 @@ function Axis() {
488
469
  }
489
470
  function AxisPublic() {
490
471
  return (target, propertyKey, descriptor) => {
491
- if (descriptor) {
472
+ if (propertyKey !== void 0) {
492
473
  Reflect.defineMetadata(AXIS_PUBLIC_KEY, true, target, propertyKey);
474
+ appendRequiredProof(target, propertyKey, "NONE");
493
475
  return descriptor;
494
476
  }
495
477
  Reflect.defineMetadata(AXIS_PUBLIC_KEY, true, target);
478
+ appendRequiredProof(target, void 0, "NONE");
496
479
  return target;
497
480
  };
498
481
  }
499
482
  function AxisAuthorized() {
500
483
  return (target, propertyKey, descriptor) => {
501
- if (descriptor) {
484
+ if (propertyKey !== void 0) {
502
485
  Reflect.defineMetadata(AXIS_AUTHORIZED_KEY, true, target, propertyKey);
486
+ appendRequiredProof(target, propertyKey, "AUTHORIZED");
503
487
  return descriptor;
504
488
  }
505
489
  Reflect.defineMetadata(AXIS_AUTHORIZED_KEY, true, target);
490
+ appendRequiredProof(target, void 0, "AUTHORIZED");
506
491
  return target;
507
492
  };
508
493
  }
509
494
  function AxisAnonymous() {
510
495
  return (target, propertyKey, descriptor) => {
511
- if (descriptor) {
496
+ if (propertyKey !== void 0) {
512
497
  Reflect.defineMetadata(AXIS_ANONYMOUS_KEY, true, target, propertyKey);
498
+ appendRequiredProof(target, propertyKey, "ANONYMOUS");
513
499
  return descriptor;
514
500
  }
515
501
  Reflect.defineMetadata(AXIS_ANONYMOUS_KEY, true, target);
502
+ appendRequiredProof(target, void 0, "ANONYMOUS");
516
503
  return target;
517
504
  };
518
505
  }
@@ -2451,6 +2438,147 @@ var init_axis_error = __esm({
2451
2438
  }
2452
2439
  });
2453
2440
 
2441
+ // src/engine/intent-builtins.ts
2442
+ function isBuiltinIntent(intent) {
2443
+ return BUILTIN_INTENTS.has(intent);
2444
+ }
2445
+ function isChainExecIntent(intent) {
2446
+ return intent === "CHAIN.EXEC" || intent === "axis.chain.exec";
2447
+ }
2448
+ function isIntentExecIntent(intent) {
2449
+ return intent === "INTENT.EXEC" || intent === "axis.intent.exec";
2450
+ }
2451
+ function routeSystemBuiltinIntent(intent, body, encoder) {
2452
+ if (intent === "system.ping" || intent === "public.ping") {
2453
+ return {
2454
+ ok: true,
2455
+ effect: "pong",
2456
+ headers: /* @__PURE__ */ new Map([[100, encoder.encode("AXIS_BACKEND_V1")]]),
2457
+ body: encoder.encode(
2458
+ JSON.stringify({
2459
+ status: "ok",
2460
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2461
+ version: "1.0.0"
2462
+ })
2463
+ )
2464
+ };
2465
+ }
2466
+ if (intent === "system.time") {
2467
+ const ts = Date.now().toString();
2468
+ return {
2469
+ ok: true,
2470
+ effect: "time",
2471
+ body: encoder.encode(
2472
+ JSON.stringify({
2473
+ ts,
2474
+ iso: (/* @__PURE__ */ new Date()).toISOString()
2475
+ })
2476
+ )
2477
+ };
2478
+ }
2479
+ if (intent === "system.echo") {
2480
+ return {
2481
+ ok: true,
2482
+ effect: "echo",
2483
+ body
2484
+ };
2485
+ }
2486
+ return void 0;
2487
+ }
2488
+ var BUILTIN_INTENTS;
2489
+ var init_intent_builtins = __esm({
2490
+ "src/engine/intent-builtins.ts"() {
2491
+ BUILTIN_INTENTS = /* @__PURE__ */ new Set([
2492
+ "system.ping",
2493
+ "public.ping",
2494
+ "system.time",
2495
+ "system.echo",
2496
+ "CHAIN.EXEC",
2497
+ "axis.chain.exec",
2498
+ "INTENT.EXEC",
2499
+ "axis.intent.exec"
2500
+ ]);
2501
+ }
2502
+ });
2503
+
2504
+ // src/engine/intent-proof-policy.ts
2505
+ function mergeProofKinds(...proofGroups) {
2506
+ const merged = /* @__PURE__ */ new Set();
2507
+ for (const proofs of proofGroups) {
2508
+ for (const proof of proofs ?? []) {
2509
+ merged.add(proof);
2510
+ }
2511
+ }
2512
+ return Array.from(merged);
2513
+ }
2514
+ function accessProofKinds(isPublic, isAnonymous, isAuthorized) {
2515
+ const proofs = [];
2516
+ if (isPublic) proofs.push("NONE");
2517
+ if (isAnonymous) proofs.push("ANONYMOUS");
2518
+ if (isAuthorized) proofs.push("AUTHORIZED");
2519
+ return proofs;
2520
+ }
2521
+ function resolveIntentProofPolicy(proto, methodName) {
2522
+ const methodProof = Reflect.getMetadata(
2523
+ REQUIRED_PROOF_METADATA_KEY,
2524
+ proto,
2525
+ methodName
2526
+ );
2527
+ const classProof = Reflect.getMetadata(
2528
+ REQUIRED_PROOF_METADATA_KEY,
2529
+ proto.constructor
2530
+ );
2531
+ const isPublicMethod = Reflect.getMetadata(
2532
+ AXIS_PUBLIC_KEY,
2533
+ proto,
2534
+ methodName
2535
+ );
2536
+ const isPublicClass = Reflect.getMetadata(
2537
+ AXIS_PUBLIC_KEY,
2538
+ proto.constructor
2539
+ );
2540
+ const isAnonymousMethod = Reflect.getMetadata(
2541
+ AXIS_ANONYMOUS_KEY,
2542
+ proto,
2543
+ methodName
2544
+ );
2545
+ const isAnonymousClass = Reflect.getMetadata(
2546
+ AXIS_ANONYMOUS_KEY,
2547
+ proto.constructor
2548
+ );
2549
+ const isAuthorizedMethod = Reflect.getMetadata(
2550
+ AXIS_AUTHORIZED_KEY,
2551
+ proto,
2552
+ methodName
2553
+ );
2554
+ const isAuthorizedClass = Reflect.getMetadata(
2555
+ AXIS_AUTHORIZED_KEY,
2556
+ proto.constructor
2557
+ );
2558
+ const methodPolicyProof = mergeProofKinds(
2559
+ methodProof,
2560
+ accessProofKinds(isPublicMethod, isAnonymousMethod, isAuthorizedMethod)
2561
+ );
2562
+ const classPolicyProof = mergeProofKinds(
2563
+ classProof,
2564
+ accessProofKinds(isPublicClass, isAnonymousClass, isAuthorizedClass)
2565
+ );
2566
+ const requiredProof = methodPolicyProof.length ? methodPolicyProof : classPolicyProof;
2567
+ return {
2568
+ requiredProof,
2569
+ isPublic: requiredProof.includes("NONE"),
2570
+ isAnonymous: requiredProof.includes("ANONYMOUS"),
2571
+ isAuthorized: requiredProof.includes("AUTHORIZED")
2572
+ };
2573
+ }
2574
+ var import_reflect_metadata12;
2575
+ var init_intent_proof_policy = __esm({
2576
+ "src/engine/intent-proof-policy.ts"() {
2577
+ import_reflect_metadata12 = require("reflect-metadata");
2578
+ init_intent_policy_decorator();
2579
+ }
2580
+ });
2581
+
2454
2582
  // src/engine/intent.router.ts
2455
2583
  var intent_router_exports = {};
2456
2584
  __export(intent_router_exports, {
@@ -2520,7 +2648,7 @@ function normalizeChainConfig(decoratorConfig, intentConfig) {
2520
2648
  ...intentConfig
2521
2649
  };
2522
2650
  }
2523
- var import_axis_protocol4, import_dto_schema, _IntentRouter, IntentRouter;
2651
+ var import_axis_protocol4, import_dto_schema, IntentRouter;
2524
2652
  var init_intent_router = __esm({
2525
2653
  "src/engine/intent.router.ts"() {
2526
2654
  import_axis_protocol4 = require("@nextera.one/axis-protocol");
@@ -2541,7 +2669,9 @@ var init_intent_router = __esm({
2541
2669
  init_cce_pipeline();
2542
2670
  init_axis_error();
2543
2671
  init_constants();
2544
- _IntentRouter = class _IntentRouter {
2672
+ init_intent_builtins();
2673
+ init_intent_proof_policy();
2674
+ IntentRouter = class _IntentRouter {
2545
2675
  constructor(dependencyResolver, observerDispatcher, sensorRegistry) {
2546
2676
  this.logger = createAxisLogger(_IntentRouter.name);
2547
2677
  this.decoder = new TextDecoder();
@@ -2572,12 +2702,6 @@ var init_intent_router = __esm({
2572
2702
  this.intentContracts = /* @__PURE__ */ new Map();
2573
2703
  /** Per-intent required proof kinds */
2574
2704
  this.intentRequiredProof = /* @__PURE__ */ new Map();
2575
- /** Intents flagged as public (no auth required) */
2576
- this.publicIntents = /* @__PURE__ */ new Set();
2577
- /** Intents flagged as anonymous-session accessible */
2578
- this.anonymousIntents = /* @__PURE__ */ new Set();
2579
- /** Intents flagged as authorized-session accessible */
2580
- this.authorizedIntents = /* @__PURE__ */ new Set();
2581
2705
  /** Per-intent rate limit config */
2582
2706
  this.intentRateLimits = /* @__PURE__ */ new Map();
2583
2707
  /** CCE handler registry */
@@ -2608,10 +2732,10 @@ var init_intent_router = __esm({
2608
2732
  }
2609
2733
  has(intent) {
2610
2734
  const resolved = this.resolveIntentAlias(intent);
2611
- return this.handlers.has(resolved) || _IntentRouter.BUILTIN_INTENTS.has(resolved);
2735
+ return this.handlers.has(resolved) || isBuiltinIntent(resolved);
2612
2736
  }
2613
2737
  getRegisteredIntents() {
2614
- return [..._IntentRouter.BUILTIN_INTENTS, ...this.handlers.keys()];
2738
+ return [...BUILTIN_INTENTS, ...this.handlers.keys()];
2615
2739
  }
2616
2740
  getIntentEntry(intent) {
2617
2741
  const resolved = this.resolveIntentAlias(intent);
@@ -2620,7 +2744,7 @@ var init_intent_router = __esm({
2620
2744
  schema: this.intentSchemas.get(resolved),
2621
2745
  validators: this.intentValidators.get(resolved),
2622
2746
  hasSensors: this.intentSensors.has(resolved),
2623
- builtin: _IntentRouter.BUILTIN_INTENTS.has(resolved),
2747
+ builtin: isBuiltinIntent(resolved),
2624
2748
  kind: this.intentKinds.get(resolved),
2625
2749
  chain: this.intentChains.get(resolved),
2626
2750
  capsulePolicy: this.intentCapsulePolicies.get(resolved),
@@ -2642,6 +2766,9 @@ var init_intent_router = __esm({
2642
2766
  * @param {any} handler - The handler function or object
2643
2767
  */
2644
2768
  register(intent, handler) {
2769
+ if (this.handlers.has(intent)) {
2770
+ this.logger.warn(`Intent ${intent} is already registered; replacing handler`);
2771
+ }
2645
2772
  this.handlers.set(intent, handler);
2646
2773
  if (typeof handler === "function" && handler.name) {
2647
2774
  this.intentHandlerRefs.set(intent, handler.name);
@@ -2752,128 +2879,7 @@ var init_intent_router = __esm({
2752
2879
  frame
2753
2880
  });
2754
2881
  let effect;
2755
- if (intent === "system.ping" || intent === "public.ping") {
2756
- this.logger.debug("PING received");
2757
- effect = {
2758
- ok: true,
2759
- effect: "pong",
2760
- headers: /* @__PURE__ */ new Map([
2761
- [100, new TextEncoder().encode("AXIS_BACKEND_V1")]
2762
- ]),
2763
- body: new TextEncoder().encode(
2764
- JSON.stringify({
2765
- status: "ok",
2766
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2767
- version: "1.0.0"
2768
- })
2769
- )
2770
- };
2771
- } else if (intent === "system.time") {
2772
- const ts = Date.now().toString();
2773
- effect = {
2774
- ok: true,
2775
- effect: "time",
2776
- body: new TextEncoder().encode(
2777
- JSON.stringify({
2778
- ts,
2779
- iso: (/* @__PURE__ */ new Date()).toISOString()
2780
- })
2781
- )
2782
- };
2783
- } else if (intent === "system.echo") {
2784
- effect = {
2785
- ok: true,
2786
- effect: "echo",
2787
- body: frame.body
2788
- };
2789
- } else if (intent === "CHAIN.EXEC" || intent === "axis.chain.exec") {
2790
- const chainRequest = this.parseChainRequestBody(frame.body);
2791
- effect = await this.executeChainRequest(frame, chainRequest);
2792
- } else if (intent === "INTENT.EXEC" || intent === "axis.intent.exec") {
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_protocol.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_protocol.TLV_CAPSULE, this.encoder.encode(capsuleId));
2806
- innerHeaders.set(import_axis_protocol.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
- effect = await this.route(innerFrame);
2821
- } else {
2822
- const handler = this.handlers.get(intent);
2823
- if (!handler) {
2824
- throw new Error(`Intent not found: ${intent}`);
2825
- }
2826
- const sensorBindings = this.intentSensors.get(intent);
2827
- if (sensorBindings && sensorBindings.length > 0) {
2828
- await this.runIntentSensors(sensorBindings, intent, frame, "before");
2829
- }
2830
- const decoder = this.intentDecoders.get(intent);
2831
- let decodedBody = frame.body;
2832
- if (decoder) {
2833
- try {
2834
- decodedBody = decoder(Buffer.from(frame.body));
2835
- } catch (decodeErr) {
2836
- throw new Error(
2837
- `IntentBody decode failed for ${intent}: ${decodeErr.message}`
2838
- );
2839
- }
2840
- }
2841
- this.enforceCapsulePolicy(
2842
- intent,
2843
- frame,
2844
- decodedBody,
2845
- this.getEffectiveCapsulePolicy(intent, frame)
2846
- );
2847
- if (typeof handler === "function") {
2848
- const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
2849
- effect = {
2850
- ok: true,
2851
- effect: "complete",
2852
- body: resultBody
2853
- };
2854
- } else {
2855
- if (typeof handler.handle === "function") {
2856
- effect = await handler.handle(frame);
2857
- } else if (typeof handler.execute === "function") {
2858
- const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
2859
- effect = {
2860
- ok: true,
2861
- effect: "complete",
2862
- body: bodyRes
2863
- };
2864
- } else {
2865
- throw new Error(
2866
- `Handler for ${intent} does not implement handle or execute`
2867
- );
2868
- }
2869
- }
2870
- if (sensorBindings && sensorBindings.length > 0) {
2871
- await this.runIntentSensors(sensorBindings, intent, frame, "after", {
2872
- decodedBody,
2873
- effect
2874
- });
2875
- }
2876
- }
2882
+ effect = await this.routeResolvedIntent(intent, frame);
2877
2883
  await this.emitIntentObservers(observerBindings, {
2878
2884
  event: "intent.completed",
2879
2885
  timestamp: Date.now(),
@@ -2898,6 +2904,134 @@ var init_intent_router = __esm({
2898
2904
  throw e;
2899
2905
  }
2900
2906
  }
2907
+ /**
2908
+ * Dispatches a resolved canonical intent to the correct execution path.
2909
+ * This keeps route() focused on observer/error lifecycle concerns.
2910
+ */
2911
+ async routeResolvedIntent(intent, frame) {
2912
+ const builtinEffect = routeSystemBuiltinIntent(
2913
+ intent,
2914
+ frame.body,
2915
+ this.encoder
2916
+ );
2917
+ if (builtinEffect) {
2918
+ if (intent === "system.ping" || intent === "public.ping") {
2919
+ this.logger.debug("PING received");
2920
+ }
2921
+ return builtinEffect;
2922
+ }
2923
+ if (isChainExecIntent(intent)) {
2924
+ const chainRequest = this.parseChainRequestBody(frame.body);
2925
+ return this.executeChainRequest(frame, chainRequest);
2926
+ }
2927
+ if (isIntentExecIntent(intent)) {
2928
+ return this.routeIntentExec(frame);
2929
+ }
2930
+ return this.routeRegisteredIntent(intent, frame);
2931
+ }
2932
+ /**
2933
+ * Handles INTENT.EXEC by building an inner frame and routing it normally.
2934
+ * The recursive route call is intentional so sensors/observers/policies for
2935
+ * the inner intent stay identical to a direct request.
2936
+ */
2937
+ async routeIntentExec(frame) {
2938
+ const execBody = this.parseIntentExecBody(frame.body);
2939
+ const innerIntent = execBody.intent;
2940
+ const innerArgs = execBody.args || {};
2941
+ if (!innerIntent) {
2942
+ throw new Error("INTENT.EXEC missing inner intent");
2943
+ }
2944
+ this.logger.debug(`EXEC: routing to inner intent '${innerIntent}'`);
2945
+ const innerHeaders = new Map(frame.headers);
2946
+ innerHeaders.set(import_axis_protocol.TLV_INTENT, this.encoder.encode(innerIntent));
2947
+ const inlineCapsule = this.toInlineCapsuleRecord(execBody.capsule);
2948
+ const capsuleId = this.extractInlineCapsuleId(inlineCapsule);
2949
+ if (capsuleId) {
2950
+ innerHeaders.set(import_axis_protocol.TLV_CAPSULE, this.encoder.encode(capsuleId));
2951
+ innerHeaders.set(import_axis_protocol.TLV_PROOF_REF, this.encoder.encode(capsuleId));
2952
+ }
2953
+ const innerFrame = withAxisExecutionContext(
2954
+ {
2955
+ ...frame,
2956
+ headers: innerHeaders,
2957
+ body: this.encodeJson(innerArgs)
2958
+ },
2959
+ mergeAxisExecutionContext(getAxisExecutionContext(frame), {
2960
+ metaIntent: "INTENT.EXEC",
2961
+ actorId: this.getActorIdFromFrame(frame),
2962
+ inlineCapsule
2963
+ }) || {}
2964
+ );
2965
+ return this.route(innerFrame);
2966
+ }
2967
+ /**
2968
+ * Executes an app-registered intent: before sensors, body decode, capsule
2969
+ * policy, handler invocation, then after sensors.
2970
+ */
2971
+ async routeRegisteredIntent(intent, frame) {
2972
+ const handler = this.handlers.get(intent);
2973
+ if (!handler) {
2974
+ throw new Error(`Intent not found: ${intent}`);
2975
+ }
2976
+ const sensorBindings = this.intentSensors.get(intent);
2977
+ if (sensorBindings && sensorBindings.length > 0) {
2978
+ await this.runIntentSensors(sensorBindings, intent, frame, "before");
2979
+ }
2980
+ const decoder = this.intentDecoders.get(intent);
2981
+ const decodedBody = this.decodeIntentBody(intent, frame, decoder);
2982
+ this.enforceCapsulePolicy(
2983
+ intent,
2984
+ frame,
2985
+ decodedBody,
2986
+ this.getEffectiveCapsulePolicy(intent, frame)
2987
+ );
2988
+ const effect = await this.invokeRegisteredHandler(
2989
+ intent,
2990
+ handler,
2991
+ frame,
2992
+ decoder,
2993
+ decodedBody
2994
+ );
2995
+ if (sensorBindings && sensorBindings.length > 0) {
2996
+ await this.runIntentSensors(sensorBindings, intent, frame, "after", {
2997
+ decodedBody,
2998
+ effect
2999
+ });
3000
+ }
3001
+ return effect;
3002
+ }
3003
+ decodeIntentBody(intent, frame, decoder) {
3004
+ if (!decoder) return frame.body;
3005
+ try {
3006
+ return decoder(Buffer.from(frame.body));
3007
+ } catch (decodeErr) {
3008
+ throw new Error(
3009
+ `IntentBody decode failed for ${intent}: ${decodeErr.message}`
3010
+ );
3011
+ }
3012
+ }
3013
+ async invokeRegisteredHandler(intent, handler, frame, decoder, decodedBody) {
3014
+ if (typeof handler === "function") {
3015
+ const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
3016
+ return {
3017
+ ok: true,
3018
+ effect: "complete",
3019
+ body: resultBody
3020
+ };
3021
+ }
3022
+ if (typeof handler.handle === "function") {
3023
+ return handler.handle(frame);
3024
+ }
3025
+ if (typeof handler.execute === "function") {
3026
+ const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
3027
+ return {
3028
+ ok: true,
3029
+ effect: "complete",
3030
+ body: bodyRes
3031
+ };
3032
+ }
3033
+ throw new Error(`Handler for ${intent} does not implement handle or execute`);
3034
+ }
2901
3035
  logIntent(intent, start, ok, error) {
2902
3036
  const diff = process.hrtime(start);
2903
3037
  const ms = (diff[0] * 1e3 + diff[1] / 1e6).toFixed(2);
@@ -2991,54 +3125,9 @@ var init_intent_router = __esm({
2991
3125
  if (contract) {
2992
3126
  this.intentContracts.set(intent, contract);
2993
3127
  }
2994
- const methodProof = Reflect.getMetadata(
2995
- REQUIRED_PROOF_METADATA_KEY,
2996
- proto,
2997
- methodName
2998
- );
2999
- const classProof = Reflect.getMetadata(
3000
- REQUIRED_PROOF_METADATA_KEY,
3001
- proto.constructor
3002
- );
3003
- const requiredProof = methodProof ?? classProof;
3004
- if (requiredProof && requiredProof.length > 0) {
3005
- this.intentRequiredProof.set(intent, requiredProof);
3006
- }
3007
- const isPublicMethod = Reflect.getMetadata(
3008
- AXIS_PUBLIC_KEY,
3009
- proto,
3010
- methodName
3011
- );
3012
- const isPublicClass = Reflect.getMetadata(
3013
- AXIS_PUBLIC_KEY,
3014
- proto.constructor
3015
- );
3016
- if (isPublicMethod || isPublicClass) {
3017
- this.publicIntents.add(intent);
3018
- }
3019
- const isAnonMethod = Reflect.getMetadata(
3020
- AXIS_ANONYMOUS_KEY,
3021
- proto,
3022
- methodName
3023
- );
3024
- const isAnonClass = Reflect.getMetadata(
3025
- AXIS_ANONYMOUS_KEY,
3026
- proto.constructor
3027
- );
3028
- if (isAnonMethod || isAnonClass) {
3029
- this.anonymousIntents.add(intent);
3030
- }
3031
- const isAuthorizedMethod = Reflect.getMetadata(
3032
- AXIS_AUTHORIZED_KEY,
3033
- proto,
3034
- methodName
3035
- );
3036
- const isAuthorizedClass = Reflect.getMetadata(
3037
- AXIS_AUTHORIZED_KEY,
3038
- proto.constructor
3039
- );
3040
- if (isAuthorizedMethod || isAuthorizedClass) {
3041
- this.authorizedIntents.add(intent);
3128
+ const proofPolicy = resolveIntentProofPolicy(proto, methodName);
3129
+ if (proofPolicy.requiredProof.length > 0) {
3130
+ this.intentRequiredProof.set(intent, proofPolicy.requiredProof);
3042
3131
  }
3043
3132
  const rateLimit = Reflect.getMetadata(
3044
3133
  AXIS_RATE_LIMIT_KEY,
@@ -3060,13 +3149,13 @@ var init_intent_router = __esm({
3060
3149
  return this.intentRequiredProof.get(this.resolveIntentAlias(intent));
3061
3150
  }
3062
3151
  isPublic(intent) {
3063
- return this.publicIntents.has(this.resolveIntentAlias(intent));
3152
+ return this.getRequiredProof(intent)?.includes("NONE") ?? false;
3064
3153
  }
3065
3154
  isAnonymous(intent) {
3066
- return this.anonymousIntents.has(this.resolveIntentAlias(intent));
3155
+ return this.getRequiredProof(intent)?.includes("ANONYMOUS") ?? false;
3067
3156
  }
3068
3157
  isAuthorized(intent) {
3069
- return this.authorizedIntents.has(this.resolveIntentAlias(intent));
3158
+ return this.getRequiredProof(intent)?.includes("AUTHORIZED") ?? false;
3070
3159
  }
3071
3160
  getRateLimit(intent) {
3072
3161
  return this.intentRateLimits.get(this.resolveIntentAlias(intent));
@@ -3087,7 +3176,7 @@ var init_intent_router = __esm({
3087
3176
  }
3088
3177
  /** The system/builtin intents (ping, time, echo, chain, intent.exec). */
3089
3178
  getSystemIntents() {
3090
- return [..._IntentRouter.BUILTIN_INTENTS];
3179
+ return [...BUILTIN_INTENTS];
3091
3180
  }
3092
3181
  /** True if every intent in the handler is public, or any one is public — returns true if ANY intent is @AxisPublic. */
3093
3182
  isHandlerPublic(handlerName) {
@@ -3160,7 +3249,7 @@ var init_intent_router = __esm({
3160
3249
  * canonical intent. Existing exact intent names always win.
3161
3250
  */
3162
3251
  resolveIntentAlias(intent) {
3163
- if (this.handlers.has(intent) || _IntentRouter.BUILTIN_INTENTS.has(intent)) {
3252
+ if (this.handlers.has(intent) || isBuiltinIntent(intent)) {
3164
3253
  return intent;
3165
3254
  }
3166
3255
  const separator = "...";
@@ -3684,18 +3773,6 @@ var init_intent_router = __esm({
3684
3773
  this.intentSchemas.set(meta.intent, schema);
3685
3774
  }
3686
3775
  };
3687
- /** Intents handled inline in route() — not in `handlers` map */
3688
- _IntentRouter.BUILTIN_INTENTS = /* @__PURE__ */ new Set([
3689
- "system.ping",
3690
- "public.ping",
3691
- "system.time",
3692
- "system.echo",
3693
- "CHAIN.EXEC",
3694
- "axis.chain.exec",
3695
- "INTENT.EXEC",
3696
- "axis.intent.exec"
3697
- ]);
3698
- IntentRouter = _IntentRouter;
3699
3776
  }
3700
3777
  });
3701
3778