@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.mjs CHANGED
@@ -129,6 +129,31 @@ var init_capsule_policy_decorator = __esm({
129
129
 
130
130
  // src/decorators/intent-policy.decorator.ts
131
131
  import "reflect-metadata";
132
+ function appendRequiredProof(target, propertyKey, proof) {
133
+ const existing = propertyKey !== void 0 ? Reflect.getMetadata(
134
+ REQUIRED_PROOF_METADATA_KEY,
135
+ target,
136
+ propertyKey
137
+ ) ?? [] : Reflect.getMetadata(
138
+ REQUIRED_PROOF_METADATA_KEY,
139
+ target
140
+ ) ?? [];
141
+ const merged = existing.includes(proof) ? existing : [...existing, proof];
142
+ if (propertyKey !== void 0) {
143
+ Reflect.defineMetadata(
144
+ REQUIRED_PROOF_METADATA_KEY,
145
+ merged,
146
+ target,
147
+ propertyKey
148
+ );
149
+ return;
150
+ }
151
+ Reflect.defineMetadata(
152
+ REQUIRED_PROOF_METADATA_KEY,
153
+ merged,
154
+ target
155
+ );
156
+ }
132
157
  function Sensitivity(level) {
133
158
  return ((target, propertyKey) => {
134
159
  if (propertyKey !== void 0) {
@@ -177,56 +202,12 @@ function RequiredProof(proofs) {
177
202
  }
178
203
  function Capsule() {
179
204
  return ((target, propertyKey) => {
180
- const existing = propertyKey !== void 0 ? Reflect.getMetadata(
181
- REQUIRED_PROOF_METADATA_KEY,
182
- target,
183
- propertyKey
184
- ) ?? [] : Reflect.getMetadata(
185
- REQUIRED_PROOF_METADATA_KEY,
186
- target
187
- ) ?? [];
188
- const merged = existing.includes("CAPSULE") ? existing : [...existing, "CAPSULE"];
189
- if (propertyKey !== void 0) {
190
- Reflect.defineMetadata(
191
- REQUIRED_PROOF_METADATA_KEY,
192
- merged,
193
- target,
194
- propertyKey
195
- );
196
- } else {
197
- Reflect.defineMetadata(
198
- REQUIRED_PROOF_METADATA_KEY,
199
- merged,
200
- target
201
- );
202
- }
205
+ appendRequiredProof(target, propertyKey, "CAPSULE");
203
206
  });
204
207
  }
205
208
  function Witness() {
206
209
  return ((target, propertyKey) => {
207
- const existing = propertyKey !== void 0 ? Reflect.getMetadata(
208
- REQUIRED_PROOF_METADATA_KEY,
209
- target,
210
- propertyKey
211
- ) ?? [] : Reflect.getMetadata(
212
- REQUIRED_PROOF_METADATA_KEY,
213
- target
214
- ) ?? [];
215
- const merged = existing.includes("WITNESS") ? existing : [...existing, "WITNESS"];
216
- if (propertyKey !== void 0) {
217
- Reflect.defineMetadata(
218
- REQUIRED_PROOF_METADATA_KEY,
219
- merged,
220
- target,
221
- propertyKey
222
- );
223
- } else {
224
- Reflect.defineMetadata(
225
- REQUIRED_PROOF_METADATA_KEY,
226
- merged,
227
- target
228
- );
229
- }
210
+ appendRequiredProof(target, propertyKey, "WITNESS");
230
211
  });
231
212
  }
232
213
  function Axis() {
@@ -236,31 +217,37 @@ function Axis() {
236
217
  }
237
218
  function AxisPublic() {
238
219
  return (target, propertyKey, descriptor) => {
239
- if (descriptor) {
220
+ if (propertyKey !== void 0) {
240
221
  Reflect.defineMetadata(AXIS_PUBLIC_KEY, true, target, propertyKey);
222
+ appendRequiredProof(target, propertyKey, "NONE");
241
223
  return descriptor;
242
224
  }
243
225
  Reflect.defineMetadata(AXIS_PUBLIC_KEY, true, target);
226
+ appendRequiredProof(target, void 0, "NONE");
244
227
  return target;
245
228
  };
246
229
  }
247
230
  function AxisAuthorized() {
248
231
  return (target, propertyKey, descriptor) => {
249
- if (descriptor) {
232
+ if (propertyKey !== void 0) {
250
233
  Reflect.defineMetadata(AXIS_AUTHORIZED_KEY, true, target, propertyKey);
234
+ appendRequiredProof(target, propertyKey, "AUTHORIZED");
251
235
  return descriptor;
252
236
  }
253
237
  Reflect.defineMetadata(AXIS_AUTHORIZED_KEY, true, target);
238
+ appendRequiredProof(target, void 0, "AUTHORIZED");
254
239
  return target;
255
240
  };
256
241
  }
257
242
  function AxisAnonymous() {
258
243
  return (target, propertyKey, descriptor) => {
259
- if (descriptor) {
244
+ if (propertyKey !== void 0) {
260
245
  Reflect.defineMetadata(AXIS_ANONYMOUS_KEY, true, target, propertyKey);
246
+ appendRequiredProof(target, propertyKey, "ANONYMOUS");
261
247
  return descriptor;
262
248
  }
263
249
  Reflect.defineMetadata(AXIS_ANONYMOUS_KEY, true, target);
250
+ appendRequiredProof(target, void 0, "ANONYMOUS");
264
251
  return target;
265
252
  };
266
253
  }
@@ -2377,6 +2364,146 @@ var init_axis_error = __esm({
2377
2364
  }
2378
2365
  });
2379
2366
 
2367
+ // src/engine/intent-builtins.ts
2368
+ function isBuiltinIntent(intent) {
2369
+ return BUILTIN_INTENTS.has(intent);
2370
+ }
2371
+ function isChainExecIntent(intent) {
2372
+ return intent === "CHAIN.EXEC" || intent === "axis.chain.exec";
2373
+ }
2374
+ function isIntentExecIntent(intent) {
2375
+ return intent === "INTENT.EXEC" || intent === "axis.intent.exec";
2376
+ }
2377
+ function routeSystemBuiltinIntent(intent, body, encoder) {
2378
+ if (intent === "system.ping" || intent === "public.ping") {
2379
+ return {
2380
+ ok: true,
2381
+ effect: "pong",
2382
+ headers: /* @__PURE__ */ new Map([[100, encoder.encode("AXIS_BACKEND_V1")]]),
2383
+ body: encoder.encode(
2384
+ JSON.stringify({
2385
+ status: "ok",
2386
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2387
+ version: "1.0.0"
2388
+ })
2389
+ )
2390
+ };
2391
+ }
2392
+ if (intent === "system.time") {
2393
+ const ts = Date.now().toString();
2394
+ return {
2395
+ ok: true,
2396
+ effect: "time",
2397
+ body: encoder.encode(
2398
+ JSON.stringify({
2399
+ ts,
2400
+ iso: (/* @__PURE__ */ new Date()).toISOString()
2401
+ })
2402
+ )
2403
+ };
2404
+ }
2405
+ if (intent === "system.echo") {
2406
+ return {
2407
+ ok: true,
2408
+ effect: "echo",
2409
+ body
2410
+ };
2411
+ }
2412
+ return void 0;
2413
+ }
2414
+ var BUILTIN_INTENTS;
2415
+ var init_intent_builtins = __esm({
2416
+ "src/engine/intent-builtins.ts"() {
2417
+ BUILTIN_INTENTS = /* @__PURE__ */ new Set([
2418
+ "system.ping",
2419
+ "public.ping",
2420
+ "system.time",
2421
+ "system.echo",
2422
+ "CHAIN.EXEC",
2423
+ "axis.chain.exec",
2424
+ "INTENT.EXEC",
2425
+ "axis.intent.exec"
2426
+ ]);
2427
+ }
2428
+ });
2429
+
2430
+ // src/engine/intent-proof-policy.ts
2431
+ import "reflect-metadata";
2432
+ function mergeProofKinds(...proofGroups) {
2433
+ const merged = /* @__PURE__ */ new Set();
2434
+ for (const proofs of proofGroups) {
2435
+ for (const proof of proofs ?? []) {
2436
+ merged.add(proof);
2437
+ }
2438
+ }
2439
+ return Array.from(merged);
2440
+ }
2441
+ function accessProofKinds(isPublic, isAnonymous, isAuthorized) {
2442
+ const proofs = [];
2443
+ if (isPublic) proofs.push("NONE");
2444
+ if (isAnonymous) proofs.push("ANONYMOUS");
2445
+ if (isAuthorized) proofs.push("AUTHORIZED");
2446
+ return proofs;
2447
+ }
2448
+ function resolveIntentProofPolicy(proto, methodName) {
2449
+ const methodProof = Reflect.getMetadata(
2450
+ REQUIRED_PROOF_METADATA_KEY,
2451
+ proto,
2452
+ methodName
2453
+ );
2454
+ const classProof = Reflect.getMetadata(
2455
+ REQUIRED_PROOF_METADATA_KEY,
2456
+ proto.constructor
2457
+ );
2458
+ const isPublicMethod = Reflect.getMetadata(
2459
+ AXIS_PUBLIC_KEY,
2460
+ proto,
2461
+ methodName
2462
+ );
2463
+ const isPublicClass = Reflect.getMetadata(
2464
+ AXIS_PUBLIC_KEY,
2465
+ proto.constructor
2466
+ );
2467
+ const isAnonymousMethod = Reflect.getMetadata(
2468
+ AXIS_ANONYMOUS_KEY,
2469
+ proto,
2470
+ methodName
2471
+ );
2472
+ const isAnonymousClass = Reflect.getMetadata(
2473
+ AXIS_ANONYMOUS_KEY,
2474
+ proto.constructor
2475
+ );
2476
+ const isAuthorizedMethod = Reflect.getMetadata(
2477
+ AXIS_AUTHORIZED_KEY,
2478
+ proto,
2479
+ methodName
2480
+ );
2481
+ const isAuthorizedClass = Reflect.getMetadata(
2482
+ AXIS_AUTHORIZED_KEY,
2483
+ proto.constructor
2484
+ );
2485
+ const methodPolicyProof = mergeProofKinds(
2486
+ methodProof,
2487
+ accessProofKinds(isPublicMethod, isAnonymousMethod, isAuthorizedMethod)
2488
+ );
2489
+ const classPolicyProof = mergeProofKinds(
2490
+ classProof,
2491
+ accessProofKinds(isPublicClass, isAnonymousClass, isAuthorizedClass)
2492
+ );
2493
+ const requiredProof = methodPolicyProof.length ? methodPolicyProof : classPolicyProof;
2494
+ return {
2495
+ requiredProof,
2496
+ isPublic: requiredProof.includes("NONE"),
2497
+ isAnonymous: requiredProof.includes("ANONYMOUS"),
2498
+ isAuthorized: requiredProof.includes("AUTHORIZED")
2499
+ };
2500
+ }
2501
+ var init_intent_proof_policy = __esm({
2502
+ "src/engine/intent-proof-policy.ts"() {
2503
+ init_intent_policy_decorator();
2504
+ }
2505
+ });
2506
+
2380
2507
  // src/engine/intent.router.ts
2381
2508
  var intent_router_exports = {};
2382
2509
  __export(intent_router_exports, {
@@ -2447,7 +2574,7 @@ function normalizeChainConfig(decoratorConfig, intentConfig) {
2447
2574
  ...intentConfig
2448
2575
  };
2449
2576
  }
2450
- var import_dto_schema, _IntentRouter, IntentRouter;
2577
+ var import_dto_schema, IntentRouter;
2451
2578
  var init_intent_router = __esm({
2452
2579
  "src/engine/intent.router.ts"() {
2453
2580
  init_handler_sensors_decorator();
@@ -2467,7 +2594,9 @@ var init_intent_router = __esm({
2467
2594
  init_cce_pipeline();
2468
2595
  init_axis_error();
2469
2596
  init_constants();
2470
- _IntentRouter = class _IntentRouter {
2597
+ init_intent_builtins();
2598
+ init_intent_proof_policy();
2599
+ IntentRouter = class _IntentRouter {
2471
2600
  constructor(dependencyResolver, observerDispatcher, sensorRegistry) {
2472
2601
  this.logger = createAxisLogger(_IntentRouter.name);
2473
2602
  this.decoder = new TextDecoder();
@@ -2498,12 +2627,6 @@ var init_intent_router = __esm({
2498
2627
  this.intentContracts = /* @__PURE__ */ new Map();
2499
2628
  /** Per-intent required proof kinds */
2500
2629
  this.intentRequiredProof = /* @__PURE__ */ new Map();
2501
- /** Intents flagged as public (no auth required) */
2502
- this.publicIntents = /* @__PURE__ */ new Set();
2503
- /** Intents flagged as anonymous-session accessible */
2504
- this.anonymousIntents = /* @__PURE__ */ new Set();
2505
- /** Intents flagged as authorized-session accessible */
2506
- this.authorizedIntents = /* @__PURE__ */ new Set();
2507
2630
  /** Per-intent rate limit config */
2508
2631
  this.intentRateLimits = /* @__PURE__ */ new Map();
2509
2632
  /** CCE handler registry */
@@ -2534,10 +2657,10 @@ var init_intent_router = __esm({
2534
2657
  }
2535
2658
  has(intent) {
2536
2659
  const resolved = this.resolveIntentAlias(intent);
2537
- return this.handlers.has(resolved) || _IntentRouter.BUILTIN_INTENTS.has(resolved);
2660
+ return this.handlers.has(resolved) || isBuiltinIntent(resolved);
2538
2661
  }
2539
2662
  getRegisteredIntents() {
2540
- return [..._IntentRouter.BUILTIN_INTENTS, ...this.handlers.keys()];
2663
+ return [...BUILTIN_INTENTS, ...this.handlers.keys()];
2541
2664
  }
2542
2665
  getIntentEntry(intent) {
2543
2666
  const resolved = this.resolveIntentAlias(intent);
@@ -2546,7 +2669,7 @@ var init_intent_router = __esm({
2546
2669
  schema: this.intentSchemas.get(resolved),
2547
2670
  validators: this.intentValidators.get(resolved),
2548
2671
  hasSensors: this.intentSensors.has(resolved),
2549
- builtin: _IntentRouter.BUILTIN_INTENTS.has(resolved),
2672
+ builtin: isBuiltinIntent(resolved),
2550
2673
  kind: this.intentKinds.get(resolved),
2551
2674
  chain: this.intentChains.get(resolved),
2552
2675
  capsulePolicy: this.intentCapsulePolicies.get(resolved),
@@ -2568,6 +2691,9 @@ var init_intent_router = __esm({
2568
2691
  * @param {any} handler - The handler function or object
2569
2692
  */
2570
2693
  register(intent, handler) {
2694
+ if (this.handlers.has(intent)) {
2695
+ this.logger.warn(`Intent ${intent} is already registered; replacing handler`);
2696
+ }
2571
2697
  this.handlers.set(intent, handler);
2572
2698
  if (typeof handler === "function" && handler.name) {
2573
2699
  this.intentHandlerRefs.set(intent, handler.name);
@@ -2678,128 +2804,7 @@ var init_intent_router = __esm({
2678
2804
  frame
2679
2805
  });
2680
2806
  let effect;
2681
- if (intent === "system.ping" || intent === "public.ping") {
2682
- this.logger.debug("PING received");
2683
- effect = {
2684
- ok: true,
2685
- effect: "pong",
2686
- headers: /* @__PURE__ */ new Map([
2687
- [100, new TextEncoder().encode("AXIS_BACKEND_V1")]
2688
- ]),
2689
- body: new TextEncoder().encode(
2690
- JSON.stringify({
2691
- status: "ok",
2692
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2693
- version: "1.0.0"
2694
- })
2695
- )
2696
- };
2697
- } else if (intent === "system.time") {
2698
- const ts = Date.now().toString();
2699
- effect = {
2700
- ok: true,
2701
- effect: "time",
2702
- body: new TextEncoder().encode(
2703
- JSON.stringify({
2704
- ts,
2705
- iso: (/* @__PURE__ */ new Date()).toISOString()
2706
- })
2707
- )
2708
- };
2709
- } else if (intent === "system.echo") {
2710
- effect = {
2711
- ok: true,
2712
- effect: "echo",
2713
- body: frame.body
2714
- };
2715
- } else if (intent === "CHAIN.EXEC" || intent === "axis.chain.exec") {
2716
- const chainRequest = this.parseChainRequestBody(frame.body);
2717
- effect = await this.executeChainRequest(frame, chainRequest);
2718
- } else if (intent === "INTENT.EXEC" || intent === "axis.intent.exec") {
2719
- const execBody = this.parseIntentExecBody(frame.body);
2720
- const innerIntent = execBody.intent;
2721
- const innerArgs = execBody.args || {};
2722
- if (!innerIntent) {
2723
- throw new Error("INTENT.EXEC missing inner intent");
2724
- }
2725
- this.logger.debug(`EXEC: routing to inner intent '${innerIntent}'`);
2726
- const innerHeaders = new Map(frame.headers);
2727
- innerHeaders.set(TLV_INTENT, this.encoder.encode(innerIntent));
2728
- const inlineCapsule = this.toInlineCapsuleRecord(execBody.capsule);
2729
- const capsuleId = this.extractInlineCapsuleId(inlineCapsule);
2730
- if (capsuleId) {
2731
- innerHeaders.set(TLV_CAPSULE, this.encoder.encode(capsuleId));
2732
- innerHeaders.set(TLV_PROOF_REF, this.encoder.encode(capsuleId));
2733
- }
2734
- const innerFrame = withAxisExecutionContext(
2735
- {
2736
- ...frame,
2737
- headers: innerHeaders,
2738
- body: this.encodeJson(innerArgs)
2739
- },
2740
- mergeAxisExecutionContext(getAxisExecutionContext(frame), {
2741
- metaIntent: "INTENT.EXEC",
2742
- actorId: this.getActorIdFromFrame(frame),
2743
- inlineCapsule
2744
- }) || {}
2745
- );
2746
- effect = await this.route(innerFrame);
2747
- } else {
2748
- const handler = this.handlers.get(intent);
2749
- if (!handler) {
2750
- throw new Error(`Intent not found: ${intent}`);
2751
- }
2752
- const sensorBindings = this.intentSensors.get(intent);
2753
- if (sensorBindings && sensorBindings.length > 0) {
2754
- await this.runIntentSensors(sensorBindings, intent, frame, "before");
2755
- }
2756
- const decoder = this.intentDecoders.get(intent);
2757
- let decodedBody = frame.body;
2758
- if (decoder) {
2759
- try {
2760
- decodedBody = decoder(Buffer.from(frame.body));
2761
- } catch (decodeErr) {
2762
- throw new Error(
2763
- `IntentBody decode failed for ${intent}: ${decodeErr.message}`
2764
- );
2765
- }
2766
- }
2767
- this.enforceCapsulePolicy(
2768
- intent,
2769
- frame,
2770
- decodedBody,
2771
- this.getEffectiveCapsulePolicy(intent, frame)
2772
- );
2773
- if (typeof handler === "function") {
2774
- const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
2775
- effect = {
2776
- ok: true,
2777
- effect: "complete",
2778
- body: resultBody
2779
- };
2780
- } else {
2781
- if (typeof handler.handle === "function") {
2782
- effect = await handler.handle(frame);
2783
- } else if (typeof handler.execute === "function") {
2784
- const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
2785
- effect = {
2786
- ok: true,
2787
- effect: "complete",
2788
- body: bodyRes
2789
- };
2790
- } else {
2791
- throw new Error(
2792
- `Handler for ${intent} does not implement handle or execute`
2793
- );
2794
- }
2795
- }
2796
- if (sensorBindings && sensorBindings.length > 0) {
2797
- await this.runIntentSensors(sensorBindings, intent, frame, "after", {
2798
- decodedBody,
2799
- effect
2800
- });
2801
- }
2802
- }
2807
+ effect = await this.routeResolvedIntent(intent, frame);
2803
2808
  await this.emitIntentObservers(observerBindings, {
2804
2809
  event: "intent.completed",
2805
2810
  timestamp: Date.now(),
@@ -2824,6 +2829,134 @@ var init_intent_router = __esm({
2824
2829
  throw e;
2825
2830
  }
2826
2831
  }
2832
+ /**
2833
+ * Dispatches a resolved canonical intent to the correct execution path.
2834
+ * This keeps route() focused on observer/error lifecycle concerns.
2835
+ */
2836
+ async routeResolvedIntent(intent, frame) {
2837
+ const builtinEffect = routeSystemBuiltinIntent(
2838
+ intent,
2839
+ frame.body,
2840
+ this.encoder
2841
+ );
2842
+ if (builtinEffect) {
2843
+ if (intent === "system.ping" || intent === "public.ping") {
2844
+ this.logger.debug("PING received");
2845
+ }
2846
+ return builtinEffect;
2847
+ }
2848
+ if (isChainExecIntent(intent)) {
2849
+ const chainRequest = this.parseChainRequestBody(frame.body);
2850
+ return this.executeChainRequest(frame, chainRequest);
2851
+ }
2852
+ if (isIntentExecIntent(intent)) {
2853
+ return this.routeIntentExec(frame);
2854
+ }
2855
+ return this.routeRegisteredIntent(intent, frame);
2856
+ }
2857
+ /**
2858
+ * Handles INTENT.EXEC by building an inner frame and routing it normally.
2859
+ * The recursive route call is intentional so sensors/observers/policies for
2860
+ * the inner intent stay identical to a direct request.
2861
+ */
2862
+ async routeIntentExec(frame) {
2863
+ const execBody = this.parseIntentExecBody(frame.body);
2864
+ const innerIntent = execBody.intent;
2865
+ const innerArgs = execBody.args || {};
2866
+ if (!innerIntent) {
2867
+ throw new Error("INTENT.EXEC missing inner intent");
2868
+ }
2869
+ this.logger.debug(`EXEC: routing to inner intent '${innerIntent}'`);
2870
+ const innerHeaders = new Map(frame.headers);
2871
+ innerHeaders.set(TLV_INTENT, this.encoder.encode(innerIntent));
2872
+ const inlineCapsule = this.toInlineCapsuleRecord(execBody.capsule);
2873
+ const capsuleId = this.extractInlineCapsuleId(inlineCapsule);
2874
+ if (capsuleId) {
2875
+ innerHeaders.set(TLV_CAPSULE, this.encoder.encode(capsuleId));
2876
+ innerHeaders.set(TLV_PROOF_REF, this.encoder.encode(capsuleId));
2877
+ }
2878
+ const innerFrame = withAxisExecutionContext(
2879
+ {
2880
+ ...frame,
2881
+ headers: innerHeaders,
2882
+ body: this.encodeJson(innerArgs)
2883
+ },
2884
+ mergeAxisExecutionContext(getAxisExecutionContext(frame), {
2885
+ metaIntent: "INTENT.EXEC",
2886
+ actorId: this.getActorIdFromFrame(frame),
2887
+ inlineCapsule
2888
+ }) || {}
2889
+ );
2890
+ return this.route(innerFrame);
2891
+ }
2892
+ /**
2893
+ * Executes an app-registered intent: before sensors, body decode, capsule
2894
+ * policy, handler invocation, then after sensors.
2895
+ */
2896
+ async routeRegisteredIntent(intent, frame) {
2897
+ const handler = this.handlers.get(intent);
2898
+ if (!handler) {
2899
+ throw new Error(`Intent not found: ${intent}`);
2900
+ }
2901
+ const sensorBindings = this.intentSensors.get(intent);
2902
+ if (sensorBindings && sensorBindings.length > 0) {
2903
+ await this.runIntentSensors(sensorBindings, intent, frame, "before");
2904
+ }
2905
+ const decoder = this.intentDecoders.get(intent);
2906
+ const decodedBody = this.decodeIntentBody(intent, frame, decoder);
2907
+ this.enforceCapsulePolicy(
2908
+ intent,
2909
+ frame,
2910
+ decodedBody,
2911
+ this.getEffectiveCapsulePolicy(intent, frame)
2912
+ );
2913
+ const effect = await this.invokeRegisteredHandler(
2914
+ intent,
2915
+ handler,
2916
+ frame,
2917
+ decoder,
2918
+ decodedBody
2919
+ );
2920
+ if (sensorBindings && sensorBindings.length > 0) {
2921
+ await this.runIntentSensors(sensorBindings, intent, frame, "after", {
2922
+ decodedBody,
2923
+ effect
2924
+ });
2925
+ }
2926
+ return effect;
2927
+ }
2928
+ decodeIntentBody(intent, frame, decoder) {
2929
+ if (!decoder) return frame.body;
2930
+ try {
2931
+ return decoder(Buffer.from(frame.body));
2932
+ } catch (decodeErr) {
2933
+ throw new Error(
2934
+ `IntentBody decode failed for ${intent}: ${decodeErr.message}`
2935
+ );
2936
+ }
2937
+ }
2938
+ async invokeRegisteredHandler(intent, handler, frame, decoder, decodedBody) {
2939
+ if (typeof handler === "function") {
2940
+ const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
2941
+ return {
2942
+ ok: true,
2943
+ effect: "complete",
2944
+ body: resultBody
2945
+ };
2946
+ }
2947
+ if (typeof handler.handle === "function") {
2948
+ return handler.handle(frame);
2949
+ }
2950
+ if (typeof handler.execute === "function") {
2951
+ const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
2952
+ return {
2953
+ ok: true,
2954
+ effect: "complete",
2955
+ body: bodyRes
2956
+ };
2957
+ }
2958
+ throw new Error(`Handler for ${intent} does not implement handle or execute`);
2959
+ }
2827
2960
  logIntent(intent, start, ok, error) {
2828
2961
  const diff = process.hrtime(start);
2829
2962
  const ms = (diff[0] * 1e3 + diff[1] / 1e6).toFixed(2);
@@ -2917,54 +3050,9 @@ var init_intent_router = __esm({
2917
3050
  if (contract) {
2918
3051
  this.intentContracts.set(intent, contract);
2919
3052
  }
2920
- const methodProof = Reflect.getMetadata(
2921
- REQUIRED_PROOF_METADATA_KEY,
2922
- proto,
2923
- methodName
2924
- );
2925
- const classProof = Reflect.getMetadata(
2926
- REQUIRED_PROOF_METADATA_KEY,
2927
- proto.constructor
2928
- );
2929
- const requiredProof = methodProof ?? classProof;
2930
- if (requiredProof && requiredProof.length > 0) {
2931
- this.intentRequiredProof.set(intent, requiredProof);
2932
- }
2933
- const isPublicMethod = Reflect.getMetadata(
2934
- AXIS_PUBLIC_KEY,
2935
- proto,
2936
- methodName
2937
- );
2938
- const isPublicClass = Reflect.getMetadata(
2939
- AXIS_PUBLIC_KEY,
2940
- proto.constructor
2941
- );
2942
- if (isPublicMethod || isPublicClass) {
2943
- this.publicIntents.add(intent);
2944
- }
2945
- const isAnonMethod = Reflect.getMetadata(
2946
- AXIS_ANONYMOUS_KEY,
2947
- proto,
2948
- methodName
2949
- );
2950
- const isAnonClass = Reflect.getMetadata(
2951
- AXIS_ANONYMOUS_KEY,
2952
- proto.constructor
2953
- );
2954
- if (isAnonMethod || isAnonClass) {
2955
- this.anonymousIntents.add(intent);
2956
- }
2957
- const isAuthorizedMethod = Reflect.getMetadata(
2958
- AXIS_AUTHORIZED_KEY,
2959
- proto,
2960
- methodName
2961
- );
2962
- const isAuthorizedClass = Reflect.getMetadata(
2963
- AXIS_AUTHORIZED_KEY,
2964
- proto.constructor
2965
- );
2966
- if (isAuthorizedMethod || isAuthorizedClass) {
2967
- this.authorizedIntents.add(intent);
3053
+ const proofPolicy = resolveIntentProofPolicy(proto, methodName);
3054
+ if (proofPolicy.requiredProof.length > 0) {
3055
+ this.intentRequiredProof.set(intent, proofPolicy.requiredProof);
2968
3056
  }
2969
3057
  const rateLimit = Reflect.getMetadata(
2970
3058
  AXIS_RATE_LIMIT_KEY,
@@ -2986,13 +3074,13 @@ var init_intent_router = __esm({
2986
3074
  return this.intentRequiredProof.get(this.resolveIntentAlias(intent));
2987
3075
  }
2988
3076
  isPublic(intent) {
2989
- return this.publicIntents.has(this.resolveIntentAlias(intent));
3077
+ return this.getRequiredProof(intent)?.includes("NONE") ?? false;
2990
3078
  }
2991
3079
  isAnonymous(intent) {
2992
- return this.anonymousIntents.has(this.resolveIntentAlias(intent));
3080
+ return this.getRequiredProof(intent)?.includes("ANONYMOUS") ?? false;
2993
3081
  }
2994
3082
  isAuthorized(intent) {
2995
- return this.authorizedIntents.has(this.resolveIntentAlias(intent));
3083
+ return this.getRequiredProof(intent)?.includes("AUTHORIZED") ?? false;
2996
3084
  }
2997
3085
  getRateLimit(intent) {
2998
3086
  return this.intentRateLimits.get(this.resolveIntentAlias(intent));
@@ -3013,7 +3101,7 @@ var init_intent_router = __esm({
3013
3101
  }
3014
3102
  /** The system/builtin intents (ping, time, echo, chain, intent.exec). */
3015
3103
  getSystemIntents() {
3016
- return [..._IntentRouter.BUILTIN_INTENTS];
3104
+ return [...BUILTIN_INTENTS];
3017
3105
  }
3018
3106
  /** True if every intent in the handler is public, or any one is public — returns true if ANY intent is @AxisPublic. */
3019
3107
  isHandlerPublic(handlerName) {
@@ -3086,7 +3174,7 @@ var init_intent_router = __esm({
3086
3174
  * canonical intent. Existing exact intent names always win.
3087
3175
  */
3088
3176
  resolveIntentAlias(intent) {
3089
- if (this.handlers.has(intent) || _IntentRouter.BUILTIN_INTENTS.has(intent)) {
3177
+ if (this.handlers.has(intent) || isBuiltinIntent(intent)) {
3090
3178
  return intent;
3091
3179
  }
3092
3180
  const separator = "...";
@@ -3610,18 +3698,6 @@ var init_intent_router = __esm({
3610
3698
  this.intentSchemas.set(meta.intent, schema);
3611
3699
  }
3612
3700
  };
3613
- /** Intents handled inline in route() — not in `handlers` map */
3614
- _IntentRouter.BUILTIN_INTENTS = /* @__PURE__ */ new Set([
3615
- "system.ping",
3616
- "public.ping",
3617
- "system.time",
3618
- "system.echo",
3619
- "CHAIN.EXEC",
3620
- "axis.chain.exec",
3621
- "INTENT.EXEC",
3622
- "axis.intent.exec"
3623
- ]);
3624
- IntentRouter = _IntentRouter;
3625
3701
  }
3626
3702
  });
3627
3703