xoonya 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
@@ -34,6 +34,12 @@ The current `1.7.0` companion slice adds a lightweight transaction proof-handoff
34
34
  - a direct handoff run path that turns transaction-side proof handoff data into a proof-native bundle
35
35
  - summary helpers that make the recommended proof follow-through explicit without widening proof scope
36
36
 
37
+ The current `1.8.0` companion slice extends that same proof-side carry to richer grouped interaction spine handoffs:
38
+
39
+ - an interaction-spine handoff center and summary surface
40
+ - a direct interaction-spine handoff run path for composed transaction spines
41
+ - proof-side summaries that preserve both pre-commit and committed-ref context without importing commerce logic
42
+
37
43
  ## Proof Model
38
44
 
39
45
  The primary proof model is layered:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xoonya",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Deterministic proof SDK for canonical events, receipts, proof bundles, and verification.",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
package/proof_sdk.js CHANGED
@@ -895,6 +895,22 @@ function buildTransactionProofHandoffCenter() {
895
895
  };
896
896
  }
897
897
 
898
+ function buildInteractionSpineProofHandoffCenter() {
899
+ return {
900
+ ok: true,
901
+ brand: "xoonya",
902
+ product: "interaction spine proof handoff center",
903
+ supported_source_refs: [
904
+ "spine.a2a.settlement",
905
+ "spine.a2c.tooling",
906
+ "spine.job.commitment"
907
+ ],
908
+ required_fields: ["transaction_id", "receipt_id", "proof_ref", "source_ref"],
909
+ optional_fields: ["task_refs", "delivery_count", "payment_ledger_count", "committed_ref", "precommit_pack_ref"],
910
+ recommended_loop: "default.proof.bundle.loop"
911
+ };
912
+ }
913
+
898
914
  function summarizeTransactionProofHandoffCenter() {
899
915
  const center = buildTransactionProofHandoffCenter();
900
916
  return {
@@ -909,6 +925,20 @@ function summarizeTransactionProofHandoffCenter() {
909
925
  };
910
926
  }
911
927
 
928
+ function summarizeInteractionSpineProofHandoffCenter() {
929
+ const center = buildInteractionSpineProofHandoffCenter();
930
+ return {
931
+ ok: true,
932
+ brand: center.brand,
933
+ product: center.product,
934
+ source_ref_count: Array.isArray(center.supported_source_refs) ? center.supported_source_refs.length : 0,
935
+ supported_source_refs: center.supported_source_refs,
936
+ required_field_count: Array.isArray(center.required_fields) ? center.required_fields.length : 0,
937
+ required_fields: center.required_fields,
938
+ recommended_loop: center.recommended_loop
939
+ };
940
+ }
941
+
912
942
  function canonicalizeTransactionProofHandoff(input) {
913
943
  const body = input && typeof input === "object" && !Array.isArray(input) ? input : {};
914
944
  const handoff = body.handoff_bundle && typeof body.handoff_bundle === "object" && !Array.isArray(body.handoff_bundle)
@@ -935,6 +965,26 @@ function canonicalizeTransactionProofHandoff(input) {
935
965
  };
936
966
  }
937
967
 
968
+ function canonicalizeInteractionSpineProofHandoff(input) {
969
+ const handoff = canonicalizeTransactionProofHandoff(input);
970
+ const body = input && typeof input === "object" && !Array.isArray(input) ? input : {};
971
+ const sourceRef = normalizeString(handoff.source_ref);
972
+ const center = buildInteractionSpineProofHandoffCenter();
973
+ if (!center.supported_source_refs.includes(sourceRef)) {
974
+ throw new Error("handoff_bundle.source_ref must be a supported interaction spine ref");
975
+ }
976
+ const raw = body.handoff_bundle && typeof body.handoff_bundle === "object" && !Array.isArray(body.handoff_bundle)
977
+ ? body.handoff_bundle
978
+ : body;
979
+ const committedRef = normalizeString(raw.committed_ref);
980
+ const precommitPackRef = normalizeString(raw.precommit_pack_ref);
981
+ return {
982
+ ...handoff,
983
+ committed_ref: committedRef || null,
984
+ precommit_pack_ref: precommitPackRef || null
985
+ };
986
+ }
987
+
938
988
  function buildTransactionProofHandoffEvent(input) {
939
989
  const handoff = canonicalizeTransactionProofHandoff(input);
940
990
  const eventHash = canonicalJsonSha256Hex({
@@ -958,6 +1008,31 @@ function buildTransactionProofHandoffEvent(input) {
958
1008
  });
959
1009
  }
960
1010
 
1011
+ function buildInteractionSpineProofHandoffEvent(input) {
1012
+ const handoff = canonicalizeInteractionSpineProofHandoff(input);
1013
+ const eventHash = canonicalJsonSha256Hex({
1014
+ source_ref: handoff.source_ref,
1015
+ transaction_id: handoff.transaction_id,
1016
+ receipt_id: handoff.receipt_id,
1017
+ proof_ref: handoff.proof_ref,
1018
+ task_refs: handoff.task_refs,
1019
+ delivery_count: handoff.delivery_count,
1020
+ payment_ledger_count: handoff.payment_ledger_count,
1021
+ committed_ref: handoff.committed_ref,
1022
+ precommit_pack_ref: handoff.precommit_pack_ref
1023
+ });
1024
+ return canonicalizeEvent({
1025
+ version: CANONICAL_EVENT_BUNDLE_VERSION,
1026
+ domain_id: "xytara.interaction_spine_handoff",
1027
+ sequence: handoff.transaction_id,
1028
+ actor_id: "xytara.interaction_spine",
1029
+ adapter_source: "xytara.spine_handoff",
1030
+ event_type: `${handoff.source_ref}.proof_handoff`,
1031
+ event_hash: eventHash,
1032
+ semantic_slots: handoff
1033
+ });
1034
+ }
1035
+
961
1036
  function runTransactionProofHandoff(input) {
962
1037
  const handoff = canonicalizeTransactionProofHandoff(input);
963
1038
  const event = buildTransactionProofHandoffEvent(input);
@@ -986,6 +1061,36 @@ function runTransactionProofHandoff(input) {
986
1061
  };
987
1062
  }
988
1063
 
1064
+ function runInteractionSpineProofHandoff(input) {
1065
+ const handoff = canonicalizeInteractionSpineProofHandoff(input);
1066
+ const event = buildInteractionSpineProofHandoffEvent(input);
1067
+ const options = input && input.options && typeof input.options === "object" && !Array.isArray(input.options)
1068
+ ? input.options
1069
+ : {};
1070
+ const receipt = emitReceipt(event, options);
1071
+ const proofBundle = buildProofBundle({
1072
+ ceb: event,
1073
+ receipt,
1074
+ evidence_refs: Array.isArray(input && input.evidence_refs) ? input.evidence_refs : [handoff.proof_ref],
1075
+ metadata: {
1076
+ handoff_kind: "interaction_spine_proof_handoff",
1077
+ source_ref: handoff.source_ref,
1078
+ committed_ref: handoff.committed_ref || null,
1079
+ precommit_pack_ref: handoff.precommit_pack_ref || null
1080
+ }
1081
+ });
1082
+ return {
1083
+ ok: true,
1084
+ handoff,
1085
+ canonical_event: event,
1086
+ event_commitment: hashEvent(event),
1087
+ receipt,
1088
+ proof_bundle: proofBundle,
1089
+ bundle_verification: verifyProofBundle(proofBundle),
1090
+ recommended_loop: "default.proof.bundle.loop"
1091
+ };
1092
+ }
1093
+
989
1094
  function summarizeTransactionProofHandoff(bundle) {
990
1095
  const item = bundle && typeof bundle === "object" ? bundle : {};
991
1096
  const handoff = item.handoff && typeof item.handoff === "object" ? item.handoff : {};
@@ -1006,6 +1111,28 @@ function summarizeTransactionProofHandoff(bundle) {
1006
1111
  };
1007
1112
  }
1008
1113
 
1114
+ function summarizeInteractionSpineProofHandoff(bundle) {
1115
+ const item = bundle && typeof bundle === "object" ? bundle : {};
1116
+ const handoff = item.handoff && typeof item.handoff === "object" ? item.handoff : {};
1117
+ const receipt = item.receipt && typeof item.receipt === "object" ? item.receipt : {};
1118
+ const proofBundle = item.proof_bundle && typeof item.proof_bundle === "object" ? item.proof_bundle : {};
1119
+ const verification = item.bundle_verification && typeof item.bundle_verification === "object" ? item.bundle_verification : {};
1120
+ return {
1121
+ ok: item.ok === true,
1122
+ source_ref: handoff.source_ref || null,
1123
+ transaction_id: handoff.transaction_id || null,
1124
+ receipt_id: handoff.receipt_id || null,
1125
+ proof_ref: handoff.proof_ref || null,
1126
+ committed_ref: handoff.committed_ref || null,
1127
+ precommit_pack_ref: handoff.precommit_pack_ref || null,
1128
+ task_ref_count: Array.isArray(handoff.task_refs) ? handoff.task_refs.length : 0,
1129
+ proof_bundle_version: proofBundle.version || null,
1130
+ emitted_receipt_id: receipt.receipt_id || null,
1131
+ bundle_valid: verification.valid === true,
1132
+ recommended_loop: item.recommended_loop || null
1133
+ };
1134
+ }
1135
+
1009
1136
  function runDefaultProofLoop(loopRef, input) {
1010
1137
  const loop = getDefaultProofLoop(loopRef);
1011
1138
  if (!loop) {
@@ -1049,15 +1176,21 @@ module.exports = {
1049
1176
  buildDefaultProofCenter,
1050
1177
  buildDefaultProofLoopCatalog,
1051
1178
  buildDefaultProofLoops,
1179
+ buildInteractionSpineProofHandoffCenter,
1052
1180
  buildTransactionProofHandoffCenter,
1181
+ buildInteractionSpineProofHandoffEvent,
1053
1182
  buildTransactionProofHandoffEvent,
1183
+ canonicalizeInteractionSpineProofHandoff,
1054
1184
  getDefaultProofLoop,
1055
1185
  canonicalizeTransactionProofHandoff,
1056
1186
  runDefaultProofLoop,
1187
+ runInteractionSpineProofHandoff,
1057
1188
  runTransactionProofHandoff,
1058
1189
  summarizeDefaultProofCenter,
1059
1190
  summarizeDefaultProofLoops,
1060
1191
  summarizeGuidedProofLoopBundle,
1192
+ summarizeInteractionSpineProofHandoff,
1193
+ summarizeInteractionSpineProofHandoffCenter,
1061
1194
  summarizeTransactionProofHandoff,
1062
1195
  summarizeTransactionProofHandoffCenter,
1063
1196
  canonicalizeEvent,
package/server.js CHANGED
@@ -107,6 +107,16 @@ async function routeRequest(req, res) {
107
107
  return;
108
108
  }
109
109
 
110
+ if (req.method === 'GET' && url.pathname === '/v1/proof-center/interaction-spine-handoff') {
111
+ sendJson(res, 200, proofSdk.buildInteractionSpineProofHandoffCenter());
112
+ return;
113
+ }
114
+
115
+ if (req.method === 'GET' && url.pathname === '/v1/proof-center/interaction-spine-handoff/summary') {
116
+ sendJson(res, 200, proofSdk.summarizeInteractionSpineProofHandoffCenter());
117
+ return;
118
+ }
119
+
110
120
  if (req.method === 'GET' && url.pathname === '/v1/proof-center/default-loop') {
111
121
  const loop = proofSdk.getDefaultProofLoop(url.searchParams.get('ref'));
112
122
  if (!loop) {
@@ -140,6 +150,17 @@ async function routeRequest(req, res) {
140
150
  return;
141
151
  }
142
152
 
153
+ if (req.method === 'POST' && url.pathname === '/v1/proof-center/interaction-spine-handoff/run') {
154
+ try {
155
+ const body = await readJsonBody(req);
156
+ const result = proofSdk.runInteractionSpineProofHandoff(body);
157
+ sendJson(res, 200, result);
158
+ } catch (error) {
159
+ sendJson(res, 400, { ok: false, reason: error.message });
160
+ }
161
+ return;
162
+ }
163
+
143
164
  if (req.method === 'POST' && url.pathname === '/v1/receipts/verify') {
144
165
  try {
145
166
  const body = await readJsonBody(req);