xytara 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -105,6 +105,22 @@ The current `1.7.0` line starts widening that surface into real grouped transact
105
105
 
106
106
  This is the first step beyond “clear default loop” toward “broader useful machine-commerce classes plus clearer commerce-to-proof follow-through.”
107
107
 
108
+ The current `1.8.0` line starts filling a thinner part of the interaction spine before committed execution:
109
+
110
+ - grouped pre-commit pack catalog, summary, and detail routes
111
+ - grouped pre-commit run routes for negotiation, admission, and commit-readiness posture
112
+ - readiness summaries that make the next committed transaction surface more explicit
113
+
114
+ This is intended to make the protocol-entry to committed-transaction transition feel more like one composable machine spine instead of a set of disconnected route families.
115
+
116
+ The same `1.8.0` line also starts exposing grouped interaction spine paths that compose:
117
+
118
+ - pre-commit readiness
119
+ - committed execution
120
+ - proof-aware handoff posture
121
+
122
+ as one clearer cross-layer machine path instead of making callers stitch the layers together manually.
123
+
108
124
  ## Package Surface
109
125
 
110
126
  The SDK is broad, but it stays organized into a few repeatable families instead of one-off surfaces.
package/index.js CHANGED
@@ -40,7 +40,7 @@ const {
40
40
  } = require("./integrations/registry");
41
41
 
42
42
  const COMMERCE_SDK_NAME = "xytara";
43
- const COMMERCE_SDK_VERSION = "1.7.0";
43
+ const COMMERCE_SDK_VERSION = "1.8.0";
44
44
  const COMMERCE_API_VERSION = "v1";
45
45
 
46
46
  function createClient(options) {
@@ -187,6 +187,123 @@ function buildTransactionClassPacks() {
187
187
  ];
188
188
  }
189
189
 
190
+ function buildPrecommitInteractionPacks() {
191
+ const center = buildDefaultTransactionCenter();
192
+ const defaultSettlementMode = center.default_settlement && center.default_settlement.settlement_mode
193
+ ? center.default_settlement.settlement_mode
194
+ : null;
195
+ const defaultPaymentProtocol = center.default_payment && center.default_payment.protocol
196
+ ? center.default_payment.protocol
197
+ : null;
198
+ return [
199
+ {
200
+ precommit_pack_ref: "precommit.a2a.settlement.readiness",
201
+ title: "A2A Settlement Readiness",
202
+ description: "Negotiate, preview admission, and confirm commit posture before a committed settlement-class transaction.",
203
+ category: "a2a",
204
+ protocol: "a2a",
205
+ task_refs: ["a2a.negotiate", "admission.preview", "a2a.commit"],
206
+ default_payment_protocol: defaultPaymentProtocol,
207
+ default_settlement_mode: defaultSettlementMode,
208
+ commitment_signal: "a2a.commit",
209
+ readiness_kind: "settlement_commit_readiness",
210
+ recommended_next_surface: "/v1/transaction-center/transaction-class-packs/run",
211
+ recommended_next_ref: "transaction.admission.settlement",
212
+ required_inputs: ["counterparty_agent_id", "intent_id", "source_zone_id", "target_zone_id"],
213
+ optional_inputs: ["task_pack_ref", "negotiation_mode", "interaction_class", "payment_protocol", "settlement_mode"]
214
+ },
215
+ {
216
+ precommit_pack_ref: "precommit.a2c.tooling.readiness",
217
+ title: "A2C Tooling Readiness",
218
+ description: "Open the session, preview the tooling pack, and confirm admission posture before committed tooling execution.",
219
+ category: "a2c",
220
+ protocol: "a2c",
221
+ task_refs: ["a2c.session.open", "a2c.pack.preview", "admission.preview"],
222
+ default_payment_protocol: defaultPaymentProtocol,
223
+ default_settlement_mode: defaultSettlementMode,
224
+ commitment_signal: "a2c.pack.preview",
225
+ readiness_kind: "tooling_commit_readiness",
226
+ recommended_next_surface: "/v1/transaction-center/task-packs/invoke",
227
+ recommended_next_ref: "default.a2c.tooling.run",
228
+ required_inputs: ["agent_id", "channel_ref", "pack_ref", "source_zone_id", "target_zone_id"],
229
+ optional_inputs: ["interaction_class", "payment_protocol", "settlement_mode"]
230
+ },
231
+ {
232
+ precommit_pack_ref: "precommit.job.commitment.readiness",
233
+ title: "Job Commitment Readiness",
234
+ description: "Quote, preview admission, and reserve the job before committing the full job transaction class.",
235
+ category: "jobs",
236
+ protocol: "job",
237
+ task_refs: ["jobs.quote", "admission.preview", "jobs.reserve"],
238
+ default_payment_protocol: defaultPaymentProtocol,
239
+ default_settlement_mode: defaultSettlementMode,
240
+ commitment_signal: "jobs.reserve",
241
+ readiness_kind: "job_commitment_readiness",
242
+ recommended_next_surface: "/v1/transaction-center/transaction-class-packs/run",
243
+ recommended_next_ref: "transaction.job.commitment",
244
+ required_inputs: ["job_type", "job_id", "source_zone_id", "target_zone_id", "intent_id"],
245
+ optional_inputs: ["interaction_class", "payment_protocol", "settlement_mode"]
246
+ }
247
+ ];
248
+ }
249
+
250
+ function buildInteractionSpinePaths() {
251
+ const center = buildDefaultTransactionCenter();
252
+ const defaultSettlementMode = center.default_settlement && center.default_settlement.settlement_mode
253
+ ? center.default_settlement.settlement_mode
254
+ : null;
255
+ const defaultPaymentProtocol = center.default_payment && center.default_payment.protocol
256
+ ? center.default_payment.protocol
257
+ : null;
258
+ return [
259
+ {
260
+ spine_path_ref: "spine.a2a.settlement",
261
+ title: "A2A Settlement Spine",
262
+ description: "Compose negotiation, admission, commit, and settlement as one grouped machine-interaction spine path.",
263
+ category: "a2a",
264
+ protocol: "a2a",
265
+ precommit_pack_ref: "precommit.a2a.settlement.readiness",
266
+ committed_ref: "transaction.admission.settlement",
267
+ task_refs: ["a2a.negotiate", "admission.preview", "a2a.commit", "settlement.submit"],
268
+ default_payment_protocol: defaultPaymentProtocol,
269
+ default_settlement_mode: defaultSettlementMode,
270
+ proof_followthrough: "default.proof.bundle.loop",
271
+ required_inputs: ["counterparty_agent_id", "intent_id", "source_zone_id", "target_zone_id"],
272
+ optional_inputs: ["task_pack_ref", "negotiation_mode", "interaction_class", "payment_protocol", "settlement_mode"]
273
+ },
274
+ {
275
+ spine_path_ref: "spine.a2c.tooling",
276
+ title: "A2C Tooling Spine",
277
+ description: "Compose session open, pack preview, admission posture, and committed tooling execution as one grouped path.",
278
+ category: "a2c",
279
+ protocol: "a2c",
280
+ precommit_pack_ref: "precommit.a2c.tooling.readiness",
281
+ committed_ref: "default.a2c.tooling.run",
282
+ task_refs: ["a2c.session.open", "a2c.pack.preview", "admission.preview", "adapter.mcp.invoke"],
283
+ default_payment_protocol: defaultPaymentProtocol,
284
+ default_settlement_mode: defaultSettlementMode,
285
+ proof_followthrough: "default.proof.bundle.loop",
286
+ required_inputs: ["agent_id", "channel_ref", "pack_ref", "tool_name", "source_zone_id", "target_zone_id"],
287
+ optional_inputs: ["arguments", "interaction_class", "payment_protocol", "settlement_mode"]
288
+ },
289
+ {
290
+ spine_path_ref: "spine.job.commitment",
291
+ title: "Job Commitment Spine",
292
+ description: "Compose quote, admission, reserve, and commit as one grouped job interaction spine path.",
293
+ category: "jobs",
294
+ protocol: "job",
295
+ precommit_pack_ref: "precommit.job.commitment.readiness",
296
+ committed_ref: "transaction.job.commitment",
297
+ task_refs: ["jobs.quote", "admission.preview", "jobs.reserve", "jobs.commit"],
298
+ default_payment_protocol: defaultPaymentProtocol,
299
+ default_settlement_mode: defaultSettlementMode,
300
+ proof_followthrough: "default.proof.bundle.loop",
301
+ required_inputs: ["job_type", "job_id", "source_zone_id", "target_zone_id"],
302
+ optional_inputs: ["intent_id", "interaction_class", "payment_protocol", "settlement_mode"]
303
+ }
304
+ ];
305
+ }
306
+
190
307
  function buildDefaultTransactionCenter() {
191
308
  const settlementProfiles = Array.isArray(catalog.settlement_profiles) ? catalog.settlement_profiles : [];
192
309
  const defaultSettlementProfile = settlementProfiles[0] || null;
@@ -403,6 +520,34 @@ function buildTransactionClassPackCatalog() {
403
520
  };
404
521
  }
405
522
 
523
+ function buildPrecommitInteractionPackCatalog() {
524
+ const center = buildDefaultTransactionCenter();
525
+ const packs = buildPrecommitInteractionPacks();
526
+ return {
527
+ ok: true,
528
+ brand: center.brand,
529
+ product: "precommit interaction packs",
530
+ default_payment_protocol: center.default_payment && center.default_payment.protocol ? center.default_payment.protocol : null,
531
+ default_settlement_mode: center.default_settlement && center.default_settlement.settlement_mode ? center.default_settlement.settlement_mode : null,
532
+ precommit_pack_count: packs.length,
533
+ precommit_packs: packs
534
+ };
535
+ }
536
+
537
+ function buildInteractionSpinePathCatalog() {
538
+ const center = buildDefaultTransactionCenter();
539
+ const paths = buildInteractionSpinePaths();
540
+ return {
541
+ ok: true,
542
+ brand: center.brand,
543
+ product: "interaction spine paths",
544
+ default_payment_protocol: center.default_payment && center.default_payment.protocol ? center.default_payment.protocol : null,
545
+ default_settlement_mode: center.default_settlement && center.default_settlement.settlement_mode ? center.default_settlement.settlement_mode : null,
546
+ spine_path_count: paths.length,
547
+ spine_paths: paths
548
+ };
549
+ }
550
+
406
551
  function summarizeTransactionClassPacks() {
407
552
  const catalogResponse = buildTransactionClassPackCatalog();
408
553
  const packs = Array.isArray(catalogResponse.class_packs) ? catalogResponse.class_packs : [];
@@ -419,12 +564,56 @@ function summarizeTransactionClassPacks() {
419
564
  };
420
565
  }
421
566
 
567
+ function summarizePrecommitInteractionPacks() {
568
+ const catalogResponse = buildPrecommitInteractionPackCatalog();
569
+ const packs = Array.isArray(catalogResponse.precommit_packs) ? catalogResponse.precommit_packs : [];
570
+ return {
571
+ ok: true,
572
+ brand: catalogResponse.brand,
573
+ product: catalogResponse.product,
574
+ default_payment_protocol: catalogResponse.default_payment_protocol,
575
+ default_settlement_mode: catalogResponse.default_settlement_mode,
576
+ precommit_pack_count: packs.length,
577
+ precommit_pack_refs: packs.map((entry) => entry && entry.precommit_pack_ref).filter(Boolean),
578
+ categories: Array.from(new Set(packs.map((entry) => entry && entry.category).filter(Boolean))),
579
+ precommit_packs: packs
580
+ };
581
+ }
582
+
583
+ function summarizeInteractionSpinePaths() {
584
+ const catalogResponse = buildInteractionSpinePathCatalog();
585
+ const paths = Array.isArray(catalogResponse.spine_paths) ? catalogResponse.spine_paths : [];
586
+ return {
587
+ ok: true,
588
+ brand: catalogResponse.brand,
589
+ product: catalogResponse.product,
590
+ default_payment_protocol: catalogResponse.default_payment_protocol,
591
+ default_settlement_mode: catalogResponse.default_settlement_mode,
592
+ spine_path_count: paths.length,
593
+ spine_path_refs: paths.map((entry) => entry && entry.spine_path_ref).filter(Boolean),
594
+ categories: Array.from(new Set(paths.map((entry) => entry && entry.category).filter(Boolean))),
595
+ spine_paths: paths
596
+ };
597
+ }
598
+
422
599
  function getTransactionClassPack(ref) {
423
600
  const normalized = String(ref || "").trim();
424
601
  if (!normalized) return null;
425
602
  return buildTransactionClassPacks().find((entry) => entry && entry.class_pack_ref === normalized) || null;
426
603
  }
427
604
 
605
+ function getPrecommitInteractionPack(ref) {
606
+ const normalized = String(ref || "").trim();
607
+ if (!normalized) return null;
608
+ return buildPrecommitInteractionPacks().find((entry) => entry && entry.precommit_pack_ref === normalized) || null;
609
+ }
610
+
611
+ function getInteractionSpinePath(ref) {
612
+ const normalized = String(ref || "").trim();
613
+ if (!normalized) return null;
614
+ return buildInteractionSpinePaths().find((entry) => entry && entry.spine_path_ref === normalized) || null;
615
+ }
616
+
428
617
  function buildCatalogResponse() {
429
618
  return {
430
619
  ok: true,
@@ -559,11 +748,15 @@ module.exports = {
559
748
  buildDefaultTransactionEconomics,
560
749
  buildDefaultTransactionCenter,
561
750
  buildDefaultTransactionGuidedLoopCatalog,
751
+ buildInteractionSpinePathCatalog,
752
+ buildPrecommitInteractionPackCatalog,
562
753
  buildDefaultTransactionTaskPackCatalog,
563
754
  buildTransactionClassPackCatalog,
564
755
  getCatalog,
565
756
  getDefaultTransactionGuidedLoop,
566
757
  getDefaultTransactionTaskPack,
758
+ getInteractionSpinePath,
759
+ getPrecommitInteractionPack,
567
760
  getTransactionClassPack,
568
761
  getTaskDetail,
569
762
  getWorkflowDetail,
@@ -573,5 +766,7 @@ module.exports = {
573
766
  summarizeDefaultTransactionEconomics,
574
767
  summarizeDefaultTransactionGuidedLoops,
575
768
  summarizeDefaultTransactionTaskPacks,
769
+ summarizeInteractionSpinePaths,
770
+ summarizePrecommitInteractionPacks,
576
771
  summarizeTransactionClassPacks
577
772
  };
@@ -2652,6 +2652,54 @@ class CommerceClient {
2652
2652
  return result && result.data && result.data.class_pack ? result.data.class_pack : null;
2653
2653
  }
2654
2654
 
2655
+ async getPrecommitInteractionPacks(forceRefresh) {
2656
+ if (!forceRefresh && this.catalogSummaryCache && this.catalogSummaryCache.precommitPacks) {
2657
+ return this.catalogSummaryCache.precommitPacks;
2658
+ }
2659
+ const result = await this.getJson("/v1/transaction-center/precommit-packs");
2660
+ if (!forceRefresh) {
2661
+ this.catalogSummaryCache = this.catalogSummaryCache || {};
2662
+ this.catalogSummaryCache.precommitPacks = result.data;
2663
+ }
2664
+ return result.data;
2665
+ }
2666
+
2667
+ async getPrecommitInteractionPacksSummary(forceRefresh) {
2668
+ const result = await this.getJson("/v1/transaction-center/precommit-packs/summary");
2669
+ return result && result.data ? result.data : { ok: true, precommit_pack_count: 0, precommit_pack_refs: [], precommit_packs: [] };
2670
+ }
2671
+
2672
+ async getPrecommitInteractionPack(packRef, forceRefresh) {
2673
+ const normalized = String(packRef || "").trim();
2674
+ if (!normalized) return null;
2675
+ const result = await this.getJson(`/v1/transaction-center/precommit-pack?ref=${encodeURIComponent(normalized)}`);
2676
+ return result && result.data && result.data.precommit_pack ? result.data.precommit_pack : null;
2677
+ }
2678
+
2679
+ async getInteractionSpinePaths(forceRefresh) {
2680
+ if (!forceRefresh && this.catalogSummaryCache && this.catalogSummaryCache.spinePaths) {
2681
+ return this.catalogSummaryCache.spinePaths;
2682
+ }
2683
+ const result = await this.getJson("/v1/transaction-center/spine-paths");
2684
+ if (!forceRefresh) {
2685
+ this.catalogSummaryCache = this.catalogSummaryCache || {};
2686
+ this.catalogSummaryCache.spinePaths = result.data;
2687
+ }
2688
+ return result.data;
2689
+ }
2690
+
2691
+ async getInteractionSpinePathsSummary(forceRefresh) {
2692
+ const result = await this.getJson("/v1/transaction-center/spine-paths/summary");
2693
+ return result && result.data ? result.data : { ok: true, spine_path_count: 0, spine_path_refs: [], spine_paths: [] };
2694
+ }
2695
+
2696
+ async getInteractionSpinePath(pathRef, forceRefresh) {
2697
+ const normalized = String(pathRef || "").trim();
2698
+ if (!normalized) return null;
2699
+ const result = await this.getJson(`/v1/transaction-center/spine-path?ref=${encodeURIComponent(normalized)}`);
2700
+ return result && result.data && result.data.spine_path ? result.data.spine_path : null;
2701
+ }
2702
+
2655
2703
  async listSettlementPayees(forceRefresh) {
2656
2704
  const summary = await this.getSettlementPayeeSummaries(forceRefresh);
2657
2705
  return extractSummaryValues(summary, "settlement_payees", "payee_agent_id");
@@ -3906,6 +3954,64 @@ class CommerceClient {
3906
3954
  };
3907
3955
  }
3908
3956
 
3957
+ async runPrecommitInteractionPack(packRef, body, options) {
3958
+ const opts = options || {};
3959
+ return this.runNamedTaskRoute("/v1/transaction-center/precommit-packs/run", {
3960
+ command: opts.command || String(packRef || "").trim() || "precommit.pack.run",
3961
+ precommit_pack_ref: String(packRef || "").trim(),
3962
+ body: body || {},
3963
+ callback_url: opts.callbackUrl || null,
3964
+ settlement_mode: opts.settlementMode || null,
3965
+ payment_protocol: opts.paymentProtocol || null,
3966
+ protocol: opts.protocol || null,
3967
+ integration_id: opts.integrationId || null,
3968
+ integration_ids: Array.isArray(opts.integrationIds) ? opts.integrationIds : [],
3969
+ integration_context: opts.integrationContext || null
3970
+ });
3971
+ }
3972
+
3973
+ async runPrecommitInteractionPackSummary(packRef, body, options) {
3974
+ const result = await this.runPrecommitInteractionPack(packRef, body, options);
3975
+ return {
3976
+ ok: result && result.ok === true,
3977
+ precommit_pack_ref: result && result.precommit_pack ? result.precommit_pack.precommit_pack_ref || null : null,
3978
+ readiness_kind: result && result.precommit_pack ? result.precommit_pack.readiness_kind || null : null,
3979
+ result_set_summary: result && result.result_set_summary ? result.result_set_summary : null,
3980
+ linked_record_summary: result && result.linked_record_summary ? result.linked_record_summary : null,
3981
+ activity_summary: result && result.activity_summary ? result.activity_summary : null,
3982
+ precommit_readiness_summary: result && result.precommit_readiness_summary ? result.precommit_readiness_summary : null
3983
+ };
3984
+ }
3985
+
3986
+ async runInteractionSpinePath(pathRef, body, options) {
3987
+ const opts = options || {};
3988
+ return this.runNamedTaskRoute("/v1/transaction-center/spine-paths/run", {
3989
+ command: opts.command || String(pathRef || "").trim() || "spine.path.run",
3990
+ spine_path_ref: String(pathRef || "").trim(),
3991
+ body: body || {},
3992
+ callback_url: opts.callbackUrl || null,
3993
+ settlement_mode: opts.settlementMode || null,
3994
+ payment_protocol: opts.paymentProtocol || null,
3995
+ protocol: opts.protocol || null,
3996
+ integration_id: opts.integrationId || null,
3997
+ integration_ids: Array.isArray(opts.integrationIds) ? opts.integrationIds : [],
3998
+ integration_context: opts.integrationContext || null
3999
+ });
4000
+ }
4001
+
4002
+ async runInteractionSpinePathSummary(pathRef, body, options) {
4003
+ const result = await this.runInteractionSpinePath(pathRef, body, options);
4004
+ return {
4005
+ ok: result && result.ok === true,
4006
+ spine_path_ref: result && result.spine_path ? result.spine_path.spine_path_ref || null : null,
4007
+ committed_ref: result && result.spine_path ? result.spine_path.committed_ref || null : null,
4008
+ result_set_summary: result && result.result_set_summary ? result.result_set_summary : null,
4009
+ linked_record_summary: result && result.linked_record_summary ? result.linked_record_summary : null,
4010
+ activity_summary: result && result.activity_summary ? result.activity_summary : null,
4011
+ spine_summary: result && result.spine_summary ? result.spine_summary : null
4012
+ };
4013
+ }
4014
+
3909
4015
  async runNamedTaskRoute(path, payload) {
3910
4016
  if (!this.apiKey || !this.walletId || !this.walletSecret) {
3911
4017
  throw new Error("named task routes require apiKey, walletId, and walletSecret");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xytara",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Machine commerce SDK for discovery, quoting, execution, lifecycle inspection, and adapters.",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
package/server.js CHANGED
@@ -7,11 +7,15 @@ const {
7
7
  buildDefaultTransactionCenter,
8
8
  buildDefaultTransactionEconomics,
9
9
  buildDefaultTransactionGuidedLoopCatalog,
10
+ buildInteractionSpinePathCatalog,
11
+ buildPrecommitInteractionPackCatalog,
10
12
  buildDefaultTransactionTaskPackCatalog,
11
13
  buildTransactionClassPackCatalog,
12
14
  getCatalog,
13
15
  getDefaultTransactionGuidedLoop,
14
16
  getDefaultTransactionTaskPack,
17
+ getInteractionSpinePath,
18
+ getPrecommitInteractionPack,
15
19
  getTransactionClassPack,
16
20
  getTaskDetail,
17
21
  getWorkflowDetail,
@@ -20,7 +24,9 @@ const {
20
24
  summarizeDefaultTransactionCenter,
21
25
  summarizeDefaultTransactionEconomics,
22
26
  summarizeDefaultTransactionGuidedLoops,
27
+ summarizeInteractionSpinePaths,
23
28
  summarizeDefaultTransactionTaskPacks,
29
+ summarizePrecommitInteractionPacks,
24
30
  summarizeTransactionClassPacks
25
31
  } = require("./lib/catalog_contract");
26
32
  const {
@@ -506,6 +512,276 @@ function buildTransactionClassPackRunPayload(body) {
506
512
  return null;
507
513
  }
508
514
 
515
+ function buildPrecommitInteractionPackRunPayload(body) {
516
+ const requestBody = body && typeof body === "object" && !Array.isArray(body) ? body : {};
517
+ const packBody = requestBody.body && typeof requestBody.body === "object" && !Array.isArray(requestBody.body)
518
+ ? requestBody.body
519
+ : requestBody;
520
+ const packRef = String(requestBody.precommit_pack_ref || "").trim();
521
+ const integrationIds = Array.isArray(requestBody.integration_ids) && requestBody.integration_ids.length > 0
522
+ ? requestBody.integration_ids
523
+ : ["builtin.payment.x402", "builtin.settlement.chain"];
524
+
525
+ if (packRef === "precommit.a2a.settlement.readiness") {
526
+ return buildNamedTaskSetPayload([
527
+ {
528
+ task_id: "task_1",
529
+ task_ref: "a2a.negotiate",
530
+ body: {
531
+ counterparty_agent_id: packBody.counterparty_agent_id,
532
+ task_pack_ref: packBody.task_pack_ref,
533
+ negotiation_mode: packBody.negotiation_mode
534
+ }
535
+ },
536
+ {
537
+ task_id: "task_2",
538
+ task_ref: "admission.preview",
539
+ body: {
540
+ source_zone_id: packBody.source_zone_id,
541
+ target_zone_id: packBody.target_zone_id,
542
+ interaction_class: packBody.interaction_class
543
+ }
544
+ },
545
+ {
546
+ task_id: "task_3",
547
+ task_ref: "a2a.commit",
548
+ body: {
549
+ negotiation_id: packBody.negotiation_id,
550
+ intent_id: packBody.intent_id
551
+ }
552
+ }
553
+ ], {
554
+ ...requestBody,
555
+ ...packBody,
556
+ protocol: requestBody.protocol || null,
557
+ payment_protocol: requestBody.payment_protocol || "x402",
558
+ integration_ids: integrationIds,
559
+ settlement_mode: requestBody.settlement_mode || "evm_payment"
560
+ }, requestBody.command || packRef);
561
+ }
562
+
563
+ if (packRef === "precommit.a2c.tooling.readiness") {
564
+ return buildNamedTaskSetPayload([
565
+ {
566
+ task_id: "task_1",
567
+ task_ref: "a2c.session.open",
568
+ body: {
569
+ agent_id: packBody.agent_id,
570
+ channel_ref: packBody.channel_ref
571
+ }
572
+ },
573
+ {
574
+ task_id: "task_2",
575
+ task_ref: "a2c.pack.preview",
576
+ body: {
577
+ agent_id: packBody.agent_id,
578
+ pack_ref: packBody.pack_ref
579
+ }
580
+ },
581
+ {
582
+ task_id: "task_3",
583
+ task_ref: "admission.preview",
584
+ body: {
585
+ source_zone_id: packBody.source_zone_id,
586
+ target_zone_id: packBody.target_zone_id,
587
+ interaction_class: packBody.interaction_class
588
+ }
589
+ }
590
+ ], {
591
+ ...requestBody,
592
+ ...packBody,
593
+ protocol: requestBody.protocol || null,
594
+ payment_protocol: requestBody.payment_protocol || "x402",
595
+ integration_ids: integrationIds,
596
+ settlement_mode: requestBody.settlement_mode || "evm_payment"
597
+ }, requestBody.command || packRef);
598
+ }
599
+
600
+ if (packRef === "precommit.job.commitment.readiness") {
601
+ return buildNamedTaskSetPayload([
602
+ {
603
+ task_id: "task_1",
604
+ task_ref: "jobs.quote",
605
+ body: {
606
+ job_type: packBody.job_type
607
+ }
608
+ },
609
+ {
610
+ task_id: "task_2",
611
+ task_ref: "admission.preview",
612
+ body: {
613
+ source_zone_id: packBody.source_zone_id,
614
+ target_zone_id: packBody.target_zone_id,
615
+ interaction_class: packBody.interaction_class
616
+ }
617
+ },
618
+ {
619
+ task_id: "task_3",
620
+ task_ref: "jobs.reserve",
621
+ body: {
622
+ job_id: packBody.job_id
623
+ }
624
+ }
625
+ ], {
626
+ ...requestBody,
627
+ ...packBody,
628
+ protocol: requestBody.protocol || null,
629
+ payment_protocol: requestBody.payment_protocol || "x402",
630
+ integration_ids: integrationIds,
631
+ settlement_mode: requestBody.settlement_mode || "evm_payment"
632
+ }, requestBody.command || packRef);
633
+ }
634
+
635
+ return null;
636
+ }
637
+
638
+ function buildInteractionSpinePathRunPayload(body) {
639
+ const requestBody = body && typeof body === "object" && !Array.isArray(body) ? body : {};
640
+ const pathBody = requestBody.body && typeof requestBody.body === "object" && !Array.isArray(requestBody.body)
641
+ ? requestBody.body
642
+ : requestBody;
643
+ const pathRef = String(requestBody.spine_path_ref || "").trim();
644
+ const integrationIds = Array.isArray(requestBody.integration_ids) && requestBody.integration_ids.length > 0
645
+ ? requestBody.integration_ids
646
+ : ["builtin.payment.x402", "builtin.settlement.chain"];
647
+
648
+ if (pathRef === "spine.a2a.settlement") {
649
+ return buildNamedTaskSetPayload([
650
+ {
651
+ task_id: "task_1",
652
+ task_ref: "a2a.negotiate",
653
+ body: {
654
+ counterparty_agent_id: pathBody.counterparty_agent_id,
655
+ task_pack_ref: pathBody.task_pack_ref,
656
+ negotiation_mode: pathBody.negotiation_mode
657
+ }
658
+ },
659
+ {
660
+ task_id: "task_2",
661
+ task_ref: "admission.preview",
662
+ body: {
663
+ source_zone_id: pathBody.source_zone_id,
664
+ target_zone_id: pathBody.target_zone_id,
665
+ interaction_class: pathBody.interaction_class
666
+ }
667
+ },
668
+ {
669
+ task_id: "task_3",
670
+ task_ref: "a2a.commit",
671
+ body: {
672
+ negotiation_id: pathBody.negotiation_id,
673
+ intent_id: pathBody.intent_id
674
+ }
675
+ },
676
+ {
677
+ task_id: "task_4",
678
+ task_ref: "settlement.submit",
679
+ body: {
680
+ intent_id: pathBody.intent_id
681
+ }
682
+ }
683
+ ], {
684
+ ...requestBody,
685
+ ...pathBody,
686
+ protocol: requestBody.protocol || null,
687
+ payment_protocol: requestBody.payment_protocol || "x402",
688
+ integration_ids: integrationIds,
689
+ settlement_mode: requestBody.settlement_mode || "evm_payment"
690
+ }, requestBody.command || pathRef);
691
+ }
692
+
693
+ if (pathRef === "spine.a2c.tooling") {
694
+ return buildNamedTaskSetPayload([
695
+ {
696
+ task_id: "task_1",
697
+ task_ref: "a2c.session.open",
698
+ body: {
699
+ agent_id: pathBody.agent_id,
700
+ channel_ref: pathBody.channel_ref
701
+ }
702
+ },
703
+ {
704
+ task_id: "task_2",
705
+ task_ref: "a2c.pack.preview",
706
+ body: {
707
+ agent_id: pathBody.agent_id,
708
+ pack_ref: pathBody.pack_ref
709
+ }
710
+ },
711
+ {
712
+ task_id: "task_3",
713
+ task_ref: "admission.preview",
714
+ body: {
715
+ source_zone_id: pathBody.source_zone_id,
716
+ target_zone_id: pathBody.target_zone_id,
717
+ interaction_class: pathBody.interaction_class
718
+ }
719
+ },
720
+ {
721
+ task_id: "task_4",
722
+ task_ref: "adapter.mcp.invoke",
723
+ body: {
724
+ tool_name: pathBody.tool_name,
725
+ arguments: pathBody.arguments && typeof pathBody.arguments === "object" && !Array.isArray(pathBody.arguments)
726
+ ? pathBody.arguments
727
+ : {}
728
+ }
729
+ }
730
+ ], {
731
+ ...requestBody,
732
+ ...pathBody,
733
+ protocol: requestBody.protocol || null,
734
+ payment_protocol: requestBody.payment_protocol || "x402",
735
+ integration_ids: integrationIds,
736
+ settlement_mode: requestBody.settlement_mode || "evm_payment"
737
+ }, requestBody.command || pathRef);
738
+ }
739
+
740
+ if (pathRef === "spine.job.commitment") {
741
+ return buildNamedTaskSetPayload([
742
+ {
743
+ task_id: "task_1",
744
+ task_ref: "jobs.quote",
745
+ body: {
746
+ job_type: pathBody.job_type
747
+ }
748
+ },
749
+ {
750
+ task_id: "task_2",
751
+ task_ref: "admission.preview",
752
+ body: {
753
+ source_zone_id: pathBody.source_zone_id,
754
+ target_zone_id: pathBody.target_zone_id,
755
+ interaction_class: pathBody.interaction_class
756
+ }
757
+ },
758
+ {
759
+ task_id: "task_3",
760
+ task_ref: "jobs.reserve",
761
+ body: {
762
+ job_id: pathBody.job_id
763
+ }
764
+ },
765
+ {
766
+ task_id: "task_4",
767
+ task_ref: "jobs.commit",
768
+ body: {
769
+ job_id: pathBody.job_id
770
+ }
771
+ }
772
+ ], {
773
+ ...requestBody,
774
+ ...pathBody,
775
+ protocol: requestBody.protocol || null,
776
+ payment_protocol: requestBody.payment_protocol || "x402",
777
+ integration_ids: integrationIds,
778
+ settlement_mode: requestBody.settlement_mode || "evm_payment"
779
+ }, requestBody.command || pathRef);
780
+ }
781
+
782
+ return null;
783
+ }
784
+
509
785
  function listTransactionRecords(filters) {
510
786
  const transactions = Array.from(state.transactions.values()).map((item) => item.transaction);
511
787
  return listRecords(new Map(transactions.map((item) => [item.transaction_id, item])), filters);
@@ -652,6 +928,55 @@ function buildProofHandoffSummary(result, sourceRef) {
652
928
  };
653
929
  }
654
930
 
931
+ function buildPrecommitReadinessSummary(result, pack) {
932
+ const resultSet = buildResultSetFromCommandResult(result);
933
+ const transaction = resultSet.transaction || {};
934
+ const taskRefs = transaction.execution && transaction.execution.results_by_task_id
935
+ ? Object.values(transaction.execution.results_by_task_id).map((entry) => entry && entry.task_ref).filter(Boolean)
936
+ : [];
937
+ const admissionChecked = taskRefs.includes("admission.preview");
938
+ const negotiationSignals = taskRefs.filter((ref) => ref === "a2a.negotiate" || ref === "a2c.session.open");
939
+ const commitmentSignals = taskRefs.filter((ref) => ref === "a2a.commit" || ref === "a2c.pack.preview" || ref === "jobs.reserve");
940
+ const readinessPosture = admissionChecked && commitmentSignals.length > 0
941
+ ? "ready_for_committed_run"
942
+ : negotiationSignals.length > 0
943
+ ? "negotiation_in_progress"
944
+ : "precommit_partial";
945
+ return {
946
+ ok: true,
947
+ precommit_pack_ref: pack && pack.precommit_pack_ref ? pack.precommit_pack_ref : null,
948
+ readiness_kind: pack && pack.readiness_kind ? pack.readiness_kind : null,
949
+ protocol: transaction.protocol || (pack && pack.protocol ? pack.protocol : null),
950
+ payment_protocol: transaction.payment && transaction.payment.protocol
951
+ ? transaction.payment.protocol
952
+ : (pack && pack.default_payment_protocol ? pack.default_payment_protocol : null),
953
+ settlement_mode: transaction.settlement && transaction.settlement.mode
954
+ ? transaction.settlement.mode
955
+ : (pack && pack.default_settlement_mode ? pack.default_settlement_mode : null),
956
+ task_refs: taskRefs,
957
+ negotiation_signal_count: negotiationSignals.length,
958
+ commitment_signal_count: commitmentSignals.length,
959
+ admission_checked: admissionChecked,
960
+ readiness_posture: readinessPosture,
961
+ recommended_next_surface: pack && pack.recommended_next_surface ? pack.recommended_next_surface : null,
962
+ recommended_next_ref: pack && pack.recommended_next_ref ? pack.recommended_next_ref : null,
963
+ transaction_id: transaction.transaction_id || null
964
+ };
965
+ }
966
+
967
+ function buildInteractionSpineSummary(result, path) {
968
+ const precommitPack = path && path.precommit_pack_ref ? getPrecommitInteractionPack(path.precommit_pack_ref) : null;
969
+ return {
970
+ ok: true,
971
+ spine_path_ref: path && path.spine_path_ref ? path.spine_path_ref : null,
972
+ precommit_pack_ref: path && path.precommit_pack_ref ? path.precommit_pack_ref : null,
973
+ committed_ref: path && path.committed_ref ? path.committed_ref : null,
974
+ proof_followthrough: path && path.proof_followthrough ? path.proof_followthrough : null,
975
+ precommit_readiness_summary: buildPrecommitReadinessSummary(result, precommitPack),
976
+ proof_handoff_summary: buildProofHandoffSummary(result, path && path.committed_ref ? path.committed_ref : null)
977
+ };
978
+ }
979
+
655
980
  function buildOperationsDashboard(filters) {
656
981
  const disputes = listRecords(state.disputes, filters);
657
982
  const refunds = listRecords(state.refunds, filters);
@@ -760,6 +1085,46 @@ async function routeRequest(req, res) {
760
1085
  return;
761
1086
  }
762
1087
 
1088
+ if (req.method === "GET" && url.pathname === "/v1/transaction-center/precommit-packs") {
1089
+ sendJson(res, 200, buildPrecommitInteractionPackCatalog());
1090
+ return;
1091
+ }
1092
+
1093
+ if (req.method === "GET" && url.pathname === "/v1/transaction-center/precommit-packs/summary") {
1094
+ sendJson(res, 200, summarizePrecommitInteractionPacks());
1095
+ return;
1096
+ }
1097
+
1098
+ if (req.method === "GET" && url.pathname === "/v1/transaction-center/precommit-pack") {
1099
+ const pack = getPrecommitInteractionPack(url.searchParams.get("ref"));
1100
+ if (!pack) {
1101
+ sendJson(res, 404, { ok: false, error: "precommit_pack_not_found" });
1102
+ return;
1103
+ }
1104
+ sendJson(res, 200, { ok: true, precommit_pack: pack });
1105
+ return;
1106
+ }
1107
+
1108
+ if (req.method === "GET" && url.pathname === "/v1/transaction-center/spine-paths") {
1109
+ sendJson(res, 200, buildInteractionSpinePathCatalog());
1110
+ return;
1111
+ }
1112
+
1113
+ if (req.method === "GET" && url.pathname === "/v1/transaction-center/spine-paths/summary") {
1114
+ sendJson(res, 200, summarizeInteractionSpinePaths());
1115
+ return;
1116
+ }
1117
+
1118
+ if (req.method === "GET" && url.pathname === "/v1/transaction-center/spine-path") {
1119
+ const path = getInteractionSpinePath(url.searchParams.get("ref"));
1120
+ if (!path) {
1121
+ sendJson(res, 404, { ok: false, error: "spine_path_not_found" });
1122
+ return;
1123
+ }
1124
+ sendJson(res, 200, { ok: true, spine_path: path });
1125
+ return;
1126
+ }
1127
+
763
1128
  if (req.method === "GET" && url.pathname === "/v1/transaction-center/transaction-class-packs") {
764
1129
  sendJson(res, 200, buildTransactionClassPackCatalog());
765
1130
  return;
@@ -1287,6 +1652,66 @@ async function routeRequest(req, res) {
1287
1652
  return;
1288
1653
  }
1289
1654
 
1655
+ if (req.method === "POST" && url.pathname === "/v1/transaction-center/precommit-packs/run") {
1656
+ const body = await readJsonBody(req);
1657
+ const packRef = String(body && body.precommit_pack_ref || "").trim();
1658
+ const pack = getPrecommitInteractionPack(packRef);
1659
+ if (!pack) {
1660
+ sendJson(res, 404, { ok: false, error: "precommit_pack_not_found" });
1661
+ return;
1662
+ }
1663
+ const payload = buildPrecommitInteractionPackRunPayload(body);
1664
+ if (!payload) {
1665
+ sendJson(res, 404, { ok: false, error: "precommit_pack_not_found" });
1666
+ return;
1667
+ }
1668
+ const result = executeCommandRequest(state, payload, req.headers);
1669
+ if (result.status !== 200) {
1670
+ sendJson(res, result.status, result.payload);
1671
+ return;
1672
+ }
1673
+ sendJson(res, 200, {
1674
+ ok: true,
1675
+ precommit_pack: pack,
1676
+ result: result.payload,
1677
+ result_set_summary: summarizeResultSetPayload(buildResultSetFromCommandResult(result.payload)),
1678
+ linked_record_summary: summarizeLinkedRecordSetPayload(buildLinkedRecordSetFromCommandResult(result.payload)),
1679
+ activity_summary: summarizeActivitySnapshotPayload(buildActivitySnapshotFromCommandResult(result.payload)),
1680
+ precommit_readiness_summary: buildPrecommitReadinessSummary(result.payload, pack)
1681
+ });
1682
+ return;
1683
+ }
1684
+
1685
+ if (req.method === "POST" && url.pathname === "/v1/transaction-center/spine-paths/run") {
1686
+ const body = await readJsonBody(req);
1687
+ const pathRef = String(body && body.spine_path_ref || "").trim();
1688
+ const path = getInteractionSpinePath(pathRef);
1689
+ if (!path) {
1690
+ sendJson(res, 404, { ok: false, error: "spine_path_not_found" });
1691
+ return;
1692
+ }
1693
+ const payload = buildInteractionSpinePathRunPayload(body);
1694
+ if (!payload) {
1695
+ sendJson(res, 404, { ok: false, error: "spine_path_not_found" });
1696
+ return;
1697
+ }
1698
+ const result = executeCommandRequest(state, payload, req.headers);
1699
+ if (result.status !== 200) {
1700
+ sendJson(res, result.status, result.payload);
1701
+ return;
1702
+ }
1703
+ sendJson(res, 200, {
1704
+ ok: true,
1705
+ spine_path: path,
1706
+ result: result.payload,
1707
+ result_set_summary: summarizeResultSetPayload(buildResultSetFromCommandResult(result.payload)),
1708
+ linked_record_summary: summarizeLinkedRecordSetPayload(buildLinkedRecordSetFromCommandResult(result.payload)),
1709
+ activity_summary: summarizeActivitySnapshotPayload(buildActivitySnapshotFromCommandResult(result.payload)),
1710
+ spine_summary: buildInteractionSpineSummary(result.payload, path)
1711
+ });
1712
+ return;
1713
+ }
1714
+
1290
1715
  if (req.method === "POST" && url.pathname === "/v1/transaction-center/default-loops/run") {
1291
1716
  const body = await readJsonBody(req);
1292
1717
  const loopRef = String(body && body.loop_ref || "").trim();