chainlesschain 0.132.0 → 0.145.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.
Files changed (135) hide show
  1. package/package.json +1 -1
  2. package/src/commands/a2a.js +230 -0
  3. package/src/commands/activitypub.js +191 -0
  4. package/src/commands/agent.js +601 -0
  5. package/src/commands/audit.js +206 -0
  6. package/src/commands/bi.js +186 -0
  7. package/src/commands/bm25.js +162 -0
  8. package/src/commands/browse.js +225 -0
  9. package/src/commands/ccron.js +178 -0
  10. package/src/commands/chat.js +207 -0
  11. package/src/commands/compliance.js +420 -0
  12. package/src/commands/compt.js +176 -0
  13. package/src/commands/consol.js +237 -0
  14. package/src/commands/cowork.js +588 -0
  15. package/src/commands/crosschain.js +216 -0
  16. package/src/commands/dao.js +216 -0
  17. package/src/commands/dlp.js +206 -0
  18. package/src/commands/economy.js +211 -0
  19. package/src/commands/evolution.js +209 -0
  20. package/src/commands/evomap.js +216 -0
  21. package/src/commands/fflag.js +230 -0
  22. package/src/commands/git.js +185 -0
  23. package/src/commands/hardening.js +209 -0
  24. package/src/commands/hmemory.js +210 -0
  25. package/src/commands/incentive.js +209 -0
  26. package/src/commands/inference.js +178 -0
  27. package/src/commands/itbudget.js +161 -0
  28. package/src/commands/kg.js +206 -0
  29. package/src/commands/lowcode.js +201 -0
  30. package/src/commands/marketplace.js +206 -0
  31. package/src/commands/matrix.js +214 -0
  32. package/src/commands/mcpscaf.js +153 -0
  33. package/src/commands/meminj.js +153 -0
  34. package/src/commands/nostr.js +213 -0
  35. package/src/commands/orchestrate.js +217 -0
  36. package/src/commands/orchgov.js +156 -0
  37. package/src/commands/pdfp.js +160 -0
  38. package/src/commands/perf.js +176 -0
  39. package/src/commands/perm.js +156 -0
  40. package/src/commands/pipeline.js +211 -0
  41. package/src/commands/planmode.js +154 -0
  42. package/src/commands/privacy.js +203 -0
  43. package/src/commands/promcomp.js +166 -0
  44. package/src/commands/recommend.js +185 -0
  45. package/src/commands/reputation.js +208 -0
  46. package/src/commands/sandbox.js +206 -0
  47. package/src/commands/seshhook.js +153 -0
  48. package/src/commands/seshsearch.js +149 -0
  49. package/src/commands/seshtail.js +152 -0
  50. package/src/commands/seshu.js +160 -0
  51. package/src/commands/sganal.js +172 -0
  52. package/src/commands/siem.js +207 -0
  53. package/src/commands/sla.js +212 -0
  54. package/src/commands/slotfill.js +154 -0
  55. package/src/commands/social.js +159 -0
  56. package/src/commands/stress.js +206 -0
  57. package/src/commands/svccont.js +157 -0
  58. package/src/commands/terraform.js +206 -0
  59. package/src/commands/tms.js +183 -0
  60. package/src/commands/topiccls.js +158 -0
  61. package/src/commands/uprof.js +154 -0
  62. package/src/commands/vcheck.js +172 -0
  63. package/src/commands/webfetch.js +150 -0
  64. package/src/commands/zkp.js +218 -0
  65. package/src/harness/prompt-compressor.js +331 -0
  66. package/src/index.js +101 -1
  67. package/src/lib/a2a-protocol.js +373 -0
  68. package/src/lib/activitypub-bridge.js +343 -0
  69. package/src/lib/agent-economy.js +358 -0
  70. package/src/lib/app-builder.js +338 -0
  71. package/src/lib/audit-logger.js +321 -0
  72. package/src/lib/autonomous-agent.js +341 -0
  73. package/src/lib/bi-engine.js +339 -0
  74. package/src/lib/bm25-search.js +333 -0
  75. package/src/lib/browser-automation.js +352 -0
  76. package/src/lib/chat-core.js +336 -0
  77. package/src/lib/claude-code-bridge.js +341 -0
  78. package/src/lib/compliance-framework-reporter.js +359 -0
  79. package/src/lib/compliance-manager.js +330 -0
  80. package/src/lib/compression-telemetry.js +333 -0
  81. package/src/lib/content-recommender.js +370 -0
  82. package/src/lib/cowork-cron.js +330 -0
  83. package/src/lib/cowork-learning.js +333 -0
  84. package/src/lib/cowork-task-runner.js +362 -0
  85. package/src/lib/cowork-workflow.js +327 -0
  86. package/src/lib/cross-chain.js +365 -0
  87. package/src/lib/dao-governance.js +339 -0
  88. package/src/lib/dlp-engine.js +343 -0
  89. package/src/lib/evolution-system.js +336 -0
  90. package/src/lib/evomap-manager.js +339 -0
  91. package/src/lib/execution-backend.js +351 -0
  92. package/src/lib/feature-flags.js +330 -0
  93. package/src/lib/git-integration.js +343 -0
  94. package/src/lib/hardening-manager.js +341 -0
  95. package/src/lib/hierarchical-memory.js +341 -0
  96. package/src/lib/inference-network.js +362 -0
  97. package/src/lib/iteration-budget.js +357 -0
  98. package/src/lib/knowledge-graph.js +333 -0
  99. package/src/lib/matrix-bridge.js +339 -0
  100. package/src/lib/mcp-scaffold.js +345 -0
  101. package/src/lib/memory-injection.js +320 -0
  102. package/src/lib/nostr-bridge.js +342 -0
  103. package/src/lib/orchestrator.js +350 -0
  104. package/src/lib/pdf-parser.js +330 -0
  105. package/src/lib/perf-tuning.js +364 -0
  106. package/src/lib/permission-engine.js +319 -0
  107. package/src/lib/pipeline-orchestrator.js +345 -0
  108. package/src/lib/plan-mode.js +328 -0
  109. package/src/lib/privacy-computing.js +335 -0
  110. package/src/lib/prompt-compressor.js +1 -10
  111. package/src/lib/reputation-optimizer.js +340 -0
  112. package/src/lib/sandbox-v2.js +327 -0
  113. package/src/lib/service-container.js +342 -0
  114. package/src/lib/session-consolidator.js +352 -0
  115. package/src/lib/session-hooks.js +340 -0
  116. package/src/lib/session-search.js +334 -0
  117. package/src/lib/session-tail.js +320 -0
  118. package/src/lib/session-usage.js +329 -0
  119. package/src/lib/siem-exporter.js +352 -0
  120. package/src/lib/skill-marketplace.js +345 -0
  121. package/src/lib/sla-manager.js +341 -0
  122. package/src/lib/slot-filler.js +333 -0
  123. package/src/lib/social-graph-analytics.js +327 -0
  124. package/src/lib/social-graph.js +304 -0
  125. package/src/lib/stress-tester.js +342 -0
  126. package/src/lib/sub-agent-registry.js +359 -0
  127. package/src/lib/task-model-selector.js +333 -0
  128. package/src/lib/terraform-manager.js +333 -0
  129. package/src/lib/todo-manager.js +339 -0
  130. package/src/lib/token-incentive.js +341 -0
  131. package/src/lib/topic-classifier.js +353 -0
  132. package/src/lib/user-profile.js +325 -0
  133. package/src/lib/version-checker.js +335 -0
  134. package/src/lib/web-fetch.js +322 -0
  135. package/src/lib/zkp-engine.js +342 -0
@@ -170,3 +170,328 @@ export async function consolidateUserProfile(llmFn) {
170
170
  // ─── Exports ────────────────────────────────────────────────────────────────
171
171
 
172
172
  export const MAX_USER_PROFILE_LENGTH = MAX_PROFILE_LENGTH;
173
+
174
+ // ===== V2 Surface: User Profile governance overlay (CLI v0.141.0) =====
175
+ export const USER_PROFILE_MATURITY_V2 = Object.freeze({
176
+ PENDING: "pending",
177
+ ACTIVE: "active",
178
+ DORMANT: "dormant",
179
+ ARCHIVED: "archived",
180
+ });
181
+ export const USER_PREF_LIFECYCLE_V2 = Object.freeze({
182
+ PROPOSED: "proposed",
183
+ APPLIED: "applied",
184
+ REJECTED: "rejected",
185
+ SUPERSEDED: "superseded",
186
+ CANCELLED: "cancelled",
187
+ });
188
+ const _upTrans = new Map([
189
+ [
190
+ USER_PROFILE_MATURITY_V2.PENDING,
191
+ new Set([
192
+ USER_PROFILE_MATURITY_V2.ACTIVE,
193
+ USER_PROFILE_MATURITY_V2.ARCHIVED,
194
+ ]),
195
+ ],
196
+ [
197
+ USER_PROFILE_MATURITY_V2.ACTIVE,
198
+ new Set([
199
+ USER_PROFILE_MATURITY_V2.DORMANT,
200
+ USER_PROFILE_MATURITY_V2.ARCHIVED,
201
+ ]),
202
+ ],
203
+ [
204
+ USER_PROFILE_MATURITY_V2.DORMANT,
205
+ new Set([
206
+ USER_PROFILE_MATURITY_V2.ACTIVE,
207
+ USER_PROFILE_MATURITY_V2.ARCHIVED,
208
+ ]),
209
+ ],
210
+ [USER_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
211
+ ]);
212
+ const _upTerminal = new Set([USER_PROFILE_MATURITY_V2.ARCHIVED]);
213
+ const _uprefTrans = new Map([
214
+ [
215
+ USER_PREF_LIFECYCLE_V2.PROPOSED,
216
+ new Set([
217
+ USER_PREF_LIFECYCLE_V2.APPLIED,
218
+ USER_PREF_LIFECYCLE_V2.REJECTED,
219
+ USER_PREF_LIFECYCLE_V2.CANCELLED,
220
+ ]),
221
+ ],
222
+ [
223
+ USER_PREF_LIFECYCLE_V2.APPLIED,
224
+ new Set([USER_PREF_LIFECYCLE_V2.SUPERSEDED]),
225
+ ],
226
+ [USER_PREF_LIFECYCLE_V2.REJECTED, new Set()],
227
+ [USER_PREF_LIFECYCLE_V2.SUPERSEDED, new Set()],
228
+ [USER_PREF_LIFECYCLE_V2.CANCELLED, new Set()],
229
+ ]);
230
+ const _upsV2 = new Map();
231
+ const _uprefsV2 = new Map();
232
+ let _upMaxActivePerOwner = 5,
233
+ _upMaxPendingPrefsPerProfile = 20,
234
+ _upIdleMs = 90 * 24 * 60 * 60 * 1000,
235
+ _uprefStuckMs = 7 * 24 * 60 * 60 * 1000;
236
+ function _upPos(n, label) {
237
+ const v = Math.floor(Number(n));
238
+ if (!Number.isFinite(v) || v <= 0)
239
+ throw new Error(`${label} must be positive integer`);
240
+ return v;
241
+ }
242
+ function _upCheckP(from, to) {
243
+ const a = _upTrans.get(from);
244
+ if (!a || !a.has(to))
245
+ throw new Error(`invalid user profile transition ${from} → ${to}`);
246
+ }
247
+ function _uprefCheck(from, to) {
248
+ const a = _uprefTrans.get(from);
249
+ if (!a || !a.has(to))
250
+ throw new Error(`invalid user pref transition ${from} → ${to}`);
251
+ }
252
+ export function setMaxActiveUserProfilesPerOwnerV2(n) {
253
+ _upMaxActivePerOwner = _upPos(n, "maxActiveUserProfilesPerOwner");
254
+ }
255
+ export function getMaxActiveUserProfilesPerOwnerV2() {
256
+ return _upMaxActivePerOwner;
257
+ }
258
+ export function setMaxPendingUserPrefsPerProfileV2(n) {
259
+ _upMaxPendingPrefsPerProfile = _upPos(n, "maxPendingUserPrefsPerProfile");
260
+ }
261
+ export function getMaxPendingUserPrefsPerProfileV2() {
262
+ return _upMaxPendingPrefsPerProfile;
263
+ }
264
+ export function setUserProfileIdleMsV2(n) {
265
+ _upIdleMs = _upPos(n, "userProfileIdleMs");
266
+ }
267
+ export function getUserProfileIdleMsV2() {
268
+ return _upIdleMs;
269
+ }
270
+ export function setUserPrefStuckMsV2(n) {
271
+ _uprefStuckMs = _upPos(n, "userPrefStuckMs");
272
+ }
273
+ export function getUserPrefStuckMsV2() {
274
+ return _uprefStuckMs;
275
+ }
276
+ export function _resetStateUserProfileV2() {
277
+ _upsV2.clear();
278
+ _uprefsV2.clear();
279
+ _upMaxActivePerOwner = 5;
280
+ _upMaxPendingPrefsPerProfile = 20;
281
+ _upIdleMs = 90 * 24 * 60 * 60 * 1000;
282
+ _uprefStuckMs = 7 * 24 * 60 * 60 * 1000;
283
+ }
284
+ export function registerUserProfileV2({ id, owner, handle, metadata } = {}) {
285
+ if (!id) throw new Error("user profile id required");
286
+ if (!owner) throw new Error("user profile owner required");
287
+ if (_upsV2.has(id)) throw new Error(`user profile ${id} already registered`);
288
+ const now = Date.now();
289
+ const p = {
290
+ id,
291
+ owner,
292
+ handle: handle || id,
293
+ status: USER_PROFILE_MATURITY_V2.PENDING,
294
+ createdAt: now,
295
+ updatedAt: now,
296
+ activatedAt: null,
297
+ archivedAt: null,
298
+ lastTouchedAt: now,
299
+ metadata: { ...(metadata || {}) },
300
+ };
301
+ _upsV2.set(id, p);
302
+ return { ...p, metadata: { ...p.metadata } };
303
+ }
304
+ function _upCountActive(owner) {
305
+ let n = 0;
306
+ for (const p of _upsV2.values())
307
+ if (p.owner === owner && p.status === USER_PROFILE_MATURITY_V2.ACTIVE) n++;
308
+ return n;
309
+ }
310
+ export function activateUserProfileV2(id) {
311
+ const p = _upsV2.get(id);
312
+ if (!p) throw new Error(`user profile ${id} not found`);
313
+ _upCheckP(p.status, USER_PROFILE_MATURITY_V2.ACTIVE);
314
+ const recovery = p.status === USER_PROFILE_MATURITY_V2.DORMANT;
315
+ if (!recovery && _upCountActive(p.owner) >= _upMaxActivePerOwner)
316
+ throw new Error(`max active user profiles for owner ${p.owner} reached`);
317
+ const now = Date.now();
318
+ p.status = USER_PROFILE_MATURITY_V2.ACTIVE;
319
+ p.updatedAt = now;
320
+ p.lastTouchedAt = now;
321
+ if (!p.activatedAt) p.activatedAt = now;
322
+ return { ...p, metadata: { ...p.metadata } };
323
+ }
324
+ export function dormantUserProfileV2(id) {
325
+ const p = _upsV2.get(id);
326
+ if (!p) throw new Error(`user profile ${id} not found`);
327
+ _upCheckP(p.status, USER_PROFILE_MATURITY_V2.DORMANT);
328
+ p.status = USER_PROFILE_MATURITY_V2.DORMANT;
329
+ p.updatedAt = Date.now();
330
+ return { ...p, metadata: { ...p.metadata } };
331
+ }
332
+ export function archiveUserProfileV2(id) {
333
+ const p = _upsV2.get(id);
334
+ if (!p) throw new Error(`user profile ${id} not found`);
335
+ _upCheckP(p.status, USER_PROFILE_MATURITY_V2.ARCHIVED);
336
+ const now = Date.now();
337
+ p.status = USER_PROFILE_MATURITY_V2.ARCHIVED;
338
+ p.updatedAt = now;
339
+ if (!p.archivedAt) p.archivedAt = now;
340
+ return { ...p, metadata: { ...p.metadata } };
341
+ }
342
+ export function touchUserProfileV2(id) {
343
+ const p = _upsV2.get(id);
344
+ if (!p) throw new Error(`user profile ${id} not found`);
345
+ if (_upTerminal.has(p.status))
346
+ throw new Error(`cannot touch terminal user profile ${id}`);
347
+ const now = Date.now();
348
+ p.lastTouchedAt = now;
349
+ p.updatedAt = now;
350
+ return { ...p, metadata: { ...p.metadata } };
351
+ }
352
+ export function getUserProfileV2(id) {
353
+ const p = _upsV2.get(id);
354
+ if (!p) return null;
355
+ return { ...p, metadata: { ...p.metadata } };
356
+ }
357
+ export function listUserProfilesV2() {
358
+ return [..._upsV2.values()].map((p) => ({
359
+ ...p,
360
+ metadata: { ...p.metadata },
361
+ }));
362
+ }
363
+ function _uprefCountPending(profileId) {
364
+ let n = 0;
365
+ for (const r of _uprefsV2.values())
366
+ if (
367
+ r.profileId === profileId &&
368
+ r.status === USER_PREF_LIFECYCLE_V2.PROPOSED
369
+ )
370
+ n++;
371
+ return n;
372
+ }
373
+ export function createUserPrefV2({ id, profileId, key, metadata } = {}) {
374
+ if (!id) throw new Error("user pref id required");
375
+ if (!profileId) throw new Error("user pref profileId required");
376
+ if (_uprefsV2.has(id)) throw new Error(`user pref ${id} already exists`);
377
+ if (!_upsV2.has(profileId))
378
+ throw new Error(`user profile ${profileId} not found`);
379
+ if (_uprefCountPending(profileId) >= _upMaxPendingPrefsPerProfile)
380
+ throw new Error(`max pending user prefs for profile ${profileId} reached`);
381
+ const now = Date.now();
382
+ const r = {
383
+ id,
384
+ profileId,
385
+ key: key || "",
386
+ status: USER_PREF_LIFECYCLE_V2.PROPOSED,
387
+ createdAt: now,
388
+ updatedAt: now,
389
+ startedAt: now,
390
+ settledAt: null,
391
+ metadata: { ...(metadata || {}) },
392
+ };
393
+ _uprefsV2.set(id, r);
394
+ return { ...r, metadata: { ...r.metadata } };
395
+ }
396
+ export function applyUserPrefV2(id) {
397
+ const r = _uprefsV2.get(id);
398
+ if (!r) throw new Error(`user pref ${id} not found`);
399
+ _uprefCheck(r.status, USER_PREF_LIFECYCLE_V2.APPLIED);
400
+ const now = Date.now();
401
+ r.status = USER_PREF_LIFECYCLE_V2.APPLIED;
402
+ r.updatedAt = now;
403
+ if (!r.settledAt) r.settledAt = now;
404
+ return { ...r, metadata: { ...r.metadata } };
405
+ }
406
+ export function rejectUserPrefV2(id, reason) {
407
+ const r = _uprefsV2.get(id);
408
+ if (!r) throw new Error(`user pref ${id} not found`);
409
+ _uprefCheck(r.status, USER_PREF_LIFECYCLE_V2.REJECTED);
410
+ const now = Date.now();
411
+ r.status = USER_PREF_LIFECYCLE_V2.REJECTED;
412
+ r.updatedAt = now;
413
+ if (!r.settledAt) r.settledAt = now;
414
+ if (reason) r.metadata.rejectReason = String(reason);
415
+ return { ...r, metadata: { ...r.metadata } };
416
+ }
417
+ export function supersedeUserPrefV2(id) {
418
+ const r = _uprefsV2.get(id);
419
+ if (!r) throw new Error(`user pref ${id} not found`);
420
+ _uprefCheck(r.status, USER_PREF_LIFECYCLE_V2.SUPERSEDED);
421
+ const now = Date.now();
422
+ r.status = USER_PREF_LIFECYCLE_V2.SUPERSEDED;
423
+ r.updatedAt = now;
424
+ if (!r.settledAt) r.settledAt = now;
425
+ return { ...r, metadata: { ...r.metadata } };
426
+ }
427
+ export function cancelUserPrefV2(id, reason) {
428
+ const r = _uprefsV2.get(id);
429
+ if (!r) throw new Error(`user pref ${id} not found`);
430
+ _uprefCheck(r.status, USER_PREF_LIFECYCLE_V2.CANCELLED);
431
+ const now = Date.now();
432
+ r.status = USER_PREF_LIFECYCLE_V2.CANCELLED;
433
+ r.updatedAt = now;
434
+ if (!r.settledAt) r.settledAt = now;
435
+ if (reason) r.metadata.cancelReason = String(reason);
436
+ return { ...r, metadata: { ...r.metadata } };
437
+ }
438
+ export function getUserPrefV2(id) {
439
+ const r = _uprefsV2.get(id);
440
+ if (!r) return null;
441
+ return { ...r, metadata: { ...r.metadata } };
442
+ }
443
+ export function listUserPrefsV2() {
444
+ return [..._uprefsV2.values()].map((r) => ({
445
+ ...r,
446
+ metadata: { ...r.metadata },
447
+ }));
448
+ }
449
+ export function autoDormantIdleUserProfilesV2({ now } = {}) {
450
+ const t = now ?? Date.now();
451
+ const flipped = [];
452
+ for (const p of _upsV2.values())
453
+ if (
454
+ p.status === USER_PROFILE_MATURITY_V2.ACTIVE &&
455
+ t - p.lastTouchedAt >= _upIdleMs
456
+ ) {
457
+ p.status = USER_PROFILE_MATURITY_V2.DORMANT;
458
+ p.updatedAt = t;
459
+ flipped.push(p.id);
460
+ }
461
+ return { flipped, count: flipped.length };
462
+ }
463
+ export function autoCancelStaleUserPrefsV2({ now } = {}) {
464
+ const t = now ?? Date.now();
465
+ const flipped = [];
466
+ for (const r of _uprefsV2.values())
467
+ if (
468
+ r.status === USER_PREF_LIFECYCLE_V2.PROPOSED &&
469
+ t - r.startedAt >= _uprefStuckMs
470
+ ) {
471
+ r.status = USER_PREF_LIFECYCLE_V2.CANCELLED;
472
+ r.updatedAt = t;
473
+ if (!r.settledAt) r.settledAt = t;
474
+ r.metadata.cancelReason = "auto-cancel-stale";
475
+ flipped.push(r.id);
476
+ }
477
+ return { flipped, count: flipped.length };
478
+ }
479
+ export function getUserProfileGovStatsV2() {
480
+ const profilesByStatus = {};
481
+ for (const v of Object.values(USER_PROFILE_MATURITY_V2))
482
+ profilesByStatus[v] = 0;
483
+ for (const p of _upsV2.values()) profilesByStatus[p.status]++;
484
+ const prefsByStatus = {};
485
+ for (const v of Object.values(USER_PREF_LIFECYCLE_V2)) prefsByStatus[v] = 0;
486
+ for (const r of _uprefsV2.values()) prefsByStatus[r.status]++;
487
+ return {
488
+ totalUserProfilesV2: _upsV2.size,
489
+ totalUserPrefsV2: _uprefsV2.size,
490
+ maxActiveUserProfilesPerOwner: _upMaxActivePerOwner,
491
+ maxPendingUserPrefsPerProfile: _upMaxPendingPrefsPerProfile,
492
+ userProfileIdleMs: _upIdleMs,
493
+ userPrefStuckMs: _uprefStuckMs,
494
+ profilesByStatus,
495
+ prefsByStatus,
496
+ };
497
+ }
@@ -98,3 +98,338 @@ function filterByChannel(releases, channel) {
98
98
  }
99
99
 
100
100
  export { fetchReleases, filterByChannel };
101
+
102
+ // =====================================================================
103
+ // Version Checker V2 governance overlay
104
+ // =====================================================================
105
+ export const VCHK_PROFILE_MATURITY_V2 = Object.freeze({
106
+ PENDING: "pending",
107
+ ACTIVE: "active",
108
+ STALE: "stale",
109
+ ARCHIVED: "archived",
110
+ });
111
+ export const VCHK_CHECK_LIFECYCLE_V2 = Object.freeze({
112
+ QUEUED: "queued",
113
+ CHECKING: "checking",
114
+ COMPLETED: "completed",
115
+ FAILED: "failed",
116
+ CANCELLED: "cancelled",
117
+ });
118
+ const _vchkPTrans = new Map([
119
+ [
120
+ VCHK_PROFILE_MATURITY_V2.PENDING,
121
+ new Set([
122
+ VCHK_PROFILE_MATURITY_V2.ACTIVE,
123
+ VCHK_PROFILE_MATURITY_V2.ARCHIVED,
124
+ ]),
125
+ ],
126
+ [
127
+ VCHK_PROFILE_MATURITY_V2.ACTIVE,
128
+ new Set([
129
+ VCHK_PROFILE_MATURITY_V2.STALE,
130
+ VCHK_PROFILE_MATURITY_V2.ARCHIVED,
131
+ ]),
132
+ ],
133
+ [
134
+ VCHK_PROFILE_MATURITY_V2.STALE,
135
+ new Set([
136
+ VCHK_PROFILE_MATURITY_V2.ACTIVE,
137
+ VCHK_PROFILE_MATURITY_V2.ARCHIVED,
138
+ ]),
139
+ ],
140
+ [VCHK_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
141
+ ]);
142
+ const _vchkPTerminal = new Set([VCHK_PROFILE_MATURITY_V2.ARCHIVED]);
143
+ const _vchkCTrans = new Map([
144
+ [
145
+ VCHK_CHECK_LIFECYCLE_V2.QUEUED,
146
+ new Set([
147
+ VCHK_CHECK_LIFECYCLE_V2.CHECKING,
148
+ VCHK_CHECK_LIFECYCLE_V2.CANCELLED,
149
+ ]),
150
+ ],
151
+ [
152
+ VCHK_CHECK_LIFECYCLE_V2.CHECKING,
153
+ new Set([
154
+ VCHK_CHECK_LIFECYCLE_V2.COMPLETED,
155
+ VCHK_CHECK_LIFECYCLE_V2.FAILED,
156
+ VCHK_CHECK_LIFECYCLE_V2.CANCELLED,
157
+ ]),
158
+ ],
159
+ [VCHK_CHECK_LIFECYCLE_V2.COMPLETED, new Set()],
160
+ [VCHK_CHECK_LIFECYCLE_V2.FAILED, new Set()],
161
+ [VCHK_CHECK_LIFECYCLE_V2.CANCELLED, new Set()],
162
+ ]);
163
+ const _vchkPsV2 = new Map();
164
+ const _vchkCsV2 = new Map();
165
+ let _vchkMaxActive = 5,
166
+ _vchkMaxPending = 10,
167
+ _vchkIdleMs = 30 * 24 * 60 * 60 * 1000,
168
+ _vchkStuckMs = 30 * 1000;
169
+ function _vchkPos(n, label) {
170
+ const v = Math.floor(Number(n));
171
+ if (!Number.isFinite(v) || v <= 0)
172
+ throw new Error(`${label} must be positive integer`);
173
+ return v;
174
+ }
175
+ function _vchkCheckP(from, to) {
176
+ const a = _vchkPTrans.get(from);
177
+ if (!a || !a.has(to))
178
+ throw new Error(`invalid vchk profile transition ${from} → ${to}`);
179
+ }
180
+ function _vchkCheckC(from, to) {
181
+ const a = _vchkCTrans.get(from);
182
+ if (!a || !a.has(to))
183
+ throw new Error(`invalid vchk check transition ${from} → ${to}`);
184
+ }
185
+ function _vchkCountActive(owner) {
186
+ let c = 0;
187
+ for (const p of _vchkPsV2.values())
188
+ if (p.owner === owner && p.status === VCHK_PROFILE_MATURITY_V2.ACTIVE) c++;
189
+ return c;
190
+ }
191
+ function _vchkCountPending(profileId) {
192
+ let c = 0;
193
+ for (const x of _vchkCsV2.values())
194
+ if (
195
+ x.profileId === profileId &&
196
+ (x.status === VCHK_CHECK_LIFECYCLE_V2.QUEUED ||
197
+ x.status === VCHK_CHECK_LIFECYCLE_V2.CHECKING)
198
+ )
199
+ c++;
200
+ return c;
201
+ }
202
+ export function setMaxActiveVchkProfilesPerOwnerV2(n) {
203
+ _vchkMaxActive = _vchkPos(n, "maxActiveVchkProfilesPerOwner");
204
+ }
205
+ export function getMaxActiveVchkProfilesPerOwnerV2() {
206
+ return _vchkMaxActive;
207
+ }
208
+ export function setMaxPendingVchkChecksPerProfileV2(n) {
209
+ _vchkMaxPending = _vchkPos(n, "maxPendingVchkChecksPerProfile");
210
+ }
211
+ export function getMaxPendingVchkChecksPerProfileV2() {
212
+ return _vchkMaxPending;
213
+ }
214
+ export function setVchkProfileIdleMsV2(n) {
215
+ _vchkIdleMs = _vchkPos(n, "vchkProfileIdleMs");
216
+ }
217
+ export function getVchkProfileIdleMsV2() {
218
+ return _vchkIdleMs;
219
+ }
220
+ export function setVchkCheckStuckMsV2(n) {
221
+ _vchkStuckMs = _vchkPos(n, "vchkCheckStuckMs");
222
+ }
223
+ export function getVchkCheckStuckMsV2() {
224
+ return _vchkStuckMs;
225
+ }
226
+ export function _resetStateVersionCheckerV2() {
227
+ _vchkPsV2.clear();
228
+ _vchkCsV2.clear();
229
+ _vchkMaxActive = 5;
230
+ _vchkMaxPending = 10;
231
+ _vchkIdleMs = 30 * 24 * 60 * 60 * 1000;
232
+ _vchkStuckMs = 30 * 1000;
233
+ }
234
+ export function registerVchkProfileV2({ id, owner, channel, metadata } = {}) {
235
+ if (!id || !owner) throw new Error("id and owner required");
236
+ if (_vchkPsV2.has(id)) throw new Error(`vchk profile ${id} already exists`);
237
+ const now = Date.now();
238
+ const p = {
239
+ id,
240
+ owner,
241
+ channel: channel || "stable",
242
+ status: VCHK_PROFILE_MATURITY_V2.PENDING,
243
+ createdAt: now,
244
+ updatedAt: now,
245
+ lastTouchedAt: now,
246
+ activatedAt: null,
247
+ archivedAt: null,
248
+ metadata: { ...(metadata || {}) },
249
+ };
250
+ _vchkPsV2.set(id, p);
251
+ return { ...p, metadata: { ...p.metadata } };
252
+ }
253
+ export function activateVchkProfileV2(id) {
254
+ const p = _vchkPsV2.get(id);
255
+ if (!p) throw new Error(`vchk profile ${id} not found`);
256
+ const isInitial = p.status === VCHK_PROFILE_MATURITY_V2.PENDING;
257
+ _vchkCheckP(p.status, VCHK_PROFILE_MATURITY_V2.ACTIVE);
258
+ if (isInitial && _vchkCountActive(p.owner) >= _vchkMaxActive)
259
+ throw new Error(`max active vchk profiles for owner ${p.owner} reached`);
260
+ const now = Date.now();
261
+ p.status = VCHK_PROFILE_MATURITY_V2.ACTIVE;
262
+ p.updatedAt = now;
263
+ p.lastTouchedAt = now;
264
+ if (!p.activatedAt) p.activatedAt = now;
265
+ return { ...p, metadata: { ...p.metadata } };
266
+ }
267
+ export function staleVchkProfileV2(id) {
268
+ const p = _vchkPsV2.get(id);
269
+ if (!p) throw new Error(`vchk profile ${id} not found`);
270
+ _vchkCheckP(p.status, VCHK_PROFILE_MATURITY_V2.STALE);
271
+ p.status = VCHK_PROFILE_MATURITY_V2.STALE;
272
+ p.updatedAt = Date.now();
273
+ return { ...p, metadata: { ...p.metadata } };
274
+ }
275
+ export function archiveVchkProfileV2(id) {
276
+ const p = _vchkPsV2.get(id);
277
+ if (!p) throw new Error(`vchk profile ${id} not found`);
278
+ _vchkCheckP(p.status, VCHK_PROFILE_MATURITY_V2.ARCHIVED);
279
+ const now = Date.now();
280
+ p.status = VCHK_PROFILE_MATURITY_V2.ARCHIVED;
281
+ p.updatedAt = now;
282
+ if (!p.archivedAt) p.archivedAt = now;
283
+ return { ...p, metadata: { ...p.metadata } };
284
+ }
285
+ export function touchVchkProfileV2(id) {
286
+ const p = _vchkPsV2.get(id);
287
+ if (!p) throw new Error(`vchk profile ${id} not found`);
288
+ if (_vchkPTerminal.has(p.status))
289
+ throw new Error(`cannot touch terminal vchk profile ${id}`);
290
+ const now = Date.now();
291
+ p.lastTouchedAt = now;
292
+ p.updatedAt = now;
293
+ return { ...p, metadata: { ...p.metadata } };
294
+ }
295
+ export function getVchkProfileV2(id) {
296
+ const p = _vchkPsV2.get(id);
297
+ if (!p) return null;
298
+ return { ...p, metadata: { ...p.metadata } };
299
+ }
300
+ export function listVchkProfilesV2() {
301
+ return [..._vchkPsV2.values()].map((p) => ({
302
+ ...p,
303
+ metadata: { ...p.metadata },
304
+ }));
305
+ }
306
+ export function createVchkCheckV2({
307
+ id,
308
+ profileId,
309
+ currentVersion,
310
+ metadata,
311
+ } = {}) {
312
+ if (!id || !profileId) throw new Error("id and profileId required");
313
+ if (_vchkCsV2.has(id)) throw new Error(`vchk check ${id} already exists`);
314
+ if (!_vchkPsV2.has(profileId))
315
+ throw new Error(`vchk profile ${profileId} not found`);
316
+ if (_vchkCountPending(profileId) >= _vchkMaxPending)
317
+ throw new Error(`max pending vchk checks for profile ${profileId} reached`);
318
+ const now = Date.now();
319
+ const c = {
320
+ id,
321
+ profileId,
322
+ currentVersion: currentVersion || "",
323
+ status: VCHK_CHECK_LIFECYCLE_V2.QUEUED,
324
+ createdAt: now,
325
+ updatedAt: now,
326
+ startedAt: null,
327
+ settledAt: null,
328
+ metadata: { ...(metadata || {}) },
329
+ };
330
+ _vchkCsV2.set(id, c);
331
+ return { ...c, metadata: { ...c.metadata } };
332
+ }
333
+ export function checkingVchkCheckV2(id) {
334
+ const c = _vchkCsV2.get(id);
335
+ if (!c) throw new Error(`vchk check ${id} not found`);
336
+ _vchkCheckC(c.status, VCHK_CHECK_LIFECYCLE_V2.CHECKING);
337
+ const now = Date.now();
338
+ c.status = VCHK_CHECK_LIFECYCLE_V2.CHECKING;
339
+ c.updatedAt = now;
340
+ if (!c.startedAt) c.startedAt = now;
341
+ return { ...c, metadata: { ...c.metadata } };
342
+ }
343
+ export function completeVchkCheckV2(id) {
344
+ const c = _vchkCsV2.get(id);
345
+ if (!c) throw new Error(`vchk check ${id} not found`);
346
+ _vchkCheckC(c.status, VCHK_CHECK_LIFECYCLE_V2.COMPLETED);
347
+ const now = Date.now();
348
+ c.status = VCHK_CHECK_LIFECYCLE_V2.COMPLETED;
349
+ c.updatedAt = now;
350
+ if (!c.settledAt) c.settledAt = now;
351
+ return { ...c, metadata: { ...c.metadata } };
352
+ }
353
+ export function failVchkCheckV2(id, reason) {
354
+ const c = _vchkCsV2.get(id);
355
+ if (!c) throw new Error(`vchk check ${id} not found`);
356
+ _vchkCheckC(c.status, VCHK_CHECK_LIFECYCLE_V2.FAILED);
357
+ const now = Date.now();
358
+ c.status = VCHK_CHECK_LIFECYCLE_V2.FAILED;
359
+ c.updatedAt = now;
360
+ if (!c.settledAt) c.settledAt = now;
361
+ if (reason) c.metadata.failReason = String(reason);
362
+ return { ...c, metadata: { ...c.metadata } };
363
+ }
364
+ export function cancelVchkCheckV2(id, reason) {
365
+ const c = _vchkCsV2.get(id);
366
+ if (!c) throw new Error(`vchk check ${id} not found`);
367
+ _vchkCheckC(c.status, VCHK_CHECK_LIFECYCLE_V2.CANCELLED);
368
+ const now = Date.now();
369
+ c.status = VCHK_CHECK_LIFECYCLE_V2.CANCELLED;
370
+ c.updatedAt = now;
371
+ if (!c.settledAt) c.settledAt = now;
372
+ if (reason) c.metadata.cancelReason = String(reason);
373
+ return { ...c, metadata: { ...c.metadata } };
374
+ }
375
+ export function getVchkCheckV2(id) {
376
+ const c = _vchkCsV2.get(id);
377
+ if (!c) return null;
378
+ return { ...c, metadata: { ...c.metadata } };
379
+ }
380
+ export function listVchkChecksV2() {
381
+ return [..._vchkCsV2.values()].map((c) => ({
382
+ ...c,
383
+ metadata: { ...c.metadata },
384
+ }));
385
+ }
386
+ export function autoStaleIdleVchkProfilesV2({ now } = {}) {
387
+ const t = now ?? Date.now();
388
+ const flipped = [];
389
+ for (const p of _vchkPsV2.values())
390
+ if (
391
+ p.status === VCHK_PROFILE_MATURITY_V2.ACTIVE &&
392
+ t - p.lastTouchedAt >= _vchkIdleMs
393
+ ) {
394
+ p.status = VCHK_PROFILE_MATURITY_V2.STALE;
395
+ p.updatedAt = t;
396
+ flipped.push(p.id);
397
+ }
398
+ return { flipped, count: flipped.length };
399
+ }
400
+ export function autoFailStuckVchkChecksV2({ now } = {}) {
401
+ const t = now ?? Date.now();
402
+ const flipped = [];
403
+ for (const c of _vchkCsV2.values())
404
+ if (
405
+ c.status === VCHK_CHECK_LIFECYCLE_V2.CHECKING &&
406
+ c.startedAt != null &&
407
+ t - c.startedAt >= _vchkStuckMs
408
+ ) {
409
+ c.status = VCHK_CHECK_LIFECYCLE_V2.FAILED;
410
+ c.updatedAt = t;
411
+ if (!c.settledAt) c.settledAt = t;
412
+ c.metadata.failReason = "auto-fail-stuck";
413
+ flipped.push(c.id);
414
+ }
415
+ return { flipped, count: flipped.length };
416
+ }
417
+ export function getVersionCheckerGovStatsV2() {
418
+ const profilesByStatus = {};
419
+ for (const v of Object.values(VCHK_PROFILE_MATURITY_V2))
420
+ profilesByStatus[v] = 0;
421
+ for (const p of _vchkPsV2.values()) profilesByStatus[p.status]++;
422
+ const checksByStatus = {};
423
+ for (const v of Object.values(VCHK_CHECK_LIFECYCLE_V2)) checksByStatus[v] = 0;
424
+ for (const c of _vchkCsV2.values()) checksByStatus[c.status]++;
425
+ return {
426
+ totalVchkProfilesV2: _vchkPsV2.size,
427
+ totalVchkChecksV2: _vchkCsV2.size,
428
+ maxActiveVchkProfilesPerOwner: _vchkMaxActive,
429
+ maxPendingVchkChecksPerProfile: _vchkMaxPending,
430
+ vchkProfileIdleMs: _vchkIdleMs,
431
+ vchkCheckStuckMs: _vchkStuckMs,
432
+ profilesByStatus,
433
+ checksByStatus,
434
+ };
435
+ }