chainlesschain 0.66.0 → 0.132.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 +380 -0
- package/src/commands/agent-network.js +254 -1
- package/src/commands/audit.js +302 -0
- package/src/commands/automation.js +271 -1
- package/src/commands/bi.js +348 -0
- package/src/commands/codegen.js +224 -0
- package/src/commands/collab.js +341 -0
- package/src/commands/compliance.js +1035 -0
- package/src/commands/cowork.js +221 -0
- package/src/commands/crosschain.js +218 -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 +341 -0
- package/src/commands/encrypt.js +341 -0
- package/src/commands/evomap.js +394 -0
- package/src/commands/export.js +256 -1
- package/src/commands/federation.js +283 -0
- package/src/commands/fusion.js +258 -0
- package/src/commands/governance.js +325 -0
- package/src/commands/hardening.js +411 -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 +318 -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/kg.js +387 -0
- package/src/commands/llm.js +263 -0
- package/src/commands/lowcode.js +356 -0
- package/src/commands/marketplace.js +256 -0
- package/src/commands/mcp.js +221 -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/note.js +244 -0
- package/src/commands/ops.js +354 -0
- package/src/commands/orchestrate.js +166 -0
- package/src/commands/org.js +277 -0
- package/src/commands/p2p.js +390 -0
- package/src/commands/perception.js +290 -0
- package/src/commands/permmem.js +251 -0
- package/src/commands/plugin-ecosystem.js +273 -0
- package/src/commands/pqc.js +393 -0
- package/src/commands/privacy.js +321 -0
- package/src/commands/quantization.js +351 -0
- package/src/commands/rcache.js +271 -0
- package/src/commands/recommend.js +340 -0
- package/src/commands/reputation.js +261 -0
- package/src/commands/runtime.js +307 -0
- package/src/commands/scim.js +262 -0
- package/src/commands/session.js +258 -0
- package/src/commands/siem.js +246 -0
- package/src/commands/skill.js +267 -1
- package/src/commands/sla.js +259 -0
- package/src/commands/social.js +256 -0
- package/src/commands/sso.js +186 -1
- package/src/commands/stress.js +230 -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/terraform.js +245 -0
- package/src/commands/tokens.js +269 -0
- package/src/commands/trust.js +249 -0
- package/src/commands/wallet.js +277 -0
- package/src/commands/workflow.js +171 -0
- package/src/commands/zkp.js +335 -0
- package/src/index.js +4 -0
- package/src/lib/a2a-protocol.js +451 -0
- package/src/lib/agent-coordinator.js +325 -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 +239 -0
- package/src/lib/audit-logger.js +379 -0
- package/src/lib/automation-engine.js +330 -0
- package/src/lib/autonomous-developer.js +350 -0
- package/src/lib/bi-engine.js +338 -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-manager.js +434 -0
- package/src/lib/content-recommendation.js +469 -0
- package/src/lib/cross-chain.js +345 -0
- package/src/lib/crypto-manager.js +350 -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 +389 -0
- package/src/lib/evomap-federation.js +177 -0
- package/src/lib/evomap-governance.js +276 -0
- package/src/lib/federation-hardening.js +259 -0
- package/src/lib/hardening-manager.js +348 -0
- package/src/lib/hook-manager.js +380 -0
- package/src/lib/inference-network.js +330 -0
- package/src/lib/instinct-manager.js +332 -0
- package/src/lib/ipfs-storage.js +334 -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/mcp-registry.js +333 -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/note-versioning.js +327 -0
- package/src/lib/org-manager.js +323 -0
- package/src/lib/p2p-manager.js +387 -0
- package/src/lib/perception.js +346 -0
- package/src/lib/perf-tuning.js +4 -1
- package/src/lib/permanent-memory.js +320 -0
- package/src/lib/plugin-ecosystem.js +377 -0
- package/src/lib/pqc-manager.js +368 -0
- package/src/lib/privacy-computing.js +427 -0
- package/src/lib/protocol-fusion.js +417 -0
- package/src/lib/quantization.js +325 -0
- package/src/lib/reputation-optimizer.js +299 -0
- package/src/lib/response-cache.js +327 -0
- package/src/lib/scim-manager.js +329 -0
- package/src/lib/session-manager.js +329 -0
- package/src/lib/siem-exporter.js +333 -0
- package/src/lib/skill-loader.js +377 -0
- package/src/lib/skill-marketplace.js +325 -0
- package/src/lib/sla-manager.js +275 -0
- package/src/lib/social-manager.js +326 -0
- package/src/lib/sso-manager.js +332 -0
- package/src/lib/stress-tester.js +330 -0
- package/src/lib/sync-manager.js +326 -0
- package/src/lib/tech-learning-engine.js +369 -0
- package/src/lib/tenant-saas.js +460 -0
- package/src/lib/terraform-manager.js +363 -0
- package/src/lib/threat-intel.js +335 -0
- package/src/lib/token-incentive.js +293 -0
- package/src/lib/token-tracker.js +329 -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/wallet-manager.js +326 -0
- package/src/lib/workflow-engine.js +322 -0
- package/src/lib/zkp-engine.js +274 -0
|
@@ -954,3 +954,325 @@ export function importWorkflow(db, definition) {
|
|
|
954
954
|
stages: definition.stages,
|
|
955
955
|
});
|
|
956
956
|
}
|
|
957
|
+
|
|
958
|
+
// ===== V2 Surface (cli 0.130.0) — in-memory governance =====
|
|
959
|
+
export const WORKFLOW_MATURITY_V2 = Object.freeze({
|
|
960
|
+
DRAFT: "draft",
|
|
961
|
+
ACTIVE: "active",
|
|
962
|
+
PAUSED: "paused",
|
|
963
|
+
RETIRED: "retired",
|
|
964
|
+
});
|
|
965
|
+
export const RUN_LIFECYCLE_V2 = Object.freeze({
|
|
966
|
+
QUEUED: "queued",
|
|
967
|
+
RUNNING: "running",
|
|
968
|
+
COMPLETED: "completed",
|
|
969
|
+
FAILED: "failed",
|
|
970
|
+
CANCELLED: "cancelled",
|
|
971
|
+
});
|
|
972
|
+
|
|
973
|
+
const _WM_V2 = WORKFLOW_MATURITY_V2;
|
|
974
|
+
const _RL_V2 = RUN_LIFECYCLE_V2;
|
|
975
|
+
const _WM_TRANS_V2 = new Map([
|
|
976
|
+
[_WM_V2.DRAFT, new Set([_WM_V2.ACTIVE, _WM_V2.RETIRED])],
|
|
977
|
+
[_WM_V2.ACTIVE, new Set([_WM_V2.PAUSED, _WM_V2.RETIRED])],
|
|
978
|
+
[_WM_V2.PAUSED, new Set([_WM_V2.ACTIVE, _WM_V2.RETIRED])],
|
|
979
|
+
[_WM_V2.RETIRED, new Set()],
|
|
980
|
+
]);
|
|
981
|
+
const _RL_TRANS_V2 = new Map([
|
|
982
|
+
[_RL_V2.QUEUED, new Set([_RL_V2.RUNNING, _RL_V2.CANCELLED])],
|
|
983
|
+
[
|
|
984
|
+
_RL_V2.RUNNING,
|
|
985
|
+
new Set([_RL_V2.COMPLETED, _RL_V2.FAILED, _RL_V2.CANCELLED]),
|
|
986
|
+
],
|
|
987
|
+
[_RL_V2.COMPLETED, new Set()],
|
|
988
|
+
[_RL_V2.FAILED, new Set()],
|
|
989
|
+
[_RL_V2.CANCELLED, new Set()],
|
|
990
|
+
]);
|
|
991
|
+
const _RL_TERM_V2 = new Set([
|
|
992
|
+
_RL_V2.COMPLETED,
|
|
993
|
+
_RL_V2.FAILED,
|
|
994
|
+
_RL_V2.CANCELLED,
|
|
995
|
+
]);
|
|
996
|
+
|
|
997
|
+
const WF_DEFAULT_MAX_ACTIVE_WORKFLOWS_PER_OWNER = 12;
|
|
998
|
+
const WF_DEFAULT_MAX_PENDING_RUNS_PER_WORKFLOW = 8;
|
|
999
|
+
const WF_DEFAULT_WORKFLOW_IDLE_MS = 60 * 24 * 60 * 60 * 1000;
|
|
1000
|
+
const WF_DEFAULT_RUN_STUCK_MS = 10 * 60 * 1000;
|
|
1001
|
+
|
|
1002
|
+
const _wfWorkflowsV2 = new Map();
|
|
1003
|
+
const _wfRunsV2 = new Map();
|
|
1004
|
+
let _wfConfigV2 = {
|
|
1005
|
+
maxActiveWorkflowsPerOwner: WF_DEFAULT_MAX_ACTIVE_WORKFLOWS_PER_OWNER,
|
|
1006
|
+
maxPendingRunsPerWorkflow: WF_DEFAULT_MAX_PENDING_RUNS_PER_WORKFLOW,
|
|
1007
|
+
workflowIdleMs: WF_DEFAULT_WORKFLOW_IDLE_MS,
|
|
1008
|
+
runStuckMs: WF_DEFAULT_RUN_STUCK_MS,
|
|
1009
|
+
};
|
|
1010
|
+
|
|
1011
|
+
function _wfPosIntV2(n, label) {
|
|
1012
|
+
if (typeof n !== "number" || !isFinite(n) || isNaN(n))
|
|
1013
|
+
throw new Error(`${label} must be positive integer`);
|
|
1014
|
+
const v = Math.floor(n);
|
|
1015
|
+
if (v <= 0) throw new Error(`${label} must be positive integer`);
|
|
1016
|
+
return v;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
export function _resetStateWorkflowEngineV2() {
|
|
1020
|
+
_wfWorkflowsV2.clear();
|
|
1021
|
+
_wfRunsV2.clear();
|
|
1022
|
+
_wfConfigV2 = {
|
|
1023
|
+
maxActiveWorkflowsPerOwner: WF_DEFAULT_MAX_ACTIVE_WORKFLOWS_PER_OWNER,
|
|
1024
|
+
maxPendingRunsPerWorkflow: WF_DEFAULT_MAX_PENDING_RUNS_PER_WORKFLOW,
|
|
1025
|
+
workflowIdleMs: WF_DEFAULT_WORKFLOW_IDLE_MS,
|
|
1026
|
+
runStuckMs: WF_DEFAULT_RUN_STUCK_MS,
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
export function setMaxActiveWorkflowsPerOwnerV2(n) {
|
|
1031
|
+
_wfConfigV2.maxActiveWorkflowsPerOwner = _wfPosIntV2(
|
|
1032
|
+
n,
|
|
1033
|
+
"maxActiveWorkflowsPerOwner",
|
|
1034
|
+
);
|
|
1035
|
+
}
|
|
1036
|
+
export function setMaxPendingRunsPerWorkflowV2(n) {
|
|
1037
|
+
_wfConfigV2.maxPendingRunsPerWorkflow = _wfPosIntV2(
|
|
1038
|
+
n,
|
|
1039
|
+
"maxPendingRunsPerWorkflow",
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
export function setWorkflowIdleMsV2(n) {
|
|
1043
|
+
_wfConfigV2.workflowIdleMs = _wfPosIntV2(n, "workflowIdleMs");
|
|
1044
|
+
}
|
|
1045
|
+
export function setRunStuckMsV2(n) {
|
|
1046
|
+
_wfConfigV2.runStuckMs = _wfPosIntV2(n, "runStuckMs");
|
|
1047
|
+
}
|
|
1048
|
+
export function getMaxActiveWorkflowsPerOwnerV2() {
|
|
1049
|
+
return _wfConfigV2.maxActiveWorkflowsPerOwner;
|
|
1050
|
+
}
|
|
1051
|
+
export function getMaxPendingRunsPerWorkflowV2() {
|
|
1052
|
+
return _wfConfigV2.maxPendingRunsPerWorkflow;
|
|
1053
|
+
}
|
|
1054
|
+
export function getWorkflowIdleMsV2() {
|
|
1055
|
+
return _wfConfigV2.workflowIdleMs;
|
|
1056
|
+
}
|
|
1057
|
+
export function getRunStuckMsV2() {
|
|
1058
|
+
return _wfConfigV2.runStuckMs;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
function _copyWorkflowV2(w) {
|
|
1062
|
+
return { ...w, metadata: { ...(w.metadata || {}) } };
|
|
1063
|
+
}
|
|
1064
|
+
function _copyRunV2(r) {
|
|
1065
|
+
return { ...r, metadata: { ...(r.metadata || {}) } };
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
export function registerWorkflowV2({ id, owner, name, metadata } = {}) {
|
|
1069
|
+
if (!id || typeof id !== "string") throw new Error("id required");
|
|
1070
|
+
if (!owner || typeof owner !== "string") throw new Error("owner required");
|
|
1071
|
+
if (_wfWorkflowsV2.has(id))
|
|
1072
|
+
throw new Error(`workflow ${id} already registered`);
|
|
1073
|
+
const now = Date.now();
|
|
1074
|
+
const w = {
|
|
1075
|
+
id,
|
|
1076
|
+
owner,
|
|
1077
|
+
name: name || id,
|
|
1078
|
+
status: _WM_V2.DRAFT,
|
|
1079
|
+
activatedAt: null,
|
|
1080
|
+
retiredAt: null,
|
|
1081
|
+
lastSeenAt: now,
|
|
1082
|
+
createdAt: now,
|
|
1083
|
+
metadata: metadata && typeof metadata === "object" ? { ...metadata } : {},
|
|
1084
|
+
};
|
|
1085
|
+
_wfWorkflowsV2.set(id, w);
|
|
1086
|
+
return _copyWorkflowV2(w);
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
function _activeWorkflowCountForOwnerV2(owner) {
|
|
1090
|
+
let c = 0;
|
|
1091
|
+
for (const w of _wfWorkflowsV2.values())
|
|
1092
|
+
if (w.owner === owner && w.status === _WM_V2.ACTIVE) c++;
|
|
1093
|
+
return c;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
function _transitionWorkflowV2(id, next) {
|
|
1097
|
+
const w = _wfWorkflowsV2.get(id);
|
|
1098
|
+
if (!w) throw new Error(`workflow ${id} not found`);
|
|
1099
|
+
const allowed = _WM_TRANS_V2.get(w.status);
|
|
1100
|
+
if (!allowed || !allowed.has(next))
|
|
1101
|
+
throw new Error(`invalid transition ${w.status} -> ${next}`);
|
|
1102
|
+
if (next === _WM_V2.ACTIVE && w.status === _WM_V2.DRAFT) {
|
|
1103
|
+
if (
|
|
1104
|
+
_activeWorkflowCountForOwnerV2(w.owner) >=
|
|
1105
|
+
_wfConfigV2.maxActiveWorkflowsPerOwner
|
|
1106
|
+
) {
|
|
1107
|
+
throw new Error(
|
|
1108
|
+
`owner ${w.owner} active-workflow cap reached (${_wfConfigV2.maxActiveWorkflowsPerOwner})`,
|
|
1109
|
+
);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
const now = Date.now();
|
|
1113
|
+
w.status = next;
|
|
1114
|
+
if (next === _WM_V2.ACTIVE && !w.activatedAt) w.activatedAt = now;
|
|
1115
|
+
if (next === _WM_V2.RETIRED && !w.retiredAt) w.retiredAt = now;
|
|
1116
|
+
w.lastSeenAt = now;
|
|
1117
|
+
return _copyWorkflowV2(w);
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
export function activateWorkflowV2(id) {
|
|
1121
|
+
return _transitionWorkflowV2(id, _WM_V2.ACTIVE);
|
|
1122
|
+
}
|
|
1123
|
+
export function pauseWorkflowV2(id) {
|
|
1124
|
+
return _transitionWorkflowV2(id, _WM_V2.PAUSED);
|
|
1125
|
+
}
|
|
1126
|
+
export function retireWorkflowV2(id) {
|
|
1127
|
+
return _transitionWorkflowV2(id, _WM_V2.RETIRED);
|
|
1128
|
+
}
|
|
1129
|
+
export function touchWorkflowV2(id) {
|
|
1130
|
+
const w = _wfWorkflowsV2.get(id);
|
|
1131
|
+
if (!w) throw new Error(`workflow ${id} not found`);
|
|
1132
|
+
w.lastSeenAt = Date.now();
|
|
1133
|
+
return _copyWorkflowV2(w);
|
|
1134
|
+
}
|
|
1135
|
+
export function getWorkflowV2(id) {
|
|
1136
|
+
const w = _wfWorkflowsV2.get(id);
|
|
1137
|
+
return w ? _copyWorkflowV2(w) : null;
|
|
1138
|
+
}
|
|
1139
|
+
export function listWorkflowsV2({ owner, status } = {}) {
|
|
1140
|
+
const out = [];
|
|
1141
|
+
for (const w of _wfWorkflowsV2.values()) {
|
|
1142
|
+
if (owner && w.owner !== owner) continue;
|
|
1143
|
+
if (status && w.status !== status) continue;
|
|
1144
|
+
out.push(_copyWorkflowV2(w));
|
|
1145
|
+
}
|
|
1146
|
+
return out;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
function _pendingRunCountForWorkflowV2(workflowId) {
|
|
1150
|
+
let c = 0;
|
|
1151
|
+
for (const r of _wfRunsV2.values()) {
|
|
1152
|
+
if (r.workflowId !== workflowId) continue;
|
|
1153
|
+
if (r.status === _RL_V2.QUEUED || r.status === _RL_V2.RUNNING) c++;
|
|
1154
|
+
}
|
|
1155
|
+
return c;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
export function createRunV2({ id, workflowId, trigger, metadata } = {}) {
|
|
1159
|
+
if (!id || typeof id !== "string") throw new Error("id required");
|
|
1160
|
+
if (!workflowId || typeof workflowId !== "string")
|
|
1161
|
+
throw new Error("workflowId required");
|
|
1162
|
+
if (_wfRunsV2.has(id)) throw new Error(`run ${id} already exists`);
|
|
1163
|
+
const wf = _wfWorkflowsV2.get(workflowId);
|
|
1164
|
+
if (!wf) throw new Error(`workflow ${workflowId} not found`);
|
|
1165
|
+
if (wf.status === _WM_V2.RETIRED)
|
|
1166
|
+
throw new Error(`workflow ${workflowId} retired`);
|
|
1167
|
+
if (
|
|
1168
|
+
_pendingRunCountForWorkflowV2(workflowId) >=
|
|
1169
|
+
_wfConfigV2.maxPendingRunsPerWorkflow
|
|
1170
|
+
) {
|
|
1171
|
+
throw new Error(
|
|
1172
|
+
`workflow ${workflowId} pending-run cap reached (${_wfConfigV2.maxPendingRunsPerWorkflow})`,
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
const now = Date.now();
|
|
1176
|
+
const r = {
|
|
1177
|
+
id,
|
|
1178
|
+
workflowId,
|
|
1179
|
+
trigger: trigger || "manual",
|
|
1180
|
+
status: _RL_V2.QUEUED,
|
|
1181
|
+
startedAt: null,
|
|
1182
|
+
settledAt: null,
|
|
1183
|
+
createdAt: now,
|
|
1184
|
+
metadata: metadata && typeof metadata === "object" ? { ...metadata } : {},
|
|
1185
|
+
};
|
|
1186
|
+
_wfRunsV2.set(id, r);
|
|
1187
|
+
return _copyRunV2(r);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
function _transitionRunV2(id, next, extra = {}) {
|
|
1191
|
+
const r = _wfRunsV2.get(id);
|
|
1192
|
+
if (!r) throw new Error(`run ${id} not found`);
|
|
1193
|
+
const allowed = _RL_TRANS_V2.get(r.status);
|
|
1194
|
+
if (!allowed || !allowed.has(next))
|
|
1195
|
+
throw new Error(`invalid transition ${r.status} -> ${next}`);
|
|
1196
|
+
const now = Date.now();
|
|
1197
|
+
r.status = next;
|
|
1198
|
+
if (next === _RL_V2.RUNNING && !r.startedAt) r.startedAt = now;
|
|
1199
|
+
if (_RL_TERM_V2.has(next) && !r.settledAt) r.settledAt = now;
|
|
1200
|
+
if (extra.error) r.metadata.error = extra.error;
|
|
1201
|
+
return _copyRunV2(r);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
export function startRunV2(id) {
|
|
1205
|
+
return _transitionRunV2(id, _RL_V2.RUNNING);
|
|
1206
|
+
}
|
|
1207
|
+
export function completeRunV2(id) {
|
|
1208
|
+
return _transitionRunV2(id, _RL_V2.COMPLETED);
|
|
1209
|
+
}
|
|
1210
|
+
export function failRunV2(id, error) {
|
|
1211
|
+
return _transitionRunV2(id, _RL_V2.FAILED, { error });
|
|
1212
|
+
}
|
|
1213
|
+
export function cancelRunV2(id) {
|
|
1214
|
+
return _transitionRunV2(id, _RL_V2.CANCELLED);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
export function getRunV2(id) {
|
|
1218
|
+
const r = _wfRunsV2.get(id);
|
|
1219
|
+
return r ? _copyRunV2(r) : null;
|
|
1220
|
+
}
|
|
1221
|
+
export function listRunsV2({ workflowId, status, trigger } = {}) {
|
|
1222
|
+
const out = [];
|
|
1223
|
+
for (const r of _wfRunsV2.values()) {
|
|
1224
|
+
if (workflowId && r.workflowId !== workflowId) continue;
|
|
1225
|
+
if (status && r.status !== status) continue;
|
|
1226
|
+
if (trigger && r.trigger !== trigger) continue;
|
|
1227
|
+
out.push(_copyRunV2(r));
|
|
1228
|
+
}
|
|
1229
|
+
return out;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
export function autoPauseIdleWorkflowsV2({ now } = {}) {
|
|
1233
|
+
const t = typeof now === "number" ? now : Date.now();
|
|
1234
|
+
const flipped = [];
|
|
1235
|
+
for (const w of _wfWorkflowsV2.values()) {
|
|
1236
|
+
if (w.status !== _WM_V2.ACTIVE) continue;
|
|
1237
|
+
if (t - w.lastSeenAt > _wfConfigV2.workflowIdleMs) {
|
|
1238
|
+
w.status = _WM_V2.PAUSED;
|
|
1239
|
+
w.lastSeenAt = t;
|
|
1240
|
+
flipped.push(_copyWorkflowV2(w));
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
return flipped;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
export function autoFailStuckRunsV2({ now } = {}) {
|
|
1247
|
+
const t = typeof now === "number" ? now : Date.now();
|
|
1248
|
+
const flipped = [];
|
|
1249
|
+
for (const r of _wfRunsV2.values()) {
|
|
1250
|
+
if (r.status !== _RL_V2.RUNNING) continue;
|
|
1251
|
+
if (r.startedAt && t - r.startedAt > _wfConfigV2.runStuckMs) {
|
|
1252
|
+
r.status = _RL_V2.FAILED;
|
|
1253
|
+
r.settledAt = t;
|
|
1254
|
+
r.metadata.error = "stuck-timeout";
|
|
1255
|
+
flipped.push(_copyRunV2(r));
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
return flipped;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
export function getWorkflowEngineStatsV2() {
|
|
1262
|
+
const workflowsByStatus = {};
|
|
1263
|
+
for (const s of Object.values(_WM_V2)) workflowsByStatus[s] = 0;
|
|
1264
|
+
for (const w of _wfWorkflowsV2.values()) workflowsByStatus[w.status]++;
|
|
1265
|
+
const runsByStatus = {};
|
|
1266
|
+
for (const s of Object.values(_RL_V2)) runsByStatus[s] = 0;
|
|
1267
|
+
for (const r of _wfRunsV2.values()) runsByStatus[r.status]++;
|
|
1268
|
+
return {
|
|
1269
|
+
totalWorkflowsV2: _wfWorkflowsV2.size,
|
|
1270
|
+
totalRunsV2: _wfRunsV2.size,
|
|
1271
|
+
maxActiveWorkflowsPerOwner: _wfConfigV2.maxActiveWorkflowsPerOwner,
|
|
1272
|
+
maxPendingRunsPerWorkflow: _wfConfigV2.maxPendingRunsPerWorkflow,
|
|
1273
|
+
workflowIdleMs: _wfConfigV2.workflowIdleMs,
|
|
1274
|
+
runStuckMs: _wfConfigV2.runStuckMs,
|
|
1275
|
+
workflowsByStatus,
|
|
1276
|
+
runsByStatus,
|
|
1277
|
+
};
|
|
1278
|
+
}
|
package/src/lib/zkp-engine.js
CHANGED
|
@@ -467,4 +467,278 @@ export function _resetState() {
|
|
|
467
467
|
_proofs.clear();
|
|
468
468
|
_verificationKeys.clear();
|
|
469
469
|
_credentials.clear();
|
|
470
|
+
_maxCircuitsPerCreator = ZKP_DEFAULT_MAX_CIRCUITS_PER_CREATOR;
|
|
471
|
+
_proofExpiryMs = ZKP_DEFAULT_PROOF_EXPIRY_MS;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/* ──────────────────────────────────────────────────────────
|
|
475
|
+
* V2 — Phase 88 surface (strictly additive)
|
|
476
|
+
* ────────────────────────────────────────────────────────── */
|
|
477
|
+
|
|
478
|
+
export const PROOF_SCHEME_V2 = PROOF_SCHEME;
|
|
479
|
+
export const CIRCUIT_STATUS_V2 = CIRCUIT_STATUS;
|
|
480
|
+
|
|
481
|
+
export const PROOF_STATUS_V2 = Object.freeze({
|
|
482
|
+
PENDING: "pending",
|
|
483
|
+
VERIFIED: "verified",
|
|
484
|
+
INVALID: "invalid",
|
|
485
|
+
EXPIRED: "expired",
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
export const ZKP_DEFAULT_MAX_CIRCUITS_PER_CREATOR = 10;
|
|
489
|
+
export const ZKP_DEFAULT_PROOF_EXPIRY_MS = 3600_000; // 1h
|
|
490
|
+
|
|
491
|
+
let _maxCircuitsPerCreator = ZKP_DEFAULT_MAX_CIRCUITS_PER_CREATOR;
|
|
492
|
+
let _proofExpiryMs = ZKP_DEFAULT_PROOF_EXPIRY_MS;
|
|
493
|
+
|
|
494
|
+
const CIRCUIT_TRANSITIONS_V2 = new Map([
|
|
495
|
+
["draft", new Set(["compiled", "failed"])],
|
|
496
|
+
["compiled", new Set(["verified", "failed"])],
|
|
497
|
+
]);
|
|
498
|
+
const CIRCUIT_TERMINALS_V2 = new Set(["verified", "failed"]);
|
|
499
|
+
|
|
500
|
+
const PROOF_TRANSITIONS_V2 = new Map([
|
|
501
|
+
["pending", new Set(["verified", "invalid", "expired"])],
|
|
502
|
+
]);
|
|
503
|
+
const PROOF_TERMINALS_V2 = new Set(["verified", "invalid", "expired"]);
|
|
504
|
+
|
|
505
|
+
/* ── Config ────────────────────────────────────────────── */
|
|
506
|
+
|
|
507
|
+
export function setMaxCircuitsPerCreator(n) {
|
|
508
|
+
if (typeof n !== "number" || Number.isNaN(n) || n < 1) {
|
|
509
|
+
throw new Error("maxCircuitsPerCreator must be a positive integer");
|
|
510
|
+
}
|
|
511
|
+
_maxCircuitsPerCreator = Math.floor(n);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
export function getMaxCircuitsPerCreator() {
|
|
515
|
+
return _maxCircuitsPerCreator;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
export function getCircuitCountByCreator(creator) {
|
|
519
|
+
if (!creator) return 0;
|
|
520
|
+
let count = 0;
|
|
521
|
+
for (const c of _circuits.values()) {
|
|
522
|
+
if (c.creator === creator) count += 1;
|
|
523
|
+
}
|
|
524
|
+
return count;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export function setProofExpiryMs(ms) {
|
|
528
|
+
if (typeof ms !== "number" || Number.isNaN(ms) || ms < 1) {
|
|
529
|
+
throw new Error("proofExpiryMs must be a positive integer");
|
|
530
|
+
}
|
|
531
|
+
_proofExpiryMs = Math.floor(ms);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
export function getProofExpiryMs() {
|
|
535
|
+
return _proofExpiryMs;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/* ── Circuit V2 ────────────────────────────────────────── */
|
|
539
|
+
|
|
540
|
+
export function compileCircuitV2(db, { name, definition, creator } = {}) {
|
|
541
|
+
if (!name) throw new Error("name is required");
|
|
542
|
+
if (creator) {
|
|
543
|
+
const count = getCircuitCountByCreator(creator);
|
|
544
|
+
if (count >= _maxCircuitsPerCreator) {
|
|
545
|
+
throw new Error(
|
|
546
|
+
`Max circuits per creator reached (${count}/${_maxCircuitsPerCreator})`,
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
const circuit = compileCircuit(db, name, definition);
|
|
551
|
+
if (creator) {
|
|
552
|
+
circuit.creator = creator;
|
|
553
|
+
}
|
|
554
|
+
return { ...circuit };
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
export function setCircuitStatusV2(db, circuitId, newStatus, patch = {}) {
|
|
558
|
+
const circuit = _circuits.get(circuitId);
|
|
559
|
+
if (!circuit) throw new Error(`Circuit not found: ${circuitId}`);
|
|
560
|
+
if (!Object.values(CIRCUIT_STATUS_V2).includes(newStatus)) {
|
|
561
|
+
throw new Error(`Unknown circuit status: ${newStatus}`);
|
|
562
|
+
}
|
|
563
|
+
const allowed = CIRCUIT_TRANSITIONS_V2.get(circuit.status);
|
|
564
|
+
if (!allowed || !allowed.has(newStatus)) {
|
|
565
|
+
throw new Error(`Invalid transition: ${circuit.status} → ${newStatus}`);
|
|
566
|
+
}
|
|
567
|
+
circuit.status = newStatus;
|
|
568
|
+
if (patch.errorMessage !== undefined)
|
|
569
|
+
circuit.errorMessage = patch.errorMessage;
|
|
570
|
+
db.prepare("UPDATE zkp_circuits SET status = ? WHERE id = ?").run(
|
|
571
|
+
newStatus,
|
|
572
|
+
circuitId,
|
|
573
|
+
);
|
|
574
|
+
return { ...circuit };
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/* ── Proof V2 ──────────────────────────────────────────── */
|
|
578
|
+
|
|
579
|
+
export function generateProofV2(
|
|
580
|
+
db,
|
|
581
|
+
{ circuitId, privateInputs, publicInputs, scheme } = {},
|
|
582
|
+
) {
|
|
583
|
+
if (!circuitId) throw new Error("circuitId is required");
|
|
584
|
+
const circuit = _circuits.get(circuitId);
|
|
585
|
+
if (!circuit) throw new Error(`Circuit not found: ${circuitId}`);
|
|
586
|
+
if (
|
|
587
|
+
circuit.status !== CIRCUIT_STATUS.COMPILED &&
|
|
588
|
+
circuit.status !== CIRCUIT_STATUS.VERIFIED
|
|
589
|
+
) {
|
|
590
|
+
throw new Error(
|
|
591
|
+
`Circuit not ready (status=${circuit.status}, must be compiled/verified)`,
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
const proof = generateProof(db, circuitId, privateInputs, publicInputs, {
|
|
595
|
+
scheme,
|
|
596
|
+
});
|
|
597
|
+
const stored = _proofs.get(proof.id);
|
|
598
|
+
stored.status = PROOF_STATUS_V2.PENDING;
|
|
599
|
+
stored.expiresAt = Date.now() + _proofExpiryMs;
|
|
600
|
+
return { ...stored };
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
export function verifyProofV2(db, proofId) {
|
|
604
|
+
const proof = _proofs.get(proofId);
|
|
605
|
+
if (!proof) throw new Error(`Proof not found: ${proofId}`);
|
|
606
|
+
const current = proof.status || PROOF_STATUS_V2.PENDING;
|
|
607
|
+
if (PROOF_TERMINALS_V2.has(current)) {
|
|
608
|
+
throw new Error(`Invalid transition: ${current} → verify (terminal)`);
|
|
609
|
+
}
|
|
610
|
+
if (proof.expiresAt && Date.now() > proof.expiresAt) {
|
|
611
|
+
proof.status = PROOF_STATUS_V2.EXPIRED;
|
|
612
|
+
db.prepare("UPDATE zkp_proofs SET verified = 0 WHERE id = ?").run(proofId);
|
|
613
|
+
return { ...proof, valid: false, reason: "expired" };
|
|
614
|
+
}
|
|
615
|
+
const result = verifyProof(db, proofId);
|
|
616
|
+
proof.status = result.valid
|
|
617
|
+
? PROOF_STATUS_V2.VERIFIED
|
|
618
|
+
: PROOF_STATUS_V2.INVALID;
|
|
619
|
+
return { ...proof, valid: result.valid };
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
export function failProof(db, proofId, { reason } = {}) {
|
|
623
|
+
const proof = _proofs.get(proofId);
|
|
624
|
+
if (!proof) throw new Error(`Proof not found: ${proofId}`);
|
|
625
|
+
const current = proof.status || PROOF_STATUS_V2.PENDING;
|
|
626
|
+
if (PROOF_TERMINALS_V2.has(current)) {
|
|
627
|
+
throw new Error(`Invalid transition: ${current} → invalid (terminal)`);
|
|
628
|
+
}
|
|
629
|
+
proof.status = PROOF_STATUS_V2.INVALID;
|
|
630
|
+
proof.verified = false;
|
|
631
|
+
if (reason !== undefined) proof.errorMessage = reason;
|
|
632
|
+
db.prepare("UPDATE zkp_proofs SET verified = 0 WHERE id = ?").run(proofId);
|
|
633
|
+
return { ...proof };
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
export function setProofStatus(db, proofId, newStatus, patch = {}) {
|
|
637
|
+
const proof = _proofs.get(proofId);
|
|
638
|
+
if (!proof) throw new Error(`Proof not found: ${proofId}`);
|
|
639
|
+
if (!Object.values(PROOF_STATUS_V2).includes(newStatus)) {
|
|
640
|
+
throw new Error(`Unknown proof status: ${newStatus}`);
|
|
641
|
+
}
|
|
642
|
+
const current = proof.status || PROOF_STATUS_V2.PENDING;
|
|
643
|
+
const allowed = PROOF_TRANSITIONS_V2.get(current);
|
|
644
|
+
if (!allowed || !allowed.has(newStatus)) {
|
|
645
|
+
throw new Error(`Invalid transition: ${current} → ${newStatus}`);
|
|
646
|
+
}
|
|
647
|
+
proof.status = newStatus;
|
|
648
|
+
if (patch.errorMessage !== undefined) proof.errorMessage = patch.errorMessage;
|
|
649
|
+
if (newStatus === PROOF_STATUS_V2.VERIFIED) {
|
|
650
|
+
proof.verified = true;
|
|
651
|
+
db.prepare("UPDATE zkp_proofs SET verified = 1 WHERE id = ?").run(proofId);
|
|
652
|
+
} else {
|
|
653
|
+
proof.verified = false;
|
|
654
|
+
db.prepare("UPDATE zkp_proofs SET verified = 0 WHERE id = ?").run(proofId);
|
|
655
|
+
}
|
|
656
|
+
return { ...proof };
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
export function autoExpireProofs(db) {
|
|
660
|
+
const now = Date.now();
|
|
661
|
+
const expired = [];
|
|
662
|
+
for (const proof of _proofs.values()) {
|
|
663
|
+
const current = proof.status || PROOF_STATUS_V2.PENDING;
|
|
664
|
+
if (PROOF_TERMINALS_V2.has(current)) continue;
|
|
665
|
+
if (proof.expiresAt && now > proof.expiresAt) {
|
|
666
|
+
proof.status = PROOF_STATUS_V2.EXPIRED;
|
|
667
|
+
proof.verified = false;
|
|
668
|
+
db.prepare("UPDATE zkp_proofs SET verified = 0 WHERE id = ?").run(
|
|
669
|
+
proof.id,
|
|
670
|
+
);
|
|
671
|
+
expired.push({ ...proof });
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
return expired;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/* ── Selective Disclosure V2 ───────────────────────────── */
|
|
678
|
+
|
|
679
|
+
export function selectiveDiscloseV2(
|
|
680
|
+
db,
|
|
681
|
+
{ credentialId, disclosedFields, requiredFields, recipientDid } = {},
|
|
682
|
+
) {
|
|
683
|
+
if (!credentialId) throw new Error("credentialId is required");
|
|
684
|
+
if (!Array.isArray(disclosedFields)) {
|
|
685
|
+
throw new Error("disclosedFields must be an array");
|
|
686
|
+
}
|
|
687
|
+
const credential = _credentials.get(credentialId);
|
|
688
|
+
if (!credential) throw new Error(`Credential not found: ${credentialId}`);
|
|
689
|
+
if (Array.isArray(requiredFields)) {
|
|
690
|
+
for (const f of requiredFields) {
|
|
691
|
+
if (!disclosedFields.includes(f)) {
|
|
692
|
+
throw new Error(`Required field missing from disclosure: ${f}`);
|
|
693
|
+
}
|
|
694
|
+
if (!(f in credential.claims)) {
|
|
695
|
+
throw new Error(`Required field not in credential: ${f}`);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
return selectiveDisclose(db, credentialId, disclosedFields, recipientDid);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/* ── V2 Stats ──────────────────────────────────────────── */
|
|
703
|
+
|
|
704
|
+
export function getZKPStatsV2() {
|
|
705
|
+
const circuitsByStatus = {};
|
|
706
|
+
for (const s of Object.values(CIRCUIT_STATUS_V2)) circuitsByStatus[s] = 0;
|
|
707
|
+
const proofsByStatus = {};
|
|
708
|
+
for (const s of Object.values(PROOF_STATUS_V2)) proofsByStatus[s] = 0;
|
|
709
|
+
const proofsByScheme = {};
|
|
710
|
+
for (const s of Object.values(PROOF_SCHEME_V2)) proofsByScheme[s] = 0;
|
|
711
|
+
|
|
712
|
+
for (const c of _circuits.values()) {
|
|
713
|
+
circuitsByStatus[c.status] = (circuitsByStatus[c.status] || 0) + 1;
|
|
714
|
+
}
|
|
715
|
+
let verifiedCount = 0;
|
|
716
|
+
let pendingCount = 0;
|
|
717
|
+
for (const p of _proofs.values()) {
|
|
718
|
+
const status = p.status || PROOF_STATUS_V2.PENDING;
|
|
719
|
+
proofsByStatus[status] = (proofsByStatus[status] || 0) + 1;
|
|
720
|
+
proofsByScheme[p.scheme] = (proofsByScheme[p.scheme] || 0) + 1;
|
|
721
|
+
if (status === PROOF_STATUS_V2.VERIFIED) verifiedCount += 1;
|
|
722
|
+
if (status === PROOF_STATUS_V2.PENDING) pendingCount += 1;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
const credentialsByDid = {};
|
|
726
|
+
for (const c of _credentials.values()) {
|
|
727
|
+
const key = c.did || "_anonymous";
|
|
728
|
+
credentialsByDid[key] = (credentialsByDid[key] || 0) + 1;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
return {
|
|
732
|
+
totalCircuits: _circuits.size,
|
|
733
|
+
totalProofs: _proofs.size,
|
|
734
|
+
totalCredentials: _credentials.size,
|
|
735
|
+
verifiedProofs: verifiedCount,
|
|
736
|
+
pendingProofs: pendingCount,
|
|
737
|
+
maxCircuitsPerCreator: _maxCircuitsPerCreator,
|
|
738
|
+
proofExpiryMs: _proofExpiryMs,
|
|
739
|
+
circuitsByStatus,
|
|
740
|
+
proofsByStatus,
|
|
741
|
+
proofsByScheme,
|
|
742
|
+
credentialsByDid,
|
|
743
|
+
};
|
|
470
744
|
}
|