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.
Files changed (209) hide show
  1. package/bin/chainlesschain.js +0 -0
  2. package/package.json +1 -1
  3. package/src/commands/a2a.js +62 -0
  4. package/src/commands/activitypub.js +61 -0
  5. package/src/commands/agent-network.js +254 -1
  6. package/src/commands/agent.js +117 -0
  7. package/src/commands/audit.js +302 -0
  8. package/src/commands/automation.js +271 -1
  9. package/src/commands/bi.js +61 -0
  10. package/src/commands/bm25.js +78 -0
  11. package/src/commands/browse.js +64 -0
  12. package/src/commands/ccron.js +78 -0
  13. package/src/commands/codegen.js +224 -0
  14. package/src/commands/collab.js +341 -0
  15. package/src/commands/compliance.js +1075 -0
  16. package/src/commands/compt.js +78 -0
  17. package/src/commands/consol.js +231 -0
  18. package/src/commands/cowork.js +263 -0
  19. package/src/commands/crosschain.js +62 -0
  20. package/src/commands/dao.js +62 -0
  21. package/src/commands/dbevo.js +284 -0
  22. package/src/commands/dev.js +252 -0
  23. package/src/commands/did.js +358 -0
  24. package/src/commands/dlp.js +61 -0
  25. package/src/commands/economy.js +56 -0
  26. package/src/commands/encrypt.js +341 -0
  27. package/src/commands/evolution.js +56 -0
  28. package/src/commands/evomap.js +61 -0
  29. package/src/commands/export.js +256 -1
  30. package/src/commands/fflag.js +178 -0
  31. package/src/commands/fusion.js +258 -0
  32. package/src/commands/git.js +45 -0
  33. package/src/commands/governance.js +325 -0
  34. package/src/commands/hardening.js +411 -0
  35. package/src/commands/hmemory.js +56 -0
  36. package/src/commands/hook.js +148 -0
  37. package/src/commands/import.js +252 -0
  38. package/src/commands/incentive.js +322 -0
  39. package/src/commands/inference.js +42 -0
  40. package/src/commands/infra.js +244 -0
  41. package/src/commands/instinct.js +260 -0
  42. package/src/commands/ipfs.js +318 -0
  43. package/src/commands/itbudget.js +45 -0
  44. package/src/commands/kg.js +387 -0
  45. package/src/commands/llm.js +263 -0
  46. package/src/commands/lowcode.js +44 -0
  47. package/src/commands/matrix.js +62 -0
  48. package/src/commands/mcp.js +221 -0
  49. package/src/commands/mcpscaf.js +41 -0
  50. package/src/commands/meminj.js +41 -0
  51. package/src/commands/memory.js +248 -0
  52. package/src/commands/multimodal.js +296 -0
  53. package/src/commands/nlprog.js +356 -0
  54. package/src/commands/nostr.js +62 -0
  55. package/src/commands/note.js +244 -0
  56. package/src/commands/ops.js +354 -0
  57. package/src/commands/orchestrate.js +166 -0
  58. package/src/commands/orchgov.js +45 -0
  59. package/src/commands/org.js +277 -0
  60. package/src/commands/p2p.js +390 -0
  61. package/src/commands/pdfp.js +78 -0
  62. package/src/commands/perception.js +290 -0
  63. package/src/commands/perf.js +39 -0
  64. package/src/commands/perm.js +45 -0
  65. package/src/commands/permmem.js +251 -0
  66. package/src/commands/pipeline.js +57 -1
  67. package/src/commands/planmode.js +45 -0
  68. package/src/commands/plugin-ecosystem.js +273 -0
  69. package/src/commands/pqc.js +393 -0
  70. package/src/commands/promcomp.js +82 -0
  71. package/src/commands/quantization.js +351 -0
  72. package/src/commands/rcache.js +271 -0
  73. package/src/commands/recommend.js +382 -0
  74. package/src/commands/runtime.js +307 -0
  75. package/src/commands/scim.js +262 -0
  76. package/src/commands/seshhook.js +41 -0
  77. package/src/commands/seshsearch.js +41 -0
  78. package/src/commands/seshtail.js +41 -0
  79. package/src/commands/seshu.js +41 -0
  80. package/src/commands/session.js +258 -0
  81. package/src/commands/sganal.js +78 -0
  82. package/src/commands/siem.js +40 -0
  83. package/src/commands/skill.js +267 -1
  84. package/src/commands/slotfill.js +41 -0
  85. package/src/commands/social.js +290 -0
  86. package/src/commands/sso.js +186 -1
  87. package/src/commands/svccont.js +45 -0
  88. package/src/commands/sync.js +256 -0
  89. package/src/commands/tech.js +338 -0
  90. package/src/commands/tenant.js +351 -0
  91. package/src/commands/tms.js +45 -0
  92. package/src/commands/tokens.js +269 -0
  93. package/src/commands/topiccls.js +45 -0
  94. package/src/commands/trust.js +249 -0
  95. package/src/commands/uprof.js +45 -0
  96. package/src/commands/vcheck.js +78 -0
  97. package/src/commands/wallet.js +277 -0
  98. package/src/commands/webfetch.js +41 -0
  99. package/src/commands/workflow.js +171 -0
  100. package/src/commands/zkp.js +62 -0
  101. package/src/harness/prompt-compressor.js +331 -0
  102. package/src/index.js +65 -1
  103. package/src/lib/a2a-protocol.js +105 -0
  104. package/src/lib/activitypub-bridge.js +105 -0
  105. package/src/lib/agent-coordinator.js +325 -0
  106. package/src/lib/agent-economy.js +105 -0
  107. package/src/lib/agent-network.js +387 -0
  108. package/src/lib/agent-router.js +395 -0
  109. package/src/lib/aiops.js +478 -0
  110. package/src/lib/app-builder.js +105 -0
  111. package/src/lib/audit-logger.js +379 -0
  112. package/src/lib/automation-engine.js +330 -0
  113. package/src/lib/autonomous-agent.js +105 -0
  114. package/src/lib/autonomous-developer.js +350 -0
  115. package/src/lib/bi-engine.js +105 -0
  116. package/src/lib/bm25-search.js +81 -0
  117. package/src/lib/browser-automation.js +105 -0
  118. package/src/lib/code-agent.js +323 -0
  119. package/src/lib/collaboration-governance.js +364 -0
  120. package/src/lib/community-governance.js +436 -0
  121. package/src/lib/compliance-framework-reporter.js +105 -0
  122. package/src/lib/compliance-manager.js +434 -0
  123. package/src/lib/compression-telemetry.js +81 -0
  124. package/src/lib/content-recommendation.js +469 -0
  125. package/src/lib/content-recommender.js +105 -0
  126. package/src/lib/cowork-cron.js +81 -0
  127. package/src/lib/cowork-task-runner.js +105 -0
  128. package/src/lib/cross-chain.js +105 -0
  129. package/src/lib/crypto-manager.js +350 -0
  130. package/src/lib/dao-governance.js +105 -0
  131. package/src/lib/dbevo.js +338 -0
  132. package/src/lib/decentral-infra.js +340 -0
  133. package/src/lib/did-manager.js +367 -0
  134. package/src/lib/dlp-engine.js +105 -0
  135. package/src/lib/evolution-system.js +105 -0
  136. package/src/lib/evomap-manager.js +105 -0
  137. package/src/lib/execution-backend.js +105 -0
  138. package/src/lib/feature-flags.js +85 -0
  139. package/src/lib/git-integration.js +105 -0
  140. package/src/lib/hardening-manager.js +348 -0
  141. package/src/lib/hierarchical-memory.js +105 -0
  142. package/src/lib/hook-manager.js +380 -0
  143. package/src/lib/inference-network.js +105 -0
  144. package/src/lib/instinct-manager.js +332 -0
  145. package/src/lib/ipfs-storage.js +334 -0
  146. package/src/lib/iteration-budget.js +105 -0
  147. package/src/lib/knowledge-exporter.js +381 -0
  148. package/src/lib/knowledge-graph.js +432 -0
  149. package/src/lib/knowledge-importer.js +379 -0
  150. package/src/lib/llm-providers.js +391 -0
  151. package/src/lib/matrix-bridge.js +105 -0
  152. package/src/lib/mcp-registry.js +333 -0
  153. package/src/lib/mcp-scaffold.js +81 -0
  154. package/src/lib/memory-injection.js +81 -0
  155. package/src/lib/memory-manager.js +330 -0
  156. package/src/lib/multimodal.js +346 -0
  157. package/src/lib/nl-programming.js +343 -0
  158. package/src/lib/nostr-bridge.js +105 -0
  159. package/src/lib/note-versioning.js +327 -0
  160. package/src/lib/orchestrator.js +105 -0
  161. package/src/lib/org-manager.js +323 -0
  162. package/src/lib/p2p-manager.js +387 -0
  163. package/src/lib/pdf-parser.js +81 -0
  164. package/src/lib/perception.js +346 -0
  165. package/src/lib/perf-tuning.js +109 -1
  166. package/src/lib/permanent-memory.js +320 -0
  167. package/src/lib/permission-engine.js +81 -0
  168. package/src/lib/pipeline-orchestrator.js +105 -0
  169. package/src/lib/plan-mode.js +81 -0
  170. package/src/lib/plugin-ecosystem.js +377 -0
  171. package/src/lib/pqc-manager.js +368 -0
  172. package/src/lib/prompt-compressor.js +1 -10
  173. package/src/lib/protocol-fusion.js +417 -0
  174. package/src/lib/quantization.js +325 -0
  175. package/src/lib/response-cache.js +327 -0
  176. package/src/lib/scim-manager.js +329 -0
  177. package/src/lib/service-container.js +81 -0
  178. package/src/lib/session-consolidator.js +105 -0
  179. package/src/lib/session-hooks.js +81 -0
  180. package/src/lib/session-manager.js +329 -0
  181. package/src/lib/session-search.js +81 -0
  182. package/src/lib/session-tail.js +81 -0
  183. package/src/lib/session-usage.js +83 -0
  184. package/src/lib/siem-exporter.js +105 -0
  185. package/src/lib/skill-loader.js +377 -0
  186. package/src/lib/slot-filler.js +81 -0
  187. package/src/lib/social-graph-analytics.js +81 -0
  188. package/src/lib/social-graph.js +81 -0
  189. package/src/lib/social-manager.js +326 -0
  190. package/src/lib/sso-manager.js +332 -0
  191. package/src/lib/sub-agent-registry.js +110 -0
  192. package/src/lib/sync-manager.js +326 -0
  193. package/src/lib/task-model-selector.js +81 -0
  194. package/src/lib/tech-learning-engine.js +369 -0
  195. package/src/lib/tenant-saas.js +460 -0
  196. package/src/lib/threat-intel.js +335 -0
  197. package/src/lib/todo-manager.js +105 -0
  198. package/src/lib/token-incentive.js +293 -0
  199. package/src/lib/token-tracker.js +329 -0
  200. package/src/lib/topic-classifier.js +105 -0
  201. package/src/lib/trust-security.js +390 -0
  202. package/src/lib/ueba.js +389 -0
  203. package/src/lib/universal-runtime.js +325 -0
  204. package/src/lib/user-profile.js +81 -0
  205. package/src/lib/version-checker.js +81 -0
  206. package/src/lib/wallet-manager.js +326 -0
  207. package/src/lib/web-fetch.js +81 -0
  208. package/src/lib/workflow-engine.js +322 -0
  209. package/src/lib/zkp-engine.js +105 -0
@@ -173,3 +173,108 @@ export class IterationBudget {
173
173
  export const DEFAULT_ITERATION_BUDGET = DEFAULT_BUDGET;
174
174
  export const BUDGET_WARNING_THRESHOLD = WARNING_THRESHOLD;
175
175
  export const BUDGET_WRAPPING_UP_THRESHOLD = WRAPPING_UP_THRESHOLD;
176
+
177
+
178
+ // ===== V2 Surface: Iteration Budget governance overlay (CLI v0.140.0) =====
179
+ export const ITER_BUDGET_PROFILE_MATURITY_V2 = Object.freeze({
180
+ PENDING: "pending", ACTIVE: "active", PAUSED: "paused", EXHAUSTED: "exhausted",
181
+ });
182
+ export const ITER_RUN_LIFECYCLE_V2 = Object.freeze({
183
+ QUEUED: "queued", RUNNING: "running", COMPLETED: "completed", FAILED: "failed", CANCELLED: "cancelled",
184
+ });
185
+
186
+ const _ibpTrans = new Map([
187
+ [ITER_BUDGET_PROFILE_MATURITY_V2.PENDING, new Set([ITER_BUDGET_PROFILE_MATURITY_V2.ACTIVE, ITER_BUDGET_PROFILE_MATURITY_V2.EXHAUSTED])],
188
+ [ITER_BUDGET_PROFILE_MATURITY_V2.ACTIVE, new Set([ITER_BUDGET_PROFILE_MATURITY_V2.PAUSED, ITER_BUDGET_PROFILE_MATURITY_V2.EXHAUSTED])],
189
+ [ITER_BUDGET_PROFILE_MATURITY_V2.PAUSED, new Set([ITER_BUDGET_PROFILE_MATURITY_V2.ACTIVE, ITER_BUDGET_PROFILE_MATURITY_V2.EXHAUSTED])],
190
+ [ITER_BUDGET_PROFILE_MATURITY_V2.EXHAUSTED, new Set()],
191
+ ]);
192
+ const _ibpTerminal = new Set([ITER_BUDGET_PROFILE_MATURITY_V2.EXHAUSTED]);
193
+ const _irTrans = new Map([
194
+ [ITER_RUN_LIFECYCLE_V2.QUEUED, new Set([ITER_RUN_LIFECYCLE_V2.RUNNING, ITER_RUN_LIFECYCLE_V2.CANCELLED])],
195
+ [ITER_RUN_LIFECYCLE_V2.RUNNING, new Set([ITER_RUN_LIFECYCLE_V2.COMPLETED, ITER_RUN_LIFECYCLE_V2.FAILED, ITER_RUN_LIFECYCLE_V2.CANCELLED])],
196
+ [ITER_RUN_LIFECYCLE_V2.COMPLETED, new Set()],
197
+ [ITER_RUN_LIFECYCLE_V2.FAILED, new Set()],
198
+ [ITER_RUN_LIFECYCLE_V2.CANCELLED, new Set()],
199
+ ]);
200
+
201
+ const _ibpsV2 = new Map();
202
+ const _irsV2 = new Map();
203
+ let _ibpMaxActivePerOwner = 4;
204
+ let _ibpMaxPendingRunsPerProfile = 8;
205
+ let _ibpIdleMs = 24 * 60 * 60 * 1000;
206
+ let _irStuckMs = 60 * 60 * 1000;
207
+
208
+ function _ibpPos(n, lbl) { const v = Math.floor(Number(n)); if (!Number.isFinite(v) || v <= 0) throw new Error(`${lbl} must be positive integer`); return v; }
209
+
210
+ export function setMaxActiveIterBudgetProfilesPerOwnerV2(n) { _ibpMaxActivePerOwner = _ibpPos(n, "maxActiveIterBudgetProfilesPerOwner"); }
211
+ export function getMaxActiveIterBudgetProfilesPerOwnerV2() { return _ibpMaxActivePerOwner; }
212
+ export function setMaxPendingIterRunsPerProfileV2(n) { _ibpMaxPendingRunsPerProfile = _ibpPos(n, "maxPendingIterRunsPerProfile"); }
213
+ export function getMaxPendingIterRunsPerProfileV2() { return _ibpMaxPendingRunsPerProfile; }
214
+ export function setIterBudgetProfileIdleMsV2(n) { _ibpIdleMs = _ibpPos(n, "iterBudgetProfileIdleMs"); }
215
+ export function getIterBudgetProfileIdleMsV2() { return _ibpIdleMs; }
216
+ export function setIterRunStuckMsV2(n) { _irStuckMs = _ibpPos(n, "iterRunStuckMs"); }
217
+ export function getIterRunStuckMsV2() { return _irStuckMs; }
218
+
219
+ export function _resetStateIterationBudgetV2() {
220
+ _ibpsV2.clear(); _irsV2.clear();
221
+ _ibpMaxActivePerOwner = 4; _ibpMaxPendingRunsPerProfile = 8;
222
+ _ibpIdleMs = 24 * 60 * 60 * 1000; _irStuckMs = 60 * 60 * 1000;
223
+ }
224
+
225
+ export function registerIterBudgetProfileV2({ id, owner, budget, metadata } = {}) {
226
+ if (!id || typeof id !== "string") throw new Error("id is required");
227
+ if (!owner || typeof owner !== "string") throw new Error("owner is required");
228
+ if (_ibpsV2.has(id)) throw new Error(`iter budget profile ${id} already registered`);
229
+ const now = Date.now();
230
+ const p = { id, owner, budget: budget || 50, status: ITER_BUDGET_PROFILE_MATURITY_V2.PENDING, createdAt: now, updatedAt: now, activatedAt: null, exhaustedAt: null, lastTouchedAt: now, metadata: { ...(metadata || {}) } };
231
+ _ibpsV2.set(id, p);
232
+ return { ...p, metadata: { ...p.metadata } };
233
+ }
234
+ function _ibpCheckP(from, to) { const a = _ibpTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid iter budget profile transition ${from} → ${to}`); }
235
+ function _ibpCountActive(owner) { let n = 0; for (const p of _ibpsV2.values()) if (p.owner === owner && p.status === ITER_BUDGET_PROFILE_MATURITY_V2.ACTIVE) n++; return n; }
236
+
237
+ export function activateIterBudgetProfileV2(id) {
238
+ const p = _ibpsV2.get(id); if (!p) throw new Error(`iter budget profile ${id} not found`);
239
+ _ibpCheckP(p.status, ITER_BUDGET_PROFILE_MATURITY_V2.ACTIVE);
240
+ const recovery = p.status === ITER_BUDGET_PROFILE_MATURITY_V2.PAUSED;
241
+ if (!recovery) { const c = _ibpCountActive(p.owner); if (c >= _ibpMaxActivePerOwner) throw new Error(`max active iter budget profiles per owner (${_ibpMaxActivePerOwner}) reached for ${p.owner}`); }
242
+ const now = Date.now(); p.status = ITER_BUDGET_PROFILE_MATURITY_V2.ACTIVE; p.updatedAt = now; p.lastTouchedAt = now; if (!p.activatedAt) p.activatedAt = now;
243
+ return { ...p, metadata: { ...p.metadata } };
244
+ }
245
+ export function pauseIterBudgetProfileV2(id) { const p = _ibpsV2.get(id); if (!p) throw new Error(`iter budget profile ${id} not found`); _ibpCheckP(p.status, ITER_BUDGET_PROFILE_MATURITY_V2.PAUSED); p.status = ITER_BUDGET_PROFILE_MATURITY_V2.PAUSED; p.updatedAt = Date.now(); return { ...p, metadata: { ...p.metadata } }; }
246
+ export function exhaustIterBudgetProfileV2(id) { const p = _ibpsV2.get(id); if (!p) throw new Error(`iter budget profile ${id} not found`); _ibpCheckP(p.status, ITER_BUDGET_PROFILE_MATURITY_V2.EXHAUSTED); const now = Date.now(); p.status = ITER_BUDGET_PROFILE_MATURITY_V2.EXHAUSTED; p.updatedAt = now; if (!p.exhaustedAt) p.exhaustedAt = now; return { ...p, metadata: { ...p.metadata } }; }
247
+ export function touchIterBudgetProfileV2(id) { const p = _ibpsV2.get(id); if (!p) throw new Error(`iter budget profile ${id} not found`); if (_ibpTerminal.has(p.status)) throw new Error(`cannot touch terminal iter budget profile ${id}`); const now = Date.now(); p.lastTouchedAt = now; p.updatedAt = now; return { ...p, metadata: { ...p.metadata } }; }
248
+ export function getIterBudgetProfileV2(id) { const p = _ibpsV2.get(id); if (!p) return null; return { ...p, metadata: { ...p.metadata } }; }
249
+ export function listIterBudgetProfilesV2() { return [..._ibpsV2.values()].map((p) => ({ ...p, metadata: { ...p.metadata } })); }
250
+
251
+ function _irCountPending(profileId) { let n = 0; for (const r of _irsV2.values()) if (r.profileId === profileId && (r.status === ITER_RUN_LIFECYCLE_V2.QUEUED || r.status === ITER_RUN_LIFECYCLE_V2.RUNNING)) n++; return n; }
252
+
253
+ export function createIterRunV2({ id, profileId, goal, metadata } = {}) {
254
+ if (!id || typeof id !== "string") throw new Error("id is required");
255
+ if (!profileId || typeof profileId !== "string") throw new Error("profileId is required");
256
+ if (_irsV2.has(id)) throw new Error(`iter run ${id} already exists`);
257
+ if (!_ibpsV2.has(profileId)) throw new Error(`iter budget profile ${profileId} not found`);
258
+ const pending = _irCountPending(profileId);
259
+ if (pending >= _ibpMaxPendingRunsPerProfile) throw new Error(`max pending iter runs per profile (${_ibpMaxPendingRunsPerProfile}) reached for ${profileId}`);
260
+ const now = Date.now();
261
+ const r = { id, profileId, goal: goal || "", status: ITER_RUN_LIFECYCLE_V2.QUEUED, createdAt: now, updatedAt: now, startedAt: null, settledAt: null, metadata: { ...(metadata || {}) } };
262
+ _irsV2.set(id, r);
263
+ return { ...r, metadata: { ...r.metadata } };
264
+ }
265
+ function _irCheckR(from, to) { const a = _irTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid iter run transition ${from} → ${to}`); }
266
+ export function startIterRunV2(id) { const r = _irsV2.get(id); if (!r) throw new Error(`iter run ${id} not found`); _irCheckR(r.status, ITER_RUN_LIFECYCLE_V2.RUNNING); const now = Date.now(); r.status = ITER_RUN_LIFECYCLE_V2.RUNNING; r.updatedAt = now; if (!r.startedAt) r.startedAt = now; return { ...r, metadata: { ...r.metadata } }; }
267
+ export function completeIterRunV2(id) { const r = _irsV2.get(id); if (!r) throw new Error(`iter run ${id} not found`); _irCheckR(r.status, ITER_RUN_LIFECYCLE_V2.COMPLETED); const now = Date.now(); r.status = ITER_RUN_LIFECYCLE_V2.COMPLETED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; return { ...r, metadata: { ...r.metadata } }; }
268
+ export function failIterRunV2(id, reason) { const r = _irsV2.get(id); if (!r) throw new Error(`iter run ${id} not found`); _irCheckR(r.status, ITER_RUN_LIFECYCLE_V2.FAILED); const now = Date.now(); r.status = ITER_RUN_LIFECYCLE_V2.FAILED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; if (reason) r.metadata.failReason = String(reason); return { ...r, metadata: { ...r.metadata } }; }
269
+ export function cancelIterRunV2(id, reason) { const r = _irsV2.get(id); if (!r) throw new Error(`iter run ${id} not found`); _irCheckR(r.status, ITER_RUN_LIFECYCLE_V2.CANCELLED); const now = Date.now(); r.status = ITER_RUN_LIFECYCLE_V2.CANCELLED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; if (reason) r.metadata.cancelReason = String(reason); return { ...r, metadata: { ...r.metadata } }; }
270
+ export function getIterRunV2(id) { const r = _irsV2.get(id); if (!r) return null; return { ...r, metadata: { ...r.metadata } }; }
271
+ export function listIterRunsV2() { return [..._irsV2.values()].map((r) => ({ ...r, metadata: { ...r.metadata } })); }
272
+
273
+ export function autoPauseIdleIterBudgetProfilesV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const p of _ibpsV2.values()) if (p.status === ITER_BUDGET_PROFILE_MATURITY_V2.ACTIVE && (t - p.lastTouchedAt) >= _ibpIdleMs) { p.status = ITER_BUDGET_PROFILE_MATURITY_V2.PAUSED; p.updatedAt = t; flipped.push(p.id); } return { flipped, count: flipped.length }; }
274
+ export function autoFailStuckIterRunsV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const r of _irsV2.values()) if (r.status === ITER_RUN_LIFECYCLE_V2.RUNNING && r.startedAt != null && (t - r.startedAt) >= _irStuckMs) { r.status = ITER_RUN_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 }; }
275
+
276
+ export function getIterationBudgetGovStatsV2() {
277
+ const profilesByStatus = {}; for (const s of Object.values(ITER_BUDGET_PROFILE_MATURITY_V2)) profilesByStatus[s] = 0; for (const p of _ibpsV2.values()) profilesByStatus[p.status]++;
278
+ const runsByStatus = {}; for (const s of Object.values(ITER_RUN_LIFECYCLE_V2)) runsByStatus[s] = 0; for (const r of _irsV2.values()) runsByStatus[r.status]++;
279
+ return { totalIterBudgetProfilesV2: _ibpsV2.size, totalIterRunsV2: _irsV2.size, maxActiveIterBudgetProfilesPerOwner: _ibpMaxActivePerOwner, maxPendingIterRunsPerProfile: _ibpMaxPendingRunsPerProfile, iterBudgetProfileIdleMs: _ibpIdleMs, iterRunStuckMs: _irStuckMs, profilesByStatus, runsByStatus };
280
+ }
@@ -300,3 +300,384 @@ function markdownToSimpleHtml(md) {
300
300
  .replace(/^/, "<p>")
301
301
  .replace(/$/, "</p>");
302
302
  }
303
+
304
+ // ─── V2 Governance Layer ────────────────────────────────────────────
305
+ //
306
+ // In-memory governance for export targets + export jobs, independent
307
+ // of the SQLite notes table read by legacy export* helpers. V2 tracks
308
+ // target maturity transitions, per-owner active-target caps, per-target
309
+ // pending-job caps, stamp-once timestamps, and bulk auto-flip routines.
310
+
311
+ export const TARGET_MATURITY_V2 = Object.freeze({
312
+ PENDING: "pending",
313
+ ACTIVE: "active",
314
+ PAUSED: "paused",
315
+ ARCHIVED: "archived",
316
+ });
317
+
318
+ export const EXPORT_JOB_LIFECYCLE_V2 = Object.freeze({
319
+ QUEUED: "queued",
320
+ RUNNING: "running",
321
+ COMPLETED: "completed",
322
+ FAILED: "failed",
323
+ CANCELLED: "cancelled",
324
+ });
325
+
326
+ const _TARGET_TRANSITIONS_V2 = new Map([
327
+ [
328
+ TARGET_MATURITY_V2.PENDING,
329
+ new Set([TARGET_MATURITY_V2.ACTIVE, TARGET_MATURITY_V2.ARCHIVED]),
330
+ ],
331
+ [
332
+ TARGET_MATURITY_V2.ACTIVE,
333
+ new Set([TARGET_MATURITY_V2.PAUSED, TARGET_MATURITY_V2.ARCHIVED]),
334
+ ],
335
+ [
336
+ TARGET_MATURITY_V2.PAUSED,
337
+ new Set([TARGET_MATURITY_V2.ACTIVE, TARGET_MATURITY_V2.ARCHIVED]),
338
+ ],
339
+ [TARGET_MATURITY_V2.ARCHIVED, new Set()],
340
+ ]);
341
+
342
+ const _TARGET_TERMINALS_V2 = new Set([TARGET_MATURITY_V2.ARCHIVED]);
343
+
344
+ const _JOB_TRANSITIONS_V2 = new Map([
345
+ [
346
+ EXPORT_JOB_LIFECYCLE_V2.QUEUED,
347
+ new Set([
348
+ EXPORT_JOB_LIFECYCLE_V2.RUNNING,
349
+ EXPORT_JOB_LIFECYCLE_V2.CANCELLED,
350
+ ]),
351
+ ],
352
+ [
353
+ EXPORT_JOB_LIFECYCLE_V2.RUNNING,
354
+ new Set([
355
+ EXPORT_JOB_LIFECYCLE_V2.COMPLETED,
356
+ EXPORT_JOB_LIFECYCLE_V2.FAILED,
357
+ EXPORT_JOB_LIFECYCLE_V2.CANCELLED,
358
+ ]),
359
+ ],
360
+ [EXPORT_JOB_LIFECYCLE_V2.COMPLETED, new Set()],
361
+ [EXPORT_JOB_LIFECYCLE_V2.FAILED, new Set()],
362
+ [EXPORT_JOB_LIFECYCLE_V2.CANCELLED, new Set()],
363
+ ]);
364
+
365
+ const _JOB_TERMINALS_V2 = new Set([
366
+ EXPORT_JOB_LIFECYCLE_V2.COMPLETED,
367
+ EXPORT_JOB_LIFECYCLE_V2.FAILED,
368
+ EXPORT_JOB_LIFECYCLE_V2.CANCELLED,
369
+ ]);
370
+
371
+ export const EXPORTER_DEFAULT_MAX_ACTIVE_TARGETS_PER_OWNER = 12;
372
+ export const EXPORTER_DEFAULT_MAX_PENDING_JOBS_PER_TARGET = 3;
373
+ export const EXPORTER_DEFAULT_TARGET_IDLE_MS = 14 * 24 * 60 * 60 * 1000; // 14 days
374
+ export const EXPORTER_DEFAULT_JOB_STUCK_MS = 25 * 60 * 1000; // 25 min
375
+
376
+ const _stateV2 = {
377
+ targets: new Map(),
378
+ jobs: new Map(),
379
+ maxActiveTargetsPerOwner: EXPORTER_DEFAULT_MAX_ACTIVE_TARGETS_PER_OWNER,
380
+ maxPendingJobsPerTarget: EXPORTER_DEFAULT_MAX_PENDING_JOBS_PER_TARGET,
381
+ targetIdleMs: EXPORTER_DEFAULT_TARGET_IDLE_MS,
382
+ jobStuckMs: EXPORTER_DEFAULT_JOB_STUCK_MS,
383
+ };
384
+
385
+ function _posIntExporterV2(n, label) {
386
+ const v = Math.floor(Number(n));
387
+ if (!Number.isFinite(v) || v <= 0) {
388
+ throw new Error(`${label} must be a positive integer, got ${n}`);
389
+ }
390
+ return v;
391
+ }
392
+
393
+ export function getMaxActiveTargetsPerOwnerV2() {
394
+ return _stateV2.maxActiveTargetsPerOwner;
395
+ }
396
+
397
+ export function setMaxActiveTargetsPerOwnerV2(n) {
398
+ _stateV2.maxActiveTargetsPerOwner = _posIntExporterV2(
399
+ n,
400
+ "maxActiveTargetsPerOwner",
401
+ );
402
+ }
403
+
404
+ export function getMaxPendingJobsPerTargetV2() {
405
+ return _stateV2.maxPendingJobsPerTarget;
406
+ }
407
+
408
+ export function setMaxPendingJobsPerTargetV2(n) {
409
+ _stateV2.maxPendingJobsPerTarget = _posIntExporterV2(
410
+ n,
411
+ "maxPendingJobsPerTarget",
412
+ );
413
+ }
414
+
415
+ export function getTargetIdleMsV2() {
416
+ return _stateV2.targetIdleMs;
417
+ }
418
+
419
+ export function setTargetIdleMsV2(ms) {
420
+ _stateV2.targetIdleMs = _posIntExporterV2(ms, "targetIdleMs");
421
+ }
422
+
423
+ export function getJobStuckMsV2() {
424
+ return _stateV2.jobStuckMs;
425
+ }
426
+
427
+ export function setJobStuckMsV2(ms) {
428
+ _stateV2.jobStuckMs = _posIntExporterV2(ms, "jobStuckMs");
429
+ }
430
+
431
+ function _copyTargetV2(t) {
432
+ return { ...t, metadata: { ...t.metadata } };
433
+ }
434
+
435
+ function _copyJobV2(j) {
436
+ return { ...j, metadata: { ...j.metadata } };
437
+ }
438
+
439
+ export function getActiveTargetCountV2(ownerId) {
440
+ let count = 0;
441
+ for (const t of _stateV2.targets.values()) {
442
+ if (t.ownerId === ownerId && t.status === TARGET_MATURITY_V2.ACTIVE)
443
+ count++;
444
+ }
445
+ return count;
446
+ }
447
+
448
+ export function getPendingJobCountV2(targetId) {
449
+ let count = 0;
450
+ for (const j of _stateV2.jobs.values()) {
451
+ if (
452
+ j.targetId === targetId &&
453
+ (j.status === EXPORT_JOB_LIFECYCLE_V2.QUEUED ||
454
+ j.status === EXPORT_JOB_LIFECYCLE_V2.RUNNING)
455
+ ) {
456
+ count++;
457
+ }
458
+ }
459
+ return count;
460
+ }
461
+
462
+ export function registerTargetV2(
463
+ id,
464
+ { ownerId, label, format, metadata } = {},
465
+ ) {
466
+ if (!id) throw new Error("target id is required");
467
+ if (!ownerId) throw new Error("ownerId is required");
468
+ if (!label) throw new Error("label is required");
469
+ if (_stateV2.targets.has(id)) throw new Error(`target ${id} already exists`);
470
+ const now = Date.now();
471
+ const target = {
472
+ id,
473
+ ownerId,
474
+ label,
475
+ format: format || "markdown",
476
+ status: TARGET_MATURITY_V2.PENDING,
477
+ createdAt: now,
478
+ lastSeenAt: now,
479
+ activatedAt: null,
480
+ archivedAt: null,
481
+ metadata: metadata ? { ...metadata } : {},
482
+ };
483
+ _stateV2.targets.set(id, target);
484
+ return _copyTargetV2(target);
485
+ }
486
+
487
+ export function getTargetV2(id) {
488
+ const t = _stateV2.targets.get(id);
489
+ return t ? _copyTargetV2(t) : null;
490
+ }
491
+
492
+ export function listTargetsV2({ ownerId, status } = {}) {
493
+ const out = [];
494
+ for (const t of _stateV2.targets.values()) {
495
+ if (ownerId && t.ownerId !== ownerId) continue;
496
+ if (status && t.status !== status) continue;
497
+ out.push(_copyTargetV2(t));
498
+ }
499
+ return out;
500
+ }
501
+
502
+ export function setTargetStatusV2(id, next) {
503
+ const t = _stateV2.targets.get(id);
504
+ if (!t) throw new Error(`target ${id} not found`);
505
+ const allowed = _TARGET_TRANSITIONS_V2.get(t.status);
506
+ if (!allowed || !allowed.has(next)) {
507
+ throw new Error(`invalid target transition: ${t.status} → ${next}`);
508
+ }
509
+ if (
510
+ t.status === TARGET_MATURITY_V2.PENDING &&
511
+ next === TARGET_MATURITY_V2.ACTIVE
512
+ ) {
513
+ const count = getActiveTargetCountV2(t.ownerId);
514
+ if (count >= _stateV2.maxActiveTargetsPerOwner) {
515
+ throw new Error(
516
+ `owner ${t.ownerId} active-target cap reached (${count}/${_stateV2.maxActiveTargetsPerOwner})`,
517
+ );
518
+ }
519
+ }
520
+ const now = Date.now();
521
+ t.status = next;
522
+ t.lastSeenAt = now;
523
+ if (next === TARGET_MATURITY_V2.ACTIVE && !t.activatedAt) t.activatedAt = now;
524
+ if (_TARGET_TERMINALS_V2.has(next) && !t.archivedAt) t.archivedAt = now;
525
+ return _copyTargetV2(t);
526
+ }
527
+
528
+ export function activateTargetV2(id) {
529
+ return setTargetStatusV2(id, TARGET_MATURITY_V2.ACTIVE);
530
+ }
531
+
532
+ export function pauseTargetV2(id) {
533
+ return setTargetStatusV2(id, TARGET_MATURITY_V2.PAUSED);
534
+ }
535
+
536
+ export function archiveTargetV2(id) {
537
+ return setTargetStatusV2(id, TARGET_MATURITY_V2.ARCHIVED);
538
+ }
539
+
540
+ export function touchTargetV2(id) {
541
+ const t = _stateV2.targets.get(id);
542
+ if (!t) throw new Error(`target ${id} not found`);
543
+ t.lastSeenAt = Date.now();
544
+ return _copyTargetV2(t);
545
+ }
546
+
547
+ export function createExportJobV2(id, { targetId, kind, metadata } = {}) {
548
+ if (!id) throw new Error("job id is required");
549
+ if (!targetId) throw new Error("targetId is required");
550
+ if (_stateV2.jobs.has(id)) throw new Error(`job ${id} already exists`);
551
+ const target = _stateV2.targets.get(targetId);
552
+ if (!target) throw new Error(`target ${targetId} not found`);
553
+ const pending = getPendingJobCountV2(targetId);
554
+ if (pending >= _stateV2.maxPendingJobsPerTarget) {
555
+ throw new Error(
556
+ `target ${targetId} pending-job cap reached (${pending}/${_stateV2.maxPendingJobsPerTarget})`,
557
+ );
558
+ }
559
+ const now = Date.now();
560
+ const job = {
561
+ id,
562
+ targetId,
563
+ kind: kind || "snapshot",
564
+ status: EXPORT_JOB_LIFECYCLE_V2.QUEUED,
565
+ createdAt: now,
566
+ lastSeenAt: now,
567
+ startedAt: null,
568
+ settledAt: null,
569
+ metadata: metadata ? { ...metadata } : {},
570
+ };
571
+ _stateV2.jobs.set(id, job);
572
+ return _copyJobV2(job);
573
+ }
574
+
575
+ export function getExportJobV2(id) {
576
+ const j = _stateV2.jobs.get(id);
577
+ return j ? _copyJobV2(j) : null;
578
+ }
579
+
580
+ export function listExportJobsV2({ targetId, status } = {}) {
581
+ const out = [];
582
+ for (const j of _stateV2.jobs.values()) {
583
+ if (targetId && j.targetId !== targetId) continue;
584
+ if (status && j.status !== status) continue;
585
+ out.push(_copyJobV2(j));
586
+ }
587
+ return out;
588
+ }
589
+
590
+ export function setExportJobStatusV2(id, next) {
591
+ const j = _stateV2.jobs.get(id);
592
+ if (!j) throw new Error(`job ${id} not found`);
593
+ const allowed = _JOB_TRANSITIONS_V2.get(j.status);
594
+ if (!allowed || !allowed.has(next)) {
595
+ throw new Error(`invalid job transition: ${j.status} → ${next}`);
596
+ }
597
+ const now = Date.now();
598
+ j.status = next;
599
+ j.lastSeenAt = now;
600
+ if (next === EXPORT_JOB_LIFECYCLE_V2.RUNNING && !j.startedAt)
601
+ j.startedAt = now;
602
+ if (_JOB_TERMINALS_V2.has(next) && !j.settledAt) j.settledAt = now;
603
+ return _copyJobV2(j);
604
+ }
605
+
606
+ export function startExportJobV2(id) {
607
+ return setExportJobStatusV2(id, EXPORT_JOB_LIFECYCLE_V2.RUNNING);
608
+ }
609
+
610
+ export function completeExportJobV2(id) {
611
+ return setExportJobStatusV2(id, EXPORT_JOB_LIFECYCLE_V2.COMPLETED);
612
+ }
613
+
614
+ export function failExportJobV2(id) {
615
+ return setExportJobStatusV2(id, EXPORT_JOB_LIFECYCLE_V2.FAILED);
616
+ }
617
+
618
+ export function cancelExportJobV2(id) {
619
+ return setExportJobStatusV2(id, EXPORT_JOB_LIFECYCLE_V2.CANCELLED);
620
+ }
621
+
622
+ export function autoPauseIdleTargetsV2({ now = Date.now() } = {}) {
623
+ const flipped = [];
624
+ for (const t of _stateV2.targets.values()) {
625
+ if (
626
+ t.status === TARGET_MATURITY_V2.ACTIVE &&
627
+ now - t.lastSeenAt > _stateV2.targetIdleMs
628
+ ) {
629
+ t.status = TARGET_MATURITY_V2.PAUSED;
630
+ t.lastSeenAt = now;
631
+ flipped.push(_copyTargetV2(t));
632
+ }
633
+ }
634
+ return flipped;
635
+ }
636
+
637
+ export function autoFailStuckExportJobsV2({ now = Date.now() } = {}) {
638
+ const flipped = [];
639
+ for (const j of _stateV2.jobs.values()) {
640
+ if (
641
+ j.status === EXPORT_JOB_LIFECYCLE_V2.RUNNING &&
642
+ now - j.lastSeenAt > _stateV2.jobStuckMs
643
+ ) {
644
+ j.status = EXPORT_JOB_LIFECYCLE_V2.FAILED;
645
+ j.lastSeenAt = now;
646
+ if (!j.settledAt) j.settledAt = now;
647
+ flipped.push(_copyJobV2(j));
648
+ }
649
+ }
650
+ return flipped;
651
+ }
652
+
653
+ export function getKnowledgeExporterStatsV2() {
654
+ const targetsByStatus = {};
655
+ for (const v of Object.values(TARGET_MATURITY_V2)) targetsByStatus[v] = 0;
656
+ for (const t of _stateV2.targets.values()) targetsByStatus[t.status]++;
657
+
658
+ const jobsByStatus = {};
659
+ for (const v of Object.values(EXPORT_JOB_LIFECYCLE_V2)) jobsByStatus[v] = 0;
660
+ for (const j of _stateV2.jobs.values()) jobsByStatus[j.status]++;
661
+
662
+ return {
663
+ totalTargetsV2: _stateV2.targets.size,
664
+ totalExportJobsV2: _stateV2.jobs.size,
665
+ maxActiveTargetsPerOwner: _stateV2.maxActiveTargetsPerOwner,
666
+ maxPendingJobsPerTarget: _stateV2.maxPendingJobsPerTarget,
667
+ targetIdleMs: _stateV2.targetIdleMs,
668
+ jobStuckMs: _stateV2.jobStuckMs,
669
+ targetsByStatus,
670
+ jobsByStatus,
671
+ };
672
+ }
673
+
674
+ export function _resetStateKnowledgeExporterV2() {
675
+ _stateV2.targets.clear();
676
+ _stateV2.jobs.clear();
677
+ _stateV2.maxActiveTargetsPerOwner =
678
+ EXPORTER_DEFAULT_MAX_ACTIVE_TARGETS_PER_OWNER;
679
+ _stateV2.maxPendingJobsPerTarget =
680
+ EXPORTER_DEFAULT_MAX_PENDING_JOBS_PER_TARGET;
681
+ _stateV2.targetIdleMs = EXPORTER_DEFAULT_TARGET_IDLE_MS;
682
+ _stateV2.jobStuckMs = EXPORTER_DEFAULT_JOB_STUCK_MS;
683
+ }