chainlesschain 0.66.0 → 0.132.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.
Files changed (143) hide show
  1. package/bin/chainlesschain.js +0 -0
  2. package/package.json +1 -1
  3. package/src/commands/a2a.js +380 -0
  4. package/src/commands/agent-network.js +254 -1
  5. package/src/commands/audit.js +302 -0
  6. package/src/commands/automation.js +271 -1
  7. package/src/commands/bi.js +348 -0
  8. package/src/commands/codegen.js +224 -0
  9. package/src/commands/collab.js +341 -0
  10. package/src/commands/compliance.js +1035 -0
  11. package/src/commands/cowork.js +221 -0
  12. package/src/commands/crosschain.js +218 -0
  13. package/src/commands/dbevo.js +284 -0
  14. package/src/commands/dev.js +252 -0
  15. package/src/commands/did.js +358 -0
  16. package/src/commands/dlp.js +341 -0
  17. package/src/commands/encrypt.js +341 -0
  18. package/src/commands/evomap.js +394 -0
  19. package/src/commands/export.js +256 -1
  20. package/src/commands/federation.js +283 -0
  21. package/src/commands/fusion.js +258 -0
  22. package/src/commands/governance.js +325 -0
  23. package/src/commands/hardening.js +411 -0
  24. package/src/commands/hook.js +148 -0
  25. package/src/commands/import.js +252 -0
  26. package/src/commands/incentive.js +322 -0
  27. package/src/commands/inference.js +318 -0
  28. package/src/commands/infra.js +244 -0
  29. package/src/commands/instinct.js +260 -0
  30. package/src/commands/ipfs.js +318 -0
  31. package/src/commands/kg.js +387 -0
  32. package/src/commands/llm.js +263 -0
  33. package/src/commands/lowcode.js +356 -0
  34. package/src/commands/marketplace.js +256 -0
  35. package/src/commands/mcp.js +221 -0
  36. package/src/commands/memory.js +248 -0
  37. package/src/commands/multimodal.js +296 -0
  38. package/src/commands/nlprog.js +356 -0
  39. package/src/commands/note.js +244 -0
  40. package/src/commands/ops.js +354 -0
  41. package/src/commands/orchestrate.js +166 -0
  42. package/src/commands/org.js +277 -0
  43. package/src/commands/p2p.js +390 -0
  44. package/src/commands/perception.js +290 -0
  45. package/src/commands/permmem.js +251 -0
  46. package/src/commands/plugin-ecosystem.js +273 -0
  47. package/src/commands/pqc.js +393 -0
  48. package/src/commands/privacy.js +321 -0
  49. package/src/commands/quantization.js +351 -0
  50. package/src/commands/rcache.js +271 -0
  51. package/src/commands/recommend.js +340 -0
  52. package/src/commands/reputation.js +261 -0
  53. package/src/commands/runtime.js +307 -0
  54. package/src/commands/scim.js +262 -0
  55. package/src/commands/session.js +258 -0
  56. package/src/commands/siem.js +246 -0
  57. package/src/commands/skill.js +267 -1
  58. package/src/commands/sla.js +259 -0
  59. package/src/commands/social.js +256 -0
  60. package/src/commands/sso.js +186 -1
  61. package/src/commands/stress.js +230 -0
  62. package/src/commands/sync.js +256 -0
  63. package/src/commands/tech.js +338 -0
  64. package/src/commands/tenant.js +351 -0
  65. package/src/commands/terraform.js +245 -0
  66. package/src/commands/tokens.js +269 -0
  67. package/src/commands/trust.js +249 -0
  68. package/src/commands/wallet.js +277 -0
  69. package/src/commands/workflow.js +171 -0
  70. package/src/commands/zkp.js +335 -0
  71. package/src/index.js +4 -0
  72. package/src/lib/a2a-protocol.js +451 -0
  73. package/src/lib/agent-coordinator.js +325 -0
  74. package/src/lib/agent-network.js +387 -0
  75. package/src/lib/agent-router.js +395 -0
  76. package/src/lib/aiops.js +478 -0
  77. package/src/lib/app-builder.js +239 -0
  78. package/src/lib/audit-logger.js +379 -0
  79. package/src/lib/automation-engine.js +330 -0
  80. package/src/lib/autonomous-developer.js +350 -0
  81. package/src/lib/bi-engine.js +338 -0
  82. package/src/lib/code-agent.js +323 -0
  83. package/src/lib/collaboration-governance.js +364 -0
  84. package/src/lib/community-governance.js +436 -0
  85. package/src/lib/compliance-manager.js +434 -0
  86. package/src/lib/content-recommendation.js +469 -0
  87. package/src/lib/cross-chain.js +345 -0
  88. package/src/lib/crypto-manager.js +350 -0
  89. package/src/lib/dbevo.js +338 -0
  90. package/src/lib/decentral-infra.js +340 -0
  91. package/src/lib/did-manager.js +367 -0
  92. package/src/lib/dlp-engine.js +389 -0
  93. package/src/lib/evomap-federation.js +177 -0
  94. package/src/lib/evomap-governance.js +276 -0
  95. package/src/lib/federation-hardening.js +259 -0
  96. package/src/lib/hardening-manager.js +348 -0
  97. package/src/lib/hook-manager.js +380 -0
  98. package/src/lib/inference-network.js +330 -0
  99. package/src/lib/instinct-manager.js +332 -0
  100. package/src/lib/ipfs-storage.js +334 -0
  101. package/src/lib/knowledge-exporter.js +381 -0
  102. package/src/lib/knowledge-graph.js +432 -0
  103. package/src/lib/knowledge-importer.js +379 -0
  104. package/src/lib/llm-providers.js +391 -0
  105. package/src/lib/mcp-registry.js +333 -0
  106. package/src/lib/memory-manager.js +330 -0
  107. package/src/lib/multimodal.js +346 -0
  108. package/src/lib/nl-programming.js +343 -0
  109. package/src/lib/note-versioning.js +327 -0
  110. package/src/lib/org-manager.js +323 -0
  111. package/src/lib/p2p-manager.js +387 -0
  112. package/src/lib/perception.js +346 -0
  113. package/src/lib/perf-tuning.js +4 -1
  114. package/src/lib/permanent-memory.js +320 -0
  115. package/src/lib/plugin-ecosystem.js +377 -0
  116. package/src/lib/pqc-manager.js +368 -0
  117. package/src/lib/privacy-computing.js +427 -0
  118. package/src/lib/protocol-fusion.js +417 -0
  119. package/src/lib/quantization.js +325 -0
  120. package/src/lib/reputation-optimizer.js +299 -0
  121. package/src/lib/response-cache.js +327 -0
  122. package/src/lib/scim-manager.js +329 -0
  123. package/src/lib/session-manager.js +329 -0
  124. package/src/lib/siem-exporter.js +333 -0
  125. package/src/lib/skill-loader.js +377 -0
  126. package/src/lib/skill-marketplace.js +325 -0
  127. package/src/lib/sla-manager.js +275 -0
  128. package/src/lib/social-manager.js +326 -0
  129. package/src/lib/sso-manager.js +332 -0
  130. package/src/lib/stress-tester.js +330 -0
  131. package/src/lib/sync-manager.js +326 -0
  132. package/src/lib/tech-learning-engine.js +369 -0
  133. package/src/lib/tenant-saas.js +460 -0
  134. package/src/lib/terraform-manager.js +363 -0
  135. package/src/lib/threat-intel.js +335 -0
  136. package/src/lib/token-incentive.js +293 -0
  137. package/src/lib/token-tracker.js +329 -0
  138. package/src/lib/trust-security.js +390 -0
  139. package/src/lib/ueba.js +389 -0
  140. package/src/lib/universal-runtime.js +325 -0
  141. package/src/lib/wallet-manager.js +326 -0
  142. package/src/lib/workflow-engine.js +322 -0
  143. package/src/lib/zkp-engine.js +274 -0
@@ -647,3 +647,439 @@ export function _resetState() {
647
647
  _proposalVotes.clear();
648
648
  _seq = 0;
649
649
  }
650
+
651
+ /* ═══════════════════════════════════════════════════════════════
652
+ * Phase 54 V2 — Proposer Maturity + Vote Delegation Lifecycle
653
+ * Strictly additive. Legacy surface above is preserved.
654
+ * ═════════════════════════════════════════════════════════════ */
655
+
656
+ export const PROPOSER_MATURITY_V2 = Object.freeze({
657
+ ONBOARDING: "onboarding",
658
+ ACTIVE: "active",
659
+ SUSPENDED: "suspended",
660
+ RETIRED: "retired",
661
+ });
662
+
663
+ export const DELEGATION_LIFECYCLE_V2 = Object.freeze({
664
+ PENDING: "pending",
665
+ ACTIVE: "active",
666
+ REVOKED: "revoked",
667
+ EXPIRED: "expired",
668
+ });
669
+
670
+ const PROPOSER_TRANSITIONS_V2 = new Map([
671
+ ["onboarding", new Set(["active", "retired"])],
672
+ ["active", new Set(["suspended", "retired"])],
673
+ ["suspended", new Set(["active", "retired"])],
674
+ ]);
675
+ const PROPOSER_TERMINALS_V2 = new Set(["retired"]);
676
+
677
+ const DELEGATION_TRANSITIONS_V2 = new Map([
678
+ ["pending", new Set(["active", "revoked", "expired"])],
679
+ ["active", new Set(["revoked", "expired"])],
680
+ ]);
681
+ const DELEGATION_TERMINALS_V2 = new Set(["revoked", "expired"]);
682
+
683
+ export const GOV_DEFAULT_MAX_ACTIVE_PROPOSERS_PER_REALM = 100;
684
+ export const GOV_DEFAULT_MAX_ACTIVE_DELEGATIONS_PER_DELEGATOR = 5;
685
+ export const GOV_DEFAULT_PROPOSER_IDLE_MS = 180 * 86400000; // 180 days
686
+ export const GOV_DEFAULT_PENDING_DELEGATION_MS = 7 * 86400000; // 7 days
687
+
688
+ let _maxActiveProposersPerRealmV2 = GOV_DEFAULT_MAX_ACTIVE_PROPOSERS_PER_REALM;
689
+ let _maxActiveDelegationsPerDelegatorV2 =
690
+ GOV_DEFAULT_MAX_ACTIVE_DELEGATIONS_PER_DELEGATOR;
691
+ let _proposerIdleMsV2 = GOV_DEFAULT_PROPOSER_IDLE_MS;
692
+ let _pendingDelegationMsV2 = GOV_DEFAULT_PENDING_DELEGATION_MS;
693
+
694
+ const _proposerStatesV2 = new Map(); // proposerId → V2 record
695
+ const _delegationStatesV2 = new Map(); // delegationId → V2 record
696
+
697
+ function _positiveIntV2(n, label) {
698
+ const num = Number(n);
699
+ if (!Number.isFinite(num) || num <= 0) {
700
+ throw new Error(`${label} must be a positive integer`);
701
+ }
702
+ return Math.floor(num);
703
+ }
704
+
705
+ function _validProposerStatusV2(s) {
706
+ return (
707
+ s === "onboarding" || s === "active" || s === "suspended" || s === "retired"
708
+ );
709
+ }
710
+
711
+ function _validDelegationStatusV2(s) {
712
+ return (
713
+ s === "pending" || s === "active" || s === "revoked" || s === "expired"
714
+ );
715
+ }
716
+
717
+ export function getDefaultMaxActiveProposersPerRealmV2() {
718
+ return GOV_DEFAULT_MAX_ACTIVE_PROPOSERS_PER_REALM;
719
+ }
720
+ export function getMaxActiveProposersPerRealmV2() {
721
+ return _maxActiveProposersPerRealmV2;
722
+ }
723
+ export function setMaxActiveProposersPerRealmV2(n) {
724
+ _maxActiveProposersPerRealmV2 = _positiveIntV2(
725
+ n,
726
+ "maxActiveProposersPerRealm",
727
+ );
728
+ return _maxActiveProposersPerRealmV2;
729
+ }
730
+
731
+ export function getDefaultMaxActiveDelegationsPerDelegatorV2() {
732
+ return GOV_DEFAULT_MAX_ACTIVE_DELEGATIONS_PER_DELEGATOR;
733
+ }
734
+ export function getMaxActiveDelegationsPerDelegatorV2() {
735
+ return _maxActiveDelegationsPerDelegatorV2;
736
+ }
737
+ export function setMaxActiveDelegationsPerDelegatorV2(n) {
738
+ _maxActiveDelegationsPerDelegatorV2 = _positiveIntV2(
739
+ n,
740
+ "maxActiveDelegationsPerDelegator",
741
+ );
742
+ return _maxActiveDelegationsPerDelegatorV2;
743
+ }
744
+
745
+ export function getDefaultProposerIdleMsV2() {
746
+ return GOV_DEFAULT_PROPOSER_IDLE_MS;
747
+ }
748
+ export function getProposerIdleMsV2() {
749
+ return _proposerIdleMsV2;
750
+ }
751
+ export function setProposerIdleMsV2(ms) {
752
+ _proposerIdleMsV2 = _positiveIntV2(ms, "proposerIdleMs");
753
+ return _proposerIdleMsV2;
754
+ }
755
+
756
+ export function getDefaultPendingDelegationMsV2() {
757
+ return GOV_DEFAULT_PENDING_DELEGATION_MS;
758
+ }
759
+ export function getPendingDelegationMsV2() {
760
+ return _pendingDelegationMsV2;
761
+ }
762
+ export function setPendingDelegationMsV2(ms) {
763
+ _pendingDelegationMsV2 = _positiveIntV2(ms, "pendingDelegationMs");
764
+ return _pendingDelegationMsV2;
765
+ }
766
+
767
+ /* ── Proposer V2 ────────────────────────────────────────────── */
768
+
769
+ export function registerProposerV2(db, config = {}) {
770
+ void db;
771
+ const proposerId = String(config.proposerId || "").trim();
772
+ if (!proposerId) throw new Error("proposerId is required");
773
+ const realm = String(config.realm || "").trim();
774
+ if (!realm) throw new Error("realm is required");
775
+ if (_proposerStatesV2.has(proposerId)) {
776
+ throw new Error(`Proposer already registered in V2: ${proposerId}`);
777
+ }
778
+
779
+ const now = Number(config.now ?? Date.now());
780
+ const initialStatus = config.initialStatus || "onboarding";
781
+ if (!_validProposerStatusV2(initialStatus)) {
782
+ throw new Error(`Invalid initial status: ${initialStatus}`);
783
+ }
784
+ if (PROPOSER_TERMINALS_V2.has(initialStatus)) {
785
+ throw new Error(
786
+ `Cannot register proposer in terminal status '${initialStatus}'`,
787
+ );
788
+ }
789
+
790
+ if (initialStatus === "active") {
791
+ let activeCount = 0;
792
+ for (const rec of _proposerStatesV2.values()) {
793
+ if (rec.realm === realm && rec.status === "active") activeCount += 1;
794
+ }
795
+ if (activeCount >= _maxActiveProposersPerRealmV2) {
796
+ throw new Error(
797
+ `Max active proposers per realm reached (${_maxActiveProposersPerRealmV2})`,
798
+ );
799
+ }
800
+ }
801
+
802
+ const record = {
803
+ proposerId,
804
+ realm,
805
+ displayName: config.displayName ? String(config.displayName) : null,
806
+ status: initialStatus,
807
+ metadata: config.metadata ? { ...config.metadata } : {},
808
+ createdAt: now,
809
+ updatedAt: now,
810
+ lastActivityAt: now,
811
+ reason: null,
812
+ };
813
+ _proposerStatesV2.set(proposerId, record);
814
+ return { ...record, metadata: { ...record.metadata } };
815
+ }
816
+
817
+ export function getProposerV2(proposerId) {
818
+ const rec = _proposerStatesV2.get(String(proposerId || ""));
819
+ if (!rec) return null;
820
+ return { ...rec, metadata: { ...rec.metadata } };
821
+ }
822
+
823
+ export function setProposerMaturityV2(db, proposerId, newStatus, patch = {}) {
824
+ void db;
825
+ const id = String(proposerId || "");
826
+ const record = _proposerStatesV2.get(id);
827
+ if (!record) throw new Error(`Proposer not registered in V2: ${id}`);
828
+ if (!_validProposerStatusV2(newStatus)) {
829
+ throw new Error(`Invalid proposer status: ${newStatus}`);
830
+ }
831
+ if (PROPOSER_TERMINALS_V2.has(record.status)) {
832
+ throw new Error(
833
+ `Proposer is in terminal status '${record.status}' and cannot transition`,
834
+ );
835
+ }
836
+ const allowed = PROPOSER_TRANSITIONS_V2.get(record.status);
837
+ if (!allowed || !allowed.has(newStatus)) {
838
+ throw new Error(`Invalid transition: ${record.status} → ${newStatus}`);
839
+ }
840
+
841
+ if (newStatus === "active" && record.status !== "active") {
842
+ let activeCount = 0;
843
+ for (const rec of _proposerStatesV2.values()) {
844
+ if (rec.realm === record.realm && rec.status === "active") {
845
+ activeCount += 1;
846
+ }
847
+ }
848
+ if (activeCount >= _maxActiveProposersPerRealmV2) {
849
+ throw new Error(
850
+ `Max active proposers per realm reached (${_maxActiveProposersPerRealmV2})`,
851
+ );
852
+ }
853
+ }
854
+
855
+ record.status = newStatus;
856
+ record.updatedAt = Number(patch.now ?? Date.now());
857
+ if (patch.reason !== undefined) record.reason = patch.reason;
858
+ if (patch.metadata && typeof patch.metadata === "object") {
859
+ record.metadata = { ...record.metadata, ...patch.metadata };
860
+ }
861
+ return { ...record, metadata: { ...record.metadata } };
862
+ }
863
+
864
+ export function activateProposer(db, proposerId, reason) {
865
+ return setProposerMaturityV2(db, proposerId, "active", { reason });
866
+ }
867
+ export function suspendProposer(db, proposerId, reason) {
868
+ return setProposerMaturityV2(db, proposerId, "suspended", { reason });
869
+ }
870
+ export function retireProposer(db, proposerId, reason) {
871
+ return setProposerMaturityV2(db, proposerId, "retired", { reason });
872
+ }
873
+
874
+ export function touchProposerActivity(proposerId) {
875
+ const rec = _proposerStatesV2.get(String(proposerId || ""));
876
+ if (!rec) throw new Error(`Proposer not registered in V2: ${proposerId}`);
877
+ rec.lastActivityAt = Date.now();
878
+ return { ...rec, metadata: { ...rec.metadata } };
879
+ }
880
+
881
+ /* ── Delegation V2 ──────────────────────────────────────────── */
882
+
883
+ export function createDelegationV2(db, config = {}) {
884
+ void db;
885
+ const delegationId = String(config.delegationId || "").trim();
886
+ if (!delegationId) throw new Error("delegationId is required");
887
+ const delegatorId = String(config.delegatorId || "").trim();
888
+ if (!delegatorId) throw new Error("delegatorId is required");
889
+ const delegateeId = String(config.delegateeId || "").trim();
890
+ if (!delegateeId) throw new Error("delegateeId is required");
891
+ if (delegatorId === delegateeId) {
892
+ throw new Error("delegatorId and delegateeId must differ");
893
+ }
894
+ const scope = String(config.scope || "").trim();
895
+ if (!scope) throw new Error("scope is required");
896
+
897
+ if (_delegationStatesV2.has(delegationId)) {
898
+ throw new Error(`Delegation already registered in V2: ${delegationId}`);
899
+ }
900
+
901
+ let openCount = 0;
902
+ for (const rec of _delegationStatesV2.values()) {
903
+ if (
904
+ rec.delegatorId === delegatorId &&
905
+ !DELEGATION_TERMINALS_V2.has(rec.status)
906
+ ) {
907
+ openCount += 1;
908
+ }
909
+ }
910
+ if (openCount >= _maxActiveDelegationsPerDelegatorV2) {
911
+ throw new Error(
912
+ `Max active delegations per delegator reached (${_maxActiveDelegationsPerDelegatorV2})`,
913
+ );
914
+ }
915
+
916
+ const now = Number(config.now ?? Date.now());
917
+ const record = {
918
+ delegationId,
919
+ delegatorId,
920
+ delegateeId,
921
+ scope,
922
+ status: "pending",
923
+ metadata: config.metadata ? { ...config.metadata } : {},
924
+ createdAt: now,
925
+ updatedAt: now,
926
+ activatedAt: null,
927
+ expiresAt: config.expiresAt ? Number(config.expiresAt) : null,
928
+ reason: null,
929
+ };
930
+ _delegationStatesV2.set(delegationId, record);
931
+ return { ...record, metadata: { ...record.metadata } };
932
+ }
933
+
934
+ export function getDelegationV2(delegationId) {
935
+ const rec = _delegationStatesV2.get(String(delegationId || ""));
936
+ if (!rec) return null;
937
+ return { ...rec, metadata: { ...rec.metadata } };
938
+ }
939
+
940
+ export function setDelegationStatusV2(db, delegationId, newStatus, patch = {}) {
941
+ void db;
942
+ const id = String(delegationId || "");
943
+ const record = _delegationStatesV2.get(id);
944
+ if (!record) throw new Error(`Delegation not registered in V2: ${id}`);
945
+ if (!_validDelegationStatusV2(newStatus)) {
946
+ throw new Error(`Invalid delegation status: ${newStatus}`);
947
+ }
948
+ if (DELEGATION_TERMINALS_V2.has(record.status)) {
949
+ throw new Error(
950
+ `Delegation is in terminal status '${record.status}' and cannot transition`,
951
+ );
952
+ }
953
+ const allowed = DELEGATION_TRANSITIONS_V2.get(record.status);
954
+ if (!allowed || !allowed.has(newStatus)) {
955
+ throw new Error(`Invalid transition: ${record.status} → ${newStatus}`);
956
+ }
957
+ const now = Number(patch.now ?? Date.now());
958
+ record.status = newStatus;
959
+ record.updatedAt = now;
960
+ if (newStatus === "active" && record.activatedAt === null) {
961
+ record.activatedAt = now;
962
+ }
963
+ if (patch.reason !== undefined) record.reason = patch.reason;
964
+ if (patch.metadata && typeof patch.metadata === "object") {
965
+ record.metadata = { ...record.metadata, ...patch.metadata };
966
+ }
967
+ return { ...record, metadata: { ...record.metadata } };
968
+ }
969
+
970
+ export function activateDelegation(db, delegationId, reason) {
971
+ return setDelegationStatusV2(db, delegationId, "active", { reason });
972
+ }
973
+ export function revokeDelegation(db, delegationId, reason) {
974
+ return setDelegationStatusV2(db, delegationId, "revoked", { reason });
975
+ }
976
+ export function expireDelegation(db, delegationId, reason) {
977
+ return setDelegationStatusV2(db, delegationId, "expired", { reason });
978
+ }
979
+
980
+ /* ── Counts ─────────────────────────────────────────────────── */
981
+
982
+ export function getActiveProposerCount(realm) {
983
+ let n = 0;
984
+ for (const rec of _proposerStatesV2.values()) {
985
+ if (rec.status !== "active") continue;
986
+ if (realm !== undefined && rec.realm !== String(realm)) continue;
987
+ n += 1;
988
+ }
989
+ return n;
990
+ }
991
+
992
+ export function getActiveDelegationCount(delegatorId) {
993
+ let n = 0;
994
+ for (const rec of _delegationStatesV2.values()) {
995
+ if (DELEGATION_TERMINALS_V2.has(rec.status)) continue;
996
+ if (delegatorId !== undefined && rec.delegatorId !== String(delegatorId)) {
997
+ continue;
998
+ }
999
+ n += 1;
1000
+ }
1001
+ return n;
1002
+ }
1003
+
1004
+ /* ── Auto-flip Bulk Ops ─────────────────────────────────────── */
1005
+
1006
+ export function autoRetireIdleProposers(db, nowMs) {
1007
+ void db;
1008
+ const now = Number(nowMs ?? Date.now());
1009
+ const flipped = [];
1010
+ for (const rec of _proposerStatesV2.values()) {
1011
+ if (rec.status !== "active" && rec.status !== "suspended") continue;
1012
+ if (now - rec.lastActivityAt > _proposerIdleMsV2) {
1013
+ rec.status = "retired";
1014
+ rec.updatedAt = now;
1015
+ rec.reason = "idle";
1016
+ flipped.push(rec.proposerId);
1017
+ }
1018
+ }
1019
+ return flipped;
1020
+ }
1021
+
1022
+ export function autoExpireStalePendingDelegations(db, nowMs) {
1023
+ void db;
1024
+ const now = Number(nowMs ?? Date.now());
1025
+ const flipped = [];
1026
+ for (const rec of _delegationStatesV2.values()) {
1027
+ if (rec.status !== "pending") continue;
1028
+ if (now - rec.createdAt > _pendingDelegationMsV2) {
1029
+ rec.status = "expired";
1030
+ rec.updatedAt = now;
1031
+ rec.reason = "pending_timeout";
1032
+ flipped.push(rec.delegationId);
1033
+ }
1034
+ }
1035
+ return flipped;
1036
+ }
1037
+
1038
+ /* ── Stats V2 ───────────────────────────────────────────────── */
1039
+
1040
+ export function getGovernanceStatsV2() {
1041
+ const proposersByStatus = {
1042
+ onboarding: 0,
1043
+ active: 0,
1044
+ suspended: 0,
1045
+ retired: 0,
1046
+ };
1047
+ const delegationsByStatus = {
1048
+ pending: 0,
1049
+ active: 0,
1050
+ revoked: 0,
1051
+ expired: 0,
1052
+ };
1053
+ for (const rec of _proposerStatesV2.values()) {
1054
+ if (proposersByStatus[rec.status] !== undefined) {
1055
+ proposersByStatus[rec.status] += 1;
1056
+ }
1057
+ }
1058
+ for (const rec of _delegationStatesV2.values()) {
1059
+ if (delegationsByStatus[rec.status] !== undefined) {
1060
+ delegationsByStatus[rec.status] += 1;
1061
+ }
1062
+ }
1063
+ return {
1064
+ totalProposersV2: _proposerStatesV2.size,
1065
+ totalDelegationsV2: _delegationStatesV2.size,
1066
+ maxActiveProposersPerRealm: _maxActiveProposersPerRealmV2,
1067
+ maxActiveDelegationsPerDelegator: _maxActiveDelegationsPerDelegatorV2,
1068
+ proposerIdleMs: _proposerIdleMsV2,
1069
+ pendingDelegationMs: _pendingDelegationMsV2,
1070
+ proposersByStatus,
1071
+ delegationsByStatus,
1072
+ };
1073
+ }
1074
+
1075
+ /* ── Reset V2 (tests) ───────────────────────────────────────── */
1076
+
1077
+ export function _resetStateV2() {
1078
+ _proposerStatesV2.clear();
1079
+ _delegationStatesV2.clear();
1080
+ _maxActiveProposersPerRealmV2 = GOV_DEFAULT_MAX_ACTIVE_PROPOSERS_PER_REALM;
1081
+ _maxActiveDelegationsPerDelegatorV2 =
1082
+ GOV_DEFAULT_MAX_ACTIVE_DELEGATIONS_PER_DELEGATOR;
1083
+ _proposerIdleMsV2 = GOV_DEFAULT_PROPOSER_IDLE_MS;
1084
+ _pendingDelegationMsV2 = GOV_DEFAULT_PENDING_DELEGATION_MS;
1085
+ }