xytara 2.3.0 → 2.4.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.
@@ -2,6 +2,26 @@
2
2
 
3
3
  const crypto = require("crypto");
4
4
  const { findTask, findWorkflow } = require("../fixtures/catalog");
5
+ const {
6
+ buildAuthoritySummary,
7
+ buildAuthorityAttentionSummary
8
+ } = require("./commerce_authority");
9
+ const {
10
+ buildMachineIdentitySummary,
11
+ buildMachineIdentityAttentionSummary
12
+ } = require("./commerce_identity");
13
+ const {
14
+ createAuthorityBinding,
15
+ renewAuthorityBinding,
16
+ revokeAuthorityBinding,
17
+ rotateAuthorityBinding
18
+ } = require("./account_auth");
19
+ const {
20
+ createIdentityBinding,
21
+ renewIdentityBinding,
22
+ revokeIdentityBinding,
23
+ rotateIdentityBinding
24
+ } = require("./identity_auth");
5
25
 
6
26
  function normalizeString(value, fallback) {
7
27
  const trimmed = typeof value === "string" ? value.trim() : "";
@@ -155,13 +175,21 @@ function actOnEconomicsReceipt(state, receiptId, body) {
155
175
 
156
176
  function recordAllocationEvent(state, body, direction) {
157
177
  const payload = ensureObject(body);
178
+ const allocationId = normalizeString(payload.allocation_id, `alloc_${state.economicsAllocations.length + 1}`);
158
179
  const event = {
159
- allocation_id: normalizeString(payload.allocation_id, `alloc_${state.economicsAllocations.length + 1}`),
180
+ allocation_id: allocationId,
160
181
  account_id: normalizeString(payload.account_id, "acct_demo"),
161
182
  budget_id: normalizeString(payload.budget_id, null),
162
183
  job_id: normalizeString(payload.job_id, null),
163
184
  agent_id: normalizeString(payload.agent_id, null),
164
185
  receipt_ref: normalizeString(payload.receipt_ref, null),
186
+ transaction_id: normalizeString(payload.transaction_id, null),
187
+ credit_spend_id: normalizeString(payload.credit_spend_id, null),
188
+ usage_meter_id: normalizeString(payload.usage_meter_id, null),
189
+ lifecycle_ref: normalizeString(payload.lifecycle_ref, null),
190
+ reserve_ref: normalizeString(payload.reserve_ref, direction === "reserve" ? `reserve.${allocationId}` : null),
191
+ commit_ref: normalizeString(payload.commit_ref, direction === "commit" ? `commit.${allocationId}` : null),
192
+ resolves_allocation_id: normalizeString(payload.resolves_allocation_id, null),
165
193
  units: typeof payload.units === "number" ? payload.units : 0,
166
194
  direction,
167
195
  reason: normalizeString(payload.reason, null),
@@ -347,6 +375,11 @@ function listCreditSpendsForAccount(state, accountId) {
347
375
  return ensureArray(state.economicsCreditSpends).filter((item) => item && item.account_id === accountId);
348
376
  }
349
377
 
378
+ function getAllocationEvent(state, allocationId) {
379
+ if (!allocationId) return null;
380
+ return ensureArray(state.economicsAllocations).find((item) => item && item.allocation_id === allocationId) || null;
381
+ }
382
+
350
383
  function getCreditSpend(state, creditSpendId) {
351
384
  if (!creditSpendId) return null;
352
385
  return ensureArray(state.economicsCreditSpends).find((item) => item && item.credit_spend_id === creditSpendId) || null;
@@ -527,21 +560,126 @@ function buildWalletSummary(state, accountId) {
527
560
  credit_balance_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/credit-balance`,
528
561
  entitlements_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/entitlements`,
529
562
  usage_meters_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/usage-meters`,
563
+ wallet_commit_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-commit-summary`,
564
+ wallet_lifecycle_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-lifecycle-summary`,
530
565
  wallet_ledger_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-ledger-summary`
531
566
  },
532
567
  generated_at_iso: nowIso()
533
568
  };
534
569
  }
535
570
 
571
+ function buildWalletLifecycleSummary(state, accountId) {
572
+ const wallet = buildWalletSummary(state, accountId);
573
+ const allocations = listAllocationEventsForAccount(state, accountId);
574
+ const railCredits = listRailCreditsForAccount(state, accountId);
575
+ const creditSpends = listCreditSpendsForAccount(state, accountId);
576
+ const usageMeters = listUsageMetersForAccount(state, accountId);
577
+ const mintedUnits = allocations
578
+ .filter((entry) => entry && entry.direction === "mint")
579
+ .reduce((sum, entry) => sum + Number(entry.units || 0), 0)
580
+ + railCredits.reduce((sum, entry) => sum + Number(entry.units || 0), 0);
581
+ const reservedUnits = allocations
582
+ .filter((entry) => entry && entry.direction === "reserve")
583
+ .reduce((sum, entry) => sum + Number(entry.units || 0), 0);
584
+ const explicitCommittedUnits = allocations
585
+ .filter((entry) => entry && entry.direction === "commit")
586
+ .reduce((sum, entry) => sum + Number(entry.units || 0), 0);
587
+ const explicitCommitSpendIds = new Set(
588
+ allocations
589
+ .filter((entry) => entry && entry.direction === "commit" && entry.credit_spend_id)
590
+ .map((entry) => entry.credit_spend_id)
591
+ );
592
+ const fallbackCommittedSpends = creditSpends.filter((entry) => entry && !explicitCommitSpendIds.has(entry.credit_spend_id));
593
+ const spendCommittedUnits = fallbackCommittedSpends.reduce((sum, entry) => sum + Number(entry.units || 0), 0);
594
+ const releasedUnits = allocations
595
+ .filter((entry) => entry && entry.direction === "release")
596
+ .reduce((sum, entry) => sum + Number(entry.units || 0), 0);
597
+ const reversedUnits = allocations
598
+ .filter((entry) => entry && entry.direction === "reverse")
599
+ .reduce((sum, entry) => sum + Number(entry.units || 0), 0);
600
+ const committedUnits = explicitCommittedUnits + spendCommittedUnits;
601
+ const openReservedUnits = Math.max(0, reservedUnits - releasedUnits);
602
+ const correctionState = reversedUnits > 0 ? "corrective_activity_present" : "none";
603
+ const reserveState = openReservedUnits > 0 ? "open_reserves_present" : reservedUnits > 0 ? "reserves_fully_resolved" : "no_reserves_recorded";
604
+ const commitState = committedUnits > 0 ? "committed_consequence_present" : "no_committed_consequence";
605
+
606
+ return {
607
+ summary_version: "xytara-wallet-lifecycle-summary-v1",
608
+ wallet_id: wallet.wallet_id,
609
+ account_id: accountId,
610
+ canonical_unit: wallet.canonical_unit,
611
+ canonical_lifecycle_model: "mint_reserve_commit_release_reverse",
612
+ lifecycle_semantics: {
613
+ mint: "introduces usage-unit capacity into the hidden machine wallet",
614
+ reserve: "places bounded pre-execution hold against available capacity before final consequence",
615
+ commit: "records final consequence against wallet capacity, including live credit-spend consequence",
616
+ release: "returns previously reserved capacity when bounded execution does not finalize against that hold",
617
+ reverse: "records explicit corrective removal or rollback against previously issued or committed capacity"
618
+ },
619
+ lifecycle_totals: {
620
+ minted_units: mintedUnits,
621
+ reserved_units: reservedUnits,
622
+ committed_units: committedUnits,
623
+ released_units: releasedUnits,
624
+ reversed_units: reversedUnits,
625
+ consumed_units: wallet.consumed_units,
626
+ open_reserved_units: openReservedUnits,
627
+ available_units: wallet.available_units
628
+ },
629
+ lifecycle_states: {
630
+ wallet_state: wallet.wallet_state,
631
+ reserve_state: reserveState,
632
+ commit_state: commitState,
633
+ correction_state: correctionState
634
+ },
635
+ record_interpretation: {
636
+ mint_sources: {
637
+ allocation_mint_count: allocations.filter((entry) => entry && entry.direction === "mint").length,
638
+ rail_credit_count: railCredits.length
639
+ },
640
+ reserve_sources: {
641
+ allocation_reserve_count: allocations.filter((entry) => entry && entry.direction === "reserve").length
642
+ },
643
+ commit_sources: {
644
+ explicit_commit_count: allocations.filter((entry) => entry && entry.direction === "commit").length,
645
+ derived_credit_spend_commit_count: fallbackCommittedSpends.length,
646
+ usage_meter_count: usageMeters.length
647
+ },
648
+ release_sources: {
649
+ allocation_release_count: allocations.filter((entry) => entry && entry.direction === "release").length
650
+ },
651
+ reverse_sources: {
652
+ allocation_reverse_count: allocations.filter((entry) => entry && entry.direction === "reverse").length
653
+ }
654
+ },
655
+ linked_surfaces: {
656
+ wallet_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet`,
657
+ wallet_commit_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-commit-summary`,
658
+ wallet_ledger_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-ledger-summary`,
659
+ credit_balance_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/credit-balance`,
660
+ treasury_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/treasury-summary`,
661
+ reconciliation_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/reconciliation-pack`
662
+ },
663
+ generated_at_iso: nowIso()
664
+ };
665
+ }
666
+
536
667
  function buildWalletLedgerSummary(state, accountId) {
537
668
  const wallet = buildWalletSummary(state, accountId);
669
+ const lifecycle = buildWalletLifecycleSummary(state, accountId);
538
670
  const allocations = listAllocationEventsForAccount(state, accountId);
539
671
  const spends = listCreditSpendsForAccount(state, accountId);
540
672
  const railCredits = listRailCreditsForAccount(state, accountId);
673
+ const explicitCommitSpendIds = new Set(
674
+ allocations
675
+ .filter((entry) => entry && entry.direction === "commit" && entry.credit_spend_id)
676
+ .map((entry) => entry.credit_spend_id)
677
+ );
678
+ const fallbackCommittedSpends = spends.filter((entry) => entry && !explicitCommitSpendIds.has(entry.credit_spend_id));
541
679
  const consequences = {
542
680
  mint_count: allocations.filter((entry) => entry && entry.direction === "mint").length + railCredits.length,
543
681
  reserve_count: allocations.filter((entry) => entry && entry.direction === "reserve").length,
544
- commit_count: allocations.filter((entry) => entry && entry.direction === "commit").length + spends.length,
682
+ commit_count: allocations.filter((entry) => entry && entry.direction === "commit").length + fallbackCommittedSpends.length,
545
683
  release_count: allocations.filter((entry) => entry && entry.direction === "release").length,
546
684
  reverse_count: allocations.filter((entry) => entry && entry.direction === "reverse").length
547
685
  };
@@ -551,6 +689,7 @@ function buildWalletLedgerSummary(state, accountId) {
551
689
  wallet_id: wallet.wallet_id,
552
690
  account_id: accountId,
553
691
  canonical_truth_posture: "allocation_and_consequence_records_with_materialized_wallet_summary",
692
+ canonical_lifecycle_model: lifecycle.canonical_lifecycle_model,
554
693
  canonical_unit: wallet.canonical_unit,
555
694
  wallet_state: wallet.wallet_state,
556
695
  wallet_summary: {
@@ -562,6 +701,7 @@ function buildWalletLedgerSummary(state, accountId) {
562
701
  reversed_units: wallet.reversed_units,
563
702
  consumed_units: wallet.consumed_units
564
703
  },
704
+ lifecycle_state_summary: lifecycle.lifecycle_states,
565
705
  ledger_lifecycle_counts: consequences,
566
706
  source_record_counts: {
567
707
  allocation_count: allocations.length,
@@ -578,6 +718,7 @@ function buildWalletLedgerSummary(state, accountId) {
578
718
  },
579
719
  linked_surfaces: {
580
720
  wallet_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet`,
721
+ wallet_lifecycle_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-lifecycle-summary`,
581
722
  ledger_export_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/ledger-export`,
582
723
  reconciliation_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/reconciliation-pack`
583
724
  },
@@ -585,6 +726,235 @@ function buildWalletLedgerSummary(state, accountId) {
585
726
  };
586
727
  }
587
728
 
729
+ function buildWalletReserveSummary(state, accountId) {
730
+ const allocations = listAllocationEventsForAccount(state, accountId);
731
+ const reserveEvents = allocations.filter((entry) => entry && entry.direction === "reserve");
732
+ const resolutionEvents = allocations.filter((entry) => entry && (entry.direction === "release" || entry.direction === "reverse"));
733
+ const reserveRows = reserveEvents.map((reserve) => {
734
+ const linkedResolutions = resolutionEvents.filter((entry) => entry && entry.resolves_allocation_id === reserve.allocation_id);
735
+ const resolvedUnits = linkedResolutions.reduce((sum, entry) => sum + Number(entry.units || 0), 0);
736
+ const openUnits = Math.max(0, Number(reserve.units || 0) - resolvedUnits);
737
+ return {
738
+ reserve_ref: reserve.reserve_ref || `reserve.${reserve.allocation_id}`,
739
+ allocation_id: reserve.allocation_id,
740
+ account_id: reserve.account_id,
741
+ units: Number(reserve.units || 0),
742
+ open_units: openUnits,
743
+ reserve_state: openUnits > 0 ? "open" : "resolved",
744
+ reason: reserve.reason || null,
745
+ created_at_iso: reserve.created_at_iso || null,
746
+ linked_resolution_count: linkedResolutions.length,
747
+ linked_resolutions: linkedResolutions.map((entry) => ({
748
+ allocation_id: entry.allocation_id,
749
+ direction: entry.direction,
750
+ units: Number(entry.units || 0),
751
+ reason: entry.reason || null,
752
+ created_at_iso: entry.created_at_iso || null
753
+ }))
754
+ };
755
+ });
756
+
757
+ return {
758
+ summary_version: "xytara-wallet-reserve-summary-v1",
759
+ account_id: accountId,
760
+ reserve_count: reserveRows.length,
761
+ open_reserve_count: reserveRows.filter((entry) => entry.reserve_state === "open").length,
762
+ resolved_reserve_count: reserveRows.filter((entry) => entry.reserve_state === "resolved").length,
763
+ total_reserved_units: reserveRows.reduce((sum, entry) => sum + entry.units, 0),
764
+ total_open_reserved_units: reserveRows.reduce((sum, entry) => sum + entry.open_units, 0),
765
+ reserves: reserveRows,
766
+ linked_surfaces: {
767
+ wallet_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet`,
768
+ wallet_commit_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-commit-summary`,
769
+ wallet_lifecycle_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-lifecycle-summary`,
770
+ wallet_ledger_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-ledger-summary`
771
+ },
772
+ generated_at_iso: nowIso()
773
+ };
774
+ }
775
+
776
+ function buildWalletCommitSummary(state, accountId) {
777
+ const allocations = listAllocationEventsForAccount(state, accountId);
778
+ const commitEvents = allocations.filter((entry) => entry && entry.direction === "commit");
779
+ const reverseEvents = allocations.filter((entry) => entry && entry.direction === "reverse");
780
+ const commitRows = commitEvents.map((commit) => {
781
+ const linkedReversals = reverseEvents.filter((entry) => entry && entry.resolves_allocation_id === commit.allocation_id);
782
+ const reversedUnits = linkedReversals.reduce((sum, entry) => sum + Number(entry.units || 0), 0);
783
+ const netCommittedUnits = Math.max(0, Number(commit.units || 0) - reversedUnits);
784
+ return {
785
+ commit_ref: commit.commit_ref || `commit.${commit.allocation_id}`,
786
+ allocation_id: commit.allocation_id,
787
+ account_id: commit.account_id,
788
+ credit_spend_id: commit.credit_spend_id || null,
789
+ usage_meter_id: commit.usage_meter_id || null,
790
+ transaction_id: commit.transaction_id || null,
791
+ receipt_ref: commit.receipt_ref || null,
792
+ units: Number(commit.units || 0),
793
+ net_committed_units: netCommittedUnits,
794
+ commit_state: netCommittedUnits > 0 ? "active" : "fully_reversed",
795
+ reason: commit.reason || null,
796
+ created_at_iso: commit.created_at_iso || null,
797
+ linked_reversal_count: linkedReversals.length,
798
+ linked_reversals: linkedReversals.map((entry) => ({
799
+ allocation_id: entry.allocation_id,
800
+ direction: entry.direction,
801
+ units: Number(entry.units || 0),
802
+ reason: entry.reason || null,
803
+ created_at_iso: entry.created_at_iso || null
804
+ }))
805
+ };
806
+ });
807
+
808
+ return {
809
+ summary_version: "xytara-wallet-commit-summary-v1",
810
+ account_id: accountId,
811
+ commit_count: commitRows.length,
812
+ active_commit_count: commitRows.filter((entry) => entry.commit_state === "active").length,
813
+ fully_reversed_commit_count: commitRows.filter((entry) => entry.commit_state === "fully_reversed").length,
814
+ total_committed_units: commitRows.reduce((sum, entry) => sum + entry.units, 0),
815
+ total_net_committed_units: commitRows.reduce((sum, entry) => sum + entry.net_committed_units, 0),
816
+ commits: commitRows,
817
+ linked_surfaces: {
818
+ wallet_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet`,
819
+ wallet_lifecycle_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-lifecycle-summary`,
820
+ wallet_commit_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-commit-summary`,
821
+ wallet_ledger_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-ledger-summary`
822
+ },
823
+ generated_at_iso: nowIso()
824
+ };
825
+ }
826
+
827
+ function buildWalletLedgerBundle(state, accountId) {
828
+ const wallet = buildWalletSummary(state, accountId);
829
+ const lifecycle = buildWalletLifecycleSummary(state, accountId);
830
+ const reserves = buildWalletReserveSummary(state, accountId);
831
+ const commits = buildWalletCommitSummary(state, accountId);
832
+ const ledger = buildWalletLedgerSummary(state, accountId);
833
+ const balance = buildCreditBalanceSummary(state, accountId);
834
+
835
+ return {
836
+ bundle_version: "xytara-wallet-ledger-bundle-v1",
837
+ account_id: accountId,
838
+ wallet_id: wallet.wallet_id,
839
+ canonical_unit: wallet.canonical_unit,
840
+ canonical_truth_posture: ledger.canonical_truth_posture,
841
+ canonical_lifecycle_model: lifecycle.canonical_lifecycle_model,
842
+ bundle_state: {
843
+ wallet_state: wallet.wallet_state,
844
+ reserve_state: lifecycle.lifecycle_states.reserve_state,
845
+ commit_state: lifecycle.lifecycle_states.commit_state,
846
+ correction_state: lifecycle.lifecycle_states.correction_state,
847
+ replenishment_posture: wallet.replenishment_posture
848
+ },
849
+ compact_totals: {
850
+ issued_units: wallet.issued_units,
851
+ available_units: wallet.available_units,
852
+ consumed_units: wallet.consumed_units,
853
+ open_reserved_units: lifecycle.lifecycle_totals.open_reserved_units,
854
+ active_commit_units: commits.total_net_committed_units,
855
+ reversed_units: lifecycle.lifecycle_totals.reversed_units
856
+ },
857
+ wallet_summary: wallet,
858
+ wallet_lifecycle_summary: lifecycle,
859
+ wallet_reserve_summary: reserves,
860
+ wallet_commit_summary: commits,
861
+ wallet_ledger_summary: ledger,
862
+ credit_balance_summary: balance,
863
+ linked_surfaces: {
864
+ wallet_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet`,
865
+ wallet_lifecycle_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-lifecycle-summary`,
866
+ wallet_reserve_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-reserve-summary`,
867
+ wallet_commit_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-commit-summary`,
868
+ wallet_ledger_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/wallet-ledger-summary`,
869
+ reconciliation_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/reconciliation-pack`
870
+ },
871
+ generated_at_iso: nowIso()
872
+ };
873
+ }
874
+
875
+ function applyWalletLifecycleEvent(state, body, direction) {
876
+ const payload = ensureObject(body);
877
+ const accountId = normalizeString(payload.account_id, "acct_demo");
878
+ const units = typeof payload.units === "number" ? payload.units : 0;
879
+ if (!(units > 0)) {
880
+ return { ok: false, reason: "units_must_be_positive", account_id: accountId };
881
+ }
882
+
883
+ let reserveTarget = null;
884
+ let resolvedTarget = null;
885
+ if (direction === "release") {
886
+ const resolvesAllocationId = normalizeString(payload.resolves_allocation_id, null);
887
+ if (!resolvesAllocationId) {
888
+ return { ok: false, reason: "resolves_allocation_id_required", account_id: accountId };
889
+ }
890
+ reserveTarget = getAllocationEvent(state, resolvesAllocationId);
891
+ if (!reserveTarget || reserveTarget.account_id !== accountId || reserveTarget.direction !== "reserve") {
892
+ return { ok: false, reason: "reserve_target_not_found", account_id: accountId, resolves_allocation_id: resolvesAllocationId };
893
+ }
894
+ }
895
+ if (direction === "reverse") {
896
+ const resolvesAllocationId = normalizeString(payload.resolves_allocation_id, null);
897
+ if (resolvesAllocationId) {
898
+ resolvedTarget = getAllocationEvent(state, resolvesAllocationId);
899
+ if (!resolvedTarget || resolvedTarget.account_id !== accountId) {
900
+ return { ok: false, reason: "reverse_target_not_found", account_id: accountId, resolves_allocation_id: resolvesAllocationId };
901
+ }
902
+ }
903
+ }
904
+
905
+ const lifecycle = buildWalletLifecycleSummary(state, accountId);
906
+ if (direction === "reserve" && lifecycle.lifecycle_totals.available_units < units) {
907
+ return {
908
+ ok: false,
909
+ reason: "insufficient_available_units",
910
+ account_id: accountId,
911
+ available_units: lifecycle.lifecycle_totals.available_units,
912
+ required_units: units
913
+ };
914
+ }
915
+
916
+ if (direction === "release" && lifecycle.lifecycle_totals.open_reserved_units < units) {
917
+ return {
918
+ ok: false,
919
+ reason: "insufficient_open_reserved_units",
920
+ account_id: accountId,
921
+ open_reserved_units: lifecycle.lifecycle_totals.open_reserved_units,
922
+ required_units: units
923
+ };
924
+ }
925
+
926
+ if (direction === "reverse" && lifecycle.lifecycle_totals.available_units < units) {
927
+ return {
928
+ ok: false,
929
+ reason: "insufficient_reversible_units",
930
+ account_id: accountId,
931
+ available_units: lifecycle.lifecycle_totals.available_units,
932
+ required_units: units
933
+ };
934
+ }
935
+
936
+ const event = recordAllocationEvent(state, {
937
+ ...payload,
938
+ reserve_ref: direction === "reserve"
939
+ ? normalizeString(payload.reserve_ref, null)
940
+ : reserveTarget
941
+ ? reserveTarget.reserve_ref || `reserve.${reserveTarget.allocation_id}`
942
+ : normalizeString(payload.reserve_ref, null)
943
+ ,
944
+ commit_ref: resolvedTarget && resolvedTarget.direction === "commit"
945
+ ? resolvedTarget.commit_ref || `commit.${resolvedTarget.allocation_id}`
946
+ : normalizeString(payload.commit_ref, null)
947
+ }, direction);
948
+ return {
949
+ ok: true,
950
+ lifecycle_event: event,
951
+ wallet_lifecycle_summary: buildWalletLifecycleSummary(state, accountId),
952
+ wallet_reserve_summary: buildWalletReserveSummary(state, accountId),
953
+ wallet_commit_summary: buildWalletCommitSummary(state, accountId),
954
+ balance: buildCreditBalanceSummary(state, accountId)
955
+ };
956
+ }
957
+
588
958
  function getWorkflowTaskRefs(workflowRef) {
589
959
  const workflow = findWorkflow(workflowRef);
590
960
  if (!workflow || !Array.isArray(workflow.tasks)) return [];
@@ -875,6 +1245,21 @@ function consumeAccountCredits(state, body) {
875
1245
  remaining_units: nextEntitlement.remaining_units
876
1246
  };
877
1247
  }
1248
+ recordAllocationEvent(state, {
1249
+ allocation_id: `alloc_commit_${spend.credit_spend_id}`,
1250
+ account_id: accountId,
1251
+ budget_id: spend.budget_id,
1252
+ job_id: normalizeString(payload.job_id, null),
1253
+ agent_id: spend.agent_id,
1254
+ receipt_ref: spend.receipt_id,
1255
+ transaction_id: spend.transaction_id,
1256
+ credit_spend_id: spend.credit_spend_id,
1257
+ usage_meter_id: usageMeter.usage_meter_id,
1258
+ lifecycle_ref: `commit.${spend.credit_spend_id}`,
1259
+ commit_ref: `commit.${spend.credit_spend_id}`,
1260
+ units,
1261
+ reason: spend.reason
1262
+ }, "commit");
878
1263
  state.economicsCreditSpends = [spend, ...ensureArray(state.economicsCreditSpends)].slice(0, 500);
879
1264
  return {
880
1265
  ok: true,
@@ -1484,6 +1869,1731 @@ function buildAgentCreditSpendPolicyView(state, accountId, agentId) {
1484
1869
  };
1485
1870
  }
1486
1871
 
1872
+ function buildPricingPolicySummary(state, accountId) {
1873
+ const balanceSummary = buildCreditBalanceSummary(state, accountId);
1874
+ const meteringSummary = buildUsageMeteringSummary(state, accountId);
1875
+ const policySummary = buildPolicySummary(state, accountId);
1876
+ const economicsIntelligence = buildEconomicsIntelligenceSummary(state, accountId);
1877
+ const replenishmentSummary = buildEntitlementReplenishmentSummary(state, accountId);
1878
+
1879
+ const pricingBands = ensureArray(meteringSummary.pricing_bands).filter(Boolean);
1880
+ const dominantPricingBand = pricingBands[0] || null;
1881
+ const usageMeterCount = Number(meteringSummary.usage_meter_count || 0);
1882
+ const totalUnits = Number(meteringSummary.total_units || 0);
1883
+
1884
+ let pricingPosture = "direct_pay_entry";
1885
+ if (usageMeterCount > 0 || Number(balanceSummary.consumed_units || 0) > 0) {
1886
+ pricingPosture = "credits_first_runtime";
1887
+ }
1888
+ if (economicsIntelligence.recommended_funding_posture === "pack_backed_credits_first") {
1889
+ pricingPosture = "pack_backed_runtime";
1890
+ }
1891
+
1892
+ let pricingRiskState = "low";
1893
+ if (replenishmentSummary.low_balance_count > 0 || policySummary.active_budget_count > 0) {
1894
+ pricingRiskState = "watch";
1895
+ }
1896
+ if (replenishmentSummary.depleted_count > 0 || (usageMeterCount > 0 && Number(balanceSummary.available_units || 0) <= Math.max(8, totalUnits))) {
1897
+ pricingRiskState = "high";
1898
+ }
1899
+
1900
+ return {
1901
+ summary_version: "xytara-pricing-policy-summary-v1",
1902
+ account_id: accountId,
1903
+ pricing_posture: pricingPosture,
1904
+ pricing_risk_state: pricingRiskState,
1905
+ dominant_pricing_band: dominantPricingBand,
1906
+ recommended_pack_id: economicsIntelligence.recommended_pack_id,
1907
+ bounded_spend_available: policySummary.bounded_spend_available,
1908
+ explanation_signals: {
1909
+ usage_meter_count: usageMeterCount,
1910
+ total_units: totalUnits,
1911
+ pricing_bands: pricingBands,
1912
+ available_units: balanceSummary.available_units,
1913
+ active_budget_count: policySummary.active_budget_count,
1914
+ agent_count: policySummary.agent_count,
1915
+ low_balance_count: replenishmentSummary.low_balance_count,
1916
+ depleted_count: replenishmentSummary.depleted_count
1917
+ },
1918
+ linked_surfaces: {
1919
+ policy_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/policy-summary`,
1920
+ policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/policy-pack`,
1921
+ economics_intelligence_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/intelligence-summary`,
1922
+ metering_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/metering-summary`
1923
+ },
1924
+ generated_at_iso: nowIso()
1925
+ };
1926
+ }
1927
+
1928
+ function buildPricingPolicyOperatorBundle(state, accountId) {
1929
+ const pricingPolicySummary = buildPricingPolicySummary(state, accountId);
1930
+ const policySummary = buildPolicySummary(state, accountId);
1931
+ const policyPack = buildAccountCreditSpendPolicyPack(state, accountId);
1932
+ const economicsIntelligence = buildEconomicsIntelligenceSummary(state, accountId);
1933
+ const treasuryIntelligence = buildTreasuryIntelligenceSummary(state, accountId);
1934
+
1935
+ let recommendedOperatorMotion = "maintain_current_pricing_posture";
1936
+ if (pricingPolicySummary.pricing_risk_state === "high") {
1937
+ recommendedOperatorMotion = "restore_pricing_headroom";
1938
+ } else if (pricingPolicySummary.pricing_posture === "pack_backed_runtime") {
1939
+ recommendedOperatorMotion = "stabilize_pack_backed_runtime";
1940
+ } else if (policySummary.bounded_spend_available) {
1941
+ recommendedOperatorMotion = "tighten_bounded_spend_pricing_controls";
1942
+ } else if (economicsIntelligence.recommended_funding_posture === "direct_pay_first") {
1943
+ recommendedOperatorMotion = "keep_direct_pay_entry_clear";
1944
+ }
1945
+
1946
+ return {
1947
+ bundle_version: "xytara-pricing-policy-operator-bundle-v1",
1948
+ account_id: accountId,
1949
+ operator_posture: {
1950
+ pricing_posture: pricingPolicySummary.pricing_posture,
1951
+ pricing_risk_state: pricingPolicySummary.pricing_risk_state,
1952
+ treasury_health_state: economicsIntelligence.treasury_health_state,
1953
+ value_capture_state: treasuryIntelligence.value_capture_state,
1954
+ recommended_operator_motion: recommendedOperatorMotion
1955
+ },
1956
+ pricing_policy_summary: pricingPolicySummary,
1957
+ policy_summary: policySummary,
1958
+ policy_pack: policyPack,
1959
+ economics_intelligence_summary: economicsIntelligence,
1960
+ treasury_intelligence_summary: treasuryIntelligence,
1961
+ linked_surfaces: {
1962
+ pricing_policy_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-summary`,
1963
+ policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/policy-pack`,
1964
+ economics_intelligence_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/intelligence-summary`,
1965
+ treasury_intelligence_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/treasury-intelligence-summary`
1966
+ },
1967
+ generated_at_iso: nowIso()
1968
+ };
1969
+ }
1970
+
1971
+ function buildPricingPolicyPack(state, accountId) {
1972
+ const pricingPolicySummary = buildPricingPolicySummary(state, accountId);
1973
+ const operatorBundle = buildPricingPolicyOperatorBundle(state, accountId);
1974
+ const pricingBandProfiles = Object.entries(PRICING_BAND_UNITS).map(([pricing_band, usage_units]) => ({
1975
+ pricing_band,
1976
+ usage_units,
1977
+ recommended_for: usage_units >= 8
1978
+ ? "high consequence or multi-step runtime work"
1979
+ : usage_units >= 3
1980
+ ? "moderate runtime execution"
1981
+ : "entry and lightweight runtime paths"
1982
+ }));
1983
+ const policyTemplates = [
1984
+ {
1985
+ template_id: "direct_pay_entry_clear",
1986
+ recommended_for: "keeping first-contact spend simple",
1987
+ target_motion: "keep_direct_pay_entry_clear",
1988
+ pricing_posture: "direct_pay_entry"
1989
+ },
1990
+ {
1991
+ template_id: "credits_first_runtime_default",
1992
+ recommended_for: "normal repeat runtime execution",
1993
+ target_motion: "maintain_current_pricing_posture",
1994
+ pricing_posture: "credits_first_runtime"
1995
+ },
1996
+ {
1997
+ template_id: "pack_backed_runtime_scale",
1998
+ recommended_for: "repeat usage with replenishment pressure",
1999
+ target_motion: "stabilize_pack_backed_runtime",
2000
+ pricing_posture: "pack_backed_runtime"
2001
+ },
2002
+ {
2003
+ template_id: "bounded_spend_guardrails",
2004
+ recommended_for: "agent and budget-constrained runtime usage",
2005
+ target_motion: "tighten_bounded_spend_pricing_controls",
2006
+ pricing_posture: "credits_first_runtime"
2007
+ }
2008
+ ];
2009
+
2010
+ return {
2011
+ pack_version: "xytara-pricing-policy-pack-v1",
2012
+ account_id: accountId,
2013
+ pricing_policy_summary: pricingPolicySummary,
2014
+ operator_bundle: operatorBundle,
2015
+ pricing_band_profiles: pricingBandProfiles,
2016
+ policy_templates: policyTemplates,
2017
+ recommended_policy_motion: operatorBundle.operator_posture.recommended_operator_motion,
2018
+ linked_surfaces: {
2019
+ pricing_policy_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-summary`,
2020
+ pricing_policy_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-operator-bundle`,
2021
+ pricing_policy_application_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-application-summary`
2022
+ },
2023
+ generated_at_iso: nowIso()
2024
+ };
2025
+ }
2026
+
2027
+ function buildPricingPolicyApplicationSummary(state, accountId, templateId) {
2028
+ const pack = buildPricingPolicyPack(state, accountId);
2029
+ const selectedTemplate = ensureArray(pack.policy_templates).find((entry) => entry.template_id === templateId)
2030
+ || ensureArray(pack.policy_templates).find((entry) => entry.target_motion === pack.recommended_policy_motion)
2031
+ || ensureArray(pack.policy_templates)[0]
2032
+ || null;
2033
+
2034
+ return {
2035
+ summary_version: "xytara-pricing-policy-application-summary-v1",
2036
+ account_id: accountId,
2037
+ recommended_policy_motion: pack.recommended_policy_motion,
2038
+ selected_template_id: selectedTemplate ? selectedTemplate.template_id : null,
2039
+ available_template_ids: ensureArray(pack.policy_templates).map((entry) => entry.template_id),
2040
+ selected_template: selectedTemplate,
2041
+ suggested_pricing_targets: {
2042
+ funding_posture: pack.pricing_policy_summary.pricing_posture,
2043
+ dominant_pricing_band: pack.pricing_policy_summary.dominant_pricing_band,
2044
+ recommended_pack_id: pack.pricing_policy_summary.recommended_pack_id,
2045
+ bounded_spend_available: pack.pricing_policy_summary.bounded_spend_available
2046
+ },
2047
+ linked_surfaces: {
2048
+ pricing_policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-pack`,
2049
+ pricing_policy_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-operator-bundle`,
2050
+ policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/policy-pack`
2051
+ },
2052
+ generated_at_iso: nowIso()
2053
+ };
2054
+ }
2055
+
2056
+ function buildPricingPolicyPackage(state, accountId) {
2057
+ const pricingPolicySummary = buildPricingPolicySummary(state, accountId);
2058
+ const operatorBundle = buildPricingPolicyOperatorBundle(state, accountId);
2059
+ const pack = buildPricingPolicyPack(state, accountId);
2060
+ const applicationSummary = buildPricingPolicyApplicationSummary(state, accountId, null);
2061
+ return {
2062
+ package_version: "xytara-pricing-policy-package-v1",
2063
+ account_id: accountId,
2064
+ package_posture: {
2065
+ pricing_posture: pricingPolicySummary.pricing_posture,
2066
+ pricing_risk_state: pricingPolicySummary.pricing_risk_state,
2067
+ recommended_operator_motion: operatorBundle.operator_posture.recommended_operator_motion,
2068
+ recommended_policy_motion: pack.recommended_policy_motion
2069
+ },
2070
+ pricing_policy_summary: pricingPolicySummary,
2071
+ pricing_policy_operator_bundle: operatorBundle,
2072
+ pricing_policy_pack: pack,
2073
+ pricing_policy_application_summary: applicationSummary,
2074
+ linked_surfaces: {
2075
+ pricing_policy_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-summary`,
2076
+ pricing_policy_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-operator-bundle`,
2077
+ pricing_policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-pack`,
2078
+ pricing_policy_application_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-application-summary`
2079
+ },
2080
+ generated_at_iso: nowIso()
2081
+ };
2082
+ }
2083
+
2084
+ function buildQuotePolicyDecisionSummary(state, body) {
2085
+ const payload = ensureObject(body);
2086
+ const accountId = normalizeString(payload.account_id, "acct_demo");
2087
+ const usagePreview = buildUsageMeterPreview(state, payload);
2088
+ const pricingPolicySummary = buildPricingPolicySummary(state, accountId);
2089
+ const policyDecision = buildCreditSpendPolicyDecision(state, payload);
2090
+ const quotedUnits = resolveUsageMeterUnits(payload, buildUsageMeterBase(payload));
2091
+ const amountMinor = quotedUnits * 100;
2092
+
2093
+ let quotePolicyState = "direct_pay_quote";
2094
+ if (pricingPolicySummary.pricing_posture !== "direct_pay_entry") {
2095
+ quotePolicyState = "credits_first_quote";
2096
+ }
2097
+ if (pricingPolicySummary.pricing_posture === "pack_backed_runtime") {
2098
+ quotePolicyState = "pack_backed_quote";
2099
+ }
2100
+
2101
+ let recommendedQuoteMotion = "issue_standard_quote";
2102
+ if (!policyDecision.ok) {
2103
+ recommendedQuoteMotion = "require_bounded_policy_repair";
2104
+ } else if (pricingPolicySummary.pricing_risk_state === "high") {
2105
+ recommendedQuoteMotion = "issue_replenishment_aware_quote";
2106
+ } else if (pricingPolicySummary.pricing_posture === "pack_backed_runtime") {
2107
+ recommendedQuoteMotion = "issue_pack_aligned_quote";
2108
+ }
2109
+
2110
+ return {
2111
+ summary_version: "xytara-quote-policy-decision-summary-v1",
2112
+ account_id: accountId,
2113
+ quote_policy_state: quotePolicyState,
2114
+ recommended_quote_motion: recommendedQuoteMotion,
2115
+ quoted_units: quotedUnits,
2116
+ quoted_amount_minor: amountMinor,
2117
+ pricing_band: usagePreview.pricing_band,
2118
+ task_domain: usagePreview.task_domain,
2119
+ policy_guard: {
2120
+ ok: Boolean(policyDecision.ok),
2121
+ reason: policyDecision.reason || null,
2122
+ budget_id: policyDecision.budget_id || null,
2123
+ agent_id: policyDecision.agent_id || null,
2124
+ max_reserve_units: policyDecision.max_reserve_units || null
2125
+ },
2126
+ linked_surfaces: {
2127
+ pricing_policy_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-summary`,
2128
+ pricing_policy_package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-package`,
2129
+ policy_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/policy-summary`
2130
+ },
2131
+ generated_at_iso: nowIso()
2132
+ };
2133
+ }
2134
+
2135
+ function buildPricingBandDecisionSummary(state, body) {
2136
+ const payload = ensureObject(body);
2137
+ const accountId = normalizeString(payload.account_id, "acct_demo");
2138
+ const usagePreview = buildUsageMeterPreview(state, payload);
2139
+ const pricingPolicySummary = buildPricingPolicySummary(state, accountId);
2140
+ const bandUnits = PRICING_BAND_UNITS[usagePreview.pricing_band] || usagePreview.usage_units || 1;
2141
+
2142
+ let bandDecisionState = "standard_band";
2143
+ if (usagePreview.pricing_band === "utility") {
2144
+ bandDecisionState = "entry_band";
2145
+ } else if (usagePreview.pricing_band === "premium" || usagePreview.pricing_band === "heavy") {
2146
+ bandDecisionState = "high_consequence_band";
2147
+ }
2148
+
2149
+ let recommendedBandMotion = "accept_detected_band";
2150
+ if (pricingPolicySummary.pricing_risk_state === "high" && bandUnits >= 8) {
2151
+ recommendedBandMotion = "review_high_unit_band";
2152
+ } else if (pricingPolicySummary.pricing_posture === "direct_pay_entry" && bandUnits > 3) {
2153
+ recommendedBandMotion = "check_entry_path_alignment";
2154
+ }
2155
+
2156
+ return {
2157
+ summary_version: "xytara-pricing-band-decision-summary-v1",
2158
+ account_id: accountId,
2159
+ pricing_band: usagePreview.pricing_band,
2160
+ usage_units: usagePreview.usage_units,
2161
+ band_units: bandUnits,
2162
+ band_decision_state: bandDecisionState,
2163
+ recommended_band_motion: recommendedBandMotion,
2164
+ task_ref: usagePreview.task_ref,
2165
+ workflow_ref: usagePreview.workflow_ref,
2166
+ task_domain: usagePreview.task_domain,
2167
+ linked_surfaces: {
2168
+ pricing_policy_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-summary`,
2169
+ pricing_policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-pack`,
2170
+ metering_preview_ref: "/v1/economics/metering/preview"
2171
+ },
2172
+ generated_at_iso: nowIso()
2173
+ };
2174
+ }
2175
+
2176
+ function buildQuotePolicyOperatorBundle(state, body) {
2177
+ const payload = ensureObject(body);
2178
+ const accountId = normalizeString(payload.account_id, "acct_demo");
2179
+ const quoteDecision = buildQuotePolicyDecisionSummary(state, payload);
2180
+ const bandDecision = buildPricingBandDecisionSummary(state, payload);
2181
+ const pricingPolicySummary = buildPricingPolicySummary(state, accountId);
2182
+
2183
+ let recommendedOperatorMotion = "maintain_quote_policy_posture";
2184
+ if (quoteDecision.policy_guard.ok === false) {
2185
+ recommendedOperatorMotion = "repair_bounded_quote_controls";
2186
+ } else if (quoteDecision.recommended_quote_motion === "issue_replenishment_aware_quote") {
2187
+ recommendedOperatorMotion = "prepare_replenishment_aligned_quote";
2188
+ } else if (bandDecision.recommended_band_motion === "review_high_unit_band") {
2189
+ recommendedOperatorMotion = "review_high_unit_quote_band";
2190
+ }
2191
+
2192
+ return {
2193
+ bundle_version: "xytara-quote-policy-operator-bundle-v1",
2194
+ account_id: accountId,
2195
+ operator_posture: {
2196
+ quote_policy_state: quoteDecision.quote_policy_state,
2197
+ pricing_band: bandDecision.pricing_band,
2198
+ pricing_risk_state: pricingPolicySummary.pricing_risk_state,
2199
+ recommended_quote_motion: quoteDecision.recommended_quote_motion,
2200
+ recommended_band_motion: bandDecision.recommended_band_motion,
2201
+ recommended_operator_motion: recommendedOperatorMotion
2202
+ },
2203
+ quote_policy_decision_summary: quoteDecision,
2204
+ pricing_band_decision_summary: bandDecision,
2205
+ pricing_policy_summary: pricingPolicySummary,
2206
+ linked_surfaces: {
2207
+ quote_policy_decision_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/quote-policy-decision-summary`,
2208
+ pricing_band_decision_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-band-decision-summary`,
2209
+ quote_policy_package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/quote-policy-package`
2210
+ },
2211
+ generated_at_iso: nowIso()
2212
+ };
2213
+ }
2214
+
2215
+ function summarizeQuotePolicyOperatorBundle(state, body) {
2216
+ const bundle = buildQuotePolicyOperatorBundle(state, body);
2217
+ return {
2218
+ bundle_version: bundle.bundle_version,
2219
+ account_id: bundle.account_id,
2220
+ quote_policy_state: bundle.operator_posture.quote_policy_state,
2221
+ pricing_band: bundle.operator_posture.pricing_band,
2222
+ recommended_operator_motion: bundle.operator_posture.recommended_operator_motion
2223
+ };
2224
+ }
2225
+
2226
+ function buildQuotePolicyPack(state, body) {
2227
+ const payload = ensureObject(body);
2228
+ const accountId = normalizeString(payload.account_id, "acct_demo");
2229
+ const operatorBundle = buildQuotePolicyOperatorBundle(state, payload);
2230
+ const pricingPolicySummary = buildPricingPolicySummary(state, accountId);
2231
+ const templates = [
2232
+ {
2233
+ template_id: "direct_pay_quote_entry",
2234
+ recommended_for: "first-contact quotes and low-friction runtime entry",
2235
+ target_motion: "issue_standard_quote",
2236
+ quote_policy_state: "direct_pay_quote"
2237
+ },
2238
+ {
2239
+ template_id: "credits_first_quote_default",
2240
+ recommended_for: "normal repeat runtime quoting",
2241
+ target_motion: "issue_standard_quote",
2242
+ quote_policy_state: "credits_first_quote"
2243
+ },
2244
+ {
2245
+ template_id: "pack_aligned_quote_flow",
2246
+ recommended_for: "repeat use with pack-backed credits posture",
2247
+ target_motion: "issue_pack_aligned_quote",
2248
+ quote_policy_state: "pack_backed_quote"
2249
+ },
2250
+ {
2251
+ template_id: "replenishment_aware_quote",
2252
+ recommended_for: "high pricing-risk or low-headroom quote posture",
2253
+ target_motion: "issue_replenishment_aware_quote",
2254
+ quote_policy_state: "credits_first_quote"
2255
+ },
2256
+ {
2257
+ template_id: "bounded_quote_guardrails",
2258
+ recommended_for: "agent or budget-constrained quoting",
2259
+ target_motion: "require_bounded_policy_repair",
2260
+ quote_policy_state: "credits_first_quote"
2261
+ }
2262
+ ];
2263
+
2264
+ return {
2265
+ pack_version: "xytara-quote-policy-pack-v1",
2266
+ account_id: accountId,
2267
+ quote_policy_operator_bundle: operatorBundle,
2268
+ pricing_policy_summary: pricingPolicySummary,
2269
+ recommended_policy_motion: operatorBundle.operator_posture.recommended_quote_motion,
2270
+ policy_templates: templates,
2271
+ linked_surfaces: {
2272
+ quote_policy_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/quote-policy-operator-bundle`,
2273
+ quote_policy_application_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/quote-policy-application-summary`,
2274
+ pricing_policy_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-summary`
2275
+ },
2276
+ generated_at_iso: nowIso()
2277
+ };
2278
+ }
2279
+
2280
+ function summarizeQuotePolicyPack(state, body) {
2281
+ const pack = buildQuotePolicyPack(state, body);
2282
+ return {
2283
+ pack_version: pack.pack_version,
2284
+ account_id: pack.account_id,
2285
+ recommended_policy_motion: pack.recommended_policy_motion,
2286
+ template_count: ensureArray(pack.policy_templates).length
2287
+ };
2288
+ }
2289
+
2290
+ function buildQuotePolicyApplicationSummary(state, body) {
2291
+ const payload = ensureObject(body);
2292
+ const accountId = normalizeString(payload.account_id, "acct_demo");
2293
+ const templateId = normalizeString(payload.template_id, null);
2294
+ const pack = buildQuotePolicyPack(state, payload);
2295
+ const selectedTemplate = ensureArray(pack.policy_templates).find((entry) => entry.template_id === templateId)
2296
+ || ensureArray(pack.policy_templates).find((entry) => entry.target_motion === pack.recommended_policy_motion)
2297
+ || ensureArray(pack.policy_templates)[0]
2298
+ || null;
2299
+
2300
+ return {
2301
+ summary_version: "xytara-quote-policy-application-summary-v1",
2302
+ account_id: accountId,
2303
+ recommended_policy_motion: pack.recommended_policy_motion,
2304
+ selected_template_id: selectedTemplate ? selectedTemplate.template_id : null,
2305
+ available_template_ids: ensureArray(pack.policy_templates).map((entry) => entry.template_id),
2306
+ selected_template: selectedTemplate,
2307
+ suggested_quote_targets: {
2308
+ quote_policy_state: pack.quote_policy_operator_bundle.operator_posture.quote_policy_state,
2309
+ pricing_band: pack.quote_policy_operator_bundle.operator_posture.pricing_band,
2310
+ recommended_quote_motion: pack.quote_policy_operator_bundle.operator_posture.recommended_quote_motion,
2311
+ pricing_risk_state: pack.pricing_policy_summary.pricing_risk_state
2312
+ },
2313
+ linked_surfaces: {
2314
+ quote_policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/quote-policy-pack`,
2315
+ quote_policy_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/quote-policy-operator-bundle`,
2316
+ quote_policy_package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/quote-policy-package`
2317
+ },
2318
+ generated_at_iso: nowIso()
2319
+ };
2320
+ }
2321
+
2322
+ function buildQuotePolicyPackage(state, body) {
2323
+ const payload = ensureObject(body);
2324
+ const accountId = normalizeString(payload.account_id, "acct_demo");
2325
+ const quoteDecision = buildQuotePolicyDecisionSummary(state, payload);
2326
+ const bandDecision = buildPricingBandDecisionSummary(state, payload);
2327
+ const pricingPolicySummary = buildPricingPolicySummary(state, accountId);
2328
+ const operatorBundle = buildQuotePolicyOperatorBundle(state, payload);
2329
+ const policyPack = buildQuotePolicyPack(state, payload);
2330
+ const applicationSummary = buildQuotePolicyApplicationSummary(state, payload);
2331
+
2332
+ return {
2333
+ package_version: "xytara-quote-policy-package-v1",
2334
+ account_id: accountId,
2335
+ package_posture: {
2336
+ quote_policy_state: quoteDecision.quote_policy_state,
2337
+ recommended_quote_motion: quoteDecision.recommended_quote_motion,
2338
+ pricing_band: bandDecision.pricing_band,
2339
+ recommended_band_motion: bandDecision.recommended_band_motion,
2340
+ pricing_risk_state: pricingPolicySummary.pricing_risk_state,
2341
+ recommended_operator_motion: operatorBundle.operator_posture.recommended_operator_motion,
2342
+ recommended_policy_motion: policyPack.recommended_policy_motion
2343
+ },
2344
+ quote_policy_decision_summary: quoteDecision,
2345
+ pricing_band_decision_summary: bandDecision,
2346
+ quote_policy_operator_bundle: operatorBundle,
2347
+ quote_policy_pack: policyPack,
2348
+ quote_policy_application_summary: applicationSummary,
2349
+ pricing_policy_summary: pricingPolicySummary,
2350
+ linked_surfaces: {
2351
+ quote_policy_decision_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/quote-policy-decision-summary`,
2352
+ pricing_band_decision_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-band-decision-summary`,
2353
+ quote_policy_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/quote-policy-operator-bundle`,
2354
+ quote_policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/quote-policy-pack`,
2355
+ quote_policy_application_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/quote-policy-application-summary`,
2356
+ pricing_policy_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-summary`
2357
+ },
2358
+ generated_at_iso: nowIso()
2359
+ };
2360
+ }
2361
+
2362
+ function summarizeQuotePolicyPackage(state, body) {
2363
+ const pack = buildQuotePolicyPackage(state, body);
2364
+ return {
2365
+ package_version: pack.package_version,
2366
+ account_id: pack.account_id,
2367
+ quote_policy_state: pack.package_posture.quote_policy_state,
2368
+ pricing_band: pack.package_posture.pricing_band,
2369
+ recommended_operator_motion: pack.package_posture.recommended_operator_motion,
2370
+ recommended_policy_motion: pack.package_posture.recommended_policy_motion
2371
+ };
2372
+ }
2373
+
2374
+ function buildTrustInputSummary(state, accountId) {
2375
+ const paymentCount = listPaymentLedgerForAccount(state, accountId).length;
2376
+ const creditSpendCount = ensureArray(state.economicsCreditSpends).filter((entry) => entry && entry.account_id === accountId).length;
2377
+ const allocationCount = ensureArray(state.economicsAllocations).filter((entry) => entry && entry.account_id === accountId).length;
2378
+ const disputeCount = listMapValuesByAccount(state.disputes, accountId).length;
2379
+ const refundCount = listMapValuesByAccount(state.refunds, accountId).length;
2380
+ const remediationCount = listMapValuesByAccount(state.remediationTickets, accountId).length;
2381
+ const activeParticipantCount = listOperatorParticipantsForAccount(state, accountId).filter((entry) => entry && entry.status === "active").length;
2382
+ const revokedParticipantCount = listOperatorParticipantsForAccount(state, accountId).filter((entry) => entry && entry.status === "revoked").length;
2383
+
2384
+ let runtimeHistoryState = "thin";
2385
+ if (paymentCount > 0 || creditSpendCount > 0 || allocationCount > 0) {
2386
+ runtimeHistoryState = "working";
2387
+ }
2388
+ if (
2389
+ paymentCount > 0
2390
+ && creditSpendCount > 0
2391
+ && allocationCount > 0
2392
+ && disputeCount === 0
2393
+ && refundCount === 0
2394
+ && remediationCount === 0
2395
+ ) {
2396
+ runtimeHistoryState = "strong";
2397
+ }
2398
+
2399
+ let reputationRiskState = "low";
2400
+ if (disputeCount > 0 || refundCount > 0 || remediationCount > 0) {
2401
+ reputationRiskState = "high";
2402
+ } else if (paymentCount === 0 || creditSpendCount === 0 || revokedParticipantCount > 0) {
2403
+ reputationRiskState = "watch";
2404
+ }
2405
+
2406
+ let recommendedInputMotion = "maintain_runtime_reputation_inputs";
2407
+ if (runtimeHistoryState === "thin") {
2408
+ recommendedInputMotion = "establish_runtime_history_inputs";
2409
+ } else if (reputationRiskState === "high") {
2410
+ recommendedInputMotion = "repair_reputation_risk_inputs";
2411
+ } else if (reputationRiskState === "watch") {
2412
+ recommendedInputMotion = "deepen_runtime_history_inputs";
2413
+ }
2414
+
2415
+ return {
2416
+ summary_version: "xytara-trust-input-summary-v1",
2417
+ account_id: accountId,
2418
+ runtime_history_state: runtimeHistoryState,
2419
+ reputation_risk_state: reputationRiskState,
2420
+ recommended_input_motion: recommendedInputMotion,
2421
+ explanation_signals: {
2422
+ payment_count: paymentCount,
2423
+ credit_spend_count: creditSpendCount,
2424
+ allocation_count: allocationCount,
2425
+ dispute_count: disputeCount,
2426
+ refund_count: refundCount,
2427
+ remediation_count: remediationCount,
2428
+ active_participant_count: activeParticipantCount,
2429
+ revoked_participant_count: revokedParticipantCount
2430
+ },
2431
+ linked_surfaces: {
2432
+ trust_layer_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-summary`,
2433
+ payment_ledger_ref: "/v1/payment-ledger",
2434
+ multi_operator_participation_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-summary`
2435
+ },
2436
+ generated_at_iso: nowIso()
2437
+ };
2438
+ }
2439
+
2440
+ function buildTrustLayerSummary(state, accountId) {
2441
+ const authoritySummary = buildAuthoritySummary(state, accountId);
2442
+ const authorityAttention = buildAuthorityAttentionSummary(state, accountId);
2443
+ const machineIdentitySummary = buildMachineIdentitySummary(state, accountId);
2444
+ const machineIdentityAttention = buildMachineIdentityAttentionSummary(state, accountId);
2445
+ const walletSummary = buildWalletSummary(state, accountId);
2446
+ const pricingPolicySummary = buildPricingPolicySummary(state, accountId);
2447
+ const trustInputSummary = buildTrustInputSummary(state, accountId);
2448
+
2449
+ const activeAuthorityBindings = Number(authoritySummary.authority_binding_count || 0);
2450
+ const activeIdentityBindings = Number(machineIdentitySummary.identity_binding_count || 0);
2451
+ const availableUnits = Number(walletSummary.available_units || 0);
2452
+
2453
+ let trustState = "early";
2454
+ if (
2455
+ activeAuthorityBindings > 0
2456
+ && activeIdentityBindings > 0
2457
+ && authorityAttention.overall_attention_state === "healthy"
2458
+ && machineIdentityAttention.overall_attention_state === "healthy"
2459
+ && trustInputSummary.runtime_history_state !== "thin"
2460
+ ) {
2461
+ trustState = "strong";
2462
+ } else if (
2463
+ activeAuthorityBindings > 0
2464
+ || activeIdentityBindings > 0
2465
+ || trustInputSummary.runtime_history_state !== "thin"
2466
+ ) {
2467
+ trustState = "working";
2468
+ }
2469
+
2470
+ let trustRiskState = "low";
2471
+ if (
2472
+ authorityAttention.overall_attention_state === "attention_required"
2473
+ || machineIdentityAttention.overall_attention_state === "attention_required"
2474
+ || pricingPolicySummary.pricing_risk_state === "high"
2475
+ || trustInputSummary.reputation_risk_state === "high"
2476
+ ) {
2477
+ trustRiskState = "high";
2478
+ } else if (
2479
+ pricingPolicySummary.pricing_risk_state === "watch"
2480
+ || availableUnits <= 0
2481
+ || trustInputSummary.reputation_risk_state === "watch"
2482
+ ) {
2483
+ trustRiskState = "watch";
2484
+ }
2485
+
2486
+ let recommendedTrustMotion = "maintain_runtime_trust_posture";
2487
+ if (trustState === "early") {
2488
+ recommendedTrustMotion = "establish_authority_and_identity_trust";
2489
+ } else if (trustRiskState === "high") {
2490
+ recommendedTrustMotion = "repair_runtime_trust_attention";
2491
+ } else if (trustInputSummary.runtime_history_state === "thin") {
2492
+ recommendedTrustMotion = "deepen_runtime_reputation_inputs";
2493
+ } else if (pricingPolicySummary.pricing_posture === "pack_backed_runtime") {
2494
+ recommendedTrustMotion = "stabilize_pack_backed_trust_posture";
2495
+ }
2496
+
2497
+ return {
2498
+ summary_version: "xytara-trust-layer-summary-v1",
2499
+ account_id: accountId,
2500
+ trust_state: trustState,
2501
+ trust_risk_state: trustRiskState,
2502
+ recommended_trust_motion: recommendedTrustMotion,
2503
+ explanation_signals: {
2504
+ authority_state: authoritySummary.authority_state,
2505
+ authority_binding_count: activeAuthorityBindings,
2506
+ authority_attention_state: authorityAttention.overall_attention_state,
2507
+ machine_identity_state: machineIdentitySummary.machine_identity_state,
2508
+ identity_binding_count: activeIdentityBindings,
2509
+ machine_identity_attention_state: machineIdentityAttention.overall_attention_state,
2510
+ pricing_posture: pricingPolicySummary.pricing_posture,
2511
+ pricing_risk_state: pricingPolicySummary.pricing_risk_state,
2512
+ available_units: availableUnits,
2513
+ runtime_history_state: trustInputSummary.runtime_history_state,
2514
+ reputation_risk_state: trustInputSummary.reputation_risk_state,
2515
+ active_participant_count: trustInputSummary.explanation_signals.active_participant_count,
2516
+ dispute_count: trustInputSummary.explanation_signals.dispute_count
2517
+ },
2518
+ linked_surfaces: {
2519
+ authority_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/authority-summary`,
2520
+ authority_attention_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/authority-attention-summary`,
2521
+ machine_identity_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/machine-identity-summary`,
2522
+ machine_identity_attention_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/machine-identity-attention-summary`,
2523
+ pricing_policy_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/pricing-policy-summary`,
2524
+ trust_input_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-input-summary`
2525
+ },
2526
+ generated_at_iso: nowIso()
2527
+ };
2528
+ }
2529
+
2530
+ function buildTrustLayerOperatorBundle(state, accountId) {
2531
+ const trustSummary = buildTrustLayerSummary(state, accountId);
2532
+ const authoritySummary = buildAuthoritySummary(state, accountId);
2533
+ const machineIdentitySummary = buildMachineIdentitySummary(state, accountId);
2534
+ const pricingPolicySummary = buildPricingPolicySummary(state, accountId);
2535
+ const trustInputSummary = buildTrustInputSummary(state, accountId);
2536
+
2537
+ let recommendedOperatorMotion = "maintain_runtime_trust_posture";
2538
+ if (trustSummary.trust_state === "early") {
2539
+ recommendedOperatorMotion = "establish_runtime_trust_foundations";
2540
+ } else if (trustSummary.trust_risk_state === "high") {
2541
+ recommendedOperatorMotion = "repair_runtime_trust_attention";
2542
+ } else if (trustInputSummary.runtime_history_state === "thin") {
2543
+ recommendedOperatorMotion = "deepen_runtime_reputation_inputs";
2544
+ } else if (pricingPolicySummary.pricing_posture === "pack_backed_runtime") {
2545
+ recommendedOperatorMotion = "stabilize_pack_backed_trust_posture";
2546
+ }
2547
+
2548
+ return {
2549
+ bundle_version: "xytara-trust-layer-operator-bundle-v1",
2550
+ account_id: accountId,
2551
+ operator_posture: {
2552
+ trust_state: trustSummary.trust_state,
2553
+ trust_risk_state: trustSummary.trust_risk_state,
2554
+ authority_state: authoritySummary.authority_state,
2555
+ machine_identity_state: machineIdentitySummary.machine_identity_state,
2556
+ runtime_history_state: trustInputSummary.runtime_history_state,
2557
+ reputation_risk_state: trustInputSummary.reputation_risk_state,
2558
+ pricing_posture: pricingPolicySummary.pricing_posture,
2559
+ recommended_operator_motion: recommendedOperatorMotion
2560
+ },
2561
+ trust_layer_summary: trustSummary,
2562
+ trust_input_summary: trustInputSummary,
2563
+ authority_summary: authoritySummary,
2564
+ machine_identity_summary: machineIdentitySummary,
2565
+ pricing_policy_summary: pricingPolicySummary,
2566
+ linked_surfaces: trustSummary.linked_surfaces,
2567
+ generated_at_iso: nowIso()
2568
+ };
2569
+ }
2570
+
2571
+ function summarizeTrustLayerOperatorBundle(state, accountId) {
2572
+ const bundle = buildTrustLayerOperatorBundle(state, accountId);
2573
+ return {
2574
+ bundle_version: bundle.bundle_version,
2575
+ account_id: bundle.account_id,
2576
+ trust_state: bundle.operator_posture.trust_state,
2577
+ trust_risk_state: bundle.operator_posture.trust_risk_state,
2578
+ recommended_operator_motion: bundle.operator_posture.recommended_operator_motion
2579
+ };
2580
+ }
2581
+
2582
+ function buildTrustLayerPolicyPack(state, accountId) {
2583
+ const operatorBundle = buildTrustLayerOperatorBundle(state, accountId);
2584
+ const templates = [
2585
+ {
2586
+ template_id: "runtime_trust_foundation",
2587
+ recommended_for: "establishing initial authority and identity trust",
2588
+ target_motion: "establish_runtime_trust_foundations",
2589
+ trust_state: "early"
2590
+ },
2591
+ {
2592
+ template_id: "runtime_trust_maintenance",
2593
+ recommended_for: "healthy continuing runtime trust posture",
2594
+ target_motion: "maintain_runtime_trust_posture",
2595
+ trust_state: "working"
2596
+ },
2597
+ {
2598
+ template_id: "trust_attention_repair",
2599
+ recommended_for: "repairing active authority, identity, or pricing risk",
2600
+ target_motion: "repair_runtime_trust_attention",
2601
+ trust_state: "working"
2602
+ },
2603
+ {
2604
+ template_id: "pack_backed_trust_stabilization",
2605
+ recommended_for: "repeat-use runtime trust with pack-backed credits",
2606
+ target_motion: "stabilize_pack_backed_trust_posture",
2607
+ trust_state: "strong"
2608
+ }
2609
+ ];
2610
+
2611
+ return {
2612
+ pack_version: "xytara-trust-layer-policy-pack-v1",
2613
+ account_id: accountId,
2614
+ trust_layer_operator_bundle: operatorBundle,
2615
+ recommended_policy_motion: operatorBundle.operator_posture.recommended_operator_motion,
2616
+ policy_templates: templates,
2617
+ linked_surfaces: {
2618
+ trust_layer_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-operator-bundle`,
2619
+ trust_layer_application_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-application-summary`,
2620
+ trust_layer_package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-package`
2621
+ },
2622
+ generated_at_iso: nowIso()
2623
+ };
2624
+ }
2625
+
2626
+ function summarizeTrustLayerPolicyPack(state, accountId) {
2627
+ const pack = buildTrustLayerPolicyPack(state, accountId);
2628
+ return {
2629
+ pack_version: pack.pack_version,
2630
+ account_id: pack.account_id,
2631
+ recommended_policy_motion: pack.recommended_policy_motion,
2632
+ template_count: ensureArray(pack.policy_templates).length
2633
+ };
2634
+ }
2635
+
2636
+ function buildTrustLayerApplicationSummary(state, accountId, templateId) {
2637
+ const pack = buildTrustLayerPolicyPack(state, accountId);
2638
+ const selectedTemplate = ensureArray(pack.policy_templates).find((entry) => entry.template_id === templateId)
2639
+ || ensureArray(pack.policy_templates).find((entry) => entry.target_motion === pack.recommended_policy_motion)
2640
+ || ensureArray(pack.policy_templates)[0]
2641
+ || null;
2642
+
2643
+ return {
2644
+ summary_version: "xytara-trust-layer-application-summary-v1",
2645
+ account_id: accountId,
2646
+ recommended_policy_motion: pack.recommended_policy_motion,
2647
+ selected_template_id: selectedTemplate ? selectedTemplate.template_id : null,
2648
+ available_template_ids: ensureArray(pack.policy_templates).map((entry) => entry.template_id),
2649
+ selected_template: selectedTemplate,
2650
+ suggested_trust_targets: {
2651
+ trust_state: pack.trust_layer_operator_bundle.operator_posture.trust_state,
2652
+ trust_risk_state: pack.trust_layer_operator_bundle.operator_posture.trust_risk_state,
2653
+ authority_state: pack.trust_layer_operator_bundle.operator_posture.authority_state,
2654
+ machine_identity_state: pack.trust_layer_operator_bundle.operator_posture.machine_identity_state
2655
+ },
2656
+ linked_surfaces: {
2657
+ trust_layer_policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-policy-pack`,
2658
+ trust_layer_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-operator-bundle`,
2659
+ trust_layer_package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-package`
2660
+ },
2661
+ generated_at_iso: nowIso()
2662
+ };
2663
+ }
2664
+
2665
+ function buildTrustLayerPackage(state, accountId) {
2666
+ const summary = buildTrustLayerSummary(state, accountId);
2667
+ const operatorBundle = buildTrustLayerOperatorBundle(state, accountId);
2668
+ const policyPack = buildTrustLayerPolicyPack(state, accountId);
2669
+ const applicationSummary = buildTrustLayerApplicationSummary(state, accountId, null);
2670
+
2671
+ return {
2672
+ package_version: "xytara-trust-layer-package-v1",
2673
+ account_id: accountId,
2674
+ package_posture: {
2675
+ trust_state: summary.trust_state,
2676
+ trust_risk_state: summary.trust_risk_state,
2677
+ recommended_operator_motion: operatorBundle.operator_posture.recommended_operator_motion,
2678
+ recommended_policy_motion: policyPack.recommended_policy_motion
2679
+ },
2680
+ trust_layer_summary: summary,
2681
+ trust_layer_operator_bundle: operatorBundle,
2682
+ trust_input_summary: operatorBundle.trust_input_summary,
2683
+ trust_layer_policy_pack: policyPack,
2684
+ trust_layer_application_summary: applicationSummary,
2685
+ linked_surfaces: {
2686
+ trust_input_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-input-summary`,
2687
+ trust_layer_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-summary`,
2688
+ trust_layer_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-operator-bundle`,
2689
+ trust_layer_policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-policy-pack`,
2690
+ trust_layer_application_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-application-summary`
2691
+ },
2692
+ generated_at_iso: nowIso()
2693
+ };
2694
+ }
2695
+
2696
+ function summarizeTrustLayerPackage(state, accountId) {
2697
+ const pack = buildTrustLayerPackage(state, accountId);
2698
+ return {
2699
+ package_version: pack.package_version,
2700
+ account_id: pack.account_id,
2701
+ trust_state: pack.package_posture.trust_state,
2702
+ trust_risk_state: pack.package_posture.trust_risk_state,
2703
+ recommended_operator_motion: pack.package_posture.recommended_operator_motion,
2704
+ recommended_policy_motion: pack.package_posture.recommended_policy_motion
2705
+ };
2706
+ }
2707
+
2708
+ function listOperatorParticipantsForAccount(state, accountId) {
2709
+ return Array.from(state.operatorParticipants.values())
2710
+ .filter((entry) => entry && entry.account_id === accountId);
2711
+ }
2712
+
2713
+ function listLegacyAgentAccountsForParticipation(state, accountId) {
2714
+ return Array.from(state.agentAccounts.values())
2715
+ .map((entry) => entry && entry.account ? entry.account : null)
2716
+ .filter(Boolean)
2717
+ .filter((entry) => entry.account_id === accountId);
2718
+ }
2719
+
2720
+ function buildMultiOperatorParticipantPublicView(entry) {
2721
+ if (!entry) return null;
2722
+ return {
2723
+ participant_id: entry.participant_id,
2724
+ account_id: entry.account_id,
2725
+ label: entry.label,
2726
+ operator_kind: entry.operator_kind,
2727
+ status: entry.status,
2728
+ participant_scope: ensureArray(entry.participant_scope),
2729
+ authority_binding_id: entry.authority_binding_id || null,
2730
+ identity_binding_id: entry.identity_binding_id || null,
2731
+ rotated_from_participant_id: entry.rotated_from_participant_id || null,
2732
+ replaced_by_participant_id: entry.replaced_by_participant_id || null,
2733
+ created_at_iso: entry.created_at_iso,
2734
+ updated_at_iso: entry.updated_at_iso,
2735
+ revoked_at_iso: entry.revoked_at_iso || null,
2736
+ revoke_reason: entry.revoke_reason || null,
2737
+ issued_by: entry.issued_by || null,
2738
+ labels: ensureArray(entry.labels)
2739
+ };
2740
+ }
2741
+
2742
+ function listMultiOperatorParticipants(state, accountId) {
2743
+ return listOperatorParticipantsForAccount(state, accountId).map((entry) => buildMultiOperatorParticipantPublicView(entry));
2744
+ }
2745
+
2746
+ function getMultiOperatorParticipant(state, accountId, participantId) {
2747
+ if (!participantId || !state.operatorParticipants.has(participantId)) return null;
2748
+ const entry = state.operatorParticipants.get(participantId);
2749
+ if (!entry || entry.account_id !== accountId) return null;
2750
+ return buildMultiOperatorParticipantPublicView(entry);
2751
+ }
2752
+
2753
+ function buildMultiOperatorAdmissionPreview(state, accountId, body) {
2754
+ const payload = ensureObject(body);
2755
+ const policyPack = buildMultiOperatorParticipationPolicyPack(state, accountId);
2756
+ const selectedTemplate = ensureArray(policyPack.policy_templates).find((entry) => entry.template_id === normalizeString(payload.template_id, null))
2757
+ || ensureArray(policyPack.policy_templates).find((entry) => entry.target_motion === policyPack.recommended_policy_motion)
2758
+ || ensureArray(policyPack.policy_templates)[0]
2759
+ || null;
2760
+ const participantLabel = normalizeString(payload.label, `operator-participant-${listOperatorParticipantsForAccount(state, accountId).length + 1}`);
2761
+ return {
2762
+ preview_version: "xytara-multi-operator-admission-preview-v1",
2763
+ account_id: accountId,
2764
+ selected_template_id: selectedTemplate ? selectedTemplate.template_id : null,
2765
+ selected_template: selectedTemplate,
2766
+ proposed_participant: {
2767
+ label: participantLabel,
2768
+ operator_kind: normalizeString(payload.operator_kind, "coordinator_operator"),
2769
+ participant_scope: ensureArray(payload.participant_scope).length > 0
2770
+ ? ensureArray(payload.participant_scope)
2771
+ : ["runtime.execute", "economics.reserve"]
2772
+ },
2773
+ planned_bindings: {
2774
+ authority_kind: normalizeString(payload.authority_kind, "delegated_runtime_spend"),
2775
+ identity_kind: normalizeString(payload.identity_kind, "registry_anchor_identity")
2776
+ },
2777
+ linked_surfaces: {
2778
+ multi_operator_policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-policy-pack`,
2779
+ multi_operator_participants_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participants`
2780
+ },
2781
+ generated_at_iso: nowIso()
2782
+ };
2783
+ }
2784
+
2785
+ function createMultiOperatorParticipant(state, accountId, body) {
2786
+ const payload = ensureObject(body);
2787
+ const createdAtIso = nowIso();
2788
+ const nextIndex = state.operatorParticipants.size + 1;
2789
+ const participantId = normalizeString(payload.participant_id, `operator_participant_${nextIndex}`);
2790
+ const participantScope = ensureArray(payload.participant_scope).length > 0
2791
+ ? ensureArray(payload.participant_scope).map((value) => String(value || "").trim()).filter(Boolean)
2792
+ : ["runtime.execute", "economics.reserve"];
2793
+ const authorityBinding = createAuthorityBinding(state, {
2794
+ binding_id: normalizeString(payload.authority_binding_id, `${participantId}_authority`),
2795
+ credential_id: normalizeString(payload.credential_id, `${participantId}_credential`),
2796
+ account_id: accountId,
2797
+ authority_kind: normalizeString(payload.authority_kind, "delegated_runtime_spend"),
2798
+ authority_scope: participantScope,
2799
+ allowed_consequence_families: ensureArray(payload.allowed_consequence_families).length > 0
2800
+ ? ensureArray(payload.allowed_consequence_families)
2801
+ : ["commit", "reserve"],
2802
+ max_commit_units: Number.isFinite(Number(payload.max_commit_units)) ? Number(payload.max_commit_units) : 5,
2803
+ max_reserve_units: Number.isFinite(Number(payload.max_reserve_units)) ? Number(payload.max_reserve_units) : 5,
2804
+ max_reversal_units: Number.isFinite(Number(payload.max_reversal_units)) ? Number(payload.max_reversal_units) : 1,
2805
+ labels: ensureArray(payload.labels),
2806
+ issued_by: normalizeString(payload.issued_by, "operator")
2807
+ });
2808
+ const identityBinding = createIdentityBinding(state, {
2809
+ binding_id: normalizeString(payload.identity_binding_id, `${participantId}_identity`),
2810
+ account_id: accountId,
2811
+ identity_kind: normalizeString(payload.identity_kind, "registry_anchor_identity"),
2812
+ identity_ref: normalizeString(payload.identity_ref, `${participantId}.identity`),
2813
+ attached_agent_account_id: participantId,
2814
+ labels: ensureArray(payload.labels),
2815
+ issued_by: normalizeString(payload.issued_by, "operator")
2816
+ });
2817
+ const participant = {
2818
+ participant_id: participantId,
2819
+ account_id: accountId,
2820
+ label: normalizeString(payload.label, participantId),
2821
+ operator_kind: normalizeString(payload.operator_kind, "coordinator_operator"),
2822
+ status: normalizeString(payload.status, "active"),
2823
+ participant_scope: participantScope,
2824
+ authority_binding_id: authorityBinding.binding_id,
2825
+ identity_binding_id: identityBinding.binding_id,
2826
+ created_at_iso: createdAtIso,
2827
+ updated_at_iso: createdAtIso,
2828
+ issued_by: normalizeString(payload.issued_by, "operator"),
2829
+ labels: ensureArray(payload.labels).map((value) => String(value || "").trim()).filter(Boolean)
2830
+ };
2831
+ state.operatorParticipants.set(participantId, participant);
2832
+ return {
2833
+ participant: buildMultiOperatorParticipantPublicView(participant),
2834
+ authority_binding: authorityBinding,
2835
+ identity_binding: identityBinding
2836
+ };
2837
+ }
2838
+
2839
+ function renewMultiOperatorParticipant(state, accountId, participantId, body) {
2840
+ const payload = ensureObject(body);
2841
+ if (!participantId || !state.operatorParticipants.has(participantId)) return null;
2842
+ const current = state.operatorParticipants.get(participantId);
2843
+ if (!current || current.account_id !== accountId) return null;
2844
+ const renewedAuthorityBinding = current.authority_binding_id
2845
+ ? renewAuthorityBinding(state, current.authority_binding_id, { expires_at_iso: normalizeString(payload.expires_at_iso, null) })
2846
+ : null;
2847
+ const renewedIdentityBinding = current.identity_binding_id
2848
+ ? renewIdentityBinding(state, current.identity_binding_id, { expires_at_iso: normalizeString(payload.expires_at_iso, null) })
2849
+ : null;
2850
+ const next = {
2851
+ ...current,
2852
+ updated_at_iso: nowIso()
2853
+ };
2854
+ state.operatorParticipants.set(participantId, next);
2855
+ return {
2856
+ participant: buildMultiOperatorParticipantPublicView(next),
2857
+ authority_binding: renewedAuthorityBinding,
2858
+ identity_binding: renewedIdentityBinding
2859
+ };
2860
+ }
2861
+
2862
+ function revokeMultiOperatorParticipant(state, accountId, participantId, body) {
2863
+ const payload = ensureObject(body);
2864
+ if (!participantId || !state.operatorParticipants.has(participantId)) return null;
2865
+ const current = state.operatorParticipants.get(participantId);
2866
+ if (!current || current.account_id !== accountId) return null;
2867
+ const revokedAuthorityBinding = current.authority_binding_id
2868
+ ? revokeAuthorityBinding(state, current.authority_binding_id, { reason: normalizeString(payload.reason, "participant_revoked") })
2869
+ : null;
2870
+ const revokedIdentityBinding = current.identity_binding_id
2871
+ ? revokeIdentityBinding(state, current.identity_binding_id, { reason: normalizeString(payload.reason, "participant_revoked") })
2872
+ : null;
2873
+ const next = {
2874
+ ...current,
2875
+ status: "revoked",
2876
+ updated_at_iso: nowIso(),
2877
+ revoked_at_iso: nowIso(),
2878
+ revoke_reason: normalizeString(payload.reason, "participant_revoked")
2879
+ };
2880
+ state.operatorParticipants.set(participantId, next);
2881
+ return {
2882
+ participant: buildMultiOperatorParticipantPublicView(next),
2883
+ authority_binding: revokedAuthorityBinding,
2884
+ identity_binding: revokedIdentityBinding
2885
+ };
2886
+ }
2887
+
2888
+ function rotateMultiOperatorParticipant(state, accountId, participantId, body) {
2889
+ const payload = ensureObject(body);
2890
+ if (!participantId || !state.operatorParticipants.has(participantId)) return null;
2891
+ const current = state.operatorParticipants.get(participantId);
2892
+ if (!current || current.account_id !== accountId) return null;
2893
+ const successorParticipantId = normalizeString(payload.successor_participant_id, `${participantId}_rotated`);
2894
+ const authorityRotation = current.authority_binding_id
2895
+ ? rotateAuthorityBinding(state, current.authority_binding_id, {
2896
+ successor_binding_id: normalizeString(payload.successor_authority_binding_id, `${successorParticipantId}_authority`),
2897
+ successor_credential_id: normalizeString(payload.successor_credential_id, `${successorParticipantId}_credential`),
2898
+ authority_scope: ensureArray(payload.participant_scope).length > 0 ? ensureArray(payload.participant_scope) : ensureArray(current.participant_scope),
2899
+ labels: ensureArray(payload.labels).length > 0 ? ensureArray(payload.labels) : ensureArray(current.labels),
2900
+ reason: normalizeString(payload.reason, "participant_rotated")
2901
+ })
2902
+ : null;
2903
+ const identityRotation = current.identity_binding_id
2904
+ ? rotateIdentityBinding(state, current.identity_binding_id, {
2905
+ successor_binding_id: normalizeString(payload.successor_identity_binding_id, `${successorParticipantId}_identity`),
2906
+ attached_agent_account_id: successorParticipantId,
2907
+ labels: ensureArray(payload.labels).length > 0 ? ensureArray(payload.labels) : ensureArray(current.labels),
2908
+ reason: normalizeString(payload.reason, "participant_rotated")
2909
+ })
2910
+ : null;
2911
+ const successor = {
2912
+ participant_id: successorParticipantId,
2913
+ account_id: accountId,
2914
+ label: normalizeString(payload.label, current.label),
2915
+ operator_kind: normalizeString(payload.operator_kind, current.operator_kind),
2916
+ status: normalizeString(payload.status, "active"),
2917
+ participant_scope: ensureArray(payload.participant_scope).length > 0
2918
+ ? ensureArray(payload.participant_scope).map((value) => String(value || "").trim()).filter(Boolean)
2919
+ : ensureArray(current.participant_scope),
2920
+ authority_binding_id: authorityRotation && authorityRotation.successor_authority_binding
2921
+ ? authorityRotation.successor_authority_binding.binding_id
2922
+ : null,
2923
+ identity_binding_id: identityRotation && identityRotation.successor_identity_binding
2924
+ ? identityRotation.successor_identity_binding.binding_id
2925
+ : null,
2926
+ rotated_from_participant_id: current.participant_id,
2927
+ replaced_by_participant_id: null,
2928
+ created_at_iso: nowIso(),
2929
+ updated_at_iso: nowIso(),
2930
+ issued_by: normalizeString(payload.issued_by, current.issued_by || "operator"),
2931
+ labels: ensureArray(payload.labels).length > 0 ? ensureArray(payload.labels).map((value) => String(value || "").trim()).filter(Boolean) : ensureArray(current.labels)
2932
+ };
2933
+ const rotated = {
2934
+ ...current,
2935
+ status: "revoked",
2936
+ replaced_by_participant_id: successorParticipantId,
2937
+ updated_at_iso: nowIso(),
2938
+ revoked_at_iso: nowIso(),
2939
+ revoke_reason: normalizeString(payload.reason, "participant_rotated")
2940
+ };
2941
+ state.operatorParticipants.set(participantId, rotated);
2942
+ state.operatorParticipants.set(successorParticipantId, successor);
2943
+ return {
2944
+ rotated_participant: buildMultiOperatorParticipantPublicView(rotated),
2945
+ successor_participant: buildMultiOperatorParticipantPublicView(successor),
2946
+ authority_rotation: authorityRotation,
2947
+ identity_rotation: identityRotation
2948
+ };
2949
+ }
2950
+
2951
+ function buildMultiOperatorParticipantRotationSummary(state, accountId, participantId) {
2952
+ const participant = getMultiOperatorParticipant(state, accountId, participantId);
2953
+ if (!participant) return null;
2954
+ return {
2955
+ summary_version: "xytara-multi-operator-participant-rotation-summary-v1",
2956
+ account_id: accountId,
2957
+ participant_id: participant.participant_id,
2958
+ status: participant.status,
2959
+ predecessor_participant_id: participant.rotated_from_participant_id || null,
2960
+ successor_participant_id: participant.replaced_by_participant_id || null,
2961
+ rotation_state: participant.rotated_from_participant_id || participant.replaced_by_participant_id ? "lineage_present" : "standalone",
2962
+ linked_surfaces: {
2963
+ participant_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participants/${encodeURIComponent(participantId)}`
2964
+ },
2965
+ generated_at_iso: nowIso()
2966
+ };
2967
+ }
2968
+
2969
+ function buildMultiOperatorReviewBundle(state, accountId) {
2970
+ const participants = listOperatorParticipantsForAccount(state, accountId);
2971
+ const reviewRows = participants.map((entry) => {
2972
+ let review_state = "healthy";
2973
+ if (entry.status === "revoked") review_state = "revoked";
2974
+ else if (!entry.authority_binding_id || !entry.identity_binding_id) review_state = "repair_required";
2975
+ else if (ensureArray(entry.participant_scope).length === 0) review_state = "attention_required";
2976
+ return {
2977
+ participant_id: entry.participant_id,
2978
+ label: entry.label,
2979
+ status: entry.status,
2980
+ operator_kind: entry.operator_kind,
2981
+ review_state,
2982
+ authority_binding_id: entry.authority_binding_id || null,
2983
+ identity_binding_id: entry.identity_binding_id || null
2984
+ };
2985
+ });
2986
+ return {
2987
+ bundle_version: "xytara-multi-operator-review-bundle-v1",
2988
+ account_id: accountId,
2989
+ review_rows: reviewRows,
2990
+ review_counts: {
2991
+ healthy_count: reviewRows.filter((entry) => entry.review_state === "healthy").length,
2992
+ attention_required_count: reviewRows.filter((entry) => entry.review_state === "attention_required").length,
2993
+ repair_required_count: reviewRows.filter((entry) => entry.review_state === "repair_required").length,
2994
+ revoked_count: reviewRows.filter((entry) => entry.review_state === "revoked").length
2995
+ },
2996
+ linked_surfaces: {
2997
+ participants_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participants`,
2998
+ package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-package`
2999
+ },
3000
+ generated_at_iso: nowIso()
3001
+ };
3002
+ }
3003
+
3004
+ function buildMultiOperatorAttentionSummary(state, accountId) {
3005
+ const reviewBundle = buildMultiOperatorReviewBundle(state, accountId);
3006
+ const attentionRows = ensureArray(reviewBundle.review_rows).filter((entry) => entry.review_state !== "healthy");
3007
+ return {
3008
+ summary_version: "xytara-multi-operator-attention-summary-v1",
3009
+ account_id: accountId,
3010
+ overall_attention_state: attentionRows.length > 0 ? "attention_required" : "healthy",
3011
+ attention_rows: attentionRows,
3012
+ linked_surfaces: {
3013
+ multi_operator_review_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-review-bundle`,
3014
+ multi_operator_package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-package`
3015
+ },
3016
+ generated_at_iso: nowIso()
3017
+ };
3018
+ }
3019
+
3020
+ function buildMultiOperatorParticipationSummary(state, accountId) {
3021
+ const authoritySummary = buildAuthoritySummary(state, accountId);
3022
+ const machineIdentitySummary = buildMachineIdentitySummary(state, accountId);
3023
+ const trustLayerSummary = buildTrustLayerSummary(state, accountId);
3024
+ const operatorParticipants = listOperatorParticipantsForAccount(state, accountId);
3025
+ const agentAccounts = listLegacyAgentAccountsForParticipation(state, accountId);
3026
+ const coordinationHandoffCount = ensureArray(state.coordinationHandoffs).length;
3027
+ const admissionCaseCount = ensureArray(state.zoneAdmissionCases).length;
3028
+ const activeAuthorityBindings = Number(authoritySummary.authority_binding_count || 0);
3029
+ const activeIdentityBindings = Number(machineIdentitySummary.identity_binding_count || 0);
3030
+ const activeParticipantCount = operatorParticipants.filter((entry) => entry.status === "active").length;
3031
+ const activeAgentCount = agentAccounts.filter((entry) => entry.status === "active").length;
3032
+ const activeOperatorCount = activeParticipantCount > 0 ? activeParticipantCount : activeAgentCount;
3033
+
3034
+ let participationState = "single_operator_only";
3035
+ if (activeOperatorCount >= 2 && activeAuthorityBindings > 0 && activeIdentityBindings > 0) {
3036
+ participationState = "multi_operator_ready";
3037
+ } else if (activeOperatorCount >= 1 || activeAuthorityBindings > 0 || activeIdentityBindings > 0) {
3038
+ participationState = "emerging_multi_operator";
3039
+ }
3040
+
3041
+ let coordinationReadinessState = "limited";
3042
+ if (coordinationHandoffCount > 0 && admissionCaseCount > 0) {
3043
+ coordinationReadinessState = "active";
3044
+ } else if (coordinationHandoffCount > 0 || admissionCaseCount > 0) {
3045
+ coordinationReadinessState = "preview_ready";
3046
+ }
3047
+
3048
+ let participationRiskState = "low";
3049
+ if (trustLayerSummary.trust_risk_state === "high" || activeOperatorCount === 0) {
3050
+ participationRiskState = "high";
3051
+ } else if (coordinationReadinessState !== "active" || participationState !== "multi_operator_ready") {
3052
+ participationRiskState = "watch";
3053
+ }
3054
+
3055
+ let recommendedParticipationMotion = "maintain_multi_operator_posture";
3056
+ if (participationState === "single_operator_only") {
3057
+ recommendedParticipationMotion = "establish_second_operator_and_bindings";
3058
+ } else if (participationRiskState === "high") {
3059
+ recommendedParticipationMotion = "repair_trust_before_multi_operator_expansion";
3060
+ } else if (coordinationReadinessState !== "active") {
3061
+ recommendedParticipationMotion = "activate_coordination_followthrough";
3062
+ } else if (participationState === "emerging_multi_operator") {
3063
+ recommendedParticipationMotion = "tighten_multi_operator_contracts";
3064
+ }
3065
+
3066
+ return {
3067
+ summary_version: "xytara-multi-operator-participation-summary-v1",
3068
+ account_id: accountId,
3069
+ multi_operator_participation_state: participationState,
3070
+ coordination_readiness_state: coordinationReadinessState,
3071
+ participation_risk_state: participationRiskState,
3072
+ recommended_participation_motion: recommendedParticipationMotion,
3073
+ explanation_signals: {
3074
+ active_operator_participant_count: activeParticipantCount,
3075
+ active_legacy_agent_account_count: activeAgentCount,
3076
+ authority_binding_count: activeAuthorityBindings,
3077
+ identity_binding_count: activeIdentityBindings,
3078
+ trust_state: trustLayerSummary.trust_state,
3079
+ trust_risk_state: trustLayerSummary.trust_risk_state,
3080
+ coordination_handoff_count: coordinationHandoffCount,
3081
+ admission_case_count: admissionCaseCount
3082
+ },
3083
+ linked_surfaces: {
3084
+ multi_operator_participants_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participants`,
3085
+ agent_accounts_ref: "/v1/agent-accounts",
3086
+ authority_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/authority-summary`,
3087
+ machine_identity_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/machine-identity-summary`,
3088
+ trust_layer_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-summary`,
3089
+ coordination_center_ref: "/v1/coordination-center/summary",
3090
+ zones_dashboard_ref: "/v1/coordination-center/zones-dashboard"
3091
+ },
3092
+ generated_at_iso: nowIso()
3093
+ };
3094
+ }
3095
+
3096
+ function buildMultiOperatorParticipationOperatorBundle(state, accountId) {
3097
+ const summary = buildMultiOperatorParticipationSummary(state, accountId);
3098
+ const authoritySummary = buildAuthoritySummary(state, accountId);
3099
+ const machineIdentitySummary = buildMachineIdentitySummary(state, accountId);
3100
+ const trustLayerSummary = buildTrustLayerSummary(state, accountId);
3101
+ const reviewBundle = buildMultiOperatorReviewBundle(state, accountId);
3102
+ const attentionSummary = buildMultiOperatorAttentionSummary(state, accountId);
3103
+ const operatorParticipants = listMultiOperatorParticipants(state, accountId);
3104
+ const agentAccounts = listLegacyAgentAccountsForParticipation(state, accountId);
3105
+ const activeOperatorCount = operatorParticipants.filter((entry) => entry.status === "active").length;
3106
+
3107
+ let recommendedOperatorMotion = "maintain_multi_operator_posture";
3108
+ if (summary.multi_operator_participation_state === "single_operator_only") {
3109
+ recommendedOperatorMotion = "issue_additional_operator_account";
3110
+ } else if (summary.participation_risk_state === "high") {
3111
+ recommendedOperatorMotion = "repair_multi_operator_trust";
3112
+ } else if (summary.coordination_readiness_state !== "active") {
3113
+ recommendedOperatorMotion = "open_coordination_followthrough";
3114
+ } else if (summary.multi_operator_participation_state === "emerging_multi_operator") {
3115
+ recommendedOperatorMotion = "tighten_multi_operator_contracts";
3116
+ }
3117
+
3118
+ return {
3119
+ bundle_version: "xytara-multi-operator-participation-operator-bundle-v1",
3120
+ account_id: accountId,
3121
+ operator_posture: {
3122
+ multi_operator_participation_state: summary.multi_operator_participation_state,
3123
+ coordination_readiness_state: summary.coordination_readiness_state,
3124
+ participation_risk_state: summary.participation_risk_state,
3125
+ active_operator_participant_count: activeOperatorCount,
3126
+ active_legacy_agent_account_count: agentAccounts.filter((entry) => entry.status === "active").length,
3127
+ authority_state: authoritySummary.authority_state,
3128
+ machine_identity_state: machineIdentitySummary.machine_identity_state,
3129
+ trust_state: trustLayerSummary.trust_state,
3130
+ overall_attention_state: attentionSummary.overall_attention_state,
3131
+ recommended_operator_motion: recommendedOperatorMotion
3132
+ },
3133
+ multi_operator_participation_summary: summary,
3134
+ multi_operator_review_bundle: reviewBundle,
3135
+ multi_operator_attention_summary: attentionSummary,
3136
+ authority_summary: authoritySummary,
3137
+ machine_identity_summary: machineIdentitySummary,
3138
+ trust_layer_summary: trustLayerSummary,
3139
+ operator_participants: operatorParticipants,
3140
+ legacy_agent_accounts: agentAccounts,
3141
+ linked_surfaces: summary.linked_surfaces,
3142
+ generated_at_iso: nowIso()
3143
+ };
3144
+ }
3145
+
3146
+ function summarizeMultiOperatorParticipationOperatorBundle(state, accountId) {
3147
+ const bundle = buildMultiOperatorParticipationOperatorBundle(state, accountId);
3148
+ return {
3149
+ bundle_version: bundle.bundle_version,
3150
+ account_id: bundle.account_id,
3151
+ multi_operator_participation_state: bundle.operator_posture.multi_operator_participation_state,
3152
+ coordination_readiness_state: bundle.operator_posture.coordination_readiness_state,
3153
+ participation_risk_state: bundle.operator_posture.participation_risk_state,
3154
+ recommended_operator_motion: bundle.operator_posture.recommended_operator_motion
3155
+ };
3156
+ }
3157
+
3158
+ function buildMultiOperatorParticipationPolicyPack(state, accountId) {
3159
+ const operatorBundle = buildMultiOperatorParticipationOperatorBundle(state, accountId);
3160
+ const templates = [
3161
+ {
3162
+ template_id: "second_operator_foundation",
3163
+ recommended_for: "opening a second operator track on top of a single-operator account",
3164
+ target_motion: "issue_additional_operator_account",
3165
+ target_state: "emerging_multi_operator"
3166
+ },
3167
+ {
3168
+ template_id: "coordination_activation",
3169
+ recommended_for: "activating cross-zone and coordination followthrough",
3170
+ target_motion: "open_coordination_followthrough",
3171
+ target_state: "emerging_multi_operator"
3172
+ },
3173
+ {
3174
+ template_id: "contract_tightening",
3175
+ recommended_for: "tightening authority and identity contracts for multiple operators",
3176
+ target_motion: "tighten_multi_operator_contracts",
3177
+ target_state: "multi_operator_ready"
3178
+ },
3179
+ {
3180
+ template_id: "multi_operator_trust_repair",
3181
+ recommended_for: "repairing trust before widening operator participation",
3182
+ target_motion: "repair_multi_operator_trust",
3183
+ target_state: "emerging_multi_operator"
3184
+ },
3185
+ {
3186
+ template_id: "steady_multi_operator_maintenance",
3187
+ recommended_for: "maintaining a healthy multi-operator runtime posture",
3188
+ target_motion: "maintain_multi_operator_posture",
3189
+ target_state: "multi_operator_ready"
3190
+ }
3191
+ ];
3192
+
3193
+ return {
3194
+ pack_version: "xytara-multi-operator-participation-policy-pack-v1",
3195
+ account_id: accountId,
3196
+ multi_operator_participation_operator_bundle: operatorBundle,
3197
+ recommended_policy_motion: operatorBundle.operator_posture.recommended_operator_motion,
3198
+ policy_templates: templates,
3199
+ linked_surfaces: {
3200
+ multi_operator_participation_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-operator-bundle`,
3201
+ multi_operator_participation_application_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-application-summary`,
3202
+ multi_operator_participation_package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-package`
3203
+ },
3204
+ generated_at_iso: nowIso()
3205
+ };
3206
+ }
3207
+
3208
+ function summarizeMultiOperatorParticipationPolicyPack(state, accountId) {
3209
+ const pack = buildMultiOperatorParticipationPolicyPack(state, accountId);
3210
+ return {
3211
+ pack_version: pack.pack_version,
3212
+ account_id: pack.account_id,
3213
+ recommended_policy_motion: pack.recommended_policy_motion,
3214
+ template_count: ensureArray(pack.policy_templates).length
3215
+ };
3216
+ }
3217
+
3218
+ function buildMultiOperatorParticipationApplicationSummary(state, accountId, templateId) {
3219
+ const pack = buildMultiOperatorParticipationPolicyPack(state, accountId);
3220
+ const selectedTemplate = ensureArray(pack.policy_templates).find((entry) => entry.template_id === templateId)
3221
+ || ensureArray(pack.policy_templates).find((entry) => entry.target_motion === pack.recommended_policy_motion)
3222
+ || ensureArray(pack.policy_templates)[0]
3223
+ || null;
3224
+
3225
+ return {
3226
+ summary_version: "xytara-multi-operator-participation-application-summary-v1",
3227
+ account_id: accountId,
3228
+ recommended_policy_motion: pack.recommended_policy_motion,
3229
+ selected_template_id: selectedTemplate ? selectedTemplate.template_id : null,
3230
+ available_template_ids: ensureArray(pack.policy_templates).map((entry) => entry.template_id),
3231
+ selected_template: selectedTemplate,
3232
+ suggested_participation_targets: {
3233
+ multi_operator_participation_state: pack.multi_operator_participation_operator_bundle.operator_posture.multi_operator_participation_state,
3234
+ coordination_readiness_state: pack.multi_operator_participation_operator_bundle.operator_posture.coordination_readiness_state,
3235
+ participation_risk_state: pack.multi_operator_participation_operator_bundle.operator_posture.participation_risk_state,
3236
+ trust_state: pack.multi_operator_participation_operator_bundle.operator_posture.trust_state
3237
+ },
3238
+ linked_surfaces: {
3239
+ multi_operator_participation_policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-policy-pack`,
3240
+ multi_operator_participation_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-operator-bundle`,
3241
+ multi_operator_participation_package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-package`
3242
+ },
3243
+ generated_at_iso: nowIso()
3244
+ };
3245
+ }
3246
+
3247
+ function buildMultiOperatorParticipationPackage(state, accountId) {
3248
+ const summary = buildMultiOperatorParticipationSummary(state, accountId);
3249
+ const operatorBundle = buildMultiOperatorParticipationOperatorBundle(state, accountId);
3250
+ const policyPack = buildMultiOperatorParticipationPolicyPack(state, accountId);
3251
+ const applicationSummary = buildMultiOperatorParticipationApplicationSummary(state, accountId, null);
3252
+ const reviewBundle = buildMultiOperatorReviewBundle(state, accountId);
3253
+ const attentionSummary = buildMultiOperatorAttentionSummary(state, accountId);
3254
+
3255
+ return {
3256
+ package_version: "xytara-multi-operator-participation-package-v1",
3257
+ account_id: accountId,
3258
+ package_posture: {
3259
+ multi_operator_participation_state: summary.multi_operator_participation_state,
3260
+ coordination_readiness_state: summary.coordination_readiness_state,
3261
+ participation_risk_state: summary.participation_risk_state,
3262
+ overall_attention_state: attentionSummary.overall_attention_state,
3263
+ recommended_operator_motion: operatorBundle.operator_posture.recommended_operator_motion,
3264
+ recommended_policy_motion: policyPack.recommended_policy_motion
3265
+ },
3266
+ multi_operator_participation_summary: summary,
3267
+ multi_operator_participation_operator_bundle: operatorBundle,
3268
+ multi_operator_participation_policy_pack: policyPack,
3269
+ multi_operator_participation_application_summary: applicationSummary,
3270
+ multi_operator_review_bundle: reviewBundle,
3271
+ multi_operator_attention_summary: attentionSummary,
3272
+ linked_surfaces: {
3273
+ multi_operator_participation_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-summary`,
3274
+ multi_operator_participation_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-operator-bundle`,
3275
+ multi_operator_participation_policy_pack_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-policy-pack`,
3276
+ multi_operator_participation_application_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-application-summary`,
3277
+ multi_operator_review_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-review-bundle`,
3278
+ multi_operator_attention_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-attention-summary`
3279
+ },
3280
+ generated_at_iso: nowIso()
3281
+ };
3282
+ }
3283
+
3284
+ function summarizeMultiOperatorParticipationPackage(state, accountId) {
3285
+ const pack = buildMultiOperatorParticipationPackage(state, accountId);
3286
+ return {
3287
+ package_version: pack.package_version,
3288
+ account_id: pack.account_id,
3289
+ multi_operator_participation_state: pack.package_posture.multi_operator_participation_state,
3290
+ coordination_readiness_state: pack.package_posture.coordination_readiness_state,
3291
+ participation_risk_state: pack.package_posture.participation_risk_state,
3292
+ recommended_operator_motion: pack.package_posture.recommended_operator_motion,
3293
+ recommended_policy_motion: pack.package_posture.recommended_policy_motion
3294
+ };
3295
+ }
3296
+
3297
+ function listNetworkParticipantsForAccount(state, accountId) {
3298
+ return Array.from(state.networkParticipants.values())
3299
+ .filter((entry) => entry && entry.account_id === accountId);
3300
+ }
3301
+
3302
+ function buildNetworkParticipantPublicView(entry) {
3303
+ if (!entry) return null;
3304
+ return {
3305
+ network_participant_id: entry.network_participant_id,
3306
+ account_id: entry.account_id,
3307
+ label: entry.label,
3308
+ network_kind: entry.network_kind,
3309
+ partner_ref: entry.partner_ref || null,
3310
+ status: entry.status,
3311
+ participation_scope: ensureArray(entry.participation_scope),
3312
+ authority_binding_id: entry.authority_binding_id || null,
3313
+ identity_binding_id: entry.identity_binding_id || null,
3314
+ created_at_iso: entry.created_at_iso,
3315
+ updated_at_iso: entry.updated_at_iso,
3316
+ issued_by: entry.issued_by || null,
3317
+ labels: ensureArray(entry.labels)
3318
+ };
3319
+ }
3320
+
3321
+ function listNetworkParticipants(state, accountId) {
3322
+ return listNetworkParticipantsForAccount(state, accountId).map((entry) => buildNetworkParticipantPublicView(entry));
3323
+ }
3324
+
3325
+ function getNetworkParticipant(state, accountId, participantId) {
3326
+ if (!participantId || !state.networkParticipants.has(participantId)) return null;
3327
+ const entry = state.networkParticipants.get(participantId);
3328
+ if (!entry || entry.account_id !== accountId) return null;
3329
+ return buildNetworkParticipantPublicView(entry);
3330
+ }
3331
+
3332
+ function buildNetworkParticipationAdmissionPreview(state, accountId, body) {
3333
+ const payload = ensureObject(body);
3334
+ const nextIndex = listNetworkParticipantsForAccount(state, accountId).length + 1;
3335
+ return {
3336
+ preview_version: "xytara-network-participation-admission-preview-v1",
3337
+ account_id: accountId,
3338
+ proposed_participant: {
3339
+ label: normalizeString(payload.label, `network-participant-${nextIndex}`),
3340
+ network_kind: normalizeString(payload.network_kind, "external_operator"),
3341
+ partner_ref: normalizeString(payload.partner_ref, `partner_${nextIndex}`),
3342
+ participation_scope: ensureArray(payload.participation_scope).length > 0
3343
+ ? ensureArray(payload.participation_scope)
3344
+ : ["network.coordinate", "runtime.execute"]
3345
+ },
3346
+ planned_bindings: {
3347
+ authority_kind: normalizeString(payload.authority_kind, "delegated_runtime_spend"),
3348
+ identity_kind: normalizeString(payload.identity_kind, "registry_anchor_identity")
3349
+ },
3350
+ linked_surfaces: {
3351
+ network_participants_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participants`,
3352
+ network_participation_package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participation-package`
3353
+ },
3354
+ generated_at_iso: nowIso()
3355
+ };
3356
+ }
3357
+
3358
+ function createNetworkParticipant(state, accountId, body) {
3359
+ const payload = ensureObject(body);
3360
+ const createdAtIso = nowIso();
3361
+ const nextIndex = state.networkParticipants.size + 1;
3362
+ const networkParticipantId = normalizeString(payload.network_participant_id, `network_participant_${nextIndex}`);
3363
+ const participationScope = ensureArray(payload.participation_scope).length > 0
3364
+ ? ensureArray(payload.participation_scope).map((value) => String(value || "").trim()).filter(Boolean)
3365
+ : ["network.coordinate", "runtime.execute"];
3366
+ const authorityBinding = createAuthorityBinding(state, {
3367
+ binding_id: normalizeString(payload.authority_binding_id, `${networkParticipantId}_authority`),
3368
+ credential_id: normalizeString(payload.credential_id, `${networkParticipantId}_credential`),
3369
+ account_id: accountId,
3370
+ authority_kind: normalizeString(payload.authority_kind, "delegated_runtime_spend"),
3371
+ authority_scope: participationScope,
3372
+ allowed_consequence_families: ensureArray(payload.allowed_consequence_families).length > 0
3373
+ ? ensureArray(payload.allowed_consequence_families)
3374
+ : ["commit", "reserve"],
3375
+ max_commit_units: Number.isFinite(Number(payload.max_commit_units)) ? Number(payload.max_commit_units) : 5,
3376
+ max_reserve_units: Number.isFinite(Number(payload.max_reserve_units)) ? Number(payload.max_reserve_units) : 5,
3377
+ max_reversal_units: Number.isFinite(Number(payload.max_reversal_units)) ? Number(payload.max_reversal_units) : 1,
3378
+ labels: ensureArray(payload.labels),
3379
+ issued_by: normalizeString(payload.issued_by, "operator")
3380
+ });
3381
+ const identityBinding = createIdentityBinding(state, {
3382
+ binding_id: normalizeString(payload.identity_binding_id, `${networkParticipantId}_identity`),
3383
+ account_id: accountId,
3384
+ identity_kind: normalizeString(payload.identity_kind, "registry_anchor_identity"),
3385
+ identity_ref: normalizeString(payload.identity_ref, `${networkParticipantId}.identity`),
3386
+ attached_agent_account_id: networkParticipantId,
3387
+ labels: ensureArray(payload.labels),
3388
+ issued_by: normalizeString(payload.issued_by, "operator")
3389
+ });
3390
+ const participant = {
3391
+ network_participant_id: networkParticipantId,
3392
+ account_id: accountId,
3393
+ label: normalizeString(payload.label, networkParticipantId),
3394
+ network_kind: normalizeString(payload.network_kind, "external_operator"),
3395
+ partner_ref: normalizeString(payload.partner_ref, null),
3396
+ status: normalizeString(payload.status, "active"),
3397
+ participation_scope: participationScope,
3398
+ authority_binding_id: authorityBinding.binding_id,
3399
+ identity_binding_id: identityBinding.binding_id,
3400
+ created_at_iso: createdAtIso,
3401
+ updated_at_iso: createdAtIso,
3402
+ issued_by: normalizeString(payload.issued_by, "operator"),
3403
+ labels: ensureArray(payload.labels).map((value) => String(value || "").trim()).filter(Boolean)
3404
+ };
3405
+ state.networkParticipants.set(networkParticipantId, participant);
3406
+ return {
3407
+ network_participant: buildNetworkParticipantPublicView(participant),
3408
+ authority_binding: authorityBinding,
3409
+ identity_binding: identityBinding
3410
+ };
3411
+ }
3412
+
3413
+ function buildNetworkParticipationReviewBundle(state, accountId) {
3414
+ const participants = listNetworkParticipantsForAccount(state, accountId);
3415
+ const reviewRows = participants.map((entry) => {
3416
+ let review_state = "healthy";
3417
+ if (entry.status !== "active") review_state = "revoked";
3418
+ else if (!entry.authority_binding_id || !entry.identity_binding_id) review_state = "repair_required";
3419
+ else if (!entry.partner_ref) review_state = "attention_required";
3420
+ return {
3421
+ network_participant_id: entry.network_participant_id,
3422
+ label: entry.label,
3423
+ network_kind: entry.network_kind,
3424
+ status: entry.status,
3425
+ partner_ref: entry.partner_ref || null,
3426
+ review_state
3427
+ };
3428
+ });
3429
+ return {
3430
+ bundle_version: "xytara-network-participation-review-bundle-v1",
3431
+ account_id: accountId,
3432
+ review_rows: reviewRows,
3433
+ review_counts: {
3434
+ healthy_count: reviewRows.filter((entry) => entry.review_state === "healthy").length,
3435
+ attention_required_count: reviewRows.filter((entry) => entry.review_state === "attention_required").length,
3436
+ repair_required_count: reviewRows.filter((entry) => entry.review_state === "repair_required").length,
3437
+ revoked_count: reviewRows.filter((entry) => entry.review_state === "revoked").length
3438
+ },
3439
+ linked_surfaces: {
3440
+ network_participants_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participants`,
3441
+ network_participation_package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participation-package`
3442
+ },
3443
+ generated_at_iso: nowIso()
3444
+ };
3445
+ }
3446
+
3447
+ function buildNetworkParticipationAttentionSummary(state, accountId) {
3448
+ const reviewBundle = buildNetworkParticipationReviewBundle(state, accountId);
3449
+ const attentionRows = ensureArray(reviewBundle.review_rows).filter((entry) => entry.review_state !== "healthy");
3450
+ return {
3451
+ summary_version: "xytara-network-participation-attention-summary-v1",
3452
+ account_id: accountId,
3453
+ overall_attention_state: attentionRows.length > 0 ? "attention_required" : "healthy",
3454
+ attention_rows: attentionRows,
3455
+ linked_surfaces: {
3456
+ network_participation_review_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participation-review-bundle`,
3457
+ network_participation_package_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participation-package`
3458
+ },
3459
+ generated_at_iso: nowIso()
3460
+ };
3461
+ }
3462
+
3463
+ function buildNetworkParticipationSummary(state, accountId) {
3464
+ const trustLayerSummary = buildTrustLayerSummary(state, accountId);
3465
+ const multiOperatorSummary = buildMultiOperatorParticipationSummary(state, accountId);
3466
+ const participants = listNetworkParticipantsForAccount(state, accountId);
3467
+ const activeParticipantCount = participants.filter((entry) => entry.status === "active").length;
3468
+ const coordinationHandoffCount = ensureArray(state.coordinationHandoffs).length;
3469
+ const admissionCaseCount = ensureArray(state.zoneAdmissionCases).length;
3470
+
3471
+ let participationState = "local_only";
3472
+ if (activeParticipantCount > 0 && multiOperatorSummary.multi_operator_participation_state !== "single_operator_only") {
3473
+ participationState = "external_network_present";
3474
+ } else if (activeParticipantCount > 0) {
3475
+ participationState = "network_edge_present";
3476
+ }
3477
+
3478
+ let networkReadinessState = "limited";
3479
+ if (activeParticipantCount > 0 && coordinationHandoffCount > 0 && admissionCaseCount > 0) {
3480
+ networkReadinessState = "active";
3481
+ } else if (activeParticipantCount > 0 || coordinationHandoffCount > 0 || admissionCaseCount > 0) {
3482
+ networkReadinessState = "preview_ready";
3483
+ }
3484
+
3485
+ let participationRiskState = "low";
3486
+ if (trustLayerSummary.trust_risk_state === "high" || activeParticipantCount === 0) {
3487
+ participationRiskState = "high";
3488
+ } else if (networkReadinessState !== "active") {
3489
+ participationRiskState = "watch";
3490
+ }
3491
+
3492
+ let recommendedParticipationMotion = "maintain_external_network_posture";
3493
+ if (activeParticipantCount === 0) {
3494
+ recommendedParticipationMotion = "admit_first_external_network_participant";
3495
+ } else if (participationRiskState === "high") {
3496
+ recommendedParticipationMotion = "repair_trust_before_external_network_expansion";
3497
+ } else if (networkReadinessState !== "active") {
3498
+ recommendedParticipationMotion = "activate_external_coordination_followthrough";
3499
+ }
3500
+
3501
+ return {
3502
+ summary_version: "xytara-network-participation-summary-v1",
3503
+ account_id: accountId,
3504
+ network_participation_state: participationState,
3505
+ network_readiness_state: networkReadinessState,
3506
+ participation_risk_state: participationRiskState,
3507
+ recommended_participation_motion: recommendedParticipationMotion,
3508
+ explanation_signals: {
3509
+ active_network_participant_count: activeParticipantCount,
3510
+ coordination_handoff_count: coordinationHandoffCount,
3511
+ admission_case_count: admissionCaseCount,
3512
+ trust_state: trustLayerSummary.trust_state,
3513
+ trust_risk_state: trustLayerSummary.trust_risk_state,
3514
+ multi_operator_participation_state: multiOperatorSummary.multi_operator_participation_state
3515
+ },
3516
+ linked_surfaces: {
3517
+ network_participants_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participants`,
3518
+ multi_operator_participation_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/multi-operator-participation-summary`,
3519
+ trust_layer_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/trust-layer-summary`,
3520
+ coordination_center_ref: "/v1/coordination-center/summary"
3521
+ },
3522
+ generated_at_iso: nowIso()
3523
+ };
3524
+ }
3525
+
3526
+ function buildNetworkParticipationOperatorBundle(state, accountId) {
3527
+ const summary = buildNetworkParticipationSummary(state, accountId);
3528
+ const reviewBundle = buildNetworkParticipationReviewBundle(state, accountId);
3529
+ const attentionSummary = buildNetworkParticipationAttentionSummary(state, accountId);
3530
+ const trustLayerSummary = buildTrustLayerSummary(state, accountId);
3531
+ const multiOperatorSummary = buildMultiOperatorParticipationSummary(state, accountId);
3532
+ const participants = listNetworkParticipants(state, accountId);
3533
+
3534
+ let recommendedOperatorMotion = "maintain_external_network_posture";
3535
+ if (summary.network_participation_state === "local_only") {
3536
+ recommendedOperatorMotion = "admit_first_external_network_participant";
3537
+ } else if (summary.participation_risk_state === "high") {
3538
+ recommendedOperatorMotion = "repair_trust_before_external_network_expansion";
3539
+ } else if (summary.network_readiness_state !== "active") {
3540
+ recommendedOperatorMotion = "activate_external_coordination_followthrough";
3541
+ }
3542
+
3543
+ return {
3544
+ bundle_version: "xytara-network-participation-operator-bundle-v1",
3545
+ account_id: accountId,
3546
+ operator_posture: {
3547
+ network_participation_state: summary.network_participation_state,
3548
+ network_readiness_state: summary.network_readiness_state,
3549
+ participation_risk_state: summary.participation_risk_state,
3550
+ active_network_participant_count: participants.filter((entry) => entry.status === "active").length,
3551
+ trust_state: trustLayerSummary.trust_state,
3552
+ multi_operator_participation_state: multiOperatorSummary.multi_operator_participation_state,
3553
+ overall_attention_state: attentionSummary.overall_attention_state,
3554
+ recommended_operator_motion: recommendedOperatorMotion
3555
+ },
3556
+ network_participation_summary: summary,
3557
+ network_participation_review_bundle: reviewBundle,
3558
+ network_participation_attention_summary: attentionSummary,
3559
+ trust_layer_summary: trustLayerSummary,
3560
+ multi_operator_participation_summary: multiOperatorSummary,
3561
+ network_participants: participants,
3562
+ linked_surfaces: summary.linked_surfaces,
3563
+ generated_at_iso: nowIso()
3564
+ };
3565
+ }
3566
+
3567
+ function buildNetworkParticipationPackage(state, accountId) {
3568
+ const summary = buildNetworkParticipationSummary(state, accountId);
3569
+ const operatorBundle = buildNetworkParticipationOperatorBundle(state, accountId);
3570
+ const reviewBundle = buildNetworkParticipationReviewBundle(state, accountId);
3571
+ const attentionSummary = buildNetworkParticipationAttentionSummary(state, accountId);
3572
+ return {
3573
+ package_version: "xytara-network-participation-package-v1",
3574
+ account_id: accountId,
3575
+ package_posture: {
3576
+ network_participation_state: summary.network_participation_state,
3577
+ network_readiness_state: summary.network_readiness_state,
3578
+ participation_risk_state: summary.participation_risk_state,
3579
+ overall_attention_state: attentionSummary.overall_attention_state,
3580
+ recommended_operator_motion: operatorBundle.operator_posture.recommended_operator_motion
3581
+ },
3582
+ network_participation_summary: summary,
3583
+ network_participation_operator_bundle: operatorBundle,
3584
+ network_participation_review_bundle: reviewBundle,
3585
+ network_participation_attention_summary: attentionSummary,
3586
+ linked_surfaces: {
3587
+ network_participation_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participation-summary`,
3588
+ network_participation_operator_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participation-operator-bundle`,
3589
+ network_participation_review_bundle_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participation-review-bundle`,
3590
+ network_participation_attention_summary_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participation-attention-summary`,
3591
+ network_participants_ref: `/v1/economics/accounts/${encodeURIComponent(accountId)}/network-participants`
3592
+ },
3593
+ generated_at_iso: nowIso()
3594
+ };
3595
+ }
3596
+
1487
3597
  function buildRailSummary(state, accountId) {
1488
3598
  const credits = listRailCreditsForAccount(state, accountId);
1489
3599
  const paymentLedger = listPaymentLedgerForAccount(state, accountId);
@@ -1703,7 +3813,12 @@ module.exports = {
1703
3813
  applyRailCredits,
1704
3814
  buildCreditBalanceSummary,
1705
3815
  buildWalletSummary,
3816
+ buildWalletLifecycleSummary,
3817
+ buildWalletReserveSummary,
3818
+ buildWalletCommitSummary,
3819
+ buildWalletLedgerBundle,
1706
3820
  buildWalletLedgerSummary,
3821
+ applyWalletLifecycleEvent,
1707
3822
  buildEconomicsIntelligenceSummary,
1708
3823
  buildTreasuryIntelligenceSummary,
1709
3824
  buildTreasurySummary,
@@ -1716,6 +3831,56 @@ module.exports = {
1716
3831
  buildPolicySummary,
1717
3832
  buildAccountCreditSpendPolicyPack,
1718
3833
  buildAgentCreditSpendPolicyView,
3834
+ buildPricingPolicySummary,
3835
+ buildPricingPolicyOperatorBundle,
3836
+ buildPricingPolicyPack,
3837
+ buildPricingPolicyApplicationSummary,
3838
+ buildPricingPolicyPackage,
3839
+ buildQuotePolicyDecisionSummary,
3840
+ buildPricingBandDecisionSummary,
3841
+ buildQuotePolicyOperatorBundle,
3842
+ summarizeQuotePolicyOperatorBundle,
3843
+ buildQuotePolicyPack,
3844
+ summarizeQuotePolicyPack,
3845
+ buildQuotePolicyApplicationSummary,
3846
+ buildQuotePolicyPackage,
3847
+ summarizeQuotePolicyPackage,
3848
+ buildTrustInputSummary,
3849
+ buildTrustLayerSummary,
3850
+ buildTrustLayerOperatorBundle,
3851
+ summarizeTrustLayerOperatorBundle,
3852
+ buildTrustLayerPolicyPack,
3853
+ summarizeTrustLayerPolicyPack,
3854
+ buildTrustLayerApplicationSummary,
3855
+ buildTrustLayerPackage,
3856
+ summarizeTrustLayerPackage,
3857
+ listNetworkParticipants,
3858
+ getNetworkParticipant,
3859
+ buildNetworkParticipationAdmissionPreview,
3860
+ createNetworkParticipant,
3861
+ buildNetworkParticipationReviewBundle,
3862
+ buildNetworkParticipationAttentionSummary,
3863
+ buildNetworkParticipationSummary,
3864
+ buildNetworkParticipationOperatorBundle,
3865
+ buildNetworkParticipationPackage,
3866
+ listMultiOperatorParticipants,
3867
+ getMultiOperatorParticipant,
3868
+ buildMultiOperatorAdmissionPreview,
3869
+ createMultiOperatorParticipant,
3870
+ renewMultiOperatorParticipant,
3871
+ revokeMultiOperatorParticipant,
3872
+ rotateMultiOperatorParticipant,
3873
+ buildMultiOperatorParticipantRotationSummary,
3874
+ buildMultiOperatorReviewBundle,
3875
+ buildMultiOperatorAttentionSummary,
3876
+ buildMultiOperatorParticipationSummary,
3877
+ buildMultiOperatorParticipationOperatorBundle,
3878
+ summarizeMultiOperatorParticipationOperatorBundle,
3879
+ buildMultiOperatorParticipationPolicyPack,
3880
+ summarizeMultiOperatorParticipationPolicyPack,
3881
+ buildMultiOperatorParticipationApplicationSummary,
3882
+ buildMultiOperatorParticipationPackage,
3883
+ summarizeMultiOperatorParticipationPackage,
1719
3884
  buildRailSummary,
1720
3885
  buildTreasuryWorkflowPack,
1721
3886
  buildTreasurySignoffPack,
@@ -1742,6 +3907,7 @@ module.exports = {
1742
3907
  listMapValuesByAccount,
1743
3908
  listEntitlementsForAccount,
1744
3909
  getEntitlement,
3910
+ getAllocationEvent,
1745
3911
  getCreditSpend,
1746
3912
  listUsageMetersForAccount,
1747
3913
  getUsageMeter,