chainlesschain 0.145.0 → 0.156.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 (184) hide show
  1. package/README.md +52 -3
  2. package/package.json +1 -1
  3. package/src/commands/a2a.js +201 -0
  4. package/src/commands/activitypub.js +207 -0
  5. package/src/commands/agent-network.js +217 -0
  6. package/src/commands/agent.js +1250 -0
  7. package/src/commands/automation.js +201 -0
  8. package/src/commands/bi.js +203 -0
  9. package/src/commands/browse.js +213 -0
  10. package/src/commands/chat.js +605 -0
  11. package/src/commands/cli-anything.js +426 -0
  12. package/src/commands/codegen.js +207 -0
  13. package/src/commands/collab.js +211 -0
  14. package/src/commands/compliance.js +822 -0
  15. package/src/commands/config.js +213 -0
  16. package/src/commands/cowork.js +1666 -0
  17. package/src/commands/crosschain.js +203 -0
  18. package/src/commands/dao.js +203 -0
  19. package/src/commands/dbevo.js +227 -0
  20. package/src/commands/dev.js +207 -0
  21. package/src/commands/did-v2.js +217 -0
  22. package/src/commands/did.js +221 -0
  23. package/src/commands/dlp.js +213 -0
  24. package/src/commands/economy.js +199 -0
  25. package/src/commands/encrypt.js +201 -0
  26. package/src/commands/evolution.js +199 -0
  27. package/src/commands/evomap.js +830 -0
  28. package/src/commands/export.js +213 -0
  29. package/src/commands/federation.js +209 -0
  30. package/src/commands/fusion.js +205 -0
  31. package/src/commands/governance.js +209 -0
  32. package/src/commands/hmemory.js +203 -0
  33. package/src/commands/hook.js +209 -0
  34. package/src/commands/import.js +209 -0
  35. package/src/commands/inference.js +207 -0
  36. package/src/commands/infra.js +203 -0
  37. package/src/commands/instinct.js +209 -0
  38. package/src/commands/ipfs.js +207 -0
  39. package/src/commands/kg.js +195 -0
  40. package/src/commands/llm.js +426 -0
  41. package/src/commands/matrix.js +207 -0
  42. package/src/commands/mcp.js +217 -0
  43. package/src/commands/memory.js +412 -0
  44. package/src/commands/multimodal.js +203 -0
  45. package/src/commands/nlprog.js +225 -0
  46. package/src/commands/nostr.js +209 -0
  47. package/src/commands/note.js +205 -0
  48. package/src/commands/ops.js +219 -0
  49. package/src/commands/orchestrate.js +406 -0
  50. package/src/commands/org.js +209 -0
  51. package/src/commands/p2p.js +209 -0
  52. package/src/commands/perception.js +209 -0
  53. package/src/commands/permmem.js +203 -0
  54. package/src/commands/pipeline.js +199 -0
  55. package/src/commands/planmode.js +426 -0
  56. package/src/commands/plugin-ecosystem.js +209 -0
  57. package/src/commands/plugin.js +209 -0
  58. package/src/commands/pqc.js +213 -0
  59. package/src/commands/quantization.js +207 -0
  60. package/src/commands/rcache.js +205 -0
  61. package/src/commands/recommend.js +233 -0
  62. package/src/commands/runtime.js +205 -0
  63. package/src/commands/scim.js +209 -0
  64. package/src/commands/services.js +207 -0
  65. package/src/commands/session.js +209 -0
  66. package/src/commands/setup.js +205 -0
  67. package/src/commands/skill.js +414 -0
  68. package/src/commands/social.js +201 -0
  69. package/src/commands/sso.js +209 -0
  70. package/src/commands/start.js +209 -0
  71. package/src/commands/stream.js +213 -0
  72. package/src/commands/sync.js +209 -0
  73. package/src/commands/tech.js +209 -0
  74. package/src/commands/tenant.js +217 -0
  75. package/src/commands/tokens.js +209 -0
  76. package/src/commands/trust.js +217 -0
  77. package/src/commands/ui.js +225 -0
  78. package/src/commands/wallet.js +209 -0
  79. package/src/commands/workflow.js +412 -0
  80. package/src/index.js +252 -0
  81. package/src/lib/a2a-protocol.js +332 -0
  82. package/src/lib/activitypub-bridge.js +334 -0
  83. package/src/lib/agent-coordinator.js +334 -0
  84. package/src/lib/agent-economy.js +334 -0
  85. package/src/lib/agent-network.js +341 -0
  86. package/src/lib/agent-router.js +333 -0
  87. package/src/lib/aiops.js +346 -0
  88. package/src/lib/automation-engine.js +335 -0
  89. package/src/lib/autonomous-agent.js +332 -0
  90. package/src/lib/autonomous-developer.js +332 -0
  91. package/src/lib/bi-engine.js +333 -0
  92. package/src/lib/browser-automation.js +334 -0
  93. package/src/lib/chat-core.js +335 -0
  94. package/src/lib/cli-anything-bridge.js +341 -0
  95. package/src/lib/cli-context-engineering.js +351 -0
  96. package/src/lib/code-agent.js +339 -0
  97. package/src/lib/collaboration-governance.js +334 -0
  98. package/src/lib/community-governance.js +346 -0
  99. package/src/lib/compliance-manager.js +334 -0
  100. package/src/lib/content-recommendation.js +351 -0
  101. package/src/lib/cowork-adapter.js +336 -0
  102. package/src/lib/cowork-evomap-adapter.js +341 -0
  103. package/src/lib/cowork-mcp-tools.js +341 -0
  104. package/src/lib/cowork-observe-html.js +341 -0
  105. package/src/lib/cowork-observe.js +341 -0
  106. package/src/lib/cowork-share.js +338 -0
  107. package/src/lib/cowork-task-templates.js +342 -1
  108. package/src/lib/cowork-template-marketplace.js +340 -0
  109. package/src/lib/cross-chain.js +339 -0
  110. package/src/lib/crypto-manager.js +334 -0
  111. package/src/lib/dao-governance.js +339 -0
  112. package/src/lib/dbevo.js +351 -0
  113. package/src/lib/decentral-infra.js +330 -0
  114. package/src/lib/did-manager.js +341 -0
  115. package/src/lib/did-v2-manager.js +341 -0
  116. package/src/lib/dlp-engine.js +339 -0
  117. package/src/lib/downloader.js +334 -0
  118. package/src/lib/evolution-system.js +334 -0
  119. package/src/lib/evomap-client.js +342 -0
  120. package/src/lib/evomap-federation.js +338 -0
  121. package/src/lib/evomap-governance.js +334 -0
  122. package/src/lib/evomap-manager.js +330 -0
  123. package/src/lib/execution-backend.js +330 -0
  124. package/src/lib/federation-hardening.js +340 -0
  125. package/src/lib/hashline.js +338 -0
  126. package/src/lib/hierarchical-memory.js +334 -0
  127. package/src/lib/hook-manager.js +341 -0
  128. package/src/lib/inference-network.js +341 -0
  129. package/src/lib/instinct-manager.js +346 -0
  130. package/src/lib/interaction-adapter.js +330 -0
  131. package/src/lib/interactive-planner.js +354 -0
  132. package/src/lib/ipfs-storage.js +334 -0
  133. package/src/lib/knowledge-exporter.js +341 -0
  134. package/src/lib/knowledge-graph.js +331 -0
  135. package/src/lib/knowledge-importer.js +341 -0
  136. package/src/lib/llm-providers.js +346 -0
  137. package/src/lib/matrix-bridge.js +339 -0
  138. package/src/lib/mcp-registry.js +346 -0
  139. package/src/lib/memory-manager.js +336 -0
  140. package/src/lib/multimodal.js +330 -0
  141. package/src/lib/nl-programming.js +341 -0
  142. package/src/lib/nostr-bridge.js +336 -0
  143. package/src/lib/note-versioning.js +339 -0
  144. package/src/lib/org-manager.js +336 -0
  145. package/src/lib/p2p-manager.js +341 -0
  146. package/src/lib/perception.js +346 -0
  147. package/src/lib/permanent-memory.js +327 -0
  148. package/src/lib/pipeline-orchestrator.js +332 -0
  149. package/src/lib/plan-mode.js +336 -0
  150. package/src/lib/plugin-autodiscovery.js +334 -0
  151. package/src/lib/plugin-ecosystem.js +346 -0
  152. package/src/lib/pqc-manager.js +346 -0
  153. package/src/lib/process-manager.js +336 -0
  154. package/src/lib/protocol-fusion.js +338 -0
  155. package/src/lib/provider-options.js +346 -0
  156. package/src/lib/provider-stream.js +348 -0
  157. package/src/lib/quantization.js +337 -0
  158. package/src/lib/response-cache.js +333 -0
  159. package/src/lib/scim-manager.js +346 -0
  160. package/src/lib/service-manager.js +337 -0
  161. package/src/lib/session-core-singletons.js +341 -0
  162. package/src/lib/session-manager.js +334 -0
  163. package/src/lib/skill-loader.js +334 -0
  164. package/src/lib/skill-mcp.js +336 -0
  165. package/src/lib/social-manager.js +330 -0
  166. package/src/lib/sso-manager.js +340 -0
  167. package/src/lib/stix-parser.js +346 -0
  168. package/src/lib/sub-agent-context.js +343 -0
  169. package/src/lib/sub-agent-profiles.js +335 -0
  170. package/src/lib/sub-agent-registry.js +336 -0
  171. package/src/lib/sync-manager.js +336 -0
  172. package/src/lib/tech-learning-engine.js +341 -0
  173. package/src/lib/tenant-saas.js +341 -0
  174. package/src/lib/threat-intel.js +330 -0
  175. package/src/lib/todo-manager.js +336 -0
  176. package/src/lib/token-tracker.js +336 -0
  177. package/src/lib/trust-security.js +343 -0
  178. package/src/lib/ueba.js +340 -0
  179. package/src/lib/universal-runtime.js +330 -0
  180. package/src/lib/wallet-manager.js +336 -0
  181. package/src/lib/web-ui-server.js +348 -0
  182. package/src/lib/workflow-engine.js +330 -0
  183. package/src/lib/workflow-expr.js +346 -0
  184. package/src/lib/ws-chat-handler.js +337 -0
@@ -601,3 +601,333 @@ export function _resetStateThreatIntelV2() {
601
601
  _feedIdleMsV2 = TI_DEFAULT_FEED_IDLE_MS;
602
602
  _indicatorStaleMsV2 = TI_DEFAULT_INDICATOR_STALE_MS;
603
603
  }
604
+
605
+ // =====================================================================
606
+ // threat-intel V2 governance overlay (iter24)
607
+ // =====================================================================
608
+ export const TIGOV_PROFILE_MATURITY_V2 = Object.freeze({
609
+ PENDING: "pending",
610
+ ACTIVE: "active",
611
+ STALE: "stale",
612
+ ARCHIVED: "archived",
613
+ });
614
+ export const TIGOV_FEED_LIFECYCLE_V2 = Object.freeze({
615
+ QUEUED: "queued",
616
+ INGESTING: "ingesting",
617
+ INGESTED: "ingested",
618
+ FAILED: "failed",
619
+ CANCELLED: "cancelled",
620
+ });
621
+ const _tigovPTrans = new Map([
622
+ [
623
+ TIGOV_PROFILE_MATURITY_V2.PENDING,
624
+ new Set([
625
+ TIGOV_PROFILE_MATURITY_V2.ACTIVE,
626
+ TIGOV_PROFILE_MATURITY_V2.ARCHIVED,
627
+ ]),
628
+ ],
629
+ [
630
+ TIGOV_PROFILE_MATURITY_V2.ACTIVE,
631
+ new Set([
632
+ TIGOV_PROFILE_MATURITY_V2.STALE,
633
+ TIGOV_PROFILE_MATURITY_V2.ARCHIVED,
634
+ ]),
635
+ ],
636
+ [
637
+ TIGOV_PROFILE_MATURITY_V2.STALE,
638
+ new Set([
639
+ TIGOV_PROFILE_MATURITY_V2.ACTIVE,
640
+ TIGOV_PROFILE_MATURITY_V2.ARCHIVED,
641
+ ]),
642
+ ],
643
+ [TIGOV_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
644
+ ]);
645
+ const _tigovPTerminal = new Set([TIGOV_PROFILE_MATURITY_V2.ARCHIVED]);
646
+ const _tigovJTrans = new Map([
647
+ [
648
+ TIGOV_FEED_LIFECYCLE_V2.QUEUED,
649
+ new Set([
650
+ TIGOV_FEED_LIFECYCLE_V2.INGESTING,
651
+ TIGOV_FEED_LIFECYCLE_V2.CANCELLED,
652
+ ]),
653
+ ],
654
+ [
655
+ TIGOV_FEED_LIFECYCLE_V2.INGESTING,
656
+ new Set([
657
+ TIGOV_FEED_LIFECYCLE_V2.INGESTED,
658
+ TIGOV_FEED_LIFECYCLE_V2.FAILED,
659
+ TIGOV_FEED_LIFECYCLE_V2.CANCELLED,
660
+ ]),
661
+ ],
662
+ [TIGOV_FEED_LIFECYCLE_V2.INGESTED, new Set()],
663
+ [TIGOV_FEED_LIFECYCLE_V2.FAILED, new Set()],
664
+ [TIGOV_FEED_LIFECYCLE_V2.CANCELLED, new Set()],
665
+ ]);
666
+ const _tigovPsV2 = new Map();
667
+ const _tigovJsV2 = new Map();
668
+ let _tigovMaxActive = 6,
669
+ _tigovMaxPending = 15,
670
+ _tigovIdleMs = 30 * 24 * 60 * 60 * 1000,
671
+ _tigovStuckMs = 60 * 1000;
672
+ function _tigovPos(n, label) {
673
+ const v = Math.floor(Number(n));
674
+ if (!Number.isFinite(v) || v <= 0)
675
+ throw new Error(`${label} must be positive integer`);
676
+ return v;
677
+ }
678
+ function _tigovCheckP(from, to) {
679
+ const a = _tigovPTrans.get(from);
680
+ if (!a || !a.has(to))
681
+ throw new Error(`invalid tigov profile transition ${from} → ${to}`);
682
+ }
683
+ function _tigovCheckJ(from, to) {
684
+ const a = _tigovJTrans.get(from);
685
+ if (!a || !a.has(to))
686
+ throw new Error(`invalid tigov feed transition ${from} → ${to}`);
687
+ }
688
+ function _tigovCountActive(owner) {
689
+ let c = 0;
690
+ for (const p of _tigovPsV2.values())
691
+ if (p.owner === owner && p.status === TIGOV_PROFILE_MATURITY_V2.ACTIVE) c++;
692
+ return c;
693
+ }
694
+ function _tigovCountPending(profileId) {
695
+ let c = 0;
696
+ for (const j of _tigovJsV2.values())
697
+ if (
698
+ j.profileId === profileId &&
699
+ (j.status === TIGOV_FEED_LIFECYCLE_V2.QUEUED ||
700
+ j.status === TIGOV_FEED_LIFECYCLE_V2.INGESTING)
701
+ )
702
+ c++;
703
+ return c;
704
+ }
705
+ export function setMaxActiveTigovProfilesPerOwnerV2(n) {
706
+ _tigovMaxActive = _tigovPos(n, "maxActiveTigovProfilesPerOwner");
707
+ }
708
+ export function getMaxActiveTigovProfilesPerOwnerV2() {
709
+ return _tigovMaxActive;
710
+ }
711
+ export function setMaxPendingTigovFeedsPerProfileV2(n) {
712
+ _tigovMaxPending = _tigovPos(n, "maxPendingTigovFeedsPerProfile");
713
+ }
714
+ export function getMaxPendingTigovFeedsPerProfileV2() {
715
+ return _tigovMaxPending;
716
+ }
717
+ export function setTigovProfileIdleMsV2(n) {
718
+ _tigovIdleMs = _tigovPos(n, "tigovProfileIdleMs");
719
+ }
720
+ export function getTigovProfileIdleMsV2() {
721
+ return _tigovIdleMs;
722
+ }
723
+ export function setTigovFeedStuckMsV2(n) {
724
+ _tigovStuckMs = _tigovPos(n, "tigovFeedStuckMs");
725
+ }
726
+ export function getTigovFeedStuckMsV2() {
727
+ return _tigovStuckMs;
728
+ }
729
+ export function _resetStateThreatIntelGovV2() {
730
+ _tigovPsV2.clear();
731
+ _tigovJsV2.clear();
732
+ _tigovMaxActive = 6;
733
+ _tigovMaxPending = 15;
734
+ _tigovIdleMs = 30 * 24 * 60 * 60 * 1000;
735
+ _tigovStuckMs = 60 * 1000;
736
+ }
737
+ export function registerTigovProfileV2({ id, owner, source, metadata } = {}) {
738
+ if (!id || !owner) throw new Error("id and owner required");
739
+ if (_tigovPsV2.has(id)) throw new Error(`tigov profile ${id} already exists`);
740
+ const now = Date.now();
741
+ const p = {
742
+ id,
743
+ owner,
744
+ source: source || "otx",
745
+ status: TIGOV_PROFILE_MATURITY_V2.PENDING,
746
+ createdAt: now,
747
+ updatedAt: now,
748
+ lastTouchedAt: now,
749
+ activatedAt: null,
750
+ archivedAt: null,
751
+ metadata: { ...(metadata || {}) },
752
+ };
753
+ _tigovPsV2.set(id, p);
754
+ return { ...p, metadata: { ...p.metadata } };
755
+ }
756
+ export function activateTigovProfileV2(id) {
757
+ const p = _tigovPsV2.get(id);
758
+ if (!p) throw new Error(`tigov profile ${id} not found`);
759
+ const isInitial = p.status === TIGOV_PROFILE_MATURITY_V2.PENDING;
760
+ _tigovCheckP(p.status, TIGOV_PROFILE_MATURITY_V2.ACTIVE);
761
+ if (isInitial && _tigovCountActive(p.owner) >= _tigovMaxActive)
762
+ throw new Error(`max active tigov profiles for owner ${p.owner} reached`);
763
+ const now = Date.now();
764
+ p.status = TIGOV_PROFILE_MATURITY_V2.ACTIVE;
765
+ p.updatedAt = now;
766
+ p.lastTouchedAt = now;
767
+ if (!p.activatedAt) p.activatedAt = now;
768
+ return { ...p, metadata: { ...p.metadata } };
769
+ }
770
+ export function staleTigovProfileV2(id) {
771
+ const p = _tigovPsV2.get(id);
772
+ if (!p) throw new Error(`tigov profile ${id} not found`);
773
+ _tigovCheckP(p.status, TIGOV_PROFILE_MATURITY_V2.STALE);
774
+ p.status = TIGOV_PROFILE_MATURITY_V2.STALE;
775
+ p.updatedAt = Date.now();
776
+ return { ...p, metadata: { ...p.metadata } };
777
+ }
778
+ export function archiveTigovProfileV2(id) {
779
+ const p = _tigovPsV2.get(id);
780
+ if (!p) throw new Error(`tigov profile ${id} not found`);
781
+ _tigovCheckP(p.status, TIGOV_PROFILE_MATURITY_V2.ARCHIVED);
782
+ const now = Date.now();
783
+ p.status = TIGOV_PROFILE_MATURITY_V2.ARCHIVED;
784
+ p.updatedAt = now;
785
+ if (!p.archivedAt) p.archivedAt = now;
786
+ return { ...p, metadata: { ...p.metadata } };
787
+ }
788
+ export function touchTigovProfileV2(id) {
789
+ const p = _tigovPsV2.get(id);
790
+ if (!p) throw new Error(`tigov profile ${id} not found`);
791
+ if (_tigovPTerminal.has(p.status))
792
+ throw new Error(`cannot touch terminal tigov profile ${id}`);
793
+ const now = Date.now();
794
+ p.lastTouchedAt = now;
795
+ p.updatedAt = now;
796
+ return { ...p, metadata: { ...p.metadata } };
797
+ }
798
+ export function getTigovProfileV2(id) {
799
+ const p = _tigovPsV2.get(id);
800
+ if (!p) return null;
801
+ return { ...p, metadata: { ...p.metadata } };
802
+ }
803
+ export function listTigovProfilesV2() {
804
+ return [..._tigovPsV2.values()].map((p) => ({
805
+ ...p,
806
+ metadata: { ...p.metadata },
807
+ }));
808
+ }
809
+ export function createTigovFeedV2({ id, profileId, indicator, metadata } = {}) {
810
+ if (!id || !profileId) throw new Error("id and profileId required");
811
+ if (_tigovJsV2.has(id)) throw new Error(`tigov feed ${id} already exists`);
812
+ if (!_tigovPsV2.has(profileId))
813
+ throw new Error(`tigov profile ${profileId} not found`);
814
+ if (_tigovCountPending(profileId) >= _tigovMaxPending)
815
+ throw new Error(`max pending tigov feeds for profile ${profileId} reached`);
816
+ const now = Date.now();
817
+ const j = {
818
+ id,
819
+ profileId,
820
+ indicator: indicator || "",
821
+ status: TIGOV_FEED_LIFECYCLE_V2.QUEUED,
822
+ createdAt: now,
823
+ updatedAt: now,
824
+ startedAt: null,
825
+ settledAt: null,
826
+ metadata: { ...(metadata || {}) },
827
+ };
828
+ _tigovJsV2.set(id, j);
829
+ return { ...j, metadata: { ...j.metadata } };
830
+ }
831
+ export function ingestingTigovFeedV2(id) {
832
+ const j = _tigovJsV2.get(id);
833
+ if (!j) throw new Error(`tigov feed ${id} not found`);
834
+ _tigovCheckJ(j.status, TIGOV_FEED_LIFECYCLE_V2.INGESTING);
835
+ const now = Date.now();
836
+ j.status = TIGOV_FEED_LIFECYCLE_V2.INGESTING;
837
+ j.updatedAt = now;
838
+ if (!j.startedAt) j.startedAt = now;
839
+ return { ...j, metadata: { ...j.metadata } };
840
+ }
841
+ export function completeFeedTigovV2(id) {
842
+ const j = _tigovJsV2.get(id);
843
+ if (!j) throw new Error(`tigov feed ${id} not found`);
844
+ _tigovCheckJ(j.status, TIGOV_FEED_LIFECYCLE_V2.INGESTED);
845
+ const now = Date.now();
846
+ j.status = TIGOV_FEED_LIFECYCLE_V2.INGESTED;
847
+ j.updatedAt = now;
848
+ if (!j.settledAt) j.settledAt = now;
849
+ return { ...j, metadata: { ...j.metadata } };
850
+ }
851
+ export function failTigovFeedV2(id, reason) {
852
+ const j = _tigovJsV2.get(id);
853
+ if (!j) throw new Error(`tigov feed ${id} not found`);
854
+ _tigovCheckJ(j.status, TIGOV_FEED_LIFECYCLE_V2.FAILED);
855
+ const now = Date.now();
856
+ j.status = TIGOV_FEED_LIFECYCLE_V2.FAILED;
857
+ j.updatedAt = now;
858
+ if (!j.settledAt) j.settledAt = now;
859
+ if (reason) j.metadata.failReason = String(reason);
860
+ return { ...j, metadata: { ...j.metadata } };
861
+ }
862
+ export function cancelTigovFeedV2(id, reason) {
863
+ const j = _tigovJsV2.get(id);
864
+ if (!j) throw new Error(`tigov feed ${id} not found`);
865
+ _tigovCheckJ(j.status, TIGOV_FEED_LIFECYCLE_V2.CANCELLED);
866
+ const now = Date.now();
867
+ j.status = TIGOV_FEED_LIFECYCLE_V2.CANCELLED;
868
+ j.updatedAt = now;
869
+ if (!j.settledAt) j.settledAt = now;
870
+ if (reason) j.metadata.cancelReason = String(reason);
871
+ return { ...j, metadata: { ...j.metadata } };
872
+ }
873
+ export function getTigovFeedV2(id) {
874
+ const j = _tigovJsV2.get(id);
875
+ if (!j) return null;
876
+ return { ...j, metadata: { ...j.metadata } };
877
+ }
878
+ export function listTigovFeedsV2() {
879
+ return [..._tigovJsV2.values()].map((j) => ({
880
+ ...j,
881
+ metadata: { ...j.metadata },
882
+ }));
883
+ }
884
+ export function autoStaleIdleTigovProfilesV2({ now } = {}) {
885
+ const t = now ?? Date.now();
886
+ const flipped = [];
887
+ for (const p of _tigovPsV2.values())
888
+ if (
889
+ p.status === TIGOV_PROFILE_MATURITY_V2.ACTIVE &&
890
+ t - p.lastTouchedAt >= _tigovIdleMs
891
+ ) {
892
+ p.status = TIGOV_PROFILE_MATURITY_V2.STALE;
893
+ p.updatedAt = t;
894
+ flipped.push(p.id);
895
+ }
896
+ return { flipped, count: flipped.length };
897
+ }
898
+ export function autoFailStuckTigovFeedsV2({ now } = {}) {
899
+ const t = now ?? Date.now();
900
+ const flipped = [];
901
+ for (const j of _tigovJsV2.values())
902
+ if (
903
+ j.status === TIGOV_FEED_LIFECYCLE_V2.INGESTING &&
904
+ j.startedAt != null &&
905
+ t - j.startedAt >= _tigovStuckMs
906
+ ) {
907
+ j.status = TIGOV_FEED_LIFECYCLE_V2.FAILED;
908
+ j.updatedAt = t;
909
+ if (!j.settledAt) j.settledAt = t;
910
+ j.metadata.failReason = "auto-fail-stuck";
911
+ flipped.push(j.id);
912
+ }
913
+ return { flipped, count: flipped.length };
914
+ }
915
+ export function getThreatIntelGovStatsV2() {
916
+ const profilesByStatus = {};
917
+ for (const v of Object.values(TIGOV_PROFILE_MATURITY_V2))
918
+ profilesByStatus[v] = 0;
919
+ for (const p of _tigovPsV2.values()) profilesByStatus[p.status]++;
920
+ const feedsByStatus = {};
921
+ for (const v of Object.values(TIGOV_FEED_LIFECYCLE_V2)) feedsByStatus[v] = 0;
922
+ for (const j of _tigovJsV2.values()) feedsByStatus[j.status]++;
923
+ return {
924
+ totalTigovProfilesV2: _tigovPsV2.size,
925
+ totalTigovFeedsV2: _tigovJsV2.size,
926
+ maxActiveTigovProfilesPerOwner: _tigovMaxActive,
927
+ maxPendingTigovFeedsPerProfile: _tigovMaxPending,
928
+ tigovProfileIdleMs: _tigovIdleMs,
929
+ tigovFeedStuckMs: _tigovStuckMs,
930
+ profilesByStatus,
931
+ feedsByStatus,
932
+ };
933
+ }
@@ -445,3 +445,339 @@ export function getTodoManagerStatsV2() {
445
445
  itemsByStatus,
446
446
  };
447
447
  }
448
+
449
+ // =====================================================================
450
+ // todo-manager V2 governance overlay (iter25)
451
+ // =====================================================================
452
+ export const TODOGOV_PROFILE_MATURITY_V2 = Object.freeze({
453
+ PENDING: "pending",
454
+ ACTIVE: "active",
455
+ PAUSED: "paused",
456
+ ARCHIVED: "archived",
457
+ });
458
+ export const TODOGOV_STEP_LIFECYCLE_V2 = Object.freeze({
459
+ QUEUED: "queued",
460
+ DOING: "doing",
461
+ DONE: "done",
462
+ FAILED: "failed",
463
+ CANCELLED: "cancelled",
464
+ });
465
+ const _todogovPTrans = new Map([
466
+ [
467
+ TODOGOV_PROFILE_MATURITY_V2.PENDING,
468
+ new Set([
469
+ TODOGOV_PROFILE_MATURITY_V2.ACTIVE,
470
+ TODOGOV_PROFILE_MATURITY_V2.ARCHIVED,
471
+ ]),
472
+ ],
473
+ [
474
+ TODOGOV_PROFILE_MATURITY_V2.ACTIVE,
475
+ new Set([
476
+ TODOGOV_PROFILE_MATURITY_V2.PAUSED,
477
+ TODOGOV_PROFILE_MATURITY_V2.ARCHIVED,
478
+ ]),
479
+ ],
480
+ [
481
+ TODOGOV_PROFILE_MATURITY_V2.PAUSED,
482
+ new Set([
483
+ TODOGOV_PROFILE_MATURITY_V2.ACTIVE,
484
+ TODOGOV_PROFILE_MATURITY_V2.ARCHIVED,
485
+ ]),
486
+ ],
487
+ [TODOGOV_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
488
+ ]);
489
+ const _todogovPTerminal = new Set([TODOGOV_PROFILE_MATURITY_V2.ARCHIVED]);
490
+ const _todogovJTrans = new Map([
491
+ [
492
+ TODOGOV_STEP_LIFECYCLE_V2.QUEUED,
493
+ new Set([
494
+ TODOGOV_STEP_LIFECYCLE_V2.DOING,
495
+ TODOGOV_STEP_LIFECYCLE_V2.CANCELLED,
496
+ ]),
497
+ ],
498
+ [
499
+ TODOGOV_STEP_LIFECYCLE_V2.DOING,
500
+ new Set([
501
+ TODOGOV_STEP_LIFECYCLE_V2.DONE,
502
+ TODOGOV_STEP_LIFECYCLE_V2.FAILED,
503
+ TODOGOV_STEP_LIFECYCLE_V2.CANCELLED,
504
+ ]),
505
+ ],
506
+ [TODOGOV_STEP_LIFECYCLE_V2.DONE, new Set()],
507
+ [TODOGOV_STEP_LIFECYCLE_V2.FAILED, new Set()],
508
+ [TODOGOV_STEP_LIFECYCLE_V2.CANCELLED, new Set()],
509
+ ]);
510
+ const _todogovPsV2 = new Map();
511
+ const _todogovJsV2 = new Map();
512
+ let _todogovMaxActive = 10,
513
+ _todogovMaxPending = 30,
514
+ _todogovIdleMs = 30 * 24 * 60 * 60 * 1000,
515
+ _todogovStuckMs = 60 * 1000;
516
+ function _todogovPos(n, label) {
517
+ const v = Math.floor(Number(n));
518
+ if (!Number.isFinite(v) || v <= 0)
519
+ throw new Error(`${label} must be positive integer`);
520
+ return v;
521
+ }
522
+ function _todogovCheckP(from, to) {
523
+ const a = _todogovPTrans.get(from);
524
+ if (!a || !a.has(to))
525
+ throw new Error(`invalid todogov profile transition ${from} → ${to}`);
526
+ }
527
+ function _todogovCheckJ(from, to) {
528
+ const a = _todogovJTrans.get(from);
529
+ if (!a || !a.has(to))
530
+ throw new Error(`invalid todogov step transition ${from} → ${to}`);
531
+ }
532
+ function _todogovCountActive(owner) {
533
+ let c = 0;
534
+ for (const p of _todogovPsV2.values())
535
+ if (p.owner === owner && p.status === TODOGOV_PROFILE_MATURITY_V2.ACTIVE)
536
+ c++;
537
+ return c;
538
+ }
539
+ function _todogovCountPending(profileId) {
540
+ let c = 0;
541
+ for (const j of _todogovJsV2.values())
542
+ if (
543
+ j.profileId === profileId &&
544
+ (j.status === TODOGOV_STEP_LIFECYCLE_V2.QUEUED ||
545
+ j.status === TODOGOV_STEP_LIFECYCLE_V2.DOING)
546
+ )
547
+ c++;
548
+ return c;
549
+ }
550
+ export function setMaxActiveTodogovProfilesPerOwnerV2(n) {
551
+ _todogovMaxActive = _todogovPos(n, "maxActiveTodogovProfilesPerOwner");
552
+ }
553
+ export function getMaxActiveTodogovProfilesPerOwnerV2() {
554
+ return _todogovMaxActive;
555
+ }
556
+ export function setMaxPendingTodogovStepsPerProfileV2(n) {
557
+ _todogovMaxPending = _todogovPos(n, "maxPendingTodogovStepsPerProfile");
558
+ }
559
+ export function getMaxPendingTodogovStepsPerProfileV2() {
560
+ return _todogovMaxPending;
561
+ }
562
+ export function setTodogovProfileIdleMsV2(n) {
563
+ _todogovIdleMs = _todogovPos(n, "todogovProfileIdleMs");
564
+ }
565
+ export function getTodogovProfileIdleMsV2() {
566
+ return _todogovIdleMs;
567
+ }
568
+ export function setTodogovStepStuckMsV2(n) {
569
+ _todogovStuckMs = _todogovPos(n, "todogovStepStuckMs");
570
+ }
571
+ export function getTodogovStepStuckMsV2() {
572
+ return _todogovStuckMs;
573
+ }
574
+ export function _resetStateTodoManagerGovV2() {
575
+ _todogovPsV2.clear();
576
+ _todogovJsV2.clear();
577
+ _todogovMaxActive = 10;
578
+ _todogovMaxPending = 30;
579
+ _todogovIdleMs = 30 * 24 * 60 * 60 * 1000;
580
+ _todogovStuckMs = 60 * 1000;
581
+ }
582
+ export function registerTodogovProfileV2({ id, owner, list, metadata } = {}) {
583
+ if (!id || !owner) throw new Error("id and owner required");
584
+ if (_todogovPsV2.has(id))
585
+ throw new Error(`todogov profile ${id} already exists`);
586
+ const now = Date.now();
587
+ const p = {
588
+ id,
589
+ owner,
590
+ list: list || "default",
591
+ status: TODOGOV_PROFILE_MATURITY_V2.PENDING,
592
+ createdAt: now,
593
+ updatedAt: now,
594
+ lastTouchedAt: now,
595
+ activatedAt: null,
596
+ archivedAt: null,
597
+ metadata: { ...(metadata || {}) },
598
+ };
599
+ _todogovPsV2.set(id, p);
600
+ return { ...p, metadata: { ...p.metadata } };
601
+ }
602
+ export function activateTodogovProfileV2(id) {
603
+ const p = _todogovPsV2.get(id);
604
+ if (!p) throw new Error(`todogov profile ${id} not found`);
605
+ const isInitial = p.status === TODOGOV_PROFILE_MATURITY_V2.PENDING;
606
+ _todogovCheckP(p.status, TODOGOV_PROFILE_MATURITY_V2.ACTIVE);
607
+ if (isInitial && _todogovCountActive(p.owner) >= _todogovMaxActive)
608
+ throw new Error(`max active todogov profiles for owner ${p.owner} reached`);
609
+ const now = Date.now();
610
+ p.status = TODOGOV_PROFILE_MATURITY_V2.ACTIVE;
611
+ p.updatedAt = now;
612
+ p.lastTouchedAt = now;
613
+ if (!p.activatedAt) p.activatedAt = now;
614
+ return { ...p, metadata: { ...p.metadata } };
615
+ }
616
+ export function pauseTodogovProfileV2(id) {
617
+ const p = _todogovPsV2.get(id);
618
+ if (!p) throw new Error(`todogov profile ${id} not found`);
619
+ _todogovCheckP(p.status, TODOGOV_PROFILE_MATURITY_V2.PAUSED);
620
+ p.status = TODOGOV_PROFILE_MATURITY_V2.PAUSED;
621
+ p.updatedAt = Date.now();
622
+ return { ...p, metadata: { ...p.metadata } };
623
+ }
624
+ export function archiveTodogovProfileV2(id) {
625
+ const p = _todogovPsV2.get(id);
626
+ if (!p) throw new Error(`todogov profile ${id} not found`);
627
+ _todogovCheckP(p.status, TODOGOV_PROFILE_MATURITY_V2.ARCHIVED);
628
+ const now = Date.now();
629
+ p.status = TODOGOV_PROFILE_MATURITY_V2.ARCHIVED;
630
+ p.updatedAt = now;
631
+ if (!p.archivedAt) p.archivedAt = now;
632
+ return { ...p, metadata: { ...p.metadata } };
633
+ }
634
+ export function touchTodogovProfileV2(id) {
635
+ const p = _todogovPsV2.get(id);
636
+ if (!p) throw new Error(`todogov profile ${id} not found`);
637
+ if (_todogovPTerminal.has(p.status))
638
+ throw new Error(`cannot touch terminal todogov profile ${id}`);
639
+ const now = Date.now();
640
+ p.lastTouchedAt = now;
641
+ p.updatedAt = now;
642
+ return { ...p, metadata: { ...p.metadata } };
643
+ }
644
+ export function getTodogovProfileV2(id) {
645
+ const p = _todogovPsV2.get(id);
646
+ if (!p) return null;
647
+ return { ...p, metadata: { ...p.metadata } };
648
+ }
649
+ export function listTodogovProfilesV2() {
650
+ return [..._todogovPsV2.values()].map((p) => ({
651
+ ...p,
652
+ metadata: { ...p.metadata },
653
+ }));
654
+ }
655
+ export function createTodogovStepV2({ id, profileId, title, metadata } = {}) {
656
+ if (!id || !profileId) throw new Error("id and profileId required");
657
+ if (_todogovJsV2.has(id))
658
+ throw new Error(`todogov step ${id} already exists`);
659
+ if (!_todogovPsV2.has(profileId))
660
+ throw new Error(`todogov profile ${profileId} not found`);
661
+ if (_todogovCountPending(profileId) >= _todogovMaxPending)
662
+ throw new Error(
663
+ `max pending todogov steps for profile ${profileId} reached`,
664
+ );
665
+ const now = Date.now();
666
+ const j = {
667
+ id,
668
+ profileId,
669
+ title: title || "",
670
+ status: TODOGOV_STEP_LIFECYCLE_V2.QUEUED,
671
+ createdAt: now,
672
+ updatedAt: now,
673
+ startedAt: null,
674
+ settledAt: null,
675
+ metadata: { ...(metadata || {}) },
676
+ };
677
+ _todogovJsV2.set(id, j);
678
+ return { ...j, metadata: { ...j.metadata } };
679
+ }
680
+ export function doingTodogovStepV2(id) {
681
+ const j = _todogovJsV2.get(id);
682
+ if (!j) throw new Error(`todogov step ${id} not found`);
683
+ _todogovCheckJ(j.status, TODOGOV_STEP_LIFECYCLE_V2.DOING);
684
+ const now = Date.now();
685
+ j.status = TODOGOV_STEP_LIFECYCLE_V2.DOING;
686
+ j.updatedAt = now;
687
+ if (!j.startedAt) j.startedAt = now;
688
+ return { ...j, metadata: { ...j.metadata } };
689
+ }
690
+ export function completeStepTodogovV2(id) {
691
+ const j = _todogovJsV2.get(id);
692
+ if (!j) throw new Error(`todogov step ${id} not found`);
693
+ _todogovCheckJ(j.status, TODOGOV_STEP_LIFECYCLE_V2.DONE);
694
+ const now = Date.now();
695
+ j.status = TODOGOV_STEP_LIFECYCLE_V2.DONE;
696
+ j.updatedAt = now;
697
+ if (!j.settledAt) j.settledAt = now;
698
+ return { ...j, metadata: { ...j.metadata } };
699
+ }
700
+ export function failTodogovStepV2(id, reason) {
701
+ const j = _todogovJsV2.get(id);
702
+ if (!j) throw new Error(`todogov step ${id} not found`);
703
+ _todogovCheckJ(j.status, TODOGOV_STEP_LIFECYCLE_V2.FAILED);
704
+ const now = Date.now();
705
+ j.status = TODOGOV_STEP_LIFECYCLE_V2.FAILED;
706
+ j.updatedAt = now;
707
+ if (!j.settledAt) j.settledAt = now;
708
+ if (reason) j.metadata.failReason = String(reason);
709
+ return { ...j, metadata: { ...j.metadata } };
710
+ }
711
+ export function cancelTodogovStepV2(id, reason) {
712
+ const j = _todogovJsV2.get(id);
713
+ if (!j) throw new Error(`todogov step ${id} not found`);
714
+ _todogovCheckJ(j.status, TODOGOV_STEP_LIFECYCLE_V2.CANCELLED);
715
+ const now = Date.now();
716
+ j.status = TODOGOV_STEP_LIFECYCLE_V2.CANCELLED;
717
+ j.updatedAt = now;
718
+ if (!j.settledAt) j.settledAt = now;
719
+ if (reason) j.metadata.cancelReason = String(reason);
720
+ return { ...j, metadata: { ...j.metadata } };
721
+ }
722
+ export function getTodogovStepV2(id) {
723
+ const j = _todogovJsV2.get(id);
724
+ if (!j) return null;
725
+ return { ...j, metadata: { ...j.metadata } };
726
+ }
727
+ export function listTodogovStepsV2() {
728
+ return [..._todogovJsV2.values()].map((j) => ({
729
+ ...j,
730
+ metadata: { ...j.metadata },
731
+ }));
732
+ }
733
+ export function autoPauseIdleTodogovProfilesV2({ now } = {}) {
734
+ const t = now ?? Date.now();
735
+ const flipped = [];
736
+ for (const p of _todogovPsV2.values())
737
+ if (
738
+ p.status === TODOGOV_PROFILE_MATURITY_V2.ACTIVE &&
739
+ t - p.lastTouchedAt >= _todogovIdleMs
740
+ ) {
741
+ p.status = TODOGOV_PROFILE_MATURITY_V2.PAUSED;
742
+ p.updatedAt = t;
743
+ flipped.push(p.id);
744
+ }
745
+ return { flipped, count: flipped.length };
746
+ }
747
+ export function autoFailStuckTodogovStepsV2({ now } = {}) {
748
+ const t = now ?? Date.now();
749
+ const flipped = [];
750
+ for (const j of _todogovJsV2.values())
751
+ if (
752
+ j.status === TODOGOV_STEP_LIFECYCLE_V2.DOING &&
753
+ j.startedAt != null &&
754
+ t - j.startedAt >= _todogovStuckMs
755
+ ) {
756
+ j.status = TODOGOV_STEP_LIFECYCLE_V2.FAILED;
757
+ j.updatedAt = t;
758
+ if (!j.settledAt) j.settledAt = t;
759
+ j.metadata.failReason = "auto-fail-stuck";
760
+ flipped.push(j.id);
761
+ }
762
+ return { flipped, count: flipped.length };
763
+ }
764
+ export function getTodoManagerGovStatsV2() {
765
+ const profilesByStatus = {};
766
+ for (const v of Object.values(TODOGOV_PROFILE_MATURITY_V2))
767
+ profilesByStatus[v] = 0;
768
+ for (const p of _todogovPsV2.values()) profilesByStatus[p.status]++;
769
+ const stepsByStatus = {};
770
+ for (const v of Object.values(TODOGOV_STEP_LIFECYCLE_V2))
771
+ stepsByStatus[v] = 0;
772
+ for (const j of _todogovJsV2.values()) stepsByStatus[j.status]++;
773
+ return {
774
+ totalTodogovProfilesV2: _todogovPsV2.size,
775
+ totalTodogovStepsV2: _todogovJsV2.size,
776
+ maxActiveTodogovProfilesPerOwner: _todogovMaxActive,
777
+ maxPendingTodogovStepsPerProfile: _todogovMaxPending,
778
+ todogovProfileIdleMs: _todogovIdleMs,
779
+ todogovStepStuckMs: _todogovStuckMs,
780
+ profilesByStatus,
781
+ stepsByStatus,
782
+ };
783
+ }