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
|
@@ -281,10 +281,444 @@ export function checkAccess(resource, action, role) {
|
|
|
281
281
|
};
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
285
|
+
V2 SURFACE (Phase 19 canonical) — strictly additive
|
|
286
|
+
═══════════════════════════════════════════════════════════════ */
|
|
287
|
+
|
|
288
|
+
export const EVIDENCE_STATUS_V2 = Object.freeze({
|
|
289
|
+
COLLECTED: "collected",
|
|
290
|
+
VERIFIED: "verified",
|
|
291
|
+
REJECTED: "rejected",
|
|
292
|
+
EXPIRED: "expired",
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
export const POLICY_STATUS_V2 = Object.freeze({
|
|
296
|
+
DRAFT: "draft",
|
|
297
|
+
ACTIVE: "active",
|
|
298
|
+
SUSPENDED: "suspended",
|
|
299
|
+
DEPRECATED: "deprecated",
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
export const REPORT_STATUS_V2 = Object.freeze({
|
|
303
|
+
PENDING: "pending",
|
|
304
|
+
GENERATING: "generating",
|
|
305
|
+
PUBLISHED: "published",
|
|
306
|
+
ARCHIVED: "archived",
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
export const SEVERITY_V2 = Object.freeze({
|
|
310
|
+
CRITICAL: "critical",
|
|
311
|
+
HIGH: "high",
|
|
312
|
+
MEDIUM: "medium",
|
|
313
|
+
LOW: "low",
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
export const FRAMEWORKS_V2 = Object.freeze([
|
|
317
|
+
"gdpr",
|
|
318
|
+
"soc2",
|
|
319
|
+
"hipaa",
|
|
320
|
+
"iso27001",
|
|
321
|
+
]);
|
|
322
|
+
export const POLICY_TYPES_V2 = Object.freeze([
|
|
323
|
+
"retention",
|
|
324
|
+
"access_control",
|
|
325
|
+
"encryption",
|
|
326
|
+
"data_classification",
|
|
327
|
+
"audit_trail",
|
|
328
|
+
]);
|
|
329
|
+
|
|
330
|
+
export const COMPLIANCE_DEFAULT_MAX_ACTIVE_POLICIES = 20;
|
|
331
|
+
export const COMPLIANCE_DEFAULT_EVIDENCE_RETENTION_MS =
|
|
332
|
+
180 * 24 * 60 * 60 * 1000; // 180 days
|
|
333
|
+
export const COMPLIANCE_DEFAULT_REPORT_RETENTION_MS = 365 * 24 * 60 * 60 * 1000; // 365 days
|
|
334
|
+
|
|
335
|
+
let _maxActivePolicies = COMPLIANCE_DEFAULT_MAX_ACTIVE_POLICIES;
|
|
336
|
+
let _evidenceRetentionMs = COMPLIANCE_DEFAULT_EVIDENCE_RETENTION_MS;
|
|
337
|
+
let _reportRetentionMs = COMPLIANCE_DEFAULT_REPORT_RETENTION_MS;
|
|
338
|
+
|
|
339
|
+
const _evidenceStatesV2 = new Map();
|
|
340
|
+
const _policyStatesV2 = new Map();
|
|
341
|
+
const _reportStatesV2 = new Map();
|
|
342
|
+
|
|
343
|
+
const EVIDENCE_TRANSITIONS_V2 = new Map([
|
|
344
|
+
["collected", new Set(["verified", "rejected", "expired"])],
|
|
345
|
+
["verified", new Set(["expired"])],
|
|
346
|
+
["rejected", new Set(["expired"])],
|
|
347
|
+
]);
|
|
348
|
+
const EVIDENCE_TERMINALS_V2 = new Set(["expired"]);
|
|
349
|
+
|
|
350
|
+
const POLICY_TRANSITIONS_V2 = new Map([
|
|
351
|
+
["draft", new Set(["active", "deprecated"])],
|
|
352
|
+
["active", new Set(["suspended", "deprecated"])],
|
|
353
|
+
["suspended", new Set(["active", "deprecated"])],
|
|
354
|
+
]);
|
|
355
|
+
const POLICY_TERMINALS_V2 = new Set(["deprecated"]);
|
|
356
|
+
|
|
357
|
+
const REPORT_TRANSITIONS_V2 = new Map([
|
|
358
|
+
["pending", new Set(["generating", "archived"])],
|
|
359
|
+
["generating", new Set(["published", "archived"])],
|
|
360
|
+
["published", new Set(["archived"])],
|
|
361
|
+
]);
|
|
362
|
+
const REPORT_TERMINALS_V2 = new Set(["archived"]);
|
|
363
|
+
|
|
364
|
+
function _positiveInt(n, label) {
|
|
365
|
+
const v = Number(n);
|
|
366
|
+
if (!Number.isFinite(v) || v <= 0) {
|
|
367
|
+
throw new Error(`${label} must be a positive integer`);
|
|
368
|
+
}
|
|
369
|
+
return Math.floor(v);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export function setMaxActivePolicies(n) {
|
|
373
|
+
_maxActivePolicies = _positiveInt(n, "maxActivePolicies");
|
|
374
|
+
return _maxActivePolicies;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export function setEvidenceRetentionMs(ms) {
|
|
378
|
+
_evidenceRetentionMs = _positiveInt(ms, "evidenceRetentionMs");
|
|
379
|
+
return _evidenceRetentionMs;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
export function setReportRetentionMs(ms) {
|
|
383
|
+
_reportRetentionMs = _positiveInt(ms, "reportRetentionMs");
|
|
384
|
+
return _reportRetentionMs;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export function getMaxActivePolicies() {
|
|
388
|
+
return _maxActivePolicies;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
export function getEvidenceRetentionMs() {
|
|
392
|
+
return _evidenceRetentionMs;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export function getReportRetentionMs() {
|
|
396
|
+
return _reportRetentionMs;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export function getActivePolicyCount(framework) {
|
|
400
|
+
let count = 0;
|
|
401
|
+
for (const entry of _policyStatesV2.values()) {
|
|
402
|
+
if (entry.status === POLICY_STATUS_V2.ACTIVE) {
|
|
403
|
+
if (!framework || entry.framework === framework) count += 1;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return count;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/* ── Evidence V2 ────────────────────────────────────────────── */
|
|
410
|
+
|
|
411
|
+
export function registerEvidenceV2(
|
|
412
|
+
db,
|
|
413
|
+
{ evidenceId, framework, type, description, source, metadata } = {},
|
|
414
|
+
) {
|
|
415
|
+
if (!evidenceId) throw new Error("evidenceId is required");
|
|
416
|
+
if (!framework) throw new Error("framework is required");
|
|
417
|
+
if (!FRAMEWORKS_V2.includes(framework)) {
|
|
418
|
+
throw new Error(
|
|
419
|
+
`Invalid framework: ${framework}. Valid: ${FRAMEWORKS_V2.join(", ")}`,
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
if (_evidenceStatesV2.has(evidenceId)) {
|
|
423
|
+
throw new Error(`Evidence already registered: ${evidenceId}`);
|
|
424
|
+
}
|
|
425
|
+
const now = Date.now();
|
|
426
|
+
const entry = {
|
|
427
|
+
evidenceId,
|
|
428
|
+
framework,
|
|
429
|
+
type: type || "general",
|
|
430
|
+
description: description || "",
|
|
431
|
+
source: source || "cli",
|
|
432
|
+
status: EVIDENCE_STATUS_V2.COLLECTED,
|
|
433
|
+
metadata: metadata || {},
|
|
434
|
+
reason: null,
|
|
435
|
+
createdAt: now,
|
|
436
|
+
updatedAt: now,
|
|
437
|
+
};
|
|
438
|
+
_evidenceStatesV2.set(evidenceId, entry);
|
|
439
|
+
return { ...entry };
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
export function getEvidenceStatusV2(evidenceId) {
|
|
443
|
+
const entry = _evidenceStatesV2.get(evidenceId);
|
|
444
|
+
return entry ? { ...entry } : null;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export function setEvidenceStatusV2(db, evidenceId, newStatus, patch = {}) {
|
|
448
|
+
const entry = _evidenceStatesV2.get(evidenceId);
|
|
449
|
+
if (!entry) throw new Error(`Evidence not found: ${evidenceId}`);
|
|
450
|
+
if (!Object.values(EVIDENCE_STATUS_V2).includes(newStatus)) {
|
|
451
|
+
throw new Error(`Invalid evidence status: ${newStatus}`);
|
|
452
|
+
}
|
|
453
|
+
if (EVIDENCE_TERMINALS_V2.has(entry.status)) {
|
|
454
|
+
throw new Error(`Evidence is terminal: ${entry.status}`);
|
|
455
|
+
}
|
|
456
|
+
const allowed = EVIDENCE_TRANSITIONS_V2.get(entry.status) || new Set();
|
|
457
|
+
if (!allowed.has(newStatus)) {
|
|
458
|
+
throw new Error(`Invalid transition: ${entry.status} → ${newStatus}`);
|
|
459
|
+
}
|
|
460
|
+
entry.status = newStatus;
|
|
461
|
+
entry.updatedAt = Date.now();
|
|
462
|
+
if (patch.reason !== undefined) entry.reason = patch.reason;
|
|
463
|
+
if (patch.metadata) entry.metadata = { ...entry.metadata, ...patch.metadata };
|
|
464
|
+
return { ...entry };
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
export function autoExpireEvidence(db, nowMs = Date.now()) {
|
|
468
|
+
const expired = [];
|
|
469
|
+
for (const entry of _evidenceStatesV2.values()) {
|
|
470
|
+
if (EVIDENCE_TERMINALS_V2.has(entry.status)) continue;
|
|
471
|
+
if (nowMs - entry.createdAt > _evidenceRetentionMs) {
|
|
472
|
+
entry.status = EVIDENCE_STATUS_V2.EXPIRED;
|
|
473
|
+
entry.updatedAt = nowMs;
|
|
474
|
+
entry.reason = "auto-expired: retention exceeded";
|
|
475
|
+
expired.push({ ...entry });
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return expired;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/* ── Policy V2 ──────────────────────────────────────────────── */
|
|
482
|
+
|
|
483
|
+
export function registerPolicyV2(
|
|
484
|
+
db,
|
|
485
|
+
{ policyId, name, type, framework, severity, rules, metadata } = {},
|
|
486
|
+
) {
|
|
487
|
+
if (!policyId) throw new Error("policyId is required");
|
|
488
|
+
if (!name) throw new Error("name is required");
|
|
489
|
+
if (!POLICY_TYPES_V2.includes(type)) {
|
|
490
|
+
throw new Error(
|
|
491
|
+
`Invalid policy type: ${type}. Valid: ${POLICY_TYPES_V2.join(", ")}`,
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
if (!FRAMEWORKS_V2.includes(framework)) {
|
|
495
|
+
throw new Error(
|
|
496
|
+
`Invalid framework: ${framework}. Valid: ${FRAMEWORKS_V2.join(", ")}`,
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
const sev = severity || SEVERITY_V2.MEDIUM;
|
|
500
|
+
if (!Object.values(SEVERITY_V2).includes(sev)) {
|
|
501
|
+
throw new Error(`Invalid severity: ${sev}`);
|
|
502
|
+
}
|
|
503
|
+
if (_policyStatesV2.has(policyId)) {
|
|
504
|
+
throw new Error(`Policy already registered: ${policyId}`);
|
|
505
|
+
}
|
|
506
|
+
const now = Date.now();
|
|
507
|
+
const entry = {
|
|
508
|
+
policyId,
|
|
509
|
+
name,
|
|
510
|
+
type,
|
|
511
|
+
framework,
|
|
512
|
+
severity: sev,
|
|
513
|
+
rules: rules || {},
|
|
514
|
+
status: POLICY_STATUS_V2.DRAFT,
|
|
515
|
+
metadata: metadata || {},
|
|
516
|
+
reason: null,
|
|
517
|
+
createdAt: now,
|
|
518
|
+
updatedAt: now,
|
|
519
|
+
};
|
|
520
|
+
_policyStatesV2.set(policyId, entry);
|
|
521
|
+
return { ...entry };
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
export function getPolicyStatusV2(policyId) {
|
|
525
|
+
const entry = _policyStatesV2.get(policyId);
|
|
526
|
+
return entry ? { ...entry } : null;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
export function setPolicyStatusV2(db, policyId, newStatus, patch = {}) {
|
|
530
|
+
const entry = _policyStatesV2.get(policyId);
|
|
531
|
+
if (!entry) throw new Error(`Policy not found: ${policyId}`);
|
|
532
|
+
if (!Object.values(POLICY_STATUS_V2).includes(newStatus)) {
|
|
533
|
+
throw new Error(`Invalid policy status: ${newStatus}`);
|
|
534
|
+
}
|
|
535
|
+
if (POLICY_TERMINALS_V2.has(entry.status)) {
|
|
536
|
+
throw new Error(`Policy is terminal: ${entry.status}`);
|
|
537
|
+
}
|
|
538
|
+
const allowed = POLICY_TRANSITIONS_V2.get(entry.status) || new Set();
|
|
539
|
+
if (!allowed.has(newStatus)) {
|
|
540
|
+
throw new Error(`Invalid transition: ${entry.status} → ${newStatus}`);
|
|
541
|
+
}
|
|
542
|
+
if (newStatus === POLICY_STATUS_V2.ACTIVE) {
|
|
543
|
+
const activeCount = getActivePolicyCount(entry.framework);
|
|
544
|
+
if (
|
|
545
|
+
entry.status !== POLICY_STATUS_V2.ACTIVE &&
|
|
546
|
+
activeCount >= _maxActivePolicies
|
|
547
|
+
) {
|
|
548
|
+
throw new Error(
|
|
549
|
+
`Max active policies reached (${activeCount}/${_maxActivePolicies}) for framework ${entry.framework}`,
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
entry.status = newStatus;
|
|
554
|
+
entry.updatedAt = Date.now();
|
|
555
|
+
if (patch.reason !== undefined) entry.reason = patch.reason;
|
|
556
|
+
if (patch.metadata) entry.metadata = { ...entry.metadata, ...patch.metadata };
|
|
557
|
+
return { ...entry };
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
export function activatePolicy(db, policyId) {
|
|
561
|
+
return setPolicyStatusV2(db, policyId, POLICY_STATUS_V2.ACTIVE);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/* ── Report V2 ──────────────────────────────────────────────── */
|
|
565
|
+
|
|
566
|
+
export function registerReportV2(
|
|
567
|
+
db,
|
|
568
|
+
{ reportId, framework, title, metadata } = {},
|
|
569
|
+
) {
|
|
570
|
+
if (!reportId) throw new Error("reportId is required");
|
|
571
|
+
if (!framework) throw new Error("framework is required");
|
|
572
|
+
if (!FRAMEWORKS_V2.includes(framework)) {
|
|
573
|
+
throw new Error(`Invalid framework: ${framework}`);
|
|
574
|
+
}
|
|
575
|
+
if (_reportStatesV2.has(reportId)) {
|
|
576
|
+
throw new Error(`Report already registered: ${reportId}`);
|
|
577
|
+
}
|
|
578
|
+
const now = Date.now();
|
|
579
|
+
const entry = {
|
|
580
|
+
reportId,
|
|
581
|
+
framework,
|
|
582
|
+
title: title || `${framework.toUpperCase()} Compliance Report`,
|
|
583
|
+
status: REPORT_STATUS_V2.PENDING,
|
|
584
|
+
score: 0,
|
|
585
|
+
summary: "",
|
|
586
|
+
metadata: metadata || {},
|
|
587
|
+
reason: null,
|
|
588
|
+
createdAt: now,
|
|
589
|
+
updatedAt: now,
|
|
590
|
+
publishedAt: null,
|
|
591
|
+
};
|
|
592
|
+
_reportStatesV2.set(reportId, entry);
|
|
593
|
+
return { ...entry };
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
export function getReportStatusV2(reportId) {
|
|
597
|
+
const entry = _reportStatesV2.get(reportId);
|
|
598
|
+
return entry ? { ...entry } : null;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
export function setReportStatusV2(db, reportId, newStatus, patch = {}) {
|
|
602
|
+
const entry = _reportStatesV2.get(reportId);
|
|
603
|
+
if (!entry) throw new Error(`Report not found: ${reportId}`);
|
|
604
|
+
if (!Object.values(REPORT_STATUS_V2).includes(newStatus)) {
|
|
605
|
+
throw new Error(`Invalid report status: ${newStatus}`);
|
|
606
|
+
}
|
|
607
|
+
if (REPORT_TERMINALS_V2.has(entry.status)) {
|
|
608
|
+
throw new Error(`Report is terminal: ${entry.status}`);
|
|
609
|
+
}
|
|
610
|
+
const allowed = REPORT_TRANSITIONS_V2.get(entry.status) || new Set();
|
|
611
|
+
if (!allowed.has(newStatus)) {
|
|
612
|
+
throw new Error(`Invalid transition: ${entry.status} → ${newStatus}`);
|
|
613
|
+
}
|
|
614
|
+
entry.status = newStatus;
|
|
615
|
+
entry.updatedAt = Date.now();
|
|
616
|
+
if (newStatus === REPORT_STATUS_V2.PUBLISHED) {
|
|
617
|
+
entry.publishedAt = entry.updatedAt;
|
|
618
|
+
if (typeof patch.score === "number") entry.score = patch.score;
|
|
619
|
+
if (typeof patch.summary === "string") entry.summary = patch.summary;
|
|
620
|
+
}
|
|
621
|
+
if (patch.reason !== undefined) entry.reason = patch.reason;
|
|
622
|
+
if (patch.metadata) entry.metadata = { ...entry.metadata, ...patch.metadata };
|
|
623
|
+
return { ...entry };
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
export function publishReport(db, reportId, { score, summary } = {}) {
|
|
627
|
+
const entry = _reportStatesV2.get(reportId);
|
|
628
|
+
if (!entry) throw new Error(`Report not found: ${reportId}`);
|
|
629
|
+
if (entry.status === REPORT_STATUS_V2.PENDING) {
|
|
630
|
+
setReportStatusV2(db, reportId, REPORT_STATUS_V2.GENERATING);
|
|
631
|
+
}
|
|
632
|
+
return setReportStatusV2(db, reportId, REPORT_STATUS_V2.PUBLISHED, {
|
|
633
|
+
score,
|
|
634
|
+
summary,
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
export function autoArchiveStaleReports(db, nowMs = Date.now()) {
|
|
639
|
+
const archived = [];
|
|
640
|
+
for (const entry of _reportStatesV2.values()) {
|
|
641
|
+
if (entry.status !== REPORT_STATUS_V2.PUBLISHED) continue;
|
|
642
|
+
if (!entry.publishedAt) continue;
|
|
643
|
+
if (nowMs - entry.publishedAt > _reportRetentionMs) {
|
|
644
|
+
entry.status = REPORT_STATUS_V2.ARCHIVED;
|
|
645
|
+
entry.updatedAt = nowMs;
|
|
646
|
+
entry.reason = "auto-archived: retention exceeded";
|
|
647
|
+
archived.push({ ...entry });
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
return archived;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/* ── Stats V2 ───────────────────────────────────────────────── */
|
|
654
|
+
|
|
655
|
+
export function getComplianceStatsV2() {
|
|
656
|
+
const evidenceByStatus = {
|
|
657
|
+
collected: 0,
|
|
658
|
+
verified: 0,
|
|
659
|
+
rejected: 0,
|
|
660
|
+
expired: 0,
|
|
661
|
+
};
|
|
662
|
+
const policyByStatus = {
|
|
663
|
+
draft: 0,
|
|
664
|
+
active: 0,
|
|
665
|
+
suspended: 0,
|
|
666
|
+
deprecated: 0,
|
|
667
|
+
};
|
|
668
|
+
const reportByStatus = {
|
|
669
|
+
pending: 0,
|
|
670
|
+
generating: 0,
|
|
671
|
+
published: 0,
|
|
672
|
+
archived: 0,
|
|
673
|
+
};
|
|
674
|
+
const policyBySeverity = {
|
|
675
|
+
critical: 0,
|
|
676
|
+
high: 0,
|
|
677
|
+
medium: 0,
|
|
678
|
+
low: 0,
|
|
679
|
+
};
|
|
680
|
+
|
|
681
|
+
for (const entry of _evidenceStatesV2.values()) {
|
|
682
|
+
if (evidenceByStatus[entry.status] !== undefined)
|
|
683
|
+
evidenceByStatus[entry.status] += 1;
|
|
684
|
+
}
|
|
685
|
+
for (const entry of _policyStatesV2.values()) {
|
|
686
|
+
if (policyByStatus[entry.status] !== undefined)
|
|
687
|
+
policyByStatus[entry.status] += 1;
|
|
688
|
+
if (policyBySeverity[entry.severity] !== undefined)
|
|
689
|
+
policyBySeverity[entry.severity] += 1;
|
|
690
|
+
}
|
|
691
|
+
for (const entry of _reportStatesV2.values()) {
|
|
692
|
+
if (reportByStatus[entry.status] !== undefined)
|
|
693
|
+
reportByStatus[entry.status] += 1;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
return {
|
|
697
|
+
totalEvidence: _evidenceStatesV2.size,
|
|
698
|
+
totalPolicies: _policyStatesV2.size,
|
|
699
|
+
activePolicies: policyByStatus.active,
|
|
700
|
+
totalReports: _reportStatesV2.size,
|
|
701
|
+
publishedReports: reportByStatus.published,
|
|
702
|
+
maxActivePolicies: _maxActivePolicies,
|
|
703
|
+
evidenceRetentionMs: _evidenceRetentionMs,
|
|
704
|
+
reportRetentionMs: _reportRetentionMs,
|
|
705
|
+
evidenceByStatus,
|
|
706
|
+
policyByStatus,
|
|
707
|
+
reportByStatus,
|
|
708
|
+
policyBySeverity,
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
|
|
284
712
|
/* ── Reset (for testing) ───────────────────────────────────── */
|
|
285
713
|
|
|
286
714
|
export function _resetState() {
|
|
287
715
|
_evidence.clear();
|
|
288
716
|
_reports.clear();
|
|
289
717
|
_policies.clear();
|
|
718
|
+
_evidenceStatesV2.clear();
|
|
719
|
+
_policyStatesV2.clear();
|
|
720
|
+
_reportStatesV2.clear();
|
|
721
|
+
_maxActivePolicies = COMPLIANCE_DEFAULT_MAX_ACTIVE_POLICIES;
|
|
722
|
+
_evidenceRetentionMs = COMPLIANCE_DEFAULT_EVIDENCE_RETENTION_MS;
|
|
723
|
+
_reportRetentionMs = COMPLIANCE_DEFAULT_REPORT_RETENTION_MS;
|
|
290
724
|
}
|
|
@@ -3,3 +3,84 @@ export {
|
|
|
3
3
|
getCompressionTelemetrySummary,
|
|
4
4
|
resetCompressionTelemetry,
|
|
5
5
|
} from "../harness/compression-telemetry.js";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
// =====================================================================
|
|
9
|
+
// Compression Telemetry V2 governance overlay
|
|
10
|
+
// =====================================================================
|
|
11
|
+
export const COMPT_PROFILE_MATURITY_V2 = Object.freeze({ PENDING: "pending", ACTIVE: "active", STALE: "stale", ARCHIVED: "archived" });
|
|
12
|
+
export const COMPT_SAMPLE_LIFECYCLE_V2 = Object.freeze({ QUEUED: "queued", RECORDING: "recording", RECORDED: "recorded", FAILED: "failed", CANCELLED: "cancelled" });
|
|
13
|
+
const _comptPTrans = new Map([
|
|
14
|
+
[COMPT_PROFILE_MATURITY_V2.PENDING, new Set([COMPT_PROFILE_MATURITY_V2.ACTIVE, COMPT_PROFILE_MATURITY_V2.ARCHIVED])],
|
|
15
|
+
[COMPT_PROFILE_MATURITY_V2.ACTIVE, new Set([COMPT_PROFILE_MATURITY_V2.STALE, COMPT_PROFILE_MATURITY_V2.ARCHIVED])],
|
|
16
|
+
[COMPT_PROFILE_MATURITY_V2.STALE, new Set([COMPT_PROFILE_MATURITY_V2.ACTIVE, COMPT_PROFILE_MATURITY_V2.ARCHIVED])],
|
|
17
|
+
[COMPT_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
18
|
+
]);
|
|
19
|
+
const _comptPTerminal = new Set([COMPT_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
20
|
+
const _comptJTrans = new Map([
|
|
21
|
+
[COMPT_SAMPLE_LIFECYCLE_V2.QUEUED, new Set([COMPT_SAMPLE_LIFECYCLE_V2.RECORDING, COMPT_SAMPLE_LIFECYCLE_V2.CANCELLED])],
|
|
22
|
+
[COMPT_SAMPLE_LIFECYCLE_V2.RECORDING, new Set([COMPT_SAMPLE_LIFECYCLE_V2.RECORDED, COMPT_SAMPLE_LIFECYCLE_V2.FAILED, COMPT_SAMPLE_LIFECYCLE_V2.CANCELLED])],
|
|
23
|
+
[COMPT_SAMPLE_LIFECYCLE_V2.RECORDED, new Set()],
|
|
24
|
+
[COMPT_SAMPLE_LIFECYCLE_V2.FAILED, new Set()],
|
|
25
|
+
[COMPT_SAMPLE_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
26
|
+
]);
|
|
27
|
+
const _comptPsV2 = new Map();
|
|
28
|
+
const _comptJsV2 = new Map();
|
|
29
|
+
let _comptMaxActive = 10, _comptMaxPending = 30, _comptIdleMs = 30 * 24 * 60 * 60 * 1000, _comptStuckMs = 30 * 1000;
|
|
30
|
+
function _comptPos(n, label) { const v = Math.floor(Number(n)); if (!Number.isFinite(v) || v <= 0) throw new Error(`${label} must be positive integer`); return v; }
|
|
31
|
+
function _comptCheckP(from, to) { const a = _comptPTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid compt profile transition ${from} → ${to}`); }
|
|
32
|
+
function _comptCheckJ(from, to) { const a = _comptJTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid compt sample transition ${from} → ${to}`); }
|
|
33
|
+
function _comptCountActive(owner) { let c = 0; for (const p of _comptPsV2.values()) if (p.owner === owner && p.status === COMPT_PROFILE_MATURITY_V2.ACTIVE) c++; return c; }
|
|
34
|
+
function _comptCountPending(profileId) { let c = 0; for (const j of _comptJsV2.values()) if (j.profileId === profileId && (j.status === COMPT_SAMPLE_LIFECYCLE_V2.QUEUED || j.status === COMPT_SAMPLE_LIFECYCLE_V2.RECORDING)) c++; return c; }
|
|
35
|
+
export function setMaxActiveComptProfilesPerOwnerV2(n) { _comptMaxActive = _comptPos(n, "maxActiveComptProfilesPerOwner"); }
|
|
36
|
+
export function getMaxActiveComptProfilesPerOwnerV2() { return _comptMaxActive; }
|
|
37
|
+
export function setMaxPendingComptSamplesPerProfileV2(n) { _comptMaxPending = _comptPos(n, "maxPendingComptSamplesPerProfile"); }
|
|
38
|
+
export function getMaxPendingComptSamplesPerProfileV2() { return _comptMaxPending; }
|
|
39
|
+
export function setComptProfileIdleMsV2(n) { _comptIdleMs = _comptPos(n, "comptProfileIdleMs"); }
|
|
40
|
+
export function getComptProfileIdleMsV2() { return _comptIdleMs; }
|
|
41
|
+
export function setComptSampleStuckMsV2(n) { _comptStuckMs = _comptPos(n, "comptSampleStuckMs"); }
|
|
42
|
+
export function getComptSampleStuckMsV2() { return _comptStuckMs; }
|
|
43
|
+
export function _resetStateCompressionTelemetryV2() { _comptPsV2.clear(); _comptJsV2.clear(); _comptMaxActive = 10; _comptMaxPending = 30; _comptIdleMs = 30 * 24 * 60 * 60 * 1000; _comptStuckMs = 30 * 1000; }
|
|
44
|
+
export function registerComptProfileV2({ id, owner, kind, metadata } = {}) {
|
|
45
|
+
if (!id || !owner) throw new Error("id and owner required");
|
|
46
|
+
if (_comptPsV2.has(id)) throw new Error(`compt profile ${id} already exists`);
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
const p = { id, owner, kind: kind || "default", status: COMPT_PROFILE_MATURITY_V2.PENDING, createdAt: now, updatedAt: now, lastTouchedAt: now, activatedAt: null, archivedAt: null, metadata: { ...(metadata || {}) } };
|
|
49
|
+
_comptPsV2.set(id, p); return { ...p, metadata: { ...p.metadata } };
|
|
50
|
+
}
|
|
51
|
+
export function activateComptProfileV2(id) {
|
|
52
|
+
const p = _comptPsV2.get(id); if (!p) throw new Error(`compt profile ${id} not found`);
|
|
53
|
+
const isInitial = p.status === COMPT_PROFILE_MATURITY_V2.PENDING;
|
|
54
|
+
_comptCheckP(p.status, COMPT_PROFILE_MATURITY_V2.ACTIVE);
|
|
55
|
+
if (isInitial && _comptCountActive(p.owner) >= _comptMaxActive) throw new Error(`max active compt profiles for owner ${p.owner} reached`);
|
|
56
|
+
const now = Date.now(); p.status = COMPT_PROFILE_MATURITY_V2.ACTIVE; p.updatedAt = now; p.lastTouchedAt = now;
|
|
57
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
58
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
59
|
+
}
|
|
60
|
+
export function staleComptProfileV2(id) { const p = _comptPsV2.get(id); if (!p) throw new Error(`compt profile ${id} not found`); _comptCheckP(p.status, COMPT_PROFILE_MATURITY_V2.STALE); p.status = COMPT_PROFILE_MATURITY_V2.STALE; p.updatedAt = Date.now(); return { ...p, metadata: { ...p.metadata } }; }
|
|
61
|
+
export function archiveComptProfileV2(id) { const p = _comptPsV2.get(id); if (!p) throw new Error(`compt profile ${id} not found`); _comptCheckP(p.status, COMPT_PROFILE_MATURITY_V2.ARCHIVED); const now = Date.now(); p.status = COMPT_PROFILE_MATURITY_V2.ARCHIVED; p.updatedAt = now; if (!p.archivedAt) p.archivedAt = now; return { ...p, metadata: { ...p.metadata } }; }
|
|
62
|
+
export function touchComptProfileV2(id) { const p = _comptPsV2.get(id); if (!p) throw new Error(`compt profile ${id} not found`); if (_comptPTerminal.has(p.status)) throw new Error(`cannot touch terminal compt profile ${id}`); const now = Date.now(); p.lastTouchedAt = now; p.updatedAt = now; return { ...p, metadata: { ...p.metadata } }; }
|
|
63
|
+
export function getComptProfileV2(id) { const p = _comptPsV2.get(id); if (!p) return null; return { ...p, metadata: { ...p.metadata } }; }
|
|
64
|
+
export function listComptProfilesV2() { return [..._comptPsV2.values()].map((p) => ({ ...p, metadata: { ...p.metadata } })); }
|
|
65
|
+
export function createComptSampleV2({ id, profileId, metric, metadata } = {}) {
|
|
66
|
+
if (!id || !profileId) throw new Error("id and profileId required");
|
|
67
|
+
if (_comptJsV2.has(id)) throw new Error(`compt sample ${id} already exists`);
|
|
68
|
+
if (!_comptPsV2.has(profileId)) throw new Error(`compt profile ${profileId} not found`);
|
|
69
|
+
if (_comptCountPending(profileId) >= _comptMaxPending) throw new Error(`max pending compt samples for profile ${profileId} reached`);
|
|
70
|
+
const now = Date.now();
|
|
71
|
+
const j = { id, profileId, metric: metric || "", status: COMPT_SAMPLE_LIFECYCLE_V2.QUEUED, createdAt: now, updatedAt: now, startedAt: null, settledAt: null, metadata: { ...(metadata || {}) } };
|
|
72
|
+
_comptJsV2.set(id, j); return { ...j, metadata: { ...j.metadata } };
|
|
73
|
+
}
|
|
74
|
+
export function recordingComptSampleV2(id) { const j = _comptJsV2.get(id); if (!j) throw new Error(`compt sample ${id} not found`); _comptCheckJ(j.status, COMPT_SAMPLE_LIFECYCLE_V2.RECORDING); const now = Date.now(); j.status = COMPT_SAMPLE_LIFECYCLE_V2.RECORDING; j.updatedAt = now; if (!j.startedAt) j.startedAt = now; return { ...j, metadata: { ...j.metadata } }; }
|
|
75
|
+
export function recordComptSampleV2(id) { const j = _comptJsV2.get(id); if (!j) throw new Error(`compt sample ${id} not found`); _comptCheckJ(j.status, COMPT_SAMPLE_LIFECYCLE_V2.RECORDED); const now = Date.now(); j.status = COMPT_SAMPLE_LIFECYCLE_V2.RECORDED; j.updatedAt = now; if (!j.settledAt) j.settledAt = now; return { ...j, metadata: { ...j.metadata } }; }
|
|
76
|
+
export function failComptSampleV2(id, reason) { const j = _comptJsV2.get(id); if (!j) throw new Error(`compt sample ${id} not found`); _comptCheckJ(j.status, COMPT_SAMPLE_LIFECYCLE_V2.FAILED); const now = Date.now(); j.status = COMPT_SAMPLE_LIFECYCLE_V2.FAILED; j.updatedAt = now; if (!j.settledAt) j.settledAt = now; if (reason) j.metadata.failReason = String(reason); return { ...j, metadata: { ...j.metadata } }; }
|
|
77
|
+
export function cancelComptSampleV2(id, reason) { const j = _comptJsV2.get(id); if (!j) throw new Error(`compt sample ${id} not found`); _comptCheckJ(j.status, COMPT_SAMPLE_LIFECYCLE_V2.CANCELLED); const now = Date.now(); j.status = COMPT_SAMPLE_LIFECYCLE_V2.CANCELLED; j.updatedAt = now; if (!j.settledAt) j.settledAt = now; if (reason) j.metadata.cancelReason = String(reason); return { ...j, metadata: { ...j.metadata } }; }
|
|
78
|
+
export function getComptSampleV2(id) { const j = _comptJsV2.get(id); if (!j) return null; return { ...j, metadata: { ...j.metadata } }; }
|
|
79
|
+
export function listComptSamplesV2() { return [..._comptJsV2.values()].map((j) => ({ ...j, metadata: { ...j.metadata } })); }
|
|
80
|
+
export function autoStaleIdleComptProfilesV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const p of _comptPsV2.values()) if (p.status === COMPT_PROFILE_MATURITY_V2.ACTIVE && (t - p.lastTouchedAt) >= _comptIdleMs) { p.status = COMPT_PROFILE_MATURITY_V2.STALE; p.updatedAt = t; flipped.push(p.id); } return { flipped, count: flipped.length }; }
|
|
81
|
+
export function autoFailStuckComptSamplesV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const j of _comptJsV2.values()) if (j.status === COMPT_SAMPLE_LIFECYCLE_V2.RECORDING && j.startedAt != null && (t - j.startedAt) >= _comptStuckMs) { j.status = COMPT_SAMPLE_LIFECYCLE_V2.FAILED; j.updatedAt = t; if (!j.settledAt) j.settledAt = t; j.metadata.failReason = "auto-fail-stuck"; flipped.push(j.id); } return { flipped, count: flipped.length }; }
|
|
82
|
+
export function getCompressionTelemetryGovStatsV2() {
|
|
83
|
+
const profilesByStatus = {}; for (const v of Object.values(COMPT_PROFILE_MATURITY_V2)) profilesByStatus[v] = 0; for (const p of _comptPsV2.values()) profilesByStatus[p.status]++;
|
|
84
|
+
const samplesByStatus = {}; for (const v of Object.values(COMPT_SAMPLE_LIFECYCLE_V2)) samplesByStatus[v] = 0; for (const j of _comptJsV2.values()) samplesByStatus[j.status]++;
|
|
85
|
+
return { totalComptProfilesV2: _comptPsV2.size, totalComptSamplesV2: _comptJsV2.size, maxActiveComptProfilesPerOwner: _comptMaxActive, maxPendingComptSamplesPerProfile: _comptMaxPending, comptProfileIdleMs: _comptIdleMs, comptSampleStuckMs: _comptStuckMs, profilesByStatus, samplesByStatus };
|
|
86
|
+
}
|