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
|
@@ -647,3 +647,439 @@ export function _resetState() {
|
|
|
647
647
|
_proposalVotes.clear();
|
|
648
648
|
_seq = 0;
|
|
649
649
|
}
|
|
650
|
+
|
|
651
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
652
|
+
* Phase 54 V2 — Proposer Maturity + Vote Delegation Lifecycle
|
|
653
|
+
* Strictly additive. Legacy surface above is preserved.
|
|
654
|
+
* ═════════════════════════════════════════════════════════════ */
|
|
655
|
+
|
|
656
|
+
export const PROPOSER_MATURITY_V2 = Object.freeze({
|
|
657
|
+
ONBOARDING: "onboarding",
|
|
658
|
+
ACTIVE: "active",
|
|
659
|
+
SUSPENDED: "suspended",
|
|
660
|
+
RETIRED: "retired",
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
export const DELEGATION_LIFECYCLE_V2 = Object.freeze({
|
|
664
|
+
PENDING: "pending",
|
|
665
|
+
ACTIVE: "active",
|
|
666
|
+
REVOKED: "revoked",
|
|
667
|
+
EXPIRED: "expired",
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
const PROPOSER_TRANSITIONS_V2 = new Map([
|
|
671
|
+
["onboarding", new Set(["active", "retired"])],
|
|
672
|
+
["active", new Set(["suspended", "retired"])],
|
|
673
|
+
["suspended", new Set(["active", "retired"])],
|
|
674
|
+
]);
|
|
675
|
+
const PROPOSER_TERMINALS_V2 = new Set(["retired"]);
|
|
676
|
+
|
|
677
|
+
const DELEGATION_TRANSITIONS_V2 = new Map([
|
|
678
|
+
["pending", new Set(["active", "revoked", "expired"])],
|
|
679
|
+
["active", new Set(["revoked", "expired"])],
|
|
680
|
+
]);
|
|
681
|
+
const DELEGATION_TERMINALS_V2 = new Set(["revoked", "expired"]);
|
|
682
|
+
|
|
683
|
+
export const GOV_DEFAULT_MAX_ACTIVE_PROPOSERS_PER_REALM = 100;
|
|
684
|
+
export const GOV_DEFAULT_MAX_ACTIVE_DELEGATIONS_PER_DELEGATOR = 5;
|
|
685
|
+
export const GOV_DEFAULT_PROPOSER_IDLE_MS = 180 * 86400000; // 180 days
|
|
686
|
+
export const GOV_DEFAULT_PENDING_DELEGATION_MS = 7 * 86400000; // 7 days
|
|
687
|
+
|
|
688
|
+
let _maxActiveProposersPerRealmV2 = GOV_DEFAULT_MAX_ACTIVE_PROPOSERS_PER_REALM;
|
|
689
|
+
let _maxActiveDelegationsPerDelegatorV2 =
|
|
690
|
+
GOV_DEFAULT_MAX_ACTIVE_DELEGATIONS_PER_DELEGATOR;
|
|
691
|
+
let _proposerIdleMsV2 = GOV_DEFAULT_PROPOSER_IDLE_MS;
|
|
692
|
+
let _pendingDelegationMsV2 = GOV_DEFAULT_PENDING_DELEGATION_MS;
|
|
693
|
+
|
|
694
|
+
const _proposerStatesV2 = new Map(); // proposerId → V2 record
|
|
695
|
+
const _delegationStatesV2 = new Map(); // delegationId → V2 record
|
|
696
|
+
|
|
697
|
+
function _positiveIntV2(n, label) {
|
|
698
|
+
const num = Number(n);
|
|
699
|
+
if (!Number.isFinite(num) || num <= 0) {
|
|
700
|
+
throw new Error(`${label} must be a positive integer`);
|
|
701
|
+
}
|
|
702
|
+
return Math.floor(num);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
function _validProposerStatusV2(s) {
|
|
706
|
+
return (
|
|
707
|
+
s === "onboarding" || s === "active" || s === "suspended" || s === "retired"
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
function _validDelegationStatusV2(s) {
|
|
712
|
+
return (
|
|
713
|
+
s === "pending" || s === "active" || s === "revoked" || s === "expired"
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
export function getDefaultMaxActiveProposersPerRealmV2() {
|
|
718
|
+
return GOV_DEFAULT_MAX_ACTIVE_PROPOSERS_PER_REALM;
|
|
719
|
+
}
|
|
720
|
+
export function getMaxActiveProposersPerRealmV2() {
|
|
721
|
+
return _maxActiveProposersPerRealmV2;
|
|
722
|
+
}
|
|
723
|
+
export function setMaxActiveProposersPerRealmV2(n) {
|
|
724
|
+
_maxActiveProposersPerRealmV2 = _positiveIntV2(
|
|
725
|
+
n,
|
|
726
|
+
"maxActiveProposersPerRealm",
|
|
727
|
+
);
|
|
728
|
+
return _maxActiveProposersPerRealmV2;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
export function getDefaultMaxActiveDelegationsPerDelegatorV2() {
|
|
732
|
+
return GOV_DEFAULT_MAX_ACTIVE_DELEGATIONS_PER_DELEGATOR;
|
|
733
|
+
}
|
|
734
|
+
export function getMaxActiveDelegationsPerDelegatorV2() {
|
|
735
|
+
return _maxActiveDelegationsPerDelegatorV2;
|
|
736
|
+
}
|
|
737
|
+
export function setMaxActiveDelegationsPerDelegatorV2(n) {
|
|
738
|
+
_maxActiveDelegationsPerDelegatorV2 = _positiveIntV2(
|
|
739
|
+
n,
|
|
740
|
+
"maxActiveDelegationsPerDelegator",
|
|
741
|
+
);
|
|
742
|
+
return _maxActiveDelegationsPerDelegatorV2;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
export function getDefaultProposerIdleMsV2() {
|
|
746
|
+
return GOV_DEFAULT_PROPOSER_IDLE_MS;
|
|
747
|
+
}
|
|
748
|
+
export function getProposerIdleMsV2() {
|
|
749
|
+
return _proposerIdleMsV2;
|
|
750
|
+
}
|
|
751
|
+
export function setProposerIdleMsV2(ms) {
|
|
752
|
+
_proposerIdleMsV2 = _positiveIntV2(ms, "proposerIdleMs");
|
|
753
|
+
return _proposerIdleMsV2;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
export function getDefaultPendingDelegationMsV2() {
|
|
757
|
+
return GOV_DEFAULT_PENDING_DELEGATION_MS;
|
|
758
|
+
}
|
|
759
|
+
export function getPendingDelegationMsV2() {
|
|
760
|
+
return _pendingDelegationMsV2;
|
|
761
|
+
}
|
|
762
|
+
export function setPendingDelegationMsV2(ms) {
|
|
763
|
+
_pendingDelegationMsV2 = _positiveIntV2(ms, "pendingDelegationMs");
|
|
764
|
+
return _pendingDelegationMsV2;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/* ── Proposer V2 ────────────────────────────────────────────── */
|
|
768
|
+
|
|
769
|
+
export function registerProposerV2(db, config = {}) {
|
|
770
|
+
void db;
|
|
771
|
+
const proposerId = String(config.proposerId || "").trim();
|
|
772
|
+
if (!proposerId) throw new Error("proposerId is required");
|
|
773
|
+
const realm = String(config.realm || "").trim();
|
|
774
|
+
if (!realm) throw new Error("realm is required");
|
|
775
|
+
if (_proposerStatesV2.has(proposerId)) {
|
|
776
|
+
throw new Error(`Proposer already registered in V2: ${proposerId}`);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
const now = Number(config.now ?? Date.now());
|
|
780
|
+
const initialStatus = config.initialStatus || "onboarding";
|
|
781
|
+
if (!_validProposerStatusV2(initialStatus)) {
|
|
782
|
+
throw new Error(`Invalid initial status: ${initialStatus}`);
|
|
783
|
+
}
|
|
784
|
+
if (PROPOSER_TERMINALS_V2.has(initialStatus)) {
|
|
785
|
+
throw new Error(
|
|
786
|
+
`Cannot register proposer in terminal status '${initialStatus}'`,
|
|
787
|
+
);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
if (initialStatus === "active") {
|
|
791
|
+
let activeCount = 0;
|
|
792
|
+
for (const rec of _proposerStatesV2.values()) {
|
|
793
|
+
if (rec.realm === realm && rec.status === "active") activeCount += 1;
|
|
794
|
+
}
|
|
795
|
+
if (activeCount >= _maxActiveProposersPerRealmV2) {
|
|
796
|
+
throw new Error(
|
|
797
|
+
`Max active proposers per realm reached (${_maxActiveProposersPerRealmV2})`,
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
const record = {
|
|
803
|
+
proposerId,
|
|
804
|
+
realm,
|
|
805
|
+
displayName: config.displayName ? String(config.displayName) : null,
|
|
806
|
+
status: initialStatus,
|
|
807
|
+
metadata: config.metadata ? { ...config.metadata } : {},
|
|
808
|
+
createdAt: now,
|
|
809
|
+
updatedAt: now,
|
|
810
|
+
lastActivityAt: now,
|
|
811
|
+
reason: null,
|
|
812
|
+
};
|
|
813
|
+
_proposerStatesV2.set(proposerId, record);
|
|
814
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
export function getProposerV2(proposerId) {
|
|
818
|
+
const rec = _proposerStatesV2.get(String(proposerId || ""));
|
|
819
|
+
if (!rec) return null;
|
|
820
|
+
return { ...rec, metadata: { ...rec.metadata } };
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
export function setProposerMaturityV2(db, proposerId, newStatus, patch = {}) {
|
|
824
|
+
void db;
|
|
825
|
+
const id = String(proposerId || "");
|
|
826
|
+
const record = _proposerStatesV2.get(id);
|
|
827
|
+
if (!record) throw new Error(`Proposer not registered in V2: ${id}`);
|
|
828
|
+
if (!_validProposerStatusV2(newStatus)) {
|
|
829
|
+
throw new Error(`Invalid proposer status: ${newStatus}`);
|
|
830
|
+
}
|
|
831
|
+
if (PROPOSER_TERMINALS_V2.has(record.status)) {
|
|
832
|
+
throw new Error(
|
|
833
|
+
`Proposer is in terminal status '${record.status}' and cannot transition`,
|
|
834
|
+
);
|
|
835
|
+
}
|
|
836
|
+
const allowed = PROPOSER_TRANSITIONS_V2.get(record.status);
|
|
837
|
+
if (!allowed || !allowed.has(newStatus)) {
|
|
838
|
+
throw new Error(`Invalid transition: ${record.status} → ${newStatus}`);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
if (newStatus === "active" && record.status !== "active") {
|
|
842
|
+
let activeCount = 0;
|
|
843
|
+
for (const rec of _proposerStatesV2.values()) {
|
|
844
|
+
if (rec.realm === record.realm && rec.status === "active") {
|
|
845
|
+
activeCount += 1;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
if (activeCount >= _maxActiveProposersPerRealmV2) {
|
|
849
|
+
throw new Error(
|
|
850
|
+
`Max active proposers per realm reached (${_maxActiveProposersPerRealmV2})`,
|
|
851
|
+
);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
record.status = newStatus;
|
|
856
|
+
record.updatedAt = Number(patch.now ?? Date.now());
|
|
857
|
+
if (patch.reason !== undefined) record.reason = patch.reason;
|
|
858
|
+
if (patch.metadata && typeof patch.metadata === "object") {
|
|
859
|
+
record.metadata = { ...record.metadata, ...patch.metadata };
|
|
860
|
+
}
|
|
861
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
export function activateProposer(db, proposerId, reason) {
|
|
865
|
+
return setProposerMaturityV2(db, proposerId, "active", { reason });
|
|
866
|
+
}
|
|
867
|
+
export function suspendProposer(db, proposerId, reason) {
|
|
868
|
+
return setProposerMaturityV2(db, proposerId, "suspended", { reason });
|
|
869
|
+
}
|
|
870
|
+
export function retireProposer(db, proposerId, reason) {
|
|
871
|
+
return setProposerMaturityV2(db, proposerId, "retired", { reason });
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
export function touchProposerActivity(proposerId) {
|
|
875
|
+
const rec = _proposerStatesV2.get(String(proposerId || ""));
|
|
876
|
+
if (!rec) throw new Error(`Proposer not registered in V2: ${proposerId}`);
|
|
877
|
+
rec.lastActivityAt = Date.now();
|
|
878
|
+
return { ...rec, metadata: { ...rec.metadata } };
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
/* ── Delegation V2 ──────────────────────────────────────────── */
|
|
882
|
+
|
|
883
|
+
export function createDelegationV2(db, config = {}) {
|
|
884
|
+
void db;
|
|
885
|
+
const delegationId = String(config.delegationId || "").trim();
|
|
886
|
+
if (!delegationId) throw new Error("delegationId is required");
|
|
887
|
+
const delegatorId = String(config.delegatorId || "").trim();
|
|
888
|
+
if (!delegatorId) throw new Error("delegatorId is required");
|
|
889
|
+
const delegateeId = String(config.delegateeId || "").trim();
|
|
890
|
+
if (!delegateeId) throw new Error("delegateeId is required");
|
|
891
|
+
if (delegatorId === delegateeId) {
|
|
892
|
+
throw new Error("delegatorId and delegateeId must differ");
|
|
893
|
+
}
|
|
894
|
+
const scope = String(config.scope || "").trim();
|
|
895
|
+
if (!scope) throw new Error("scope is required");
|
|
896
|
+
|
|
897
|
+
if (_delegationStatesV2.has(delegationId)) {
|
|
898
|
+
throw new Error(`Delegation already registered in V2: ${delegationId}`);
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
let openCount = 0;
|
|
902
|
+
for (const rec of _delegationStatesV2.values()) {
|
|
903
|
+
if (
|
|
904
|
+
rec.delegatorId === delegatorId &&
|
|
905
|
+
!DELEGATION_TERMINALS_V2.has(rec.status)
|
|
906
|
+
) {
|
|
907
|
+
openCount += 1;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
if (openCount >= _maxActiveDelegationsPerDelegatorV2) {
|
|
911
|
+
throw new Error(
|
|
912
|
+
`Max active delegations per delegator reached (${_maxActiveDelegationsPerDelegatorV2})`,
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
const now = Number(config.now ?? Date.now());
|
|
917
|
+
const record = {
|
|
918
|
+
delegationId,
|
|
919
|
+
delegatorId,
|
|
920
|
+
delegateeId,
|
|
921
|
+
scope,
|
|
922
|
+
status: "pending",
|
|
923
|
+
metadata: config.metadata ? { ...config.metadata } : {},
|
|
924
|
+
createdAt: now,
|
|
925
|
+
updatedAt: now,
|
|
926
|
+
activatedAt: null,
|
|
927
|
+
expiresAt: config.expiresAt ? Number(config.expiresAt) : null,
|
|
928
|
+
reason: null,
|
|
929
|
+
};
|
|
930
|
+
_delegationStatesV2.set(delegationId, record);
|
|
931
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
export function getDelegationV2(delegationId) {
|
|
935
|
+
const rec = _delegationStatesV2.get(String(delegationId || ""));
|
|
936
|
+
if (!rec) return null;
|
|
937
|
+
return { ...rec, metadata: { ...rec.metadata } };
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
export function setDelegationStatusV2(db, delegationId, newStatus, patch = {}) {
|
|
941
|
+
void db;
|
|
942
|
+
const id = String(delegationId || "");
|
|
943
|
+
const record = _delegationStatesV2.get(id);
|
|
944
|
+
if (!record) throw new Error(`Delegation not registered in V2: ${id}`);
|
|
945
|
+
if (!_validDelegationStatusV2(newStatus)) {
|
|
946
|
+
throw new Error(`Invalid delegation status: ${newStatus}`);
|
|
947
|
+
}
|
|
948
|
+
if (DELEGATION_TERMINALS_V2.has(record.status)) {
|
|
949
|
+
throw new Error(
|
|
950
|
+
`Delegation is in terminal status '${record.status}' and cannot transition`,
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
const allowed = DELEGATION_TRANSITIONS_V2.get(record.status);
|
|
954
|
+
if (!allowed || !allowed.has(newStatus)) {
|
|
955
|
+
throw new Error(`Invalid transition: ${record.status} → ${newStatus}`);
|
|
956
|
+
}
|
|
957
|
+
const now = Number(patch.now ?? Date.now());
|
|
958
|
+
record.status = newStatus;
|
|
959
|
+
record.updatedAt = now;
|
|
960
|
+
if (newStatus === "active" && record.activatedAt === null) {
|
|
961
|
+
record.activatedAt = now;
|
|
962
|
+
}
|
|
963
|
+
if (patch.reason !== undefined) record.reason = patch.reason;
|
|
964
|
+
if (patch.metadata && typeof patch.metadata === "object") {
|
|
965
|
+
record.metadata = { ...record.metadata, ...patch.metadata };
|
|
966
|
+
}
|
|
967
|
+
return { ...record, metadata: { ...record.metadata } };
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
export function activateDelegation(db, delegationId, reason) {
|
|
971
|
+
return setDelegationStatusV2(db, delegationId, "active", { reason });
|
|
972
|
+
}
|
|
973
|
+
export function revokeDelegation(db, delegationId, reason) {
|
|
974
|
+
return setDelegationStatusV2(db, delegationId, "revoked", { reason });
|
|
975
|
+
}
|
|
976
|
+
export function expireDelegation(db, delegationId, reason) {
|
|
977
|
+
return setDelegationStatusV2(db, delegationId, "expired", { reason });
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/* ── Counts ─────────────────────────────────────────────────── */
|
|
981
|
+
|
|
982
|
+
export function getActiveProposerCount(realm) {
|
|
983
|
+
let n = 0;
|
|
984
|
+
for (const rec of _proposerStatesV2.values()) {
|
|
985
|
+
if (rec.status !== "active") continue;
|
|
986
|
+
if (realm !== undefined && rec.realm !== String(realm)) continue;
|
|
987
|
+
n += 1;
|
|
988
|
+
}
|
|
989
|
+
return n;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
export function getActiveDelegationCount(delegatorId) {
|
|
993
|
+
let n = 0;
|
|
994
|
+
for (const rec of _delegationStatesV2.values()) {
|
|
995
|
+
if (DELEGATION_TERMINALS_V2.has(rec.status)) continue;
|
|
996
|
+
if (delegatorId !== undefined && rec.delegatorId !== String(delegatorId)) {
|
|
997
|
+
continue;
|
|
998
|
+
}
|
|
999
|
+
n += 1;
|
|
1000
|
+
}
|
|
1001
|
+
return n;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/* ── Auto-flip Bulk Ops ─────────────────────────────────────── */
|
|
1005
|
+
|
|
1006
|
+
export function autoRetireIdleProposers(db, nowMs) {
|
|
1007
|
+
void db;
|
|
1008
|
+
const now = Number(nowMs ?? Date.now());
|
|
1009
|
+
const flipped = [];
|
|
1010
|
+
for (const rec of _proposerStatesV2.values()) {
|
|
1011
|
+
if (rec.status !== "active" && rec.status !== "suspended") continue;
|
|
1012
|
+
if (now - rec.lastActivityAt > _proposerIdleMsV2) {
|
|
1013
|
+
rec.status = "retired";
|
|
1014
|
+
rec.updatedAt = now;
|
|
1015
|
+
rec.reason = "idle";
|
|
1016
|
+
flipped.push(rec.proposerId);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
return flipped;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
export function autoExpireStalePendingDelegations(db, nowMs) {
|
|
1023
|
+
void db;
|
|
1024
|
+
const now = Number(nowMs ?? Date.now());
|
|
1025
|
+
const flipped = [];
|
|
1026
|
+
for (const rec of _delegationStatesV2.values()) {
|
|
1027
|
+
if (rec.status !== "pending") continue;
|
|
1028
|
+
if (now - rec.createdAt > _pendingDelegationMsV2) {
|
|
1029
|
+
rec.status = "expired";
|
|
1030
|
+
rec.updatedAt = now;
|
|
1031
|
+
rec.reason = "pending_timeout";
|
|
1032
|
+
flipped.push(rec.delegationId);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
return flipped;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/* ── Stats V2 ───────────────────────────────────────────────── */
|
|
1039
|
+
|
|
1040
|
+
export function getGovernanceStatsV2() {
|
|
1041
|
+
const proposersByStatus = {
|
|
1042
|
+
onboarding: 0,
|
|
1043
|
+
active: 0,
|
|
1044
|
+
suspended: 0,
|
|
1045
|
+
retired: 0,
|
|
1046
|
+
};
|
|
1047
|
+
const delegationsByStatus = {
|
|
1048
|
+
pending: 0,
|
|
1049
|
+
active: 0,
|
|
1050
|
+
revoked: 0,
|
|
1051
|
+
expired: 0,
|
|
1052
|
+
};
|
|
1053
|
+
for (const rec of _proposerStatesV2.values()) {
|
|
1054
|
+
if (proposersByStatus[rec.status] !== undefined) {
|
|
1055
|
+
proposersByStatus[rec.status] += 1;
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
for (const rec of _delegationStatesV2.values()) {
|
|
1059
|
+
if (delegationsByStatus[rec.status] !== undefined) {
|
|
1060
|
+
delegationsByStatus[rec.status] += 1;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
return {
|
|
1064
|
+
totalProposersV2: _proposerStatesV2.size,
|
|
1065
|
+
totalDelegationsV2: _delegationStatesV2.size,
|
|
1066
|
+
maxActiveProposersPerRealm: _maxActiveProposersPerRealmV2,
|
|
1067
|
+
maxActiveDelegationsPerDelegator: _maxActiveDelegationsPerDelegatorV2,
|
|
1068
|
+
proposerIdleMs: _proposerIdleMsV2,
|
|
1069
|
+
pendingDelegationMs: _pendingDelegationMsV2,
|
|
1070
|
+
proposersByStatus,
|
|
1071
|
+
delegationsByStatus,
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
/* ── Reset V2 (tests) ───────────────────────────────────────── */
|
|
1076
|
+
|
|
1077
|
+
export function _resetStateV2() {
|
|
1078
|
+
_proposerStatesV2.clear();
|
|
1079
|
+
_delegationStatesV2.clear();
|
|
1080
|
+
_maxActiveProposersPerRealmV2 = GOV_DEFAULT_MAX_ACTIVE_PROPOSERS_PER_REALM;
|
|
1081
|
+
_maxActiveDelegationsPerDelegatorV2 =
|
|
1082
|
+
GOV_DEFAULT_MAX_ACTIVE_DELEGATIONS_PER_DELEGATOR;
|
|
1083
|
+
_proposerIdleMsV2 = GOV_DEFAULT_PROPOSER_IDLE_MS;
|
|
1084
|
+
_pendingDelegationMsV2 = GOV_DEFAULT_PENDING_DELEGATION_MS;
|
|
1085
|
+
}
|
|
@@ -598,3 +598,108 @@ export function generateFrameworkReport(frameworkId, opts = {}) {
|
|
|
598
598
|
export function _resetState() {
|
|
599
599
|
_customTemplates.clear();
|
|
600
600
|
}
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
// ===== V2 Surface: Compliance Framework Reporter governance overlay (CLI v0.138.0) =====
|
|
604
|
+
export const COMPLIANCE_FW_MATURITY_V2 = Object.freeze({
|
|
605
|
+
PENDING: "pending", ACTIVE: "active", DEPRECATED: "deprecated", ARCHIVED: "archived",
|
|
606
|
+
});
|
|
607
|
+
export const COMPLIANCE_FW_REPORT_LIFECYCLE_V2 = Object.freeze({
|
|
608
|
+
QUEUED: "queued", GENERATING: "generating", COMPLETED: "completed", FAILED: "failed", CANCELLED: "cancelled",
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
const _cfwTrans = new Map([
|
|
612
|
+
[COMPLIANCE_FW_MATURITY_V2.PENDING, new Set([COMPLIANCE_FW_MATURITY_V2.ACTIVE, COMPLIANCE_FW_MATURITY_V2.ARCHIVED])],
|
|
613
|
+
[COMPLIANCE_FW_MATURITY_V2.ACTIVE, new Set([COMPLIANCE_FW_MATURITY_V2.DEPRECATED, COMPLIANCE_FW_MATURITY_V2.ARCHIVED])],
|
|
614
|
+
[COMPLIANCE_FW_MATURITY_V2.DEPRECATED, new Set([COMPLIANCE_FW_MATURITY_V2.ACTIVE, COMPLIANCE_FW_MATURITY_V2.ARCHIVED])],
|
|
615
|
+
[COMPLIANCE_FW_MATURITY_V2.ARCHIVED, new Set()],
|
|
616
|
+
]);
|
|
617
|
+
const _cfwTerminal = new Set([COMPLIANCE_FW_MATURITY_V2.ARCHIVED]);
|
|
618
|
+
const _cfwRepTrans = new Map([
|
|
619
|
+
[COMPLIANCE_FW_REPORT_LIFECYCLE_V2.QUEUED, new Set([COMPLIANCE_FW_REPORT_LIFECYCLE_V2.GENERATING, COMPLIANCE_FW_REPORT_LIFECYCLE_V2.CANCELLED])],
|
|
620
|
+
[COMPLIANCE_FW_REPORT_LIFECYCLE_V2.GENERATING, new Set([COMPLIANCE_FW_REPORT_LIFECYCLE_V2.COMPLETED, COMPLIANCE_FW_REPORT_LIFECYCLE_V2.FAILED, COMPLIANCE_FW_REPORT_LIFECYCLE_V2.CANCELLED])],
|
|
621
|
+
[COMPLIANCE_FW_REPORT_LIFECYCLE_V2.COMPLETED, new Set()],
|
|
622
|
+
[COMPLIANCE_FW_REPORT_LIFECYCLE_V2.FAILED, new Set()],
|
|
623
|
+
[COMPLIANCE_FW_REPORT_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
624
|
+
]);
|
|
625
|
+
|
|
626
|
+
const _cfwsV2 = new Map();
|
|
627
|
+
const _cfwReports = new Map();
|
|
628
|
+
let _cfwMaxActivePerOwner = 8;
|
|
629
|
+
let _cfwMaxPendingReportsPerFw = 15;
|
|
630
|
+
let _cfwIdleMs = 90 * 24 * 60 * 60 * 1000;
|
|
631
|
+
let _cfwReportStuckMs = 10 * 60 * 1000;
|
|
632
|
+
|
|
633
|
+
function _cfwPos(n, lbl) { const v = Math.floor(Number(n)); if (!Number.isFinite(v) || v <= 0) throw new Error(`${lbl} must be positive integer`); return v; }
|
|
634
|
+
|
|
635
|
+
export function setMaxActiveComplianceFwsPerOwnerV2(n) { _cfwMaxActivePerOwner = _cfwPos(n, "maxActiveComplianceFwsPerOwner"); }
|
|
636
|
+
export function getMaxActiveComplianceFwsPerOwnerV2() { return _cfwMaxActivePerOwner; }
|
|
637
|
+
export function setMaxPendingComplianceFwReportsPerFwV2(n) { _cfwMaxPendingReportsPerFw = _cfwPos(n, "maxPendingComplianceFwReportsPerFw"); }
|
|
638
|
+
export function getMaxPendingComplianceFwReportsPerFwV2() { return _cfwMaxPendingReportsPerFw; }
|
|
639
|
+
export function setComplianceFwIdleMsV2(n) { _cfwIdleMs = _cfwPos(n, "complianceFwIdleMs"); }
|
|
640
|
+
export function getComplianceFwIdleMsV2() { return _cfwIdleMs; }
|
|
641
|
+
export function setComplianceFwReportStuckMsV2(n) { _cfwReportStuckMs = _cfwPos(n, "complianceFwReportStuckMs"); }
|
|
642
|
+
export function getComplianceFwReportStuckMsV2() { return _cfwReportStuckMs; }
|
|
643
|
+
|
|
644
|
+
export function _resetStateComplianceFwReporterV2() {
|
|
645
|
+
_cfwsV2.clear(); _cfwReports.clear();
|
|
646
|
+
_cfwMaxActivePerOwner = 8; _cfwMaxPendingReportsPerFw = 15;
|
|
647
|
+
_cfwIdleMs = 90 * 24 * 60 * 60 * 1000; _cfwReportStuckMs = 10 * 60 * 1000;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
export function registerComplianceFwV2({ id, owner, name, metadata } = {}) {
|
|
651
|
+
if (!id || typeof id !== "string") throw new Error("id is required");
|
|
652
|
+
if (!owner || typeof owner !== "string") throw new Error("owner is required");
|
|
653
|
+
if (_cfwsV2.has(id)) throw new Error(`compliance framework ${id} already registered`);
|
|
654
|
+
const now = Date.now();
|
|
655
|
+
const f = { id, owner, name: name || id, status: COMPLIANCE_FW_MATURITY_V2.PENDING, createdAt: now, updatedAt: now, activatedAt: null, archivedAt: null, lastTouchedAt: now, metadata: { ...(metadata || {}) } };
|
|
656
|
+
_cfwsV2.set(id, f);
|
|
657
|
+
return { ...f, metadata: { ...f.metadata } };
|
|
658
|
+
}
|
|
659
|
+
function _cfwCheckF(from, to) { const a = _cfwTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid compliance framework transition ${from} → ${to}`); }
|
|
660
|
+
function _cfwCountActive(owner) { let n = 0; for (const f of _cfwsV2.values()) if (f.owner === owner && f.status === COMPLIANCE_FW_MATURITY_V2.ACTIVE) n++; return n; }
|
|
661
|
+
|
|
662
|
+
export function activateComplianceFwV2(id) {
|
|
663
|
+
const f = _cfwsV2.get(id); if (!f) throw new Error(`compliance framework ${id} not found`);
|
|
664
|
+
_cfwCheckF(f.status, COMPLIANCE_FW_MATURITY_V2.ACTIVE);
|
|
665
|
+
const recovery = f.status === COMPLIANCE_FW_MATURITY_V2.DEPRECATED;
|
|
666
|
+
if (!recovery) { const c = _cfwCountActive(f.owner); if (c >= _cfwMaxActivePerOwner) throw new Error(`max active compliance frameworks per owner (${_cfwMaxActivePerOwner}) reached for ${f.owner}`); }
|
|
667
|
+
const now = Date.now(); f.status = COMPLIANCE_FW_MATURITY_V2.ACTIVE; f.updatedAt = now; f.lastTouchedAt = now; if (!f.activatedAt) f.activatedAt = now;
|
|
668
|
+
return { ...f, metadata: { ...f.metadata } };
|
|
669
|
+
}
|
|
670
|
+
export function deprecateComplianceFwV2(id) { const f = _cfwsV2.get(id); if (!f) throw new Error(`compliance framework ${id} not found`); _cfwCheckF(f.status, COMPLIANCE_FW_MATURITY_V2.DEPRECATED); f.status = COMPLIANCE_FW_MATURITY_V2.DEPRECATED; f.updatedAt = Date.now(); return { ...f, metadata: { ...f.metadata } }; }
|
|
671
|
+
export function archiveComplianceFwV2(id) { const f = _cfwsV2.get(id); if (!f) throw new Error(`compliance framework ${id} not found`); _cfwCheckF(f.status, COMPLIANCE_FW_MATURITY_V2.ARCHIVED); const now = Date.now(); f.status = COMPLIANCE_FW_MATURITY_V2.ARCHIVED; f.updatedAt = now; if (!f.archivedAt) f.archivedAt = now; return { ...f, metadata: { ...f.metadata } }; }
|
|
672
|
+
export function touchComplianceFwV2(id) { const f = _cfwsV2.get(id); if (!f) throw new Error(`compliance framework ${id} not found`); if (_cfwTerminal.has(f.status)) throw new Error(`cannot touch terminal compliance framework ${id}`); const now = Date.now(); f.lastTouchedAt = now; f.updatedAt = now; return { ...f, metadata: { ...f.metadata } }; }
|
|
673
|
+
export function getComplianceFwV2(id) { const f = _cfwsV2.get(id); if (!f) return null; return { ...f, metadata: { ...f.metadata } }; }
|
|
674
|
+
export function listComplianceFwsV2() { return [..._cfwsV2.values()].map((f) => ({ ...f, metadata: { ...f.metadata } })); }
|
|
675
|
+
|
|
676
|
+
function _cfwCountPendingReports(frameworkId) { let n = 0; for (const r of _cfwReports.values()) if (r.frameworkId === frameworkId && (r.status === COMPLIANCE_FW_REPORT_LIFECYCLE_V2.QUEUED || r.status === COMPLIANCE_FW_REPORT_LIFECYCLE_V2.GENERATING)) n++; return n; }
|
|
677
|
+
|
|
678
|
+
export function createComplianceFwReportV2({ id, frameworkId, format, metadata } = {}) {
|
|
679
|
+
if (!id || typeof id !== "string") throw new Error("id is required");
|
|
680
|
+
if (!frameworkId || typeof frameworkId !== "string") throw new Error("frameworkId is required");
|
|
681
|
+
if (_cfwReports.has(id)) throw new Error(`compliance framework report ${id} already exists`);
|
|
682
|
+
if (!_cfwsV2.has(frameworkId)) throw new Error(`compliance framework ${frameworkId} not found`);
|
|
683
|
+
const pending = _cfwCountPendingReports(frameworkId);
|
|
684
|
+
if (pending >= _cfwMaxPendingReportsPerFw) throw new Error(`max pending compliance framework reports per framework (${_cfwMaxPendingReportsPerFw}) reached for ${frameworkId}`);
|
|
685
|
+
const now = Date.now();
|
|
686
|
+
const r = { id, frameworkId, format: format || "markdown", status: COMPLIANCE_FW_REPORT_LIFECYCLE_V2.QUEUED, createdAt: now, updatedAt: now, startedAt: null, settledAt: null, metadata: { ...(metadata || {}) } };
|
|
687
|
+
_cfwReports.set(id, r);
|
|
688
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
689
|
+
}
|
|
690
|
+
function _cfwCheckR(from, to) { const a = _cfwRepTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid compliance framework report transition ${from} → ${to}`); }
|
|
691
|
+
export function startComplianceFwReportV2(id) { const r = _cfwReports.get(id); if (!r) throw new Error(`compliance framework report ${id} not found`); _cfwCheckR(r.status, COMPLIANCE_FW_REPORT_LIFECYCLE_V2.GENERATING); const now = Date.now(); r.status = COMPLIANCE_FW_REPORT_LIFECYCLE_V2.GENERATING; r.updatedAt = now; if (!r.startedAt) r.startedAt = now; return { ...r, metadata: { ...r.metadata } }; }
|
|
692
|
+
export function completeComplianceFwReportV2(id) { const r = _cfwReports.get(id); if (!r) throw new Error(`compliance framework report ${id} not found`); _cfwCheckR(r.status, COMPLIANCE_FW_REPORT_LIFECYCLE_V2.COMPLETED); const now = Date.now(); r.status = COMPLIANCE_FW_REPORT_LIFECYCLE_V2.COMPLETED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; return { ...r, metadata: { ...r.metadata } }; }
|
|
693
|
+
export function failComplianceFwReportV2(id, reason) { const r = _cfwReports.get(id); if (!r) throw new Error(`compliance framework report ${id} not found`); _cfwCheckR(r.status, COMPLIANCE_FW_REPORT_LIFECYCLE_V2.FAILED); const now = Date.now(); r.status = COMPLIANCE_FW_REPORT_LIFECYCLE_V2.FAILED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; if (reason) r.metadata.failReason = String(reason); return { ...r, metadata: { ...r.metadata } }; }
|
|
694
|
+
export function cancelComplianceFwReportV2(id, reason) { const r = _cfwReports.get(id); if (!r) throw new Error(`compliance framework report ${id} not found`); _cfwCheckR(r.status, COMPLIANCE_FW_REPORT_LIFECYCLE_V2.CANCELLED); const now = Date.now(); r.status = COMPLIANCE_FW_REPORT_LIFECYCLE_V2.CANCELLED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; if (reason) r.metadata.cancelReason = String(reason); return { ...r, metadata: { ...r.metadata } }; }
|
|
695
|
+
export function getComplianceFwReportV2(id) { const r = _cfwReports.get(id); if (!r) return null; return { ...r, metadata: { ...r.metadata } }; }
|
|
696
|
+
export function listComplianceFwReportsV2() { return [..._cfwReports.values()].map((r) => ({ ...r, metadata: { ...r.metadata } })); }
|
|
697
|
+
|
|
698
|
+
export function autoDeprecateIdleComplianceFwsV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const f of _cfwsV2.values()) if (f.status === COMPLIANCE_FW_MATURITY_V2.ACTIVE && (t - f.lastTouchedAt) >= _cfwIdleMs) { f.status = COMPLIANCE_FW_MATURITY_V2.DEPRECATED; f.updatedAt = t; flipped.push(f.id); } return { flipped, count: flipped.length }; }
|
|
699
|
+
export function autoFailStuckComplianceFwReportsV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const r of _cfwReports.values()) if (r.status === COMPLIANCE_FW_REPORT_LIFECYCLE_V2.GENERATING && r.startedAt != null && (t - r.startedAt) >= _cfwReportStuckMs) { r.status = COMPLIANCE_FW_REPORT_LIFECYCLE_V2.FAILED; r.updatedAt = t; if (!r.settledAt) r.settledAt = t; r.metadata.failReason = "auto-fail-stuck"; flipped.push(r.id); } return { flipped, count: flipped.length }; }
|
|
700
|
+
|
|
701
|
+
export function getComplianceFwReporterGovStatsV2() {
|
|
702
|
+
const fwsByStatus = {}; for (const s of Object.values(COMPLIANCE_FW_MATURITY_V2)) fwsByStatus[s] = 0; for (const f of _cfwsV2.values()) fwsByStatus[f.status]++;
|
|
703
|
+
const reportsByStatus = {}; for (const s of Object.values(COMPLIANCE_FW_REPORT_LIFECYCLE_V2)) reportsByStatus[s] = 0; for (const r of _cfwReports.values()) reportsByStatus[r.status]++;
|
|
704
|
+
return { totalComplianceFwsV2: _cfwsV2.size, totalComplianceFwReportsV2: _cfwReports.size, maxActiveComplianceFwsPerOwner: _cfwMaxActivePerOwner, maxPendingComplianceFwReportsPerFw: _cfwMaxPendingReportsPerFw, complianceFwIdleMs: _cfwIdleMs, complianceFwReportStuckMs: _cfwReportStuckMs, fwsByStatus, reportsByStatus };
|
|
705
|
+
}
|