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.
- package/bin/chainlesschain.js +0 -0
- package/package.json +1 -1
- package/src/commands/a2a.js +62 -0
- package/src/commands/activitypub.js +61 -0
- package/src/commands/agent-network.js +254 -1
- package/src/commands/agent.js +117 -0
- package/src/commands/audit.js +302 -0
- package/src/commands/automation.js +271 -1
- package/src/commands/bi.js +61 -0
- package/src/commands/bm25.js +78 -0
- package/src/commands/browse.js +64 -0
- package/src/commands/ccron.js +78 -0
- package/src/commands/codegen.js +224 -0
- package/src/commands/collab.js +341 -0
- package/src/commands/compliance.js +1075 -0
- package/src/commands/compt.js +78 -0
- package/src/commands/consol.js +231 -0
- package/src/commands/cowork.js +263 -0
- package/src/commands/crosschain.js +62 -0
- package/src/commands/dao.js +62 -0
- package/src/commands/dbevo.js +284 -0
- package/src/commands/dev.js +252 -0
- package/src/commands/did.js +358 -0
- package/src/commands/dlp.js +61 -0
- package/src/commands/economy.js +56 -0
- package/src/commands/encrypt.js +341 -0
- package/src/commands/evolution.js +56 -0
- package/src/commands/evomap.js +61 -0
- package/src/commands/export.js +256 -1
- package/src/commands/fflag.js +178 -0
- package/src/commands/fusion.js +258 -0
- package/src/commands/git.js +45 -0
- package/src/commands/governance.js +325 -0
- package/src/commands/hardening.js +411 -0
- package/src/commands/hmemory.js +56 -0
- package/src/commands/hook.js +148 -0
- package/src/commands/import.js +252 -0
- package/src/commands/incentive.js +322 -0
- package/src/commands/inference.js +42 -0
- package/src/commands/infra.js +244 -0
- package/src/commands/instinct.js +260 -0
- package/src/commands/ipfs.js +318 -0
- package/src/commands/itbudget.js +45 -0
- package/src/commands/kg.js +387 -0
- package/src/commands/llm.js +263 -0
- package/src/commands/lowcode.js +44 -0
- package/src/commands/matrix.js +62 -0
- package/src/commands/mcp.js +221 -0
- package/src/commands/mcpscaf.js +41 -0
- package/src/commands/meminj.js +41 -0
- package/src/commands/memory.js +248 -0
- package/src/commands/multimodal.js +296 -0
- package/src/commands/nlprog.js +356 -0
- package/src/commands/nostr.js +62 -0
- package/src/commands/note.js +244 -0
- package/src/commands/ops.js +354 -0
- package/src/commands/orchestrate.js +166 -0
- package/src/commands/orchgov.js +45 -0
- package/src/commands/org.js +277 -0
- package/src/commands/p2p.js +390 -0
- package/src/commands/pdfp.js +78 -0
- package/src/commands/perception.js +290 -0
- package/src/commands/perf.js +39 -0
- package/src/commands/perm.js +45 -0
- package/src/commands/permmem.js +251 -0
- package/src/commands/pipeline.js +57 -1
- package/src/commands/planmode.js +45 -0
- package/src/commands/plugin-ecosystem.js +273 -0
- package/src/commands/pqc.js +393 -0
- package/src/commands/promcomp.js +82 -0
- package/src/commands/quantization.js +351 -0
- package/src/commands/rcache.js +271 -0
- package/src/commands/recommend.js +382 -0
- package/src/commands/runtime.js +307 -0
- package/src/commands/scim.js +262 -0
- package/src/commands/seshhook.js +41 -0
- package/src/commands/seshsearch.js +41 -0
- package/src/commands/seshtail.js +41 -0
- package/src/commands/seshu.js +41 -0
- package/src/commands/session.js +258 -0
- package/src/commands/sganal.js +78 -0
- package/src/commands/siem.js +40 -0
- package/src/commands/skill.js +267 -1
- package/src/commands/slotfill.js +41 -0
- package/src/commands/social.js +290 -0
- package/src/commands/sso.js +186 -1
- package/src/commands/svccont.js +45 -0
- package/src/commands/sync.js +256 -0
- package/src/commands/tech.js +338 -0
- package/src/commands/tenant.js +351 -0
- package/src/commands/tms.js +45 -0
- package/src/commands/tokens.js +269 -0
- package/src/commands/topiccls.js +45 -0
- package/src/commands/trust.js +249 -0
- package/src/commands/uprof.js +45 -0
- package/src/commands/vcheck.js +78 -0
- package/src/commands/wallet.js +277 -0
- package/src/commands/webfetch.js +41 -0
- package/src/commands/workflow.js +171 -0
- package/src/commands/zkp.js +62 -0
- package/src/harness/prompt-compressor.js +331 -0
- package/src/index.js +65 -1
- package/src/lib/a2a-protocol.js +105 -0
- package/src/lib/activitypub-bridge.js +105 -0
- package/src/lib/agent-coordinator.js +325 -0
- package/src/lib/agent-economy.js +105 -0
- package/src/lib/agent-network.js +387 -0
- package/src/lib/agent-router.js +395 -0
- package/src/lib/aiops.js +478 -0
- package/src/lib/app-builder.js +105 -0
- package/src/lib/audit-logger.js +379 -0
- package/src/lib/automation-engine.js +330 -0
- package/src/lib/autonomous-agent.js +105 -0
- package/src/lib/autonomous-developer.js +350 -0
- package/src/lib/bi-engine.js +105 -0
- package/src/lib/bm25-search.js +81 -0
- package/src/lib/browser-automation.js +105 -0
- package/src/lib/code-agent.js +323 -0
- package/src/lib/collaboration-governance.js +364 -0
- package/src/lib/community-governance.js +436 -0
- package/src/lib/compliance-framework-reporter.js +105 -0
- package/src/lib/compliance-manager.js +434 -0
- package/src/lib/compression-telemetry.js +81 -0
- package/src/lib/content-recommendation.js +469 -0
- package/src/lib/content-recommender.js +105 -0
- package/src/lib/cowork-cron.js +81 -0
- package/src/lib/cowork-task-runner.js +105 -0
- package/src/lib/cross-chain.js +105 -0
- package/src/lib/crypto-manager.js +350 -0
- package/src/lib/dao-governance.js +105 -0
- package/src/lib/dbevo.js +338 -0
- package/src/lib/decentral-infra.js +340 -0
- package/src/lib/did-manager.js +367 -0
- package/src/lib/dlp-engine.js +105 -0
- package/src/lib/evolution-system.js +105 -0
- package/src/lib/evomap-manager.js +105 -0
- package/src/lib/execution-backend.js +105 -0
- package/src/lib/feature-flags.js +85 -0
- package/src/lib/git-integration.js +105 -0
- package/src/lib/hardening-manager.js +348 -0
- package/src/lib/hierarchical-memory.js +105 -0
- package/src/lib/hook-manager.js +380 -0
- package/src/lib/inference-network.js +105 -0
- package/src/lib/instinct-manager.js +332 -0
- package/src/lib/ipfs-storage.js +334 -0
- package/src/lib/iteration-budget.js +105 -0
- package/src/lib/knowledge-exporter.js +381 -0
- package/src/lib/knowledge-graph.js +432 -0
- package/src/lib/knowledge-importer.js +379 -0
- package/src/lib/llm-providers.js +391 -0
- package/src/lib/matrix-bridge.js +105 -0
- package/src/lib/mcp-registry.js +333 -0
- package/src/lib/mcp-scaffold.js +81 -0
- package/src/lib/memory-injection.js +81 -0
- package/src/lib/memory-manager.js +330 -0
- package/src/lib/multimodal.js +346 -0
- package/src/lib/nl-programming.js +343 -0
- package/src/lib/nostr-bridge.js +105 -0
- package/src/lib/note-versioning.js +327 -0
- package/src/lib/orchestrator.js +105 -0
- package/src/lib/org-manager.js +323 -0
- package/src/lib/p2p-manager.js +387 -0
- package/src/lib/pdf-parser.js +81 -0
- package/src/lib/perception.js +346 -0
- package/src/lib/perf-tuning.js +109 -1
- package/src/lib/permanent-memory.js +320 -0
- package/src/lib/permission-engine.js +81 -0
- package/src/lib/pipeline-orchestrator.js +105 -0
- package/src/lib/plan-mode.js +81 -0
- package/src/lib/plugin-ecosystem.js +377 -0
- package/src/lib/pqc-manager.js +368 -0
- package/src/lib/prompt-compressor.js +1 -10
- package/src/lib/protocol-fusion.js +417 -0
- package/src/lib/quantization.js +325 -0
- package/src/lib/response-cache.js +327 -0
- package/src/lib/scim-manager.js +329 -0
- package/src/lib/service-container.js +81 -0
- package/src/lib/session-consolidator.js +105 -0
- package/src/lib/session-hooks.js +81 -0
- package/src/lib/session-manager.js +329 -0
- package/src/lib/session-search.js +81 -0
- package/src/lib/session-tail.js +81 -0
- package/src/lib/session-usage.js +83 -0
- package/src/lib/siem-exporter.js +105 -0
- package/src/lib/skill-loader.js +377 -0
- package/src/lib/slot-filler.js +81 -0
- package/src/lib/social-graph-analytics.js +81 -0
- package/src/lib/social-graph.js +81 -0
- package/src/lib/social-manager.js +326 -0
- package/src/lib/sso-manager.js +332 -0
- package/src/lib/sub-agent-registry.js +110 -0
- package/src/lib/sync-manager.js +326 -0
- package/src/lib/task-model-selector.js +81 -0
- package/src/lib/tech-learning-engine.js +369 -0
- package/src/lib/tenant-saas.js +460 -0
- package/src/lib/threat-intel.js +335 -0
- package/src/lib/todo-manager.js +105 -0
- package/src/lib/token-incentive.js +293 -0
- package/src/lib/token-tracker.js +329 -0
- package/src/lib/topic-classifier.js +105 -0
- package/src/lib/trust-security.js +390 -0
- package/src/lib/ueba.js +389 -0
- package/src/lib/universal-runtime.js +325 -0
- package/src/lib/user-profile.js +81 -0
- package/src/lib/version-checker.js +81 -0
- package/src/lib/wallet-manager.js +326 -0
- package/src/lib/web-fetch.js +81 -0
- package/src/lib/workflow-engine.js +322 -0
- package/src/lib/zkp-engine.js +105 -0
package/src/lib/ueba.js
CHANGED
|
@@ -401,3 +401,392 @@ export function loadAllBaselines(db) {
|
|
|
401
401
|
}
|
|
402
402
|
return deserializeBaseline(dict);
|
|
403
403
|
}
|
|
404
|
+
|
|
405
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
406
|
+
* V2 Surface — UEBA V2 (additive)
|
|
407
|
+
* Baseline maturity + investigation lifecycle + caps + auto-flip
|
|
408
|
+
* ═══════════════════════════════════════════════════════════════ */
|
|
409
|
+
|
|
410
|
+
export const BASELINE_MATURITY_V2 = Object.freeze({
|
|
411
|
+
DRAFT: "draft",
|
|
412
|
+
ACTIVE: "active",
|
|
413
|
+
STALE: "stale",
|
|
414
|
+
ARCHIVED: "archived",
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
export const INVESTIGATION_V2 = Object.freeze({
|
|
418
|
+
OPEN: "open",
|
|
419
|
+
INVESTIGATING: "investigating",
|
|
420
|
+
CLOSED: "closed",
|
|
421
|
+
DISMISSED: "dismissed",
|
|
422
|
+
ESCALATED: "escalated",
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
const _BASELINE_TRANS_V2 = new Map([
|
|
426
|
+
[
|
|
427
|
+
BASELINE_MATURITY_V2.DRAFT,
|
|
428
|
+
new Set([BASELINE_MATURITY_V2.ACTIVE, BASELINE_MATURITY_V2.ARCHIVED]),
|
|
429
|
+
],
|
|
430
|
+
[
|
|
431
|
+
BASELINE_MATURITY_V2.ACTIVE,
|
|
432
|
+
new Set([BASELINE_MATURITY_V2.STALE, BASELINE_MATURITY_V2.ARCHIVED]),
|
|
433
|
+
],
|
|
434
|
+
[
|
|
435
|
+
BASELINE_MATURITY_V2.STALE,
|
|
436
|
+
new Set([BASELINE_MATURITY_V2.ACTIVE, BASELINE_MATURITY_V2.ARCHIVED]),
|
|
437
|
+
],
|
|
438
|
+
[BASELINE_MATURITY_V2.ARCHIVED, new Set()],
|
|
439
|
+
]);
|
|
440
|
+
|
|
441
|
+
const _INVESTIGATION_TRANS_V2 = new Map([
|
|
442
|
+
[
|
|
443
|
+
INVESTIGATION_V2.OPEN,
|
|
444
|
+
new Set([
|
|
445
|
+
INVESTIGATION_V2.INVESTIGATING,
|
|
446
|
+
INVESTIGATION_V2.DISMISSED,
|
|
447
|
+
INVESTIGATION_V2.ESCALATED,
|
|
448
|
+
]),
|
|
449
|
+
],
|
|
450
|
+
[
|
|
451
|
+
INVESTIGATION_V2.INVESTIGATING,
|
|
452
|
+
new Set([
|
|
453
|
+
INVESTIGATION_V2.CLOSED,
|
|
454
|
+
INVESTIGATION_V2.ESCALATED,
|
|
455
|
+
INVESTIGATION_V2.DISMISSED,
|
|
456
|
+
]),
|
|
457
|
+
],
|
|
458
|
+
[INVESTIGATION_V2.CLOSED, new Set()],
|
|
459
|
+
[INVESTIGATION_V2.DISMISSED, new Set()],
|
|
460
|
+
[INVESTIGATION_V2.ESCALATED, new Set()],
|
|
461
|
+
]);
|
|
462
|
+
|
|
463
|
+
const _BASELINE_TERMINAL_V2 = new Set([BASELINE_MATURITY_V2.ARCHIVED]);
|
|
464
|
+
const _INVESTIGATION_TERMINAL_V2 = new Set([
|
|
465
|
+
INVESTIGATION_V2.CLOSED,
|
|
466
|
+
INVESTIGATION_V2.DISMISSED,
|
|
467
|
+
INVESTIGATION_V2.ESCALATED,
|
|
468
|
+
]);
|
|
469
|
+
|
|
470
|
+
export const UEBA_DEFAULT_MAX_ACTIVE_BASELINES_PER_OWNER = 20;
|
|
471
|
+
export const UEBA_DEFAULT_MAX_OPEN_INVESTIGATIONS_PER_ANALYST = 10;
|
|
472
|
+
export const UEBA_DEFAULT_BASELINE_STALE_MS = 30 * 24 * 60 * 60 * 1000;
|
|
473
|
+
export const UEBA_DEFAULT_INVESTIGATION_STUCK_MS = 14 * 24 * 60 * 60 * 1000;
|
|
474
|
+
|
|
475
|
+
let _uebaMaxActiveBaselines = UEBA_DEFAULT_MAX_ACTIVE_BASELINES_PER_OWNER;
|
|
476
|
+
let _uebaMaxOpenInvestigations =
|
|
477
|
+
UEBA_DEFAULT_MAX_OPEN_INVESTIGATIONS_PER_ANALYST;
|
|
478
|
+
let _uebaBaselineStaleMs = UEBA_DEFAULT_BASELINE_STALE_MS;
|
|
479
|
+
let _uebaInvestigationStuckMs = UEBA_DEFAULT_INVESTIGATION_STUCK_MS;
|
|
480
|
+
|
|
481
|
+
const _baselinesV2 = new Map();
|
|
482
|
+
const _investigationsV2 = new Map();
|
|
483
|
+
|
|
484
|
+
function _posIntUebaV2(n, label) {
|
|
485
|
+
const v = Number.isInteger(n) ? n : Math.floor(n);
|
|
486
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
487
|
+
throw new Error(`${label} must be a positive integer`);
|
|
488
|
+
return v;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export function getMaxActiveBaselinesPerOwnerV2() {
|
|
492
|
+
return _uebaMaxActiveBaselines;
|
|
493
|
+
}
|
|
494
|
+
export function setMaxActiveBaselinesPerOwnerV2(n) {
|
|
495
|
+
_uebaMaxActiveBaselines = _posIntUebaV2(n, "maxActiveBaselinesPerOwner");
|
|
496
|
+
return _uebaMaxActiveBaselines;
|
|
497
|
+
}
|
|
498
|
+
export function getMaxOpenInvestigationsPerAnalystV2() {
|
|
499
|
+
return _uebaMaxOpenInvestigations;
|
|
500
|
+
}
|
|
501
|
+
export function setMaxOpenInvestigationsPerAnalystV2(n) {
|
|
502
|
+
_uebaMaxOpenInvestigations = _posIntUebaV2(
|
|
503
|
+
n,
|
|
504
|
+
"maxOpenInvestigationsPerAnalyst",
|
|
505
|
+
);
|
|
506
|
+
return _uebaMaxOpenInvestigations;
|
|
507
|
+
}
|
|
508
|
+
export function getBaselineStaleMsV2() {
|
|
509
|
+
return _uebaBaselineStaleMs;
|
|
510
|
+
}
|
|
511
|
+
export function setBaselineStaleMsV2(n) {
|
|
512
|
+
_uebaBaselineStaleMs = _posIntUebaV2(n, "baselineStaleMs");
|
|
513
|
+
return _uebaBaselineStaleMs;
|
|
514
|
+
}
|
|
515
|
+
export function getInvestigationStuckMsV2() {
|
|
516
|
+
return _uebaInvestigationStuckMs;
|
|
517
|
+
}
|
|
518
|
+
export function setInvestigationStuckMsV2(n) {
|
|
519
|
+
_uebaInvestigationStuckMs = _posIntUebaV2(n, "investigationStuckMs");
|
|
520
|
+
return _uebaInvestigationStuckMs;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
export function getActiveBaselineCountV2(owner) {
|
|
524
|
+
if (!owner) throw new Error("owner is required");
|
|
525
|
+
let c = 0;
|
|
526
|
+
for (const b of _baselinesV2.values()) {
|
|
527
|
+
if (b.owner !== owner) continue;
|
|
528
|
+
if (b.status === BASELINE_MATURITY_V2.ARCHIVED) continue;
|
|
529
|
+
if (b.status === BASELINE_MATURITY_V2.DRAFT) continue;
|
|
530
|
+
c++;
|
|
531
|
+
}
|
|
532
|
+
return c;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
export function getOpenInvestigationCountV2(analyst) {
|
|
536
|
+
if (!analyst) throw new Error("analyst is required");
|
|
537
|
+
let c = 0;
|
|
538
|
+
for (const i of _investigationsV2.values()) {
|
|
539
|
+
if (i.analyst !== analyst) continue;
|
|
540
|
+
if (_INVESTIGATION_TERMINAL_V2.has(i.status)) continue;
|
|
541
|
+
c++;
|
|
542
|
+
}
|
|
543
|
+
return c;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
export function createBaselineV2({ id, owner, entity, metadata }) {
|
|
547
|
+
if (!id) throw new Error("id is required");
|
|
548
|
+
if (!owner) throw new Error("owner is required");
|
|
549
|
+
if (!entity) throw new Error("entity is required");
|
|
550
|
+
if (_baselinesV2.has(id)) throw new Error(`baseline ${id} already exists`);
|
|
551
|
+
const now = Date.now();
|
|
552
|
+
const baseline = {
|
|
553
|
+
id,
|
|
554
|
+
owner,
|
|
555
|
+
entity: String(entity),
|
|
556
|
+
status: BASELINE_MATURITY_V2.DRAFT,
|
|
557
|
+
createdAt: now,
|
|
558
|
+
updatedAt: now,
|
|
559
|
+
activatedAt: null,
|
|
560
|
+
lastRefreshedAt: now,
|
|
561
|
+
metadata: metadata ? { ...metadata } : {},
|
|
562
|
+
};
|
|
563
|
+
_baselinesV2.set(id, baseline);
|
|
564
|
+
return { ...baseline, metadata: { ...baseline.metadata } };
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
export function getBaselineV2(id) {
|
|
568
|
+
const b = _baselinesV2.get(id);
|
|
569
|
+
if (!b) return null;
|
|
570
|
+
return { ...b, metadata: { ...b.metadata } };
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
export function listBaselinesV2({ owner, status } = {}) {
|
|
574
|
+
const out = [];
|
|
575
|
+
for (const b of _baselinesV2.values()) {
|
|
576
|
+
if (owner && b.owner !== owner) continue;
|
|
577
|
+
if (status && b.status !== status) continue;
|
|
578
|
+
out.push({ ...b, metadata: { ...b.metadata } });
|
|
579
|
+
}
|
|
580
|
+
return out;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
export function setBaselineMaturityV2(
|
|
584
|
+
id,
|
|
585
|
+
nextStatus,
|
|
586
|
+
{ reason, metadata } = {},
|
|
587
|
+
) {
|
|
588
|
+
const b = _baselinesV2.get(id);
|
|
589
|
+
if (!b) throw new Error(`baseline ${id} not found`);
|
|
590
|
+
if (!_BASELINE_TRANS_V2.has(b.status))
|
|
591
|
+
throw new Error(`unknown status ${b.status}`);
|
|
592
|
+
const allowed = _BASELINE_TRANS_V2.get(b.status);
|
|
593
|
+
if (!allowed.has(nextStatus)) {
|
|
594
|
+
throw new Error(
|
|
595
|
+
`cannot transition baseline ${id} from ${b.status} to ${nextStatus}`,
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
if (nextStatus === BASELINE_MATURITY_V2.ACTIVE) {
|
|
599
|
+
const wasActive =
|
|
600
|
+
b.status === BASELINE_MATURITY_V2.ACTIVE ||
|
|
601
|
+
b.status === BASELINE_MATURITY_V2.STALE;
|
|
602
|
+
if (
|
|
603
|
+
!wasActive &&
|
|
604
|
+
getActiveBaselineCountV2(b.owner) >= _uebaMaxActiveBaselines
|
|
605
|
+
) {
|
|
606
|
+
throw new Error(
|
|
607
|
+
`owner ${b.owner} exceeds max active baseline cap ${_uebaMaxActiveBaselines}`,
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
const now = Date.now();
|
|
612
|
+
b.status = nextStatus;
|
|
613
|
+
b.updatedAt = now;
|
|
614
|
+
b.lastRefreshedAt = now;
|
|
615
|
+
if (nextStatus === BASELINE_MATURITY_V2.ACTIVE && !b.activatedAt)
|
|
616
|
+
b.activatedAt = now;
|
|
617
|
+
if (reason) b.reason = reason;
|
|
618
|
+
if (metadata) b.metadata = { ...b.metadata, ...metadata };
|
|
619
|
+
return { ...b, metadata: { ...b.metadata } };
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
export function activateBaselineV2(id, opts) {
|
|
623
|
+
return setBaselineMaturityV2(id, BASELINE_MATURITY_V2.ACTIVE, opts);
|
|
624
|
+
}
|
|
625
|
+
export function markBaselineStaleV2(id, opts) {
|
|
626
|
+
return setBaselineMaturityV2(id, BASELINE_MATURITY_V2.STALE, opts);
|
|
627
|
+
}
|
|
628
|
+
export function archiveBaselineV2(id, opts) {
|
|
629
|
+
return setBaselineMaturityV2(id, BASELINE_MATURITY_V2.ARCHIVED, opts);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
export function refreshBaselineV2(id) {
|
|
633
|
+
const b = _baselinesV2.get(id);
|
|
634
|
+
if (!b) throw new Error(`baseline ${id} not found`);
|
|
635
|
+
if (_BASELINE_TERMINAL_V2.has(b.status))
|
|
636
|
+
throw new Error(`baseline ${id} is terminal`);
|
|
637
|
+
b.lastRefreshedAt = Date.now();
|
|
638
|
+
return { ...b, metadata: { ...b.metadata } };
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
export function openInvestigationV2({
|
|
642
|
+
id,
|
|
643
|
+
analyst,
|
|
644
|
+
baselineId,
|
|
645
|
+
summary,
|
|
646
|
+
metadata,
|
|
647
|
+
}) {
|
|
648
|
+
if (!id) throw new Error("id is required");
|
|
649
|
+
if (!analyst) throw new Error("analyst is required");
|
|
650
|
+
if (!baselineId) throw new Error("baselineId is required");
|
|
651
|
+
if (!_baselinesV2.has(baselineId))
|
|
652
|
+
throw new Error(`baseline ${baselineId} not found`);
|
|
653
|
+
if (_investigationsV2.has(id))
|
|
654
|
+
throw new Error(`investigation ${id} already exists`);
|
|
655
|
+
if (getOpenInvestigationCountV2(analyst) >= _uebaMaxOpenInvestigations) {
|
|
656
|
+
throw new Error(
|
|
657
|
+
`analyst ${analyst} exceeds max open investigation cap ${_uebaMaxOpenInvestigations}`,
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
const now = Date.now();
|
|
661
|
+
const inv = {
|
|
662
|
+
id,
|
|
663
|
+
analyst,
|
|
664
|
+
baselineId,
|
|
665
|
+
summary: summary ? String(summary) : "",
|
|
666
|
+
status: INVESTIGATION_V2.OPEN,
|
|
667
|
+
createdAt: now,
|
|
668
|
+
updatedAt: now,
|
|
669
|
+
startedAt: null,
|
|
670
|
+
closedAt: null,
|
|
671
|
+
metadata: metadata ? { ...metadata } : {},
|
|
672
|
+
};
|
|
673
|
+
_investigationsV2.set(id, inv);
|
|
674
|
+
return { ...inv, metadata: { ...inv.metadata } };
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
export function getInvestigationV2(id) {
|
|
678
|
+
const i = _investigationsV2.get(id);
|
|
679
|
+
if (!i) return null;
|
|
680
|
+
return { ...i, metadata: { ...i.metadata } };
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
export function listInvestigationsV2({ analyst, status, baselineId } = {}) {
|
|
684
|
+
const out = [];
|
|
685
|
+
for (const i of _investigationsV2.values()) {
|
|
686
|
+
if (analyst && i.analyst !== analyst) continue;
|
|
687
|
+
if (status && i.status !== status) continue;
|
|
688
|
+
if (baselineId && i.baselineId !== baselineId) continue;
|
|
689
|
+
out.push({ ...i, metadata: { ...i.metadata } });
|
|
690
|
+
}
|
|
691
|
+
return out;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
export function setInvestigationStatusV2(
|
|
695
|
+
id,
|
|
696
|
+
nextStatus,
|
|
697
|
+
{ reason, metadata } = {},
|
|
698
|
+
) {
|
|
699
|
+
const i = _investigationsV2.get(id);
|
|
700
|
+
if (!i) throw new Error(`investigation ${id} not found`);
|
|
701
|
+
if (!_INVESTIGATION_TRANS_V2.has(i.status))
|
|
702
|
+
throw new Error(`unknown status ${i.status}`);
|
|
703
|
+
const allowed = _INVESTIGATION_TRANS_V2.get(i.status);
|
|
704
|
+
if (!allowed.has(nextStatus)) {
|
|
705
|
+
throw new Error(
|
|
706
|
+
`cannot transition investigation ${id} from ${i.status} to ${nextStatus}`,
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
const now = Date.now();
|
|
710
|
+
i.status = nextStatus;
|
|
711
|
+
i.updatedAt = now;
|
|
712
|
+
if (nextStatus === INVESTIGATION_V2.INVESTIGATING && !i.startedAt)
|
|
713
|
+
i.startedAt = now;
|
|
714
|
+
if (_INVESTIGATION_TERMINAL_V2.has(nextStatus)) i.closedAt = now;
|
|
715
|
+
if (reason) i.reason = reason;
|
|
716
|
+
if (metadata) i.metadata = { ...i.metadata, ...metadata };
|
|
717
|
+
return { ...i, metadata: { ...i.metadata } };
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
export function startInvestigationV2(id, opts) {
|
|
721
|
+
return setInvestigationStatusV2(id, INVESTIGATION_V2.INVESTIGATING, opts);
|
|
722
|
+
}
|
|
723
|
+
export function closeInvestigationV2(id, opts) {
|
|
724
|
+
return setInvestigationStatusV2(id, INVESTIGATION_V2.CLOSED, opts);
|
|
725
|
+
}
|
|
726
|
+
export function dismissInvestigationV2(id, opts) {
|
|
727
|
+
return setInvestigationStatusV2(id, INVESTIGATION_V2.DISMISSED, opts);
|
|
728
|
+
}
|
|
729
|
+
export function escalateInvestigationV2(id, opts) {
|
|
730
|
+
return setInvestigationStatusV2(id, INVESTIGATION_V2.ESCALATED, opts);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
export function autoMarkStaleBaselinesV2({ now } = {}) {
|
|
734
|
+
const t = now ?? Date.now();
|
|
735
|
+
const out = [];
|
|
736
|
+
for (const b of _baselinesV2.values()) {
|
|
737
|
+
if (b.status !== BASELINE_MATURITY_V2.ACTIVE) continue;
|
|
738
|
+
if (t - b.lastRefreshedAt > _uebaBaselineStaleMs) {
|
|
739
|
+
b.status = BASELINE_MATURITY_V2.STALE;
|
|
740
|
+
b.updatedAt = t;
|
|
741
|
+
out.push(b.id);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
return out;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
export function autoEscalateStuckInvestigationsV2({ now } = {}) {
|
|
748
|
+
const t = now ?? Date.now();
|
|
749
|
+
const out = [];
|
|
750
|
+
for (const i of _investigationsV2.values()) {
|
|
751
|
+
if (i.status !== INVESTIGATION_V2.INVESTIGATING) continue;
|
|
752
|
+
if (i.startedAt == null) continue;
|
|
753
|
+
if (t - i.startedAt > _uebaInvestigationStuckMs) {
|
|
754
|
+
i.status = INVESTIGATION_V2.ESCALATED;
|
|
755
|
+
i.closedAt = t;
|
|
756
|
+
i.updatedAt = t;
|
|
757
|
+
i.reason = i.reason || "auto-escalate: stuck investigating";
|
|
758
|
+
out.push(i.id);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return out;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
export function getUebaStatsV2() {
|
|
765
|
+
const baselinesByStatus = {};
|
|
766
|
+
for (const v of Object.values(BASELINE_MATURITY_V2)) baselinesByStatus[v] = 0;
|
|
767
|
+
for (const b of _baselinesV2.values()) baselinesByStatus[b.status]++;
|
|
768
|
+
const investigationsByStatus = {};
|
|
769
|
+
for (const v of Object.values(INVESTIGATION_V2))
|
|
770
|
+
investigationsByStatus[v] = 0;
|
|
771
|
+
for (const i of _investigationsV2.values())
|
|
772
|
+
investigationsByStatus[i.status]++;
|
|
773
|
+
return {
|
|
774
|
+
totalBaselinesV2: _baselinesV2.size,
|
|
775
|
+
totalInvestigationsV2: _investigationsV2.size,
|
|
776
|
+
maxActiveBaselinesPerOwner: _uebaMaxActiveBaselines,
|
|
777
|
+
maxOpenInvestigationsPerAnalyst: _uebaMaxOpenInvestigations,
|
|
778
|
+
baselineStaleMs: _uebaBaselineStaleMs,
|
|
779
|
+
investigationStuckMs: _uebaInvestigationStuckMs,
|
|
780
|
+
baselinesByStatus,
|
|
781
|
+
investigationsByStatus,
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
export function _resetStateUebaV2() {
|
|
786
|
+
_baselinesV2.clear();
|
|
787
|
+
_investigationsV2.clear();
|
|
788
|
+
_uebaMaxActiveBaselines = UEBA_DEFAULT_MAX_ACTIVE_BASELINES_PER_OWNER;
|
|
789
|
+
_uebaMaxOpenInvestigations = UEBA_DEFAULT_MAX_OPEN_INVESTIGATIONS_PER_ANALYST;
|
|
790
|
+
_uebaBaselineStaleMs = UEBA_DEFAULT_BASELINE_STALE_MS;
|
|
791
|
+
_uebaInvestigationStuckMs = UEBA_DEFAULT_INVESTIGATION_STUCK_MS;
|
|
792
|
+
}
|