chainlesschain 0.143.0 → 0.152.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/commands/a2a.js +196 -28
- package/src/commands/activitypub.js +364 -27
- package/src/commands/agent-network.js +217 -0
- package/src/commands/agent.js +587 -103
- package/src/commands/audit.js +206 -0
- package/src/commands/automation.js +201 -0
- package/src/commands/bi.js +355 -27
- package/src/commands/bm25.js +111 -27
- package/src/commands/browse.js +403 -29
- package/src/commands/ccron.js +128 -28
- package/src/commands/chat.js +207 -0
- package/src/commands/codegen.js +207 -0
- package/src/commands/collab.js +211 -0
- package/src/commands/compliance.js +824 -34
- package/src/commands/compt.js +127 -29
- package/src/commands/consol.js +8 -2
- package/src/commands/cowork.js +783 -34
- package/src/commands/crosschain.js +182 -28
- package/src/commands/dao.js +182 -28
- package/src/commands/dbevo.js +227 -0
- package/src/commands/dev.js +207 -0
- package/src/commands/did-v2.js +217 -0
- package/src/commands/did.js +221 -0
- package/src/commands/dlp.js +385 -27
- package/src/commands/economy.js +205 -50
- package/src/commands/evolution.js +203 -50
- package/src/commands/evomap.js +387 -27
- package/src/commands/export.js +213 -0
- package/src/commands/federation.js +209 -0
- package/src/commands/fflag.js +74 -22
- package/src/commands/fusion.js +205 -0
- package/src/commands/git.js +177 -37
- package/src/commands/governance.js +209 -0
- package/src/commands/hardening.js +209 -0
- package/src/commands/hmemory.js +204 -50
- package/src/commands/hook.js +209 -0
- package/src/commands/import.js +209 -0
- package/src/commands/incentive.js +209 -0
- package/src/commands/inference.js +170 -34
- package/src/commands/infra.js +203 -0
- package/src/commands/instinct.js +209 -0
- package/src/commands/ipfs.js +207 -0
- package/src/commands/itbudget.js +149 -33
- package/src/commands/kg.js +206 -0
- package/src/commands/llm.js +217 -0
- package/src/commands/lowcode.js +195 -38
- package/src/commands/marketplace.js +206 -0
- package/src/commands/matrix.js +386 -27
- package/src/commands/mcp.js +217 -0
- package/src/commands/mcpscaf.js +145 -33
- package/src/commands/meminj.js +145 -33
- package/src/commands/memory.js +209 -0
- package/src/commands/multimodal.js +203 -0
- package/src/commands/nlprog.js +225 -0
- package/src/commands/nostr.js +387 -27
- package/src/commands/note.js +205 -0
- package/src/commands/ops.js +219 -0
- package/src/commands/orchestrate.js +217 -0
- package/src/commands/orchgov.js +144 -33
- package/src/commands/org.js +209 -0
- package/src/commands/p2p.js +209 -0
- package/src/commands/pdfp.js +109 -27
- package/src/commands/perception.js +209 -0
- package/src/commands/perf.js +169 -32
- package/src/commands/perm.js +144 -33
- package/src/commands/permmem.js +203 -0
- package/src/commands/pipeline.js +207 -52
- package/src/commands/planmode.js +141 -32
- package/src/commands/plugin-ecosystem.js +209 -0
- package/src/commands/pqc.js +213 -0
- package/src/commands/privacy.js +203 -0
- package/src/commands/promcomp.js +111 -27
- package/src/commands/quantization.js +207 -0
- package/src/commands/rcache.js +205 -0
- package/src/commands/recommend.js +410 -34
- package/src/commands/reputation.js +208 -0
- package/src/commands/runtime.js +205 -0
- package/src/commands/sandbox.js +206 -0
- package/src/commands/scim.js +209 -0
- package/src/commands/seshhook.js +145 -33
- package/src/commands/seshsearch.js +141 -33
- package/src/commands/seshtail.js +144 -33
- package/src/commands/seshu.js +152 -33
- package/src/commands/session.js +209 -0
- package/src/commands/sganal.js +123 -29
- package/src/commands/siem.js +201 -34
- package/src/commands/skill.js +207 -0
- package/src/commands/sla.js +212 -0
- package/src/commands/slotfill.js +146 -33
- package/src/commands/social.js +358 -32
- package/src/commands/sso.js +209 -0
- package/src/commands/stress.js +206 -0
- package/src/commands/svccont.js +145 -33
- package/src/commands/sync.js +209 -0
- package/src/commands/tech.js +209 -0
- package/src/commands/tenant.js +217 -0
- package/src/commands/terraform.js +206 -0
- package/src/commands/tms.js +171 -33
- package/src/commands/tokens.js +209 -0
- package/src/commands/topiccls.js +146 -33
- package/src/commands/trust.js +217 -0
- package/src/commands/uprof.js +141 -32
- package/src/commands/vcheck.js +122 -28
- package/src/commands/wallet.js +209 -0
- package/src/commands/webfetch.js +141 -32
- package/src/commands/workflow.js +203 -0
- package/src/commands/zkp.js +184 -28
- package/src/index.js +180 -0
- package/src/lib/a2a-protocol.js +319 -51
- package/src/lib/activitypub-bridge.js +622 -50
- package/src/lib/agent-economy.js +304 -51
- package/src/lib/agent-network.js +341 -0
- package/src/lib/aiops.js +346 -0
- package/src/lib/app-builder.js +279 -46
- package/src/lib/audit-logger.js +321 -0
- package/src/lib/automation-engine.js +335 -0
- package/src/lib/autonomous-agent.js +284 -48
- package/src/lib/autonomous-developer.js +332 -0
- package/src/lib/bi-engine.js +616 -49
- package/src/lib/bm25-search.js +301 -49
- package/src/lib/browser-automation.js +630 -49
- package/src/lib/chat-core.js +336 -0
- package/src/lib/claude-code-bridge.js +341 -0
- package/src/lib/code-agent.js +339 -0
- package/src/lib/collaboration-governance.js +334 -0
- package/src/lib/community-governance.js +346 -0
- package/src/lib/compliance-framework-reporter.js +305 -51
- package/src/lib/compliance-manager.js +330 -0
- package/src/lib/compression-telemetry.js +301 -49
- package/src/lib/content-recommendation.js +351 -0
- package/src/lib/content-recommender.js +317 -52
- package/src/lib/cowork-cron.js +298 -49
- package/src/lib/cowork-learning.js +333 -0
- package/src/lib/cowork-share.js +338 -0
- package/src/lib/cowork-task-runner.js +308 -51
- package/src/lib/cowork-workflow.js +327 -0
- package/src/lib/cross-chain.js +311 -51
- package/src/lib/dao-governance.js +280 -46
- package/src/lib/dbevo.js +351 -0
- package/src/lib/decentral-infra.js +330 -0
- package/src/lib/did-manager.js +341 -0
- package/src/lib/did-v2-manager.js +341 -0
- package/src/lib/dlp-engine.js +626 -49
- package/src/lib/evolution-system.js +278 -47
- package/src/lib/evomap-governance.js +334 -0
- package/src/lib/evomap-manager.js +280 -46
- package/src/lib/execution-backend.js +294 -48
- package/src/lib/feature-flags.js +294 -49
- package/src/lib/federation-hardening.js +340 -0
- package/src/lib/git-integration.js +285 -47
- package/src/lib/hardening-manager.js +341 -0
- package/src/lib/hierarchical-memory.js +284 -48
- package/src/lib/hook-manager.js +341 -0
- package/src/lib/inference-network.js +308 -51
- package/src/lib/instinct-manager.js +346 -0
- package/src/lib/ipfs-storage.js +334 -0
- package/src/lib/iteration-budget.js +302 -50
- package/src/lib/knowledge-exporter.js +341 -0
- package/src/lib/knowledge-graph.js +333 -0
- package/src/lib/knowledge-importer.js +341 -0
- package/src/lib/llm-providers.js +346 -0
- package/src/lib/matrix-bridge.js +620 -47
- package/src/lib/mcp-registry.js +346 -0
- package/src/lib/mcp-scaffold.js +318 -54
- package/src/lib/memory-injection.js +288 -49
- package/src/lib/memory-manager.js +336 -0
- package/src/lib/multimodal.js +330 -0
- package/src/lib/nl-programming.js +341 -0
- package/src/lib/nostr-bridge.js +622 -49
- package/src/lib/note-versioning.js +339 -0
- package/src/lib/orchestrator.js +293 -48
- package/src/lib/org-manager.js +336 -0
- package/src/lib/p2p-manager.js +341 -0
- package/src/lib/pdf-parser.js +298 -49
- package/src/lib/perception.js +346 -0
- package/src/lib/perf-tuning.js +309 -50
- package/src/lib/permanent-memory.js +327 -0
- package/src/lib/permission-engine.js +287 -49
- package/src/lib/pipeline-orchestrator.js +289 -49
- package/src/lib/plan-mode.js +298 -51
- package/src/lib/plugin-ecosystem.js +346 -0
- package/src/lib/pqc-manager.js +346 -0
- package/src/lib/privacy-computing.js +335 -0
- package/src/lib/protocol-fusion.js +338 -0
- package/src/lib/quantization.js +337 -0
- package/src/lib/reputation-optimizer.js +340 -0
- package/src/lib/response-cache.js +333 -0
- package/src/lib/sandbox-v2.js +327 -0
- package/src/lib/scim-manager.js +346 -0
- package/src/lib/service-container.js +313 -52
- package/src/lib/session-consolidator.js +296 -49
- package/src/lib/session-hooks.js +312 -53
- package/src/lib/session-manager.js +334 -0
- package/src/lib/session-search.js +304 -51
- package/src/lib/session-tail.js +288 -49
- package/src/lib/session-usage.js +298 -52
- package/src/lib/siem-exporter.js +298 -51
- package/src/lib/skill-loader.js +334 -0
- package/src/lib/skill-marketplace.js +345 -0
- package/src/lib/sla-manager.js +341 -0
- package/src/lib/slot-filler.js +303 -51
- package/src/lib/social-graph-analytics.js +295 -49
- package/src/lib/social-graph.js +272 -49
- package/src/lib/social-manager.js +330 -0
- package/src/lib/sso-manager.js +340 -0
- package/src/lib/stress-tester.js +342 -0
- package/src/lib/sub-agent-registry.js +302 -53
- package/src/lib/sync-manager.js +336 -0
- package/src/lib/task-model-selector.js +302 -50
- package/src/lib/tech-learning-engine.js +341 -0
- package/src/lib/tenant-saas.js +341 -0
- package/src/lib/terraform-manager.js +333 -0
- package/src/lib/threat-intel.js +330 -0
- package/src/lib/todo-manager.js +281 -47
- package/src/lib/token-incentive.js +341 -0
- package/src/lib/token-tracker.js +336 -0
- package/src/lib/topic-classifier.js +297 -49
- package/src/lib/trust-security.js +343 -0
- package/src/lib/ueba.js +340 -0
- package/src/lib/universal-runtime.js +330 -0
- package/src/lib/user-profile.js +294 -50
- package/src/lib/version-checker.js +304 -50
- package/src/lib/wallet-manager.js +336 -0
- package/src/lib/web-fetch.js +292 -51
- package/src/lib/workflow-engine.js +330 -0
- package/src/lib/zkp-engine.js +286 -49
|
@@ -562,3 +562,336 @@ export function getTerraformStatsV2() {
|
|
|
562
562
|
totalResources,
|
|
563
563
|
};
|
|
564
564
|
}
|
|
565
|
+
|
|
566
|
+
// =====================================================================
|
|
567
|
+
// terraform-manager V2 governance overlay (iter16)
|
|
568
|
+
// =====================================================================
|
|
569
|
+
export const TFGOV_PROFILE_MATURITY_V2 = Object.freeze({
|
|
570
|
+
PENDING: "pending",
|
|
571
|
+
ACTIVE: "active",
|
|
572
|
+
DRIFTED: "drifted",
|
|
573
|
+
ARCHIVED: "archived",
|
|
574
|
+
});
|
|
575
|
+
export const TFGOV_APPLY_LIFECYCLE_V2 = Object.freeze({
|
|
576
|
+
QUEUED: "queued",
|
|
577
|
+
APPLYING: "applying",
|
|
578
|
+
APPLIED: "applied",
|
|
579
|
+
FAILED: "failed",
|
|
580
|
+
CANCELLED: "cancelled",
|
|
581
|
+
});
|
|
582
|
+
const _tfgovPTrans = new Map([
|
|
583
|
+
[
|
|
584
|
+
TFGOV_PROFILE_MATURITY_V2.PENDING,
|
|
585
|
+
new Set([
|
|
586
|
+
TFGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
587
|
+
TFGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
588
|
+
]),
|
|
589
|
+
],
|
|
590
|
+
[
|
|
591
|
+
TFGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
592
|
+
new Set([
|
|
593
|
+
TFGOV_PROFILE_MATURITY_V2.DRIFTED,
|
|
594
|
+
TFGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
595
|
+
]),
|
|
596
|
+
],
|
|
597
|
+
[
|
|
598
|
+
TFGOV_PROFILE_MATURITY_V2.DRIFTED,
|
|
599
|
+
new Set([
|
|
600
|
+
TFGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
601
|
+
TFGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
602
|
+
]),
|
|
603
|
+
],
|
|
604
|
+
[TFGOV_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
605
|
+
]);
|
|
606
|
+
const _tfgovPTerminal = new Set([TFGOV_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
607
|
+
const _tfgovJTrans = new Map([
|
|
608
|
+
[
|
|
609
|
+
TFGOV_APPLY_LIFECYCLE_V2.QUEUED,
|
|
610
|
+
new Set([
|
|
611
|
+
TFGOV_APPLY_LIFECYCLE_V2.APPLYING,
|
|
612
|
+
TFGOV_APPLY_LIFECYCLE_V2.CANCELLED,
|
|
613
|
+
]),
|
|
614
|
+
],
|
|
615
|
+
[
|
|
616
|
+
TFGOV_APPLY_LIFECYCLE_V2.APPLYING,
|
|
617
|
+
new Set([
|
|
618
|
+
TFGOV_APPLY_LIFECYCLE_V2.APPLIED,
|
|
619
|
+
TFGOV_APPLY_LIFECYCLE_V2.FAILED,
|
|
620
|
+
TFGOV_APPLY_LIFECYCLE_V2.CANCELLED,
|
|
621
|
+
]),
|
|
622
|
+
],
|
|
623
|
+
[TFGOV_APPLY_LIFECYCLE_V2.APPLIED, new Set()],
|
|
624
|
+
[TFGOV_APPLY_LIFECYCLE_V2.FAILED, new Set()],
|
|
625
|
+
[TFGOV_APPLY_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
626
|
+
]);
|
|
627
|
+
const _tfgovPsV2 = new Map();
|
|
628
|
+
const _tfgovJsV2 = new Map();
|
|
629
|
+
let _tfgovMaxActive = 6,
|
|
630
|
+
_tfgovMaxPending = 12,
|
|
631
|
+
_tfgovIdleMs = 30 * 24 * 60 * 60 * 1000,
|
|
632
|
+
_tfgovStuckMs = 60 * 1000;
|
|
633
|
+
function _tfgovPos(n, label) {
|
|
634
|
+
const v = Math.floor(Number(n));
|
|
635
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
636
|
+
throw new Error(`${label} must be positive integer`);
|
|
637
|
+
return v;
|
|
638
|
+
}
|
|
639
|
+
function _tfgovCheckP(from, to) {
|
|
640
|
+
const a = _tfgovPTrans.get(from);
|
|
641
|
+
if (!a || !a.has(to))
|
|
642
|
+
throw new Error(`invalid tfgov profile transition ${from} → ${to}`);
|
|
643
|
+
}
|
|
644
|
+
function _tfgovCheckJ(from, to) {
|
|
645
|
+
const a = _tfgovJTrans.get(from);
|
|
646
|
+
if (!a || !a.has(to))
|
|
647
|
+
throw new Error(`invalid tfgov apply transition ${from} → ${to}`);
|
|
648
|
+
}
|
|
649
|
+
function _tfgovCountActive(owner) {
|
|
650
|
+
let c = 0;
|
|
651
|
+
for (const p of _tfgovPsV2.values())
|
|
652
|
+
if (p.owner === owner && p.status === TFGOV_PROFILE_MATURITY_V2.ACTIVE) c++;
|
|
653
|
+
return c;
|
|
654
|
+
}
|
|
655
|
+
function _tfgovCountPending(profileId) {
|
|
656
|
+
let c = 0;
|
|
657
|
+
for (const j of _tfgovJsV2.values())
|
|
658
|
+
if (
|
|
659
|
+
j.profileId === profileId &&
|
|
660
|
+
(j.status === TFGOV_APPLY_LIFECYCLE_V2.QUEUED ||
|
|
661
|
+
j.status === TFGOV_APPLY_LIFECYCLE_V2.APPLYING)
|
|
662
|
+
)
|
|
663
|
+
c++;
|
|
664
|
+
return c;
|
|
665
|
+
}
|
|
666
|
+
export function setMaxActiveTfgovProfilesPerOwnerV2(n) {
|
|
667
|
+
_tfgovMaxActive = _tfgovPos(n, "maxActiveTfgovProfilesPerOwner");
|
|
668
|
+
}
|
|
669
|
+
export function getMaxActiveTfgovProfilesPerOwnerV2() {
|
|
670
|
+
return _tfgovMaxActive;
|
|
671
|
+
}
|
|
672
|
+
export function setMaxPendingTfgovApplysPerProfileV2(n) {
|
|
673
|
+
_tfgovMaxPending = _tfgovPos(n, "maxPendingTfgovApplysPerProfile");
|
|
674
|
+
}
|
|
675
|
+
export function getMaxPendingTfgovApplysPerProfileV2() {
|
|
676
|
+
return _tfgovMaxPending;
|
|
677
|
+
}
|
|
678
|
+
export function setTfgovProfileIdleMsV2(n) {
|
|
679
|
+
_tfgovIdleMs = _tfgovPos(n, "tfgovProfileIdleMs");
|
|
680
|
+
}
|
|
681
|
+
export function getTfgovProfileIdleMsV2() {
|
|
682
|
+
return _tfgovIdleMs;
|
|
683
|
+
}
|
|
684
|
+
export function setTfgovApplyStuckMsV2(n) {
|
|
685
|
+
_tfgovStuckMs = _tfgovPos(n, "tfgovApplyStuckMs");
|
|
686
|
+
}
|
|
687
|
+
export function getTfgovApplyStuckMsV2() {
|
|
688
|
+
return _tfgovStuckMs;
|
|
689
|
+
}
|
|
690
|
+
export function _resetStateTerraformManagerV2() {
|
|
691
|
+
_tfgovPsV2.clear();
|
|
692
|
+
_tfgovJsV2.clear();
|
|
693
|
+
_tfgovMaxActive = 6;
|
|
694
|
+
_tfgovMaxPending = 12;
|
|
695
|
+
_tfgovIdleMs = 30 * 24 * 60 * 60 * 1000;
|
|
696
|
+
_tfgovStuckMs = 60 * 1000;
|
|
697
|
+
}
|
|
698
|
+
export function registerTfgovProfileV2({ id, owner, provider, metadata } = {}) {
|
|
699
|
+
if (!id || !owner) throw new Error("id and owner required");
|
|
700
|
+
if (_tfgovPsV2.has(id)) throw new Error(`tfgov profile ${id} already exists`);
|
|
701
|
+
const now = Date.now();
|
|
702
|
+
const p = {
|
|
703
|
+
id,
|
|
704
|
+
owner,
|
|
705
|
+
provider: provider || "aws",
|
|
706
|
+
status: TFGOV_PROFILE_MATURITY_V2.PENDING,
|
|
707
|
+
createdAt: now,
|
|
708
|
+
updatedAt: now,
|
|
709
|
+
lastTouchedAt: now,
|
|
710
|
+
activatedAt: null,
|
|
711
|
+
archivedAt: null,
|
|
712
|
+
metadata: { ...(metadata || {}) },
|
|
713
|
+
};
|
|
714
|
+
_tfgovPsV2.set(id, p);
|
|
715
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
716
|
+
}
|
|
717
|
+
export function activateTfgovProfileV2(id) {
|
|
718
|
+
const p = _tfgovPsV2.get(id);
|
|
719
|
+
if (!p) throw new Error(`tfgov profile ${id} not found`);
|
|
720
|
+
const isInitial = p.status === TFGOV_PROFILE_MATURITY_V2.PENDING;
|
|
721
|
+
_tfgovCheckP(p.status, TFGOV_PROFILE_MATURITY_V2.ACTIVE);
|
|
722
|
+
if (isInitial && _tfgovCountActive(p.owner) >= _tfgovMaxActive)
|
|
723
|
+
throw new Error(`max active tfgov profiles for owner ${p.owner} reached`);
|
|
724
|
+
const now = Date.now();
|
|
725
|
+
p.status = TFGOV_PROFILE_MATURITY_V2.ACTIVE;
|
|
726
|
+
p.updatedAt = now;
|
|
727
|
+
p.lastTouchedAt = now;
|
|
728
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
729
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
730
|
+
}
|
|
731
|
+
export function driftTfgovProfileV2(id) {
|
|
732
|
+
const p = _tfgovPsV2.get(id);
|
|
733
|
+
if (!p) throw new Error(`tfgov profile ${id} not found`);
|
|
734
|
+
_tfgovCheckP(p.status, TFGOV_PROFILE_MATURITY_V2.DRIFTED);
|
|
735
|
+
p.status = TFGOV_PROFILE_MATURITY_V2.DRIFTED;
|
|
736
|
+
p.updatedAt = Date.now();
|
|
737
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
738
|
+
}
|
|
739
|
+
export function archiveTfgovProfileV2(id) {
|
|
740
|
+
const p = _tfgovPsV2.get(id);
|
|
741
|
+
if (!p) throw new Error(`tfgov profile ${id} not found`);
|
|
742
|
+
_tfgovCheckP(p.status, TFGOV_PROFILE_MATURITY_V2.ARCHIVED);
|
|
743
|
+
const now = Date.now();
|
|
744
|
+
p.status = TFGOV_PROFILE_MATURITY_V2.ARCHIVED;
|
|
745
|
+
p.updatedAt = now;
|
|
746
|
+
if (!p.archivedAt) p.archivedAt = now;
|
|
747
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
748
|
+
}
|
|
749
|
+
export function touchTfgovProfileV2(id) {
|
|
750
|
+
const p = _tfgovPsV2.get(id);
|
|
751
|
+
if (!p) throw new Error(`tfgov profile ${id} not found`);
|
|
752
|
+
if (_tfgovPTerminal.has(p.status))
|
|
753
|
+
throw new Error(`cannot touch terminal tfgov profile ${id}`);
|
|
754
|
+
const now = Date.now();
|
|
755
|
+
p.lastTouchedAt = now;
|
|
756
|
+
p.updatedAt = now;
|
|
757
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
758
|
+
}
|
|
759
|
+
export function getTfgovProfileV2(id) {
|
|
760
|
+
const p = _tfgovPsV2.get(id);
|
|
761
|
+
if (!p) return null;
|
|
762
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
763
|
+
}
|
|
764
|
+
export function listTfgovProfilesV2() {
|
|
765
|
+
return [..._tfgovPsV2.values()].map((p) => ({
|
|
766
|
+
...p,
|
|
767
|
+
metadata: { ...p.metadata },
|
|
768
|
+
}));
|
|
769
|
+
}
|
|
770
|
+
export function createTfgovApplyV2({ id, profileId, resource, metadata } = {}) {
|
|
771
|
+
if (!id || !profileId) throw new Error("id and profileId required");
|
|
772
|
+
if (_tfgovJsV2.has(id)) throw new Error(`tfgov apply ${id} already exists`);
|
|
773
|
+
if (!_tfgovPsV2.has(profileId))
|
|
774
|
+
throw new Error(`tfgov profile ${profileId} not found`);
|
|
775
|
+
if (_tfgovCountPending(profileId) >= _tfgovMaxPending)
|
|
776
|
+
throw new Error(
|
|
777
|
+
`max pending tfgov applys for profile ${profileId} reached`,
|
|
778
|
+
);
|
|
779
|
+
const now = Date.now();
|
|
780
|
+
const j = {
|
|
781
|
+
id,
|
|
782
|
+
profileId,
|
|
783
|
+
resource: resource || "",
|
|
784
|
+
status: TFGOV_APPLY_LIFECYCLE_V2.QUEUED,
|
|
785
|
+
createdAt: now,
|
|
786
|
+
updatedAt: now,
|
|
787
|
+
startedAt: null,
|
|
788
|
+
settledAt: null,
|
|
789
|
+
metadata: { ...(metadata || {}) },
|
|
790
|
+
};
|
|
791
|
+
_tfgovJsV2.set(id, j);
|
|
792
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
793
|
+
}
|
|
794
|
+
export function applyingTfgovApplyV2(id) {
|
|
795
|
+
const j = _tfgovJsV2.get(id);
|
|
796
|
+
if (!j) throw new Error(`tfgov apply ${id} not found`);
|
|
797
|
+
_tfgovCheckJ(j.status, TFGOV_APPLY_LIFECYCLE_V2.APPLYING);
|
|
798
|
+
const now = Date.now();
|
|
799
|
+
j.status = TFGOV_APPLY_LIFECYCLE_V2.APPLYING;
|
|
800
|
+
j.updatedAt = now;
|
|
801
|
+
if (!j.startedAt) j.startedAt = now;
|
|
802
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
803
|
+
}
|
|
804
|
+
export function completeApplyTfgovV2(id) {
|
|
805
|
+
const j = _tfgovJsV2.get(id);
|
|
806
|
+
if (!j) throw new Error(`tfgov apply ${id} not found`);
|
|
807
|
+
_tfgovCheckJ(j.status, TFGOV_APPLY_LIFECYCLE_V2.APPLIED);
|
|
808
|
+
const now = Date.now();
|
|
809
|
+
j.status = TFGOV_APPLY_LIFECYCLE_V2.APPLIED;
|
|
810
|
+
j.updatedAt = now;
|
|
811
|
+
if (!j.settledAt) j.settledAt = now;
|
|
812
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
813
|
+
}
|
|
814
|
+
export function failTfgovApplyV2(id, reason) {
|
|
815
|
+
const j = _tfgovJsV2.get(id);
|
|
816
|
+
if (!j) throw new Error(`tfgov apply ${id} not found`);
|
|
817
|
+
_tfgovCheckJ(j.status, TFGOV_APPLY_LIFECYCLE_V2.FAILED);
|
|
818
|
+
const now = Date.now();
|
|
819
|
+
j.status = TFGOV_APPLY_LIFECYCLE_V2.FAILED;
|
|
820
|
+
j.updatedAt = now;
|
|
821
|
+
if (!j.settledAt) j.settledAt = now;
|
|
822
|
+
if (reason) j.metadata.failReason = String(reason);
|
|
823
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
824
|
+
}
|
|
825
|
+
export function cancelTfgovApplyV2(id, reason) {
|
|
826
|
+
const j = _tfgovJsV2.get(id);
|
|
827
|
+
if (!j) throw new Error(`tfgov apply ${id} not found`);
|
|
828
|
+
_tfgovCheckJ(j.status, TFGOV_APPLY_LIFECYCLE_V2.CANCELLED);
|
|
829
|
+
const now = Date.now();
|
|
830
|
+
j.status = TFGOV_APPLY_LIFECYCLE_V2.CANCELLED;
|
|
831
|
+
j.updatedAt = now;
|
|
832
|
+
if (!j.settledAt) j.settledAt = now;
|
|
833
|
+
if (reason) j.metadata.cancelReason = String(reason);
|
|
834
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
835
|
+
}
|
|
836
|
+
export function getTfgovApplyV2(id) {
|
|
837
|
+
const j = _tfgovJsV2.get(id);
|
|
838
|
+
if (!j) return null;
|
|
839
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
840
|
+
}
|
|
841
|
+
export function listTfgovApplysV2() {
|
|
842
|
+
return [..._tfgovJsV2.values()].map((j) => ({
|
|
843
|
+
...j,
|
|
844
|
+
metadata: { ...j.metadata },
|
|
845
|
+
}));
|
|
846
|
+
}
|
|
847
|
+
export function autoDriftIdleTfgovProfilesV2({ now } = {}) {
|
|
848
|
+
const t = now ?? Date.now();
|
|
849
|
+
const flipped = [];
|
|
850
|
+
for (const p of _tfgovPsV2.values())
|
|
851
|
+
if (
|
|
852
|
+
p.status === TFGOV_PROFILE_MATURITY_V2.ACTIVE &&
|
|
853
|
+
t - p.lastTouchedAt >= _tfgovIdleMs
|
|
854
|
+
) {
|
|
855
|
+
p.status = TFGOV_PROFILE_MATURITY_V2.DRIFTED;
|
|
856
|
+
p.updatedAt = t;
|
|
857
|
+
flipped.push(p.id);
|
|
858
|
+
}
|
|
859
|
+
return { flipped, count: flipped.length };
|
|
860
|
+
}
|
|
861
|
+
export function autoFailStuckTfgovApplysV2({ now } = {}) {
|
|
862
|
+
const t = now ?? Date.now();
|
|
863
|
+
const flipped = [];
|
|
864
|
+
for (const j of _tfgovJsV2.values())
|
|
865
|
+
if (
|
|
866
|
+
j.status === TFGOV_APPLY_LIFECYCLE_V2.APPLYING &&
|
|
867
|
+
j.startedAt != null &&
|
|
868
|
+
t - j.startedAt >= _tfgovStuckMs
|
|
869
|
+
) {
|
|
870
|
+
j.status = TFGOV_APPLY_LIFECYCLE_V2.FAILED;
|
|
871
|
+
j.updatedAt = t;
|
|
872
|
+
if (!j.settledAt) j.settledAt = t;
|
|
873
|
+
j.metadata.failReason = "auto-fail-stuck";
|
|
874
|
+
flipped.push(j.id);
|
|
875
|
+
}
|
|
876
|
+
return { flipped, count: flipped.length };
|
|
877
|
+
}
|
|
878
|
+
export function getTerraformManagerGovStatsV2() {
|
|
879
|
+
const profilesByStatus = {};
|
|
880
|
+
for (const v of Object.values(TFGOV_PROFILE_MATURITY_V2))
|
|
881
|
+
profilesByStatus[v] = 0;
|
|
882
|
+
for (const p of _tfgovPsV2.values()) profilesByStatus[p.status]++;
|
|
883
|
+
const applysByStatus = {};
|
|
884
|
+
for (const v of Object.values(TFGOV_APPLY_LIFECYCLE_V2))
|
|
885
|
+
applysByStatus[v] = 0;
|
|
886
|
+
for (const j of _tfgovJsV2.values()) applysByStatus[j.status]++;
|
|
887
|
+
return {
|
|
888
|
+
totalTfgovProfilesV2: _tfgovPsV2.size,
|
|
889
|
+
totalTfgovApplysV2: _tfgovJsV2.size,
|
|
890
|
+
maxActiveTfgovProfilesPerOwner: _tfgovMaxActive,
|
|
891
|
+
maxPendingTfgovApplysPerProfile: _tfgovMaxPending,
|
|
892
|
+
tfgovProfileIdleMs: _tfgovIdleMs,
|
|
893
|
+
tfgovApplyStuckMs: _tfgovStuckMs,
|
|
894
|
+
profilesByStatus,
|
|
895
|
+
applysByStatus,
|
|
896
|
+
};
|
|
897
|
+
}
|
package/src/lib/threat-intel.js
CHANGED
|
@@ -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
|
+
}
|