chainlesschain 0.81.0 → 0.143.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 (209) hide show
  1. package/bin/chainlesschain.js +0 -0
  2. package/package.json +1 -1
  3. package/src/commands/a2a.js +62 -0
  4. package/src/commands/activitypub.js +61 -0
  5. package/src/commands/agent-network.js +254 -1
  6. package/src/commands/agent.js +117 -0
  7. package/src/commands/audit.js +302 -0
  8. package/src/commands/automation.js +271 -1
  9. package/src/commands/bi.js +61 -0
  10. package/src/commands/bm25.js +78 -0
  11. package/src/commands/browse.js +64 -0
  12. package/src/commands/ccron.js +78 -0
  13. package/src/commands/codegen.js +224 -0
  14. package/src/commands/collab.js +341 -0
  15. package/src/commands/compliance.js +1075 -0
  16. package/src/commands/compt.js +78 -0
  17. package/src/commands/consol.js +231 -0
  18. package/src/commands/cowork.js +263 -0
  19. package/src/commands/crosschain.js +62 -0
  20. package/src/commands/dao.js +62 -0
  21. package/src/commands/dbevo.js +284 -0
  22. package/src/commands/dev.js +252 -0
  23. package/src/commands/did.js +358 -0
  24. package/src/commands/dlp.js +61 -0
  25. package/src/commands/economy.js +56 -0
  26. package/src/commands/encrypt.js +341 -0
  27. package/src/commands/evolution.js +56 -0
  28. package/src/commands/evomap.js +61 -0
  29. package/src/commands/export.js +256 -1
  30. package/src/commands/fflag.js +178 -0
  31. package/src/commands/fusion.js +258 -0
  32. package/src/commands/git.js +45 -0
  33. package/src/commands/governance.js +325 -0
  34. package/src/commands/hardening.js +411 -0
  35. package/src/commands/hmemory.js +56 -0
  36. package/src/commands/hook.js +148 -0
  37. package/src/commands/import.js +252 -0
  38. package/src/commands/incentive.js +322 -0
  39. package/src/commands/inference.js +42 -0
  40. package/src/commands/infra.js +244 -0
  41. package/src/commands/instinct.js +260 -0
  42. package/src/commands/ipfs.js +318 -0
  43. package/src/commands/itbudget.js +45 -0
  44. package/src/commands/kg.js +387 -0
  45. package/src/commands/llm.js +263 -0
  46. package/src/commands/lowcode.js +44 -0
  47. package/src/commands/matrix.js +62 -0
  48. package/src/commands/mcp.js +221 -0
  49. package/src/commands/mcpscaf.js +41 -0
  50. package/src/commands/meminj.js +41 -0
  51. package/src/commands/memory.js +248 -0
  52. package/src/commands/multimodal.js +296 -0
  53. package/src/commands/nlprog.js +356 -0
  54. package/src/commands/nostr.js +62 -0
  55. package/src/commands/note.js +244 -0
  56. package/src/commands/ops.js +354 -0
  57. package/src/commands/orchestrate.js +166 -0
  58. package/src/commands/orchgov.js +45 -0
  59. package/src/commands/org.js +277 -0
  60. package/src/commands/p2p.js +390 -0
  61. package/src/commands/pdfp.js +78 -0
  62. package/src/commands/perception.js +290 -0
  63. package/src/commands/perf.js +39 -0
  64. package/src/commands/perm.js +45 -0
  65. package/src/commands/permmem.js +251 -0
  66. package/src/commands/pipeline.js +57 -1
  67. package/src/commands/planmode.js +45 -0
  68. package/src/commands/plugin-ecosystem.js +273 -0
  69. package/src/commands/pqc.js +393 -0
  70. package/src/commands/promcomp.js +82 -0
  71. package/src/commands/quantization.js +351 -0
  72. package/src/commands/rcache.js +271 -0
  73. package/src/commands/recommend.js +382 -0
  74. package/src/commands/runtime.js +307 -0
  75. package/src/commands/scim.js +262 -0
  76. package/src/commands/seshhook.js +41 -0
  77. package/src/commands/seshsearch.js +41 -0
  78. package/src/commands/seshtail.js +41 -0
  79. package/src/commands/seshu.js +41 -0
  80. package/src/commands/session.js +258 -0
  81. package/src/commands/sganal.js +78 -0
  82. package/src/commands/siem.js +40 -0
  83. package/src/commands/skill.js +267 -1
  84. package/src/commands/slotfill.js +41 -0
  85. package/src/commands/social.js +290 -0
  86. package/src/commands/sso.js +186 -1
  87. package/src/commands/svccont.js +45 -0
  88. package/src/commands/sync.js +256 -0
  89. package/src/commands/tech.js +338 -0
  90. package/src/commands/tenant.js +351 -0
  91. package/src/commands/tms.js +45 -0
  92. package/src/commands/tokens.js +269 -0
  93. package/src/commands/topiccls.js +45 -0
  94. package/src/commands/trust.js +249 -0
  95. package/src/commands/uprof.js +45 -0
  96. package/src/commands/vcheck.js +78 -0
  97. package/src/commands/wallet.js +277 -0
  98. package/src/commands/webfetch.js +41 -0
  99. package/src/commands/workflow.js +171 -0
  100. package/src/commands/zkp.js +62 -0
  101. package/src/harness/prompt-compressor.js +331 -0
  102. package/src/index.js +65 -1
  103. package/src/lib/a2a-protocol.js +105 -0
  104. package/src/lib/activitypub-bridge.js +105 -0
  105. package/src/lib/agent-coordinator.js +325 -0
  106. package/src/lib/agent-economy.js +105 -0
  107. package/src/lib/agent-network.js +387 -0
  108. package/src/lib/agent-router.js +395 -0
  109. package/src/lib/aiops.js +478 -0
  110. package/src/lib/app-builder.js +105 -0
  111. package/src/lib/audit-logger.js +379 -0
  112. package/src/lib/automation-engine.js +330 -0
  113. package/src/lib/autonomous-agent.js +105 -0
  114. package/src/lib/autonomous-developer.js +350 -0
  115. package/src/lib/bi-engine.js +105 -0
  116. package/src/lib/bm25-search.js +81 -0
  117. package/src/lib/browser-automation.js +105 -0
  118. package/src/lib/code-agent.js +323 -0
  119. package/src/lib/collaboration-governance.js +364 -0
  120. package/src/lib/community-governance.js +436 -0
  121. package/src/lib/compliance-framework-reporter.js +105 -0
  122. package/src/lib/compliance-manager.js +434 -0
  123. package/src/lib/compression-telemetry.js +81 -0
  124. package/src/lib/content-recommendation.js +469 -0
  125. package/src/lib/content-recommender.js +105 -0
  126. package/src/lib/cowork-cron.js +81 -0
  127. package/src/lib/cowork-task-runner.js +105 -0
  128. package/src/lib/cross-chain.js +105 -0
  129. package/src/lib/crypto-manager.js +350 -0
  130. package/src/lib/dao-governance.js +105 -0
  131. package/src/lib/dbevo.js +338 -0
  132. package/src/lib/decentral-infra.js +340 -0
  133. package/src/lib/did-manager.js +367 -0
  134. package/src/lib/dlp-engine.js +105 -0
  135. package/src/lib/evolution-system.js +105 -0
  136. package/src/lib/evomap-manager.js +105 -0
  137. package/src/lib/execution-backend.js +105 -0
  138. package/src/lib/feature-flags.js +85 -0
  139. package/src/lib/git-integration.js +105 -0
  140. package/src/lib/hardening-manager.js +348 -0
  141. package/src/lib/hierarchical-memory.js +105 -0
  142. package/src/lib/hook-manager.js +380 -0
  143. package/src/lib/inference-network.js +105 -0
  144. package/src/lib/instinct-manager.js +332 -0
  145. package/src/lib/ipfs-storage.js +334 -0
  146. package/src/lib/iteration-budget.js +105 -0
  147. package/src/lib/knowledge-exporter.js +381 -0
  148. package/src/lib/knowledge-graph.js +432 -0
  149. package/src/lib/knowledge-importer.js +379 -0
  150. package/src/lib/llm-providers.js +391 -0
  151. package/src/lib/matrix-bridge.js +105 -0
  152. package/src/lib/mcp-registry.js +333 -0
  153. package/src/lib/mcp-scaffold.js +81 -0
  154. package/src/lib/memory-injection.js +81 -0
  155. package/src/lib/memory-manager.js +330 -0
  156. package/src/lib/multimodal.js +346 -0
  157. package/src/lib/nl-programming.js +343 -0
  158. package/src/lib/nostr-bridge.js +105 -0
  159. package/src/lib/note-versioning.js +327 -0
  160. package/src/lib/orchestrator.js +105 -0
  161. package/src/lib/org-manager.js +323 -0
  162. package/src/lib/p2p-manager.js +387 -0
  163. package/src/lib/pdf-parser.js +81 -0
  164. package/src/lib/perception.js +346 -0
  165. package/src/lib/perf-tuning.js +109 -1
  166. package/src/lib/permanent-memory.js +320 -0
  167. package/src/lib/permission-engine.js +81 -0
  168. package/src/lib/pipeline-orchestrator.js +105 -0
  169. package/src/lib/plan-mode.js +81 -0
  170. package/src/lib/plugin-ecosystem.js +377 -0
  171. package/src/lib/pqc-manager.js +368 -0
  172. package/src/lib/prompt-compressor.js +1 -10
  173. package/src/lib/protocol-fusion.js +417 -0
  174. package/src/lib/quantization.js +325 -0
  175. package/src/lib/response-cache.js +327 -0
  176. package/src/lib/scim-manager.js +329 -0
  177. package/src/lib/service-container.js +81 -0
  178. package/src/lib/session-consolidator.js +105 -0
  179. package/src/lib/session-hooks.js +81 -0
  180. package/src/lib/session-manager.js +329 -0
  181. package/src/lib/session-search.js +81 -0
  182. package/src/lib/session-tail.js +81 -0
  183. package/src/lib/session-usage.js +83 -0
  184. package/src/lib/siem-exporter.js +105 -0
  185. package/src/lib/skill-loader.js +377 -0
  186. package/src/lib/slot-filler.js +81 -0
  187. package/src/lib/social-graph-analytics.js +81 -0
  188. package/src/lib/social-graph.js +81 -0
  189. package/src/lib/social-manager.js +326 -0
  190. package/src/lib/sso-manager.js +332 -0
  191. package/src/lib/sub-agent-registry.js +110 -0
  192. package/src/lib/sync-manager.js +326 -0
  193. package/src/lib/task-model-selector.js +81 -0
  194. package/src/lib/tech-learning-engine.js +369 -0
  195. package/src/lib/tenant-saas.js +460 -0
  196. package/src/lib/threat-intel.js +335 -0
  197. package/src/lib/todo-manager.js +105 -0
  198. package/src/lib/token-incentive.js +293 -0
  199. package/src/lib/token-tracker.js +329 -0
  200. package/src/lib/topic-classifier.js +105 -0
  201. package/src/lib/trust-security.js +390 -0
  202. package/src/lib/ueba.js +389 -0
  203. package/src/lib/universal-runtime.js +325 -0
  204. package/src/lib/user-profile.js +81 -0
  205. package/src/lib/version-checker.js +81 -0
  206. package/src/lib/wallet-manager.js +326 -0
  207. package/src/lib/web-fetch.js +81 -0
  208. package/src/lib/workflow-engine.js +322 -0
  209. package/src/lib/zkp-engine.js +105 -0
@@ -863,3 +863,108 @@ export function _resetState() {
863
863
  maxSingleAllocation: 100000,
864
864
  };
865
865
  }
866
+
867
+
868
+ // ===== V2 Surface: DAO Governance overlay (CLI v0.136.0) =====
869
+ export const DAO_ORG_MATURITY_V2 = Object.freeze({
870
+ PENDING: "pending", ACTIVE: "active", PAUSED: "paused", DISSOLVED: "dissolved",
871
+ });
872
+ export const DAO_PROPOSAL_LIFECYCLE_V2 = Object.freeze({
873
+ QUEUED: "queued", VOTING: "voting", PASSED: "passed", FAILED: "failed", CANCELLED: "cancelled",
874
+ });
875
+
876
+ const _daoOrgTrans = new Map([
877
+ [DAO_ORG_MATURITY_V2.PENDING, new Set([DAO_ORG_MATURITY_V2.ACTIVE, DAO_ORG_MATURITY_V2.DISSOLVED])],
878
+ [DAO_ORG_MATURITY_V2.ACTIVE, new Set([DAO_ORG_MATURITY_V2.PAUSED, DAO_ORG_MATURITY_V2.DISSOLVED])],
879
+ [DAO_ORG_MATURITY_V2.PAUSED, new Set([DAO_ORG_MATURITY_V2.ACTIVE, DAO_ORG_MATURITY_V2.DISSOLVED])],
880
+ [DAO_ORG_MATURITY_V2.DISSOLVED, new Set()],
881
+ ]);
882
+ const _daoOrgTerminal = new Set([DAO_ORG_MATURITY_V2.DISSOLVED]);
883
+ const _daoPropTrans = new Map([
884
+ [DAO_PROPOSAL_LIFECYCLE_V2.QUEUED, new Set([DAO_PROPOSAL_LIFECYCLE_V2.VOTING, DAO_PROPOSAL_LIFECYCLE_V2.CANCELLED])],
885
+ [DAO_PROPOSAL_LIFECYCLE_V2.VOTING, new Set([DAO_PROPOSAL_LIFECYCLE_V2.PASSED, DAO_PROPOSAL_LIFECYCLE_V2.FAILED, DAO_PROPOSAL_LIFECYCLE_V2.CANCELLED])],
886
+ [DAO_PROPOSAL_LIFECYCLE_V2.PASSED, new Set()],
887
+ [DAO_PROPOSAL_LIFECYCLE_V2.FAILED, new Set()],
888
+ [DAO_PROPOSAL_LIFECYCLE_V2.CANCELLED, new Set()],
889
+ ]);
890
+
891
+ const _daoOrgs = new Map();
892
+ const _daoProps = new Map();
893
+ let _daoMaxActivePerOwner = 8;
894
+ let _daoMaxPendingPerOrg = 50;
895
+ let _daoOrgIdleMs = 7 * 24 * 60 * 60 * 1000;
896
+ let _daoPropStuckMs = 2 * 60 * 1000;
897
+
898
+ function _daoPos(n, lbl) { const v = Math.floor(Number(n)); if (!Number.isFinite(v) || v <= 0) throw new Error(`${lbl} must be positive integer`); return v; }
899
+
900
+ export function setMaxActiveDaoOrgsPerOwnerV2(n) { _daoMaxActivePerOwner = _daoPos(n, "maxActiveDaoOrgsPerOwner"); }
901
+ export function getMaxActiveDaoOrgsPerOwnerV2() { return _daoMaxActivePerOwner; }
902
+ export function setMaxPendingDaoProposalsPerOrgV2(n) { _daoMaxPendingPerOrg = _daoPos(n, "maxPendingDaoProposalsPerOrg"); }
903
+ export function getMaxPendingDaoProposalsPerOrgV2() { return _daoMaxPendingPerOrg; }
904
+ export function setDaoOrgIdleMsV2(n) { _daoOrgIdleMs = _daoPos(n, "daoOrgIdleMs"); }
905
+ export function getDaoOrgIdleMsV2() { return _daoOrgIdleMs; }
906
+ export function setDaoProposalStuckMsV2(n) { _daoPropStuckMs = _daoPos(n, "daoProposalStuckMs"); }
907
+ export function getDaoProposalStuckMsV2() { return _daoPropStuckMs; }
908
+
909
+ export function _resetStateDaoGovernanceV2() {
910
+ _daoOrgs.clear(); _daoProps.clear();
911
+ _daoMaxActivePerOwner = 8; _daoMaxPendingPerOrg = 50;
912
+ _daoOrgIdleMs = 7 * 24 * 60 * 60 * 1000; _daoPropStuckMs = 2 * 60 * 1000;
913
+ }
914
+
915
+ export function registerDaoOrgV2({ id, owner, name, metadata } = {}) {
916
+ if (!id || typeof id !== "string") throw new Error("id is required");
917
+ if (!owner || typeof owner !== "string") throw new Error("owner is required");
918
+ if (_daoOrgs.has(id)) throw new Error(`dao org ${id} already registered`);
919
+ const now = Date.now();
920
+ const o = { id, owner, name: name || id, status: DAO_ORG_MATURITY_V2.PENDING, createdAt: now, updatedAt: now, activatedAt: null, dissolvedAt: null, lastTouchedAt: now, metadata: { ...(metadata || {}) } };
921
+ _daoOrgs.set(id, o);
922
+ return { ...o, metadata: { ...o.metadata } };
923
+ }
924
+ function _daoCheckO(from, to) { const a = _daoOrgTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid dao org transition ${from} → ${to}`); }
925
+ function _daoCountActive(owner) { let n = 0; for (const o of _daoOrgs.values()) if (o.owner === owner && o.status === DAO_ORG_MATURITY_V2.ACTIVE) n++; return n; }
926
+
927
+ export function activateDaoOrgV2(id) {
928
+ const o = _daoOrgs.get(id); if (!o) throw new Error(`dao org ${id} not found`);
929
+ _daoCheckO(o.status, DAO_ORG_MATURITY_V2.ACTIVE);
930
+ const recovery = o.status === DAO_ORG_MATURITY_V2.PAUSED;
931
+ if (!recovery) { const a = _daoCountActive(o.owner); if (a >= _daoMaxActivePerOwner) throw new Error(`max active dao orgs per owner (${_daoMaxActivePerOwner}) reached for ${o.owner}`); }
932
+ const now = Date.now(); o.status = DAO_ORG_MATURITY_V2.ACTIVE; o.updatedAt = now; o.lastTouchedAt = now; if (!o.activatedAt) o.activatedAt = now;
933
+ return { ...o, metadata: { ...o.metadata } };
934
+ }
935
+ export function pauseDaoOrgV2(id) { const o = _daoOrgs.get(id); if (!o) throw new Error(`dao org ${id} not found`); _daoCheckO(o.status, DAO_ORG_MATURITY_V2.PAUSED); o.status = DAO_ORG_MATURITY_V2.PAUSED; o.updatedAt = Date.now(); return { ...o, metadata: { ...o.metadata } }; }
936
+ export function dissolveDaoOrgV2(id) { const o = _daoOrgs.get(id); if (!o) throw new Error(`dao org ${id} not found`); _daoCheckO(o.status, DAO_ORG_MATURITY_V2.DISSOLVED); const now = Date.now(); o.status = DAO_ORG_MATURITY_V2.DISSOLVED; o.updatedAt = now; if (!o.dissolvedAt) o.dissolvedAt = now; return { ...o, metadata: { ...o.metadata } }; }
937
+ export function touchDaoOrgV2(id) { const o = _daoOrgs.get(id); if (!o) throw new Error(`dao org ${id} not found`); if (_daoOrgTerminal.has(o.status)) throw new Error(`cannot touch terminal dao org ${id}`); const now = Date.now(); o.lastTouchedAt = now; o.updatedAt = now; return { ...o, metadata: { ...o.metadata } }; }
938
+ export function getDaoOrgV2(id) { const o = _daoOrgs.get(id); if (!o) return null; return { ...o, metadata: { ...o.metadata } }; }
939
+ export function listDaoOrgsV2() { return [..._daoOrgs.values()].map((o) => ({ ...o, metadata: { ...o.metadata } })); }
940
+
941
+ function _daoCountPending(oid) { let n = 0; for (const p of _daoProps.values()) if (p.orgId === oid && (p.status === DAO_PROPOSAL_LIFECYCLE_V2.QUEUED || p.status === DAO_PROPOSAL_LIFECYCLE_V2.VOTING)) n++; return n; }
942
+
943
+ export function createDaoProposalV2({ id, orgId, title, metadata } = {}) {
944
+ if (!id || typeof id !== "string") throw new Error("id is required");
945
+ if (!orgId || typeof orgId !== "string") throw new Error("orgId is required");
946
+ if (_daoProps.has(id)) throw new Error(`dao proposal ${id} already exists`);
947
+ if (!_daoOrgs.has(orgId)) throw new Error(`dao org ${orgId} not found`);
948
+ const pending = _daoCountPending(orgId);
949
+ if (pending >= _daoMaxPendingPerOrg) throw new Error(`max pending dao proposals per org (${_daoMaxPendingPerOrg}) reached for ${orgId}`);
950
+ const now = Date.now();
951
+ const p = { id, orgId, title: title || id, status: DAO_PROPOSAL_LIFECYCLE_V2.QUEUED, createdAt: now, updatedAt: now, startedAt: null, settledAt: null, metadata: { ...(metadata || {}) } };
952
+ _daoProps.set(id, p);
953
+ return { ...p, metadata: { ...p.metadata } };
954
+ }
955
+ function _daoCheckP(from, to) { const a = _daoPropTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid dao proposal transition ${from} → ${to}`); }
956
+ export function startDaoProposalV2(id) { const p = _daoProps.get(id); if (!p) throw new Error(`dao proposal ${id} not found`); _daoCheckP(p.status, DAO_PROPOSAL_LIFECYCLE_V2.VOTING); const now = Date.now(); p.status = DAO_PROPOSAL_LIFECYCLE_V2.VOTING; p.updatedAt = now; if (!p.startedAt) p.startedAt = now; return { ...p, metadata: { ...p.metadata } }; }
957
+ export function passDaoProposalV2(id) { const p = _daoProps.get(id); if (!p) throw new Error(`dao proposal ${id} not found`); _daoCheckP(p.status, DAO_PROPOSAL_LIFECYCLE_V2.PASSED); const now = Date.now(); p.status = DAO_PROPOSAL_LIFECYCLE_V2.PASSED; p.updatedAt = now; if (!p.settledAt) p.settledAt = now; return { ...p, metadata: { ...p.metadata } }; }
958
+ export function failDaoProposalV2(id, reason) { const p = _daoProps.get(id); if (!p) throw new Error(`dao proposal ${id} not found`); _daoCheckP(p.status, DAO_PROPOSAL_LIFECYCLE_V2.FAILED); const now = Date.now(); p.status = DAO_PROPOSAL_LIFECYCLE_V2.FAILED; p.updatedAt = now; if (!p.settledAt) p.settledAt = now; if (reason) p.metadata.failReason = String(reason); return { ...p, metadata: { ...p.metadata } }; }
959
+ export function cancelDaoProposalV2(id, reason) { const p = _daoProps.get(id); if (!p) throw new Error(`dao proposal ${id} not found`); _daoCheckP(p.status, DAO_PROPOSAL_LIFECYCLE_V2.CANCELLED); const now = Date.now(); p.status = DAO_PROPOSAL_LIFECYCLE_V2.CANCELLED; p.updatedAt = now; if (!p.settledAt) p.settledAt = now; if (reason) p.metadata.cancelReason = String(reason); return { ...p, metadata: { ...p.metadata } }; }
960
+ export function getDaoProposalV2(id) { const p = _daoProps.get(id); if (!p) return null; return { ...p, metadata: { ...p.metadata } }; }
961
+ export function listDaoProposalsV2() { return [..._daoProps.values()].map((p) => ({ ...p, metadata: { ...p.metadata } })); }
962
+
963
+ export function autoPauseIdleDaoOrgsV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const o of _daoOrgs.values()) if (o.status === DAO_ORG_MATURITY_V2.ACTIVE && (t - o.lastTouchedAt) >= _daoOrgIdleMs) { o.status = DAO_ORG_MATURITY_V2.PAUSED; o.updatedAt = t; flipped.push(o.id); } return { flipped, count: flipped.length }; }
964
+ export function autoFailStuckDaoProposalsV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const p of _daoProps.values()) if (p.status === DAO_PROPOSAL_LIFECYCLE_V2.VOTING && p.startedAt != null && (t - p.startedAt) >= _daoPropStuckMs) { p.status = DAO_PROPOSAL_LIFECYCLE_V2.FAILED; p.updatedAt = t; if (!p.settledAt) p.settledAt = t; p.metadata.failReason = "auto-fail-stuck"; flipped.push(p.id); } return { flipped, count: flipped.length }; }
965
+
966
+ export function getDaoGovernanceGovStatsV2() {
967
+ const orgsByStatus = {}; for (const s of Object.values(DAO_ORG_MATURITY_V2)) orgsByStatus[s] = 0; for (const o of _daoOrgs.values()) orgsByStatus[o.status]++;
968
+ const proposalsByStatus = {}; for (const s of Object.values(DAO_PROPOSAL_LIFECYCLE_V2)) proposalsByStatus[s] = 0; for (const p of _daoProps.values()) proposalsByStatus[p.status]++;
969
+ return { totalOrgsV2: _daoOrgs.size, totalProposalsV2: _daoProps.size, maxActiveDaoOrgsPerOwner: _daoMaxActivePerOwner, maxPendingDaoProposalsPerOrg: _daoMaxPendingPerOrg, daoOrgIdleMs: _daoOrgIdleMs, daoProposalStuckMs: _daoPropStuckMs, orgsByStatus, proposalsByStatus };
970
+ }
package/src/lib/dbevo.js CHANGED
@@ -667,3 +667,341 @@ export function _resetState() {
667
667
  _suggestions.clear();
668
668
  _slowQueryThresholdMs = 100;
669
669
  }
670
+
671
+ /* ═════════════════════════════════════════════════════════ *
672
+ * Phase 80 V2 — Schema Baseline + Migration-Run Lifecycle
673
+ * ═════════════════════════════════════════════════════════ */
674
+
675
+ export const SCHEMA_BASELINE_V2 = Object.freeze({
676
+ DRAFT: "draft",
677
+ VALIDATED: "validated",
678
+ ACTIVE: "active",
679
+ DEPRECATED: "deprecated",
680
+ RETIRED: "retired",
681
+ });
682
+
683
+ export const MIGRATION_RUN_V2 = Object.freeze({
684
+ QUEUED: "queued",
685
+ RUNNING: "running",
686
+ APPLIED: "applied",
687
+ FAILED: "failed",
688
+ ROLLED_BACK: "rolled_back",
689
+ });
690
+
691
+ const BASELINE_TRANSITIONS_V2 = new Map([
692
+ ["draft", new Set(["validated", "retired"])],
693
+ ["validated", new Set(["active", "retired"])],
694
+ ["active", new Set(["deprecated", "retired"])],
695
+ ["deprecated", new Set(["active", "retired"])],
696
+ ]);
697
+ const BASELINE_TERMINALS_V2 = new Set(["retired"]);
698
+
699
+ const RUN_TRANSITIONS_V2 = new Map([
700
+ ["queued", new Set(["running", "failed"])],
701
+ ["running", new Set(["applied", "failed", "rolled_back"])],
702
+ ["applied", new Set(["rolled_back"])],
703
+ ]);
704
+ const RUN_TERMINALS_V2 = new Set(["failed", "rolled_back"]);
705
+
706
+ export const DBEVO_DEFAULT_MAX_ACTIVE_BASELINES_PER_DB = 1;
707
+ export const DBEVO_DEFAULT_MAX_RUNNING_MIGRATIONS_PER_DB = 1;
708
+ export const DBEVO_DEFAULT_BASELINE_IDLE_MS = 180 * 86400000; // 180 days
709
+ export const DBEVO_DEFAULT_MIGRATION_STUCK_MS = 30 * 60000; // 30 minutes
710
+
711
+ let _maxActiveBaselinesPerDbV2 = DBEVO_DEFAULT_MAX_ACTIVE_BASELINES_PER_DB;
712
+ let _maxRunningMigrationsPerDbV2 = DBEVO_DEFAULT_MAX_RUNNING_MIGRATIONS_PER_DB;
713
+ let _baselineIdleMsV2 = DBEVO_DEFAULT_BASELINE_IDLE_MS;
714
+ let _migrationStuckMsV2 = DBEVO_DEFAULT_MIGRATION_STUCK_MS;
715
+
716
+ function _positiveIntV2(n, label) {
717
+ const v = Math.floor(Number(n));
718
+ if (!Number.isFinite(v) || v <= 0)
719
+ throw new Error(`${label} must be a positive integer`);
720
+ return v;
721
+ }
722
+
723
+ export function getDefaultMaxActiveBaselinesPerDbV2() {
724
+ return DBEVO_DEFAULT_MAX_ACTIVE_BASELINES_PER_DB;
725
+ }
726
+ export function getMaxActiveBaselinesPerDbV2() {
727
+ return _maxActiveBaselinesPerDbV2;
728
+ }
729
+ export function setMaxActiveBaselinesPerDbV2(n) {
730
+ return (_maxActiveBaselinesPerDbV2 = _positiveIntV2(
731
+ n,
732
+ "maxActiveBaselinesPerDb",
733
+ ));
734
+ }
735
+ export function getDefaultMaxRunningMigrationsPerDbV2() {
736
+ return DBEVO_DEFAULT_MAX_RUNNING_MIGRATIONS_PER_DB;
737
+ }
738
+ export function getMaxRunningMigrationsPerDbV2() {
739
+ return _maxRunningMigrationsPerDbV2;
740
+ }
741
+ export function setMaxRunningMigrationsPerDbV2(n) {
742
+ return (_maxRunningMigrationsPerDbV2 = _positiveIntV2(
743
+ n,
744
+ "maxRunningMigrationsPerDb",
745
+ ));
746
+ }
747
+ export function getDefaultBaselineIdleMsV2() {
748
+ return DBEVO_DEFAULT_BASELINE_IDLE_MS;
749
+ }
750
+ export function getBaselineIdleMsV2() {
751
+ return _baselineIdleMsV2;
752
+ }
753
+ export function setBaselineIdleMsV2(ms) {
754
+ return (_baselineIdleMsV2 = _positiveIntV2(ms, "baselineIdleMs"));
755
+ }
756
+ export function getDefaultMigrationStuckMsV2() {
757
+ return DBEVO_DEFAULT_MIGRATION_STUCK_MS;
758
+ }
759
+ export function getMigrationStuckMsV2() {
760
+ return _migrationStuckMsV2;
761
+ }
762
+ export function setMigrationStuckMsV2(ms) {
763
+ return (_migrationStuckMsV2 = _positiveIntV2(ms, "migrationStuckMs"));
764
+ }
765
+
766
+ const _baselinesV2 = new Map();
767
+ const _runsV2 = new Map();
768
+
769
+ export function registerBaselineV2(
770
+ _db,
771
+ { baselineId, databaseId, version, initialStatus, metadata } = {},
772
+ ) {
773
+ if (!baselineId) throw new Error("baselineId is required");
774
+ if (!databaseId) throw new Error("databaseId is required");
775
+ if (!version) throw new Error("version is required");
776
+ if (_baselinesV2.has(baselineId))
777
+ throw new Error(`Baseline ${baselineId} already exists`);
778
+ const status = initialStatus || SCHEMA_BASELINE_V2.DRAFT;
779
+ if (!Object.values(SCHEMA_BASELINE_V2).includes(status))
780
+ throw new Error(`Invalid initial status: ${status}`);
781
+ if (BASELINE_TERMINALS_V2.has(status))
782
+ throw new Error(`Cannot register in terminal status: ${status}`);
783
+ if (status === SCHEMA_BASELINE_V2.ACTIVE) {
784
+ if (getActiveBaselineCount(databaseId) >= _maxActiveBaselinesPerDbV2)
785
+ throw new Error(
786
+ `Database ${databaseId} reached active-baseline cap (${_maxActiveBaselinesPerDbV2})`,
787
+ );
788
+ }
789
+ const now = Date.now();
790
+ const record = {
791
+ baselineId,
792
+ databaseId,
793
+ version,
794
+ status,
795
+ metadata: metadata || {},
796
+ createdAt: now,
797
+ updatedAt: now,
798
+ lastTouchedAt: now,
799
+ };
800
+ _baselinesV2.set(baselineId, record);
801
+ return { ...record, metadata: { ...record.metadata } };
802
+ }
803
+
804
+ export function getBaselineV2(baselineId) {
805
+ const r = _baselinesV2.get(baselineId);
806
+ return r ? { ...r, metadata: { ...r.metadata } } : null;
807
+ }
808
+
809
+ export function setBaselineStatusV2(_db, baselineId, newStatus, patch = {}) {
810
+ const record = _baselinesV2.get(baselineId);
811
+ if (!record) throw new Error(`Unknown baseline: ${baselineId}`);
812
+ if (!Object.values(SCHEMA_BASELINE_V2).includes(newStatus))
813
+ throw new Error(`Invalid status: ${newStatus}`);
814
+ const allowed = BASELINE_TRANSITIONS_V2.get(record.status) || new Set();
815
+ if (!allowed.has(newStatus))
816
+ throw new Error(`Invalid transition: ${record.status} -> ${newStatus}`);
817
+ if (newStatus === SCHEMA_BASELINE_V2.ACTIVE) {
818
+ if (getActiveBaselineCount(record.databaseId) >= _maxActiveBaselinesPerDbV2)
819
+ throw new Error(
820
+ `Database ${record.databaseId} reached active-baseline cap (${_maxActiveBaselinesPerDbV2})`,
821
+ );
822
+ }
823
+ record.status = newStatus;
824
+ record.updatedAt = Date.now();
825
+ if (patch.reason !== undefined) record.lastReason = patch.reason;
826
+ if (patch.metadata)
827
+ record.metadata = { ...record.metadata, ...patch.metadata };
828
+ return { ...record, metadata: { ...record.metadata } };
829
+ }
830
+
831
+ export function validateBaseline(db, id, reason) {
832
+ return setBaselineStatusV2(db, id, SCHEMA_BASELINE_V2.VALIDATED, { reason });
833
+ }
834
+ export function activateBaseline(db, id, reason) {
835
+ return setBaselineStatusV2(db, id, SCHEMA_BASELINE_V2.ACTIVE, { reason });
836
+ }
837
+ export function deprecateBaseline(db, id, reason) {
838
+ return setBaselineStatusV2(db, id, SCHEMA_BASELINE_V2.DEPRECATED, { reason });
839
+ }
840
+ export function retireBaseline(db, id, reason) {
841
+ return setBaselineStatusV2(db, id, SCHEMA_BASELINE_V2.RETIRED, { reason });
842
+ }
843
+
844
+ export function touchBaselineActivity(baselineId) {
845
+ const record = _baselinesV2.get(baselineId);
846
+ if (!record) throw new Error(`Unknown baseline: ${baselineId}`);
847
+ record.lastTouchedAt = Date.now();
848
+ record.updatedAt = record.lastTouchedAt;
849
+ return { ...record, metadata: { ...record.metadata } };
850
+ }
851
+
852
+ export function enqueueMigrationRunV2(
853
+ _db,
854
+ { runId, databaseId, migrationId, direction, metadata } = {},
855
+ ) {
856
+ if (!runId) throw new Error("runId is required");
857
+ if (!databaseId) throw new Error("databaseId is required");
858
+ if (!migrationId) throw new Error("migrationId is required");
859
+ if (!direction) throw new Error("direction is required");
860
+ if (!Object.values(MIGRATION_DIRECTION).includes(direction))
861
+ throw new Error(`Invalid direction: ${direction}`);
862
+ if (_runsV2.has(runId)) throw new Error(`Run ${runId} already exists`);
863
+ const now = Date.now();
864
+ const record = {
865
+ runId,
866
+ databaseId,
867
+ migrationId,
868
+ direction,
869
+ status: MIGRATION_RUN_V2.QUEUED,
870
+ metadata: metadata || {},
871
+ createdAt: now,
872
+ updatedAt: now,
873
+ };
874
+ _runsV2.set(runId, record);
875
+ return { ...record, metadata: { ...record.metadata } };
876
+ }
877
+
878
+ export function getMigrationRunV2(runId) {
879
+ const r = _runsV2.get(runId);
880
+ return r ? { ...r, metadata: { ...r.metadata } } : null;
881
+ }
882
+
883
+ export function setMigrationRunStatusV2(_db, runId, newStatus, patch = {}) {
884
+ const record = _runsV2.get(runId);
885
+ if (!record) throw new Error(`Unknown run: ${runId}`);
886
+ if (!Object.values(MIGRATION_RUN_V2).includes(newStatus))
887
+ throw new Error(`Invalid status: ${newStatus}`);
888
+ const allowed = RUN_TRANSITIONS_V2.get(record.status) || new Set();
889
+ if (!allowed.has(newStatus))
890
+ throw new Error(`Invalid transition: ${record.status} -> ${newStatus}`);
891
+ if (newStatus === MIGRATION_RUN_V2.RUNNING) {
892
+ if (
893
+ getRunningMigrationCount(record.databaseId) >=
894
+ _maxRunningMigrationsPerDbV2
895
+ )
896
+ throw new Error(
897
+ `Database ${record.databaseId} reached running-migration cap (${_maxRunningMigrationsPerDbV2})`,
898
+ );
899
+ if (!record.startedAt) record.startedAt = Date.now();
900
+ }
901
+ record.status = newStatus;
902
+ record.updatedAt = Date.now();
903
+ if (patch.reason !== undefined) record.lastReason = patch.reason;
904
+ if (patch.metadata)
905
+ record.metadata = { ...record.metadata, ...patch.metadata };
906
+ return { ...record, metadata: { ...record.metadata } };
907
+ }
908
+
909
+ export function startMigrationRun(db, id, reason) {
910
+ return setMigrationRunStatusV2(db, id, MIGRATION_RUN_V2.RUNNING, { reason });
911
+ }
912
+ export function applyMigrationRun(db, id, reason) {
913
+ return setMigrationRunStatusV2(db, id, MIGRATION_RUN_V2.APPLIED, { reason });
914
+ }
915
+ export function failMigrationRun(db, id, reason) {
916
+ return setMigrationRunStatusV2(db, id, MIGRATION_RUN_V2.FAILED, { reason });
917
+ }
918
+ export function rollbackMigrationRun(db, id, reason) {
919
+ return setMigrationRunStatusV2(db, id, MIGRATION_RUN_V2.ROLLED_BACK, {
920
+ reason,
921
+ });
922
+ }
923
+
924
+ export function getActiveBaselineCount(databaseId) {
925
+ let n = 0;
926
+ for (const r of _baselinesV2.values()) {
927
+ if (r.status !== SCHEMA_BASELINE_V2.ACTIVE) continue;
928
+ if (databaseId && r.databaseId !== databaseId) continue;
929
+ n++;
930
+ }
931
+ return n;
932
+ }
933
+
934
+ export function getRunningMigrationCount(databaseId) {
935
+ let n = 0;
936
+ for (const r of _runsV2.values()) {
937
+ if (r.status !== MIGRATION_RUN_V2.RUNNING) continue;
938
+ if (databaseId && r.databaseId !== databaseId) continue;
939
+ n++;
940
+ }
941
+ return n;
942
+ }
943
+
944
+ export function autoRetireIdleBaselines(_db, nowMs) {
945
+ const now = nowMs ?? Date.now();
946
+ const flipped = [];
947
+ for (const r of _baselinesV2.values()) {
948
+ if (
949
+ r.status === SCHEMA_BASELINE_V2.DEPRECATED ||
950
+ r.status === SCHEMA_BASELINE_V2.DRAFT ||
951
+ r.status === SCHEMA_BASELINE_V2.VALIDATED
952
+ ) {
953
+ if (now - r.lastTouchedAt > _baselineIdleMsV2) {
954
+ r.status = SCHEMA_BASELINE_V2.RETIRED;
955
+ r.updatedAt = now;
956
+ r.lastReason = "idle_timeout";
957
+ flipped.push(r.baselineId);
958
+ }
959
+ }
960
+ }
961
+ return { flipped, count: flipped.length };
962
+ }
963
+
964
+ export function autoFailStuckMigrationRuns(_db, nowMs) {
965
+ const now = nowMs ?? Date.now();
966
+ const flipped = [];
967
+ for (const r of _runsV2.values()) {
968
+ if (r.status === MIGRATION_RUN_V2.RUNNING) {
969
+ const anchor = r.startedAt || r.createdAt;
970
+ if (now - anchor > _migrationStuckMsV2) {
971
+ r.status = MIGRATION_RUN_V2.FAILED;
972
+ r.updatedAt = now;
973
+ r.lastReason = "migration_timeout";
974
+ flipped.push(r.runId);
975
+ }
976
+ }
977
+ }
978
+ return { flipped, count: flipped.length };
979
+ }
980
+
981
+ export function getDbEvoStatsV2() {
982
+ const baselinesByStatus = {};
983
+ for (const s of Object.values(SCHEMA_BASELINE_V2)) baselinesByStatus[s] = 0;
984
+ const runsByStatus = {};
985
+ for (const s of Object.values(MIGRATION_RUN_V2)) runsByStatus[s] = 0;
986
+ for (const r of _baselinesV2.values()) baselinesByStatus[r.status]++;
987
+ for (const r of _runsV2.values()) runsByStatus[r.status]++;
988
+ return {
989
+ totalBaselinesV2: _baselinesV2.size,
990
+ totalRunsV2: _runsV2.size,
991
+ maxActiveBaselinesPerDb: _maxActiveBaselinesPerDbV2,
992
+ maxRunningMigrationsPerDb: _maxRunningMigrationsPerDbV2,
993
+ baselineIdleMs: _baselineIdleMsV2,
994
+ migrationStuckMs: _migrationStuckMsV2,
995
+ baselinesByStatus,
996
+ runsByStatus,
997
+ };
998
+ }
999
+
1000
+ export function _resetStateV2() {
1001
+ _maxActiveBaselinesPerDbV2 = DBEVO_DEFAULT_MAX_ACTIVE_BASELINES_PER_DB;
1002
+ _maxRunningMigrationsPerDbV2 = DBEVO_DEFAULT_MAX_RUNNING_MIGRATIONS_PER_DB;
1003
+ _baselineIdleMsV2 = DBEVO_DEFAULT_BASELINE_IDLE_MS;
1004
+ _migrationStuckMsV2 = DBEVO_DEFAULT_MIGRATION_STUCK_MS;
1005
+ _baselinesV2.clear();
1006
+ _runsV2.clear();
1007
+ }