@dcyfr/ai 1.0.4 → 2.1.1

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 (411) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/README.md +381 -9
  3. package/dist/ai/agents/agent-loader.d.ts +12 -0
  4. package/dist/ai/agents/agent-loader.d.ts.map +1 -1
  5. package/dist/ai/agents/agent-loader.js +74 -65
  6. package/dist/ai/agents/agent-loader.js.map +1 -1
  7. package/dist/ai/agents/agent-registry.d.ts +2 -0
  8. package/dist/ai/agents/agent-registry.d.ts.map +1 -1
  9. package/dist/ai/agents/agent-registry.js +15 -14
  10. package/dist/ai/agents/agent-registry.js.map +1 -1
  11. package/dist/ai/agents/agent-router.d.ts +20 -5
  12. package/dist/ai/agents/agent-router.d.ts.map +1 -1
  13. package/dist/ai/agents/agent-router.js +89 -43
  14. package/dist/ai/agents/agent-router.js.map +1 -1
  15. package/dist/ai/agents/index.d.ts +6 -1
  16. package/dist/ai/agents/index.d.ts.map +1 -1
  17. package/dist/ai/agents/index.js +9 -3
  18. package/dist/ai/agents/index.js.map +1 -1
  19. package/dist/ai/agents/instruction-template.d.ts +45 -0
  20. package/dist/ai/agents/instruction-template.d.ts.map +1 -0
  21. package/dist/ai/agents/instruction-template.js +197 -0
  22. package/dist/ai/agents/instruction-template.js.map +1 -0
  23. package/dist/ai/agents/persona-resolver.d.ts +90 -0
  24. package/dist/ai/agents/persona-resolver.d.ts.map +1 -0
  25. package/dist/ai/agents/persona-resolver.js +121 -0
  26. package/dist/ai/agents/persona-resolver.js.map +1 -0
  27. package/dist/ai/agents/schema.d.ts +166 -0
  28. package/dist/ai/agents/schema.d.ts.map +1 -0
  29. package/dist/ai/agents/schema.js +94 -0
  30. package/dist/ai/agents/schema.js.map +1 -0
  31. package/dist/ai/agents/types.d.ts +102 -0
  32. package/dist/ai/agents/types.d.ts.map +1 -1
  33. package/dist/ai/agents-builtin/architecture/index.js +3 -3
  34. package/dist/ai/agents-builtin/content/index.js +1 -1
  35. package/dist/ai/agents-builtin/data/index.js +1 -1
  36. package/dist/ai/agents-builtin/development/index.js +4 -4
  37. package/dist/ai/agents-builtin/devops/index.js +1 -1
  38. package/dist/ai/agents-builtin/index.js +33 -33
  39. package/dist/ai/agents-builtin/performance/index.js +1 -1
  40. package/dist/ai/agents-builtin/research/index.js +1 -1
  41. package/dist/ai/agents-builtin/security/index.js +1 -1
  42. package/dist/ai/agents-builtin/testing/index.js +2 -2
  43. package/dist/ai/config/loader.d.ts.map +1 -1
  44. package/dist/ai/config/loader.js +6 -3
  45. package/dist/ai/config/loader.js.map +1 -1
  46. package/dist/ai/config/schema.d.ts +242 -1156
  47. package/dist/ai/config/schema.d.ts.map +1 -1
  48. package/dist/ai/config/schema.js +69 -20
  49. package/dist/ai/config/schema.js.map +1 -1
  50. package/dist/ai/core/provider-registry.d.ts +32 -0
  51. package/dist/ai/core/provider-registry.d.ts.map +1 -1
  52. package/dist/ai/core/provider-registry.js +189 -14
  53. package/dist/ai/core/provider-registry.js.map +1 -1
  54. package/dist/ai/core/telemetry-engine.d.ts +26 -0
  55. package/dist/ai/core/telemetry-engine.d.ts.map +1 -1
  56. package/dist/ai/core/telemetry-engine.js +81 -1
  57. package/dist/ai/core/telemetry-engine.js.map +1 -1
  58. package/dist/ai/delegation/agent-registry.d.ts +143 -0
  59. package/dist/ai/delegation/agent-registry.d.ts.map +1 -0
  60. package/dist/ai/delegation/agent-registry.js +231 -0
  61. package/dist/ai/delegation/agent-registry.js.map +1 -0
  62. package/dist/ai/delegation/blast-radius-tracker.d.ts +65 -0
  63. package/dist/ai/delegation/blast-radius-tracker.d.ts.map +1 -0
  64. package/dist/ai/delegation/blast-radius-tracker.js +81 -0
  65. package/dist/ai/delegation/blast-radius-tracker.js.map +1 -0
  66. package/dist/ai/delegation/capability-bootstrap.d.ts +40 -0
  67. package/dist/ai/delegation/capability-bootstrap.d.ts.map +1 -0
  68. package/dist/ai/delegation/capability-bootstrap.js +431 -0
  69. package/dist/ai/delegation/capability-bootstrap.js.map +1 -0
  70. package/dist/ai/delegation/capability-registry.d.ts +81 -0
  71. package/dist/ai/delegation/capability-registry.d.ts.map +1 -0
  72. package/dist/ai/delegation/capability-registry.js +339 -0
  73. package/dist/ai/delegation/capability-registry.js.map +1 -0
  74. package/dist/ai/delegation/chain-tracker.d.ts +152 -0
  75. package/dist/ai/delegation/chain-tracker.d.ts.map +1 -0
  76. package/dist/ai/delegation/chain-tracker.js +336 -0
  77. package/dist/ai/delegation/chain-tracker.js.map +1 -0
  78. package/dist/ai/delegation/circuit-breaker.d.ts +59 -0
  79. package/dist/ai/delegation/circuit-breaker.d.ts.map +1 -0
  80. package/dist/ai/delegation/circuit-breaker.js +153 -0
  81. package/dist/ai/delegation/circuit-breaker.js.map +1 -0
  82. package/dist/ai/delegation/contract-manager.d.ts +415 -0
  83. package/dist/ai/delegation/contract-manager.d.ts.map +1 -0
  84. package/dist/ai/delegation/contract-manager.js +1258 -0
  85. package/dist/ai/delegation/contract-manager.js.map +1 -0
  86. package/dist/ai/delegation/delegation-manager.d.ts +505 -0
  87. package/dist/ai/delegation/delegation-manager.d.ts.map +1 -0
  88. package/dist/ai/delegation/delegation-manager.js +773 -0
  89. package/dist/ai/delegation/delegation-manager.js.map +1 -0
  90. package/dist/ai/delegation/event-schemas.d.ts +101 -0
  91. package/dist/ai/delegation/event-schemas.d.ts.map +1 -0
  92. package/dist/ai/delegation/event-schemas.js +59 -0
  93. package/dist/ai/delegation/event-schemas.js.map +1 -0
  94. package/dist/ai/delegation/execution-mode-dashboard.d.ts +109 -0
  95. package/dist/ai/delegation/execution-mode-dashboard.d.ts.map +1 -0
  96. package/dist/ai/delegation/execution-mode-dashboard.js +167 -0
  97. package/dist/ai/delegation/execution-mode-dashboard.js.map +1 -0
  98. package/dist/ai/delegation/feature-flags.d.ts +191 -0
  99. package/dist/ai/delegation/feature-flags.d.ts.map +1 -0
  100. package/dist/ai/delegation/feature-flags.js +332 -0
  101. package/dist/ai/delegation/feature-flags.js.map +1 -0
  102. package/dist/ai/delegation/index.d.ts +51 -0
  103. package/dist/ai/delegation/index.d.ts.map +1 -0
  104. package/dist/ai/delegation/index.js +39 -0
  105. package/dist/ai/delegation/index.js.map +1 -0
  106. package/dist/ai/delegation/middleware/chain-depth-middleware.d.ts +39 -0
  107. package/dist/ai/delegation/middleware/chain-depth-middleware.d.ts.map +1 -0
  108. package/dist/ai/delegation/middleware/chain-depth-middleware.js +77 -0
  109. package/dist/ai/delegation/middleware/chain-depth-middleware.js.map +1 -0
  110. package/dist/ai/delegation/middleware/chain-tracker-middleware.d.ts +46 -0
  111. package/dist/ai/delegation/middleware/chain-tracker-middleware.d.ts.map +1 -0
  112. package/dist/ai/delegation/middleware/chain-tracker-middleware.js +89 -0
  113. package/dist/ai/delegation/middleware/chain-tracker-middleware.js.map +1 -0
  114. package/dist/ai/delegation/middleware/content-policy-middleware.d.ts +31 -0
  115. package/dist/ai/delegation/middleware/content-policy-middleware.d.ts.map +1 -0
  116. package/dist/ai/delegation/middleware/content-policy-middleware.js +82 -0
  117. package/dist/ai/delegation/middleware/content-policy-middleware.js.map +1 -0
  118. package/dist/ai/delegation/middleware/feature-flag-middleware.d.ts +46 -0
  119. package/dist/ai/delegation/middleware/feature-flag-middleware.d.ts.map +1 -0
  120. package/dist/ai/delegation/middleware/feature-flag-middleware.js +59 -0
  121. package/dist/ai/delegation/middleware/feature-flag-middleware.js.map +1 -0
  122. package/dist/ai/delegation/middleware/identity-middleware.d.ts +23 -0
  123. package/dist/ai/delegation/middleware/identity-middleware.d.ts.map +1 -0
  124. package/dist/ai/delegation/middleware/identity-middleware.js +64 -0
  125. package/dist/ai/delegation/middleware/identity-middleware.js.map +1 -0
  126. package/dist/ai/delegation/middleware/permissions-middleware.d.ts +48 -0
  127. package/dist/ai/delegation/middleware/permissions-middleware.d.ts.map +1 -0
  128. package/dist/ai/delegation/middleware/permissions-middleware.js +107 -0
  129. package/dist/ai/delegation/middleware/permissions-middleware.js.map +1 -0
  130. package/dist/ai/delegation/middleware/rate-limiter-middleware.d.ts +38 -0
  131. package/dist/ai/delegation/middleware/rate-limiter-middleware.d.ts.map +1 -0
  132. package/dist/ai/delegation/middleware/rate-limiter-middleware.js +65 -0
  133. package/dist/ai/delegation/middleware/rate-limiter-middleware.js.map +1 -0
  134. package/dist/ai/delegation/middleware/reputation-middleware.d.ts +39 -0
  135. package/dist/ai/delegation/middleware/reputation-middleware.d.ts.map +1 -0
  136. package/dist/ai/delegation/middleware/reputation-middleware.js +75 -0
  137. package/dist/ai/delegation/middleware/reputation-middleware.js.map +1 -0
  138. package/dist/ai/delegation/middleware/resource-limiter-middleware.d.ts +52 -0
  139. package/dist/ai/delegation/middleware/resource-limiter-middleware.d.ts.map +1 -0
  140. package/dist/ai/delegation/middleware/resource-limiter-middleware.js +112 -0
  141. package/dist/ai/delegation/middleware/resource-limiter-middleware.js.map +1 -0
  142. package/dist/ai/delegation/middleware/threat-validator-middleware.d.ts +23 -0
  143. package/dist/ai/delegation/middleware/threat-validator-middleware.d.ts.map +1 -0
  144. package/dist/ai/delegation/middleware/threat-validator-middleware.js +83 -0
  145. package/dist/ai/delegation/middleware/threat-validator-middleware.js.map +1 -0
  146. package/dist/ai/delegation/middleware/tlp-middleware.d.ts +23 -0
  147. package/dist/ai/delegation/middleware/tlp-middleware.d.ts.map +1 -0
  148. package/dist/ai/delegation/middleware/tlp-middleware.js +59 -0
  149. package/dist/ai/delegation/middleware/tlp-middleware.js.map +1 -0
  150. package/dist/ai/delegation/monitoring.d.ts +298 -0
  151. package/dist/ai/delegation/monitoring.d.ts.map +1 -0
  152. package/dist/ai/delegation/monitoring.js +584 -0
  153. package/dist/ai/delegation/monitoring.js.map +1 -0
  154. package/dist/ai/delegation/security-middleware-chain.d.ts +71 -0
  155. package/dist/ai/delegation/security-middleware-chain.d.ts.map +1 -0
  156. package/dist/ai/delegation/security-middleware-chain.js +163 -0
  157. package/dist/ai/delegation/security-middleware-chain.js.map +1 -0
  158. package/dist/ai/delegation/session-checkpoint.d.ts +77 -0
  159. package/dist/ai/delegation/session-checkpoint.d.ts.map +1 -0
  160. package/dist/ai/delegation/session-checkpoint.js +131 -0
  161. package/dist/ai/delegation/session-checkpoint.js.map +1 -0
  162. package/dist/ai/delegation/session-manager.d.ts +131 -0
  163. package/dist/ai/delegation/session-manager.d.ts.map +1 -0
  164. package/dist/ai/delegation/session-manager.js +243 -0
  165. package/dist/ai/delegation/session-manager.js.map +1 -0
  166. package/dist/ai/delegation/session-queue.d.ts +95 -0
  167. package/dist/ai/delegation/session-queue.d.ts.map +1 -0
  168. package/dist/ai/delegation/session-queue.js +136 -0
  169. package/dist/ai/delegation/session-queue.js.map +1 -0
  170. package/dist/ai/delegation/timeout-watchdog.d.ts +60 -0
  171. package/dist/ai/delegation/timeout-watchdog.d.ts.map +1 -0
  172. package/dist/ai/delegation/timeout-watchdog.js +100 -0
  173. package/dist/ai/delegation/timeout-watchdog.js.map +1 -0
  174. package/dist/ai/examples/integration-demo.d.ts +27 -0
  175. package/dist/ai/examples/integration-demo.d.ts.map +1 -0
  176. package/dist/ai/examples/integration-demo.js +536 -0
  177. package/dist/ai/examples/integration-demo.js.map +1 -0
  178. package/dist/ai/index.d.ts +25 -0
  179. package/dist/ai/index.d.ts.map +1 -1
  180. package/dist/ai/index.js +34 -11
  181. package/dist/ai/index.js.map +1 -1
  182. package/dist/ai/mcp/servers/analytics/index.js +67 -11
  183. package/dist/ai/mcp/servers/analytics/index.js.map +1 -1
  184. package/dist/ai/mcp/servers/content-manager/index.d.ts.map +1 -1
  185. package/dist/ai/mcp/servers/content-manager/index.js +50 -4
  186. package/dist/ai/mcp/servers/content-manager/index.js.map +1 -1
  187. package/dist/ai/mcp/servers/delegation-monitor/index.d.ts +36 -0
  188. package/dist/ai/mcp/servers/delegation-monitor/index.d.ts.map +1 -0
  189. package/dist/ai/mcp/servers/delegation-monitor/index.js +757 -0
  190. package/dist/ai/mcp/servers/delegation-monitor/index.js.map +1 -0
  191. package/dist/ai/mcp/servers/design-tokens/index.d.ts.map +1 -1
  192. package/dist/ai/mcp/servers/design-tokens/index.js +62 -39
  193. package/dist/ai/mcp/servers/design-tokens/index.js.map +1 -1
  194. package/dist/ai/mcp/servers/promptintel/index.js +15 -3
  195. package/dist/ai/mcp/servers/promptintel/index.js.map +1 -1
  196. package/dist/ai/mcp/servers/shared/rate-limiter.d.ts.map +1 -1
  197. package/dist/ai/mcp/servers/shared/rate-limiter.js +3 -1
  198. package/dist/ai/mcp/servers/shared/rate-limiter.js.map +1 -1
  199. package/dist/ai/mcp/servers/shared/redis-client.d.ts.map +1 -1
  200. package/dist/ai/mcp/servers/shared/redis-client.js +54 -47
  201. package/dist/ai/mcp/servers/shared/redis-client.js.map +1 -1
  202. package/dist/ai/mcp/servers/shared/types.d.ts +9 -0
  203. package/dist/ai/mcp/servers/shared/types.d.ts.map +1 -1
  204. package/dist/ai/mcp/servers/shared/utils.d.ts +9 -1
  205. package/dist/ai/mcp/servers/shared/utils.d.ts.map +1 -1
  206. package/dist/ai/mcp/servers/shared/utils.js +52 -2
  207. package/dist/ai/mcp/servers/shared/utils.js.map +1 -1
  208. package/dist/ai/memory/config.d.ts +18 -3
  209. package/dist/ai/memory/config.d.ts.map +1 -1
  210. package/dist/ai/memory/config.js +61 -15
  211. package/dist/ai/memory/config.js.map +1 -1
  212. package/dist/ai/memory/dcyfr-memory.d.ts +4 -0
  213. package/dist/ai/memory/dcyfr-memory.d.ts.map +1 -1
  214. package/dist/ai/memory/dcyfr-memory.js +44 -6
  215. package/dist/ai/memory/dcyfr-memory.js.map +1 -1
  216. package/dist/ai/memory/mem0-client.d.ts.map +1 -1
  217. package/dist/ai/memory/mem0-client.js +53 -14
  218. package/dist/ai/memory/mem0-client.js.map +1 -1
  219. package/dist/ai/permissions/attenuation-engine.d.ts +159 -0
  220. package/dist/ai/permissions/attenuation-engine.d.ts.map +1 -0
  221. package/dist/ai/permissions/attenuation-engine.js +511 -0
  222. package/dist/ai/permissions/attenuation-engine.js.map +1 -0
  223. package/dist/ai/plugins/plugin-loader.d.ts +4 -0
  224. package/dist/ai/plugins/plugin-loader.d.ts.map +1 -1
  225. package/dist/ai/plugins/plugin-loader.js +28 -28
  226. package/dist/ai/plugins/plugin-loader.js.map +1 -1
  227. package/dist/ai/reputation/execution-mode-reputation.d.ts +104 -0
  228. package/dist/ai/reputation/execution-mode-reputation.d.ts.map +1 -0
  229. package/dist/ai/reputation/execution-mode-reputation.js +142 -0
  230. package/dist/ai/reputation/execution-mode-reputation.js.map +1 -0
  231. package/dist/ai/reputation/reputation-engine.d.ts +204 -0
  232. package/dist/ai/reputation/reputation-engine.d.ts.map +1 -0
  233. package/dist/ai/reputation/reputation-engine.js +426 -0
  234. package/dist/ai/reputation/reputation-engine.js.map +1 -0
  235. package/dist/ai/runtime/agent-runtime.d.ts +193 -0
  236. package/dist/ai/runtime/agent-runtime.d.ts.map +1 -0
  237. package/dist/ai/runtime/agent-runtime.js +1009 -0
  238. package/dist/ai/runtime/agent-runtime.js.map +1 -0
  239. package/dist/ai/runtime/index.d.ts +11 -0
  240. package/dist/ai/runtime/index.d.ts.map +1 -0
  241. package/dist/ai/runtime/index.js +9 -0
  242. package/dist/ai/runtime/index.js.map +1 -0
  243. package/dist/ai/runtime/telemetry-schema.d.ts +192 -0
  244. package/dist/ai/runtime/telemetry-schema.d.ts.map +1 -0
  245. package/dist/ai/runtime/telemetry-schema.js +200 -0
  246. package/dist/ai/runtime/telemetry-schema.js.map +1 -0
  247. package/dist/ai/runtime/types.d.ts +236 -0
  248. package/dist/ai/runtime/types.d.ts.map +1 -0
  249. package/dist/ai/runtime/types.js +10 -0
  250. package/dist/ai/runtime/types.js.map +1 -0
  251. package/dist/ai/src/batch-processor.d.ts +298 -0
  252. package/dist/ai/src/batch-processor.d.ts.map +1 -0
  253. package/dist/ai/src/batch-processor.js +520 -0
  254. package/dist/ai/src/batch-processor.js.map +1 -0
  255. package/dist/ai/src/capability-bootstrap.d.ts +222 -0
  256. package/dist/ai/src/capability-bootstrap.d.ts.map +1 -0
  257. package/dist/ai/src/capability-bootstrap.js +421 -0
  258. package/dist/ai/src/capability-bootstrap.js.map +1 -0
  259. package/dist/ai/src/capability-manifest-generator.d.ts +61 -0
  260. package/dist/ai/src/capability-manifest-generator.d.ts.map +1 -0
  261. package/dist/ai/src/capability-manifest-generator.js +700 -0
  262. package/dist/ai/src/capability-manifest-generator.js.map +1 -0
  263. package/dist/ai/src/capability-registry.d.ts +157 -0
  264. package/dist/ai/src/capability-registry.d.ts.map +1 -0
  265. package/dist/ai/src/capability-registry.js +577 -0
  266. package/dist/ai/src/capability-registry.js.map +1 -0
  267. package/dist/ai/src/cli/telemetry-dashboard.d.ts +132 -0
  268. package/dist/ai/src/cli/telemetry-dashboard.d.ts.map +1 -0
  269. package/dist/ai/src/cli/telemetry-dashboard.js +565 -0
  270. package/dist/ai/src/cli/telemetry-dashboard.js.map +1 -0
  271. package/dist/ai/src/delegation/feature-flags.d.ts +213 -0
  272. package/dist/ai/src/delegation/feature-flags.d.ts.map +1 -0
  273. package/dist/ai/src/delegation/feature-flags.js +395 -0
  274. package/dist/ai/src/delegation/feature-flags.js.map +1 -0
  275. package/dist/ai/src/delegation/liability-firebreak.d.ts +303 -0
  276. package/dist/ai/src/delegation/liability-firebreak.d.ts.map +1 -0
  277. package/dist/ai/src/delegation/liability-firebreak.js +643 -0
  278. package/dist/ai/src/delegation/liability-firebreak.js.map +1 -0
  279. package/dist/ai/src/delegation/security-threat-model.d.ts +171 -0
  280. package/dist/ai/src/delegation/security-threat-model.d.ts.map +1 -0
  281. package/dist/ai/src/delegation/security-threat-model.js +723 -0
  282. package/dist/ai/src/delegation/security-threat-model.js.map +1 -0
  283. package/dist/ai/src/delegation/tlp-enforcement.d.ts +146 -0
  284. package/dist/ai/src/delegation/tlp-enforcement.d.ts.map +1 -0
  285. package/dist/ai/src/delegation/tlp-enforcement.js +382 -0
  286. package/dist/ai/src/delegation/tlp-enforcement.js.map +1 -0
  287. package/dist/ai/src/delegation-capability-integration.d.ts +154 -0
  288. package/dist/ai/src/delegation-capability-integration.d.ts.map +1 -0
  289. package/dist/ai/src/delegation-capability-integration.js +351 -0
  290. package/dist/ai/src/delegation-capability-integration.js.map +1 -0
  291. package/dist/ai/src/end-to-end-workflow-orchestrator.d.ts +325 -0
  292. package/dist/ai/src/end-to-end-workflow-orchestrator.d.ts.map +1 -0
  293. package/dist/ai/src/end-to-end-workflow-orchestrator.js +801 -0
  294. package/dist/ai/src/end-to-end-workflow-orchestrator.js.map +1 -0
  295. package/dist/ai/src/enhanced-capability-detection.d.ts +237 -0
  296. package/dist/ai/src/enhanced-capability-detection.d.ts.map +1 -0
  297. package/dist/ai/src/enhanced-capability-detection.js +448 -0
  298. package/dist/ai/src/enhanced-capability-detection.js.map +1 -0
  299. package/dist/ai/src/intelligent-cache-manager.d.ts +327 -0
  300. package/dist/ai/src/intelligent-cache-manager.d.ts.map +1 -0
  301. package/dist/ai/src/intelligent-cache-manager.js +634 -0
  302. package/dist/ai/src/intelligent-cache-manager.js.map +1 -0
  303. package/dist/ai/src/mcp-auto-configuration.d.ts +232 -0
  304. package/dist/ai/src/mcp-auto-configuration.d.ts.map +1 -0
  305. package/dist/ai/src/mcp-auto-configuration.js +445 -0
  306. package/dist/ai/src/mcp-auto-configuration.js.map +1 -0
  307. package/dist/ai/src/performance-profiler.d.ts +351 -0
  308. package/dist/ai/src/performance-profiler.d.ts.map +1 -0
  309. package/dist/ai/src/performance-profiler.js +475 -0
  310. package/dist/ai/src/performance-profiler.js.map +1 -0
  311. package/dist/ai/src/personas/hooks/before-llm-call.d.ts +96 -0
  312. package/dist/ai/src/personas/hooks/before-llm-call.d.ts.map +1 -0
  313. package/dist/ai/src/personas/hooks/before-llm-call.js +83 -0
  314. package/dist/ai/src/personas/hooks/before-llm-call.js.map +1 -0
  315. package/dist/ai/src/personas/index.d.ts +10 -0
  316. package/dist/ai/src/personas/index.d.ts.map +1 -0
  317. package/dist/ai/src/personas/index.js +10 -0
  318. package/dist/ai/src/personas/index.js.map +1 -0
  319. package/dist/ai/src/personas/persona-loader.d.ts +42 -0
  320. package/dist/ai/src/personas/persona-loader.d.ts.map +1 -0
  321. package/dist/ai/src/personas/persona-loader.js +162 -0
  322. package/dist/ai/src/personas/persona-loader.js.map +1 -0
  323. package/dist/ai/src/personas/types.d.ts +199 -0
  324. package/dist/ai/src/personas/types.d.ts.map +1 -0
  325. package/dist/ai/src/personas/types.js +7 -0
  326. package/dist/ai/src/personas/types.js.map +1 -0
  327. package/dist/ai/src/personas/voice-resolver.d.ts +40 -0
  328. package/dist/ai/src/personas/voice-resolver.d.ts.map +1 -0
  329. package/dist/ai/src/personas/voice-resolver.js +201 -0
  330. package/dist/ai/src/personas/voice-resolver.js.map +1 -0
  331. package/dist/ai/src/resource-monitor.d.ts +311 -0
  332. package/dist/ai/src/resource-monitor.d.ts.map +1 -0
  333. package/dist/ai/src/resource-monitor.js +475 -0
  334. package/dist/ai/src/resource-monitor.js.map +1 -0
  335. package/dist/ai/src/runtime/agent-runtime.d.ts +340 -0
  336. package/dist/ai/src/runtime/agent-runtime.d.ts.map +1 -0
  337. package/dist/ai/src/runtime/agent-runtime.js +1084 -0
  338. package/dist/ai/src/runtime/agent-runtime.js.map +1 -0
  339. package/dist/ai/src/telemetry/delegation-telemetry.d.ts +287 -0
  340. package/dist/ai/src/telemetry/delegation-telemetry.d.ts.map +1 -0
  341. package/dist/ai/src/telemetry/delegation-telemetry.js +389 -0
  342. package/dist/ai/src/telemetry/delegation-telemetry.js.map +1 -0
  343. package/dist/ai/src/telemetry/index.d.ts +48 -0
  344. package/dist/ai/src/telemetry/index.d.ts.map +1 -0
  345. package/dist/ai/src/telemetry/index.js +48 -0
  346. package/dist/ai/src/telemetry/index.js.map +1 -0
  347. package/dist/ai/src/telemetry/runtime-telemetry-integration.d.ts +67 -0
  348. package/dist/ai/src/telemetry/runtime-telemetry-integration.d.ts.map +1 -0
  349. package/dist/ai/src/telemetry/runtime-telemetry-integration.js +415 -0
  350. package/dist/ai/src/telemetry/runtime-telemetry-integration.js.map +1 -0
  351. package/dist/ai/src/telemetry/telemetry-utils.d.ts +119 -0
  352. package/dist/ai/src/telemetry/telemetry-utils.d.ts.map +1 -0
  353. package/dist/ai/src/telemetry/telemetry-utils.js +250 -0
  354. package/dist/ai/src/telemetry/telemetry-utils.js.map +1 -0
  355. package/dist/ai/src/types/agent-capabilities.d.ts +227 -0
  356. package/dist/ai/src/types/agent-capabilities.d.ts.map +1 -0
  357. package/dist/ai/src/types/agent-capabilities.js +11 -0
  358. package/dist/ai/src/types/agent-capabilities.js.map +1 -0
  359. package/dist/ai/src/types/context-verification.d.ts +158 -0
  360. package/dist/ai/src/types/context-verification.d.ts.map +1 -0
  361. package/dist/ai/src/types/context-verification.js +73 -0
  362. package/dist/ai/src/types/context-verification.js.map +1 -0
  363. package/dist/ai/src/types/delegation-contracts.d.ts +296 -0
  364. package/dist/ai/src/types/delegation-contracts.d.ts.map +1 -0
  365. package/dist/ai/src/types/delegation-contracts.js +17 -0
  366. package/dist/ai/src/types/delegation-contracts.js.map +1 -0
  367. package/dist/ai/src/validation-pipeline-integration.d.ts +266 -0
  368. package/dist/ai/src/validation-pipeline-integration.d.ts.map +1 -0
  369. package/dist/ai/src/validation-pipeline-integration.js +695 -0
  370. package/dist/ai/src/validation-pipeline-integration.js.map +1 -0
  371. package/dist/ai/src/verification/multi-modal-formatters.d.ts +57 -0
  372. package/dist/ai/src/verification/multi-modal-formatters.d.ts.map +1 -0
  373. package/dist/ai/src/verification/multi-modal-formatters.js +655 -0
  374. package/dist/ai/src/verification/multi-modal-formatters.js.map +1 -0
  375. package/dist/ai/src/verification/output-formatter.d.ts +186 -0
  376. package/dist/ai/src/verification/output-formatter.d.ts.map +1 -0
  377. package/dist/ai/src/verification/output-formatter.js +296 -0
  378. package/dist/ai/src/verification/output-formatter.js.map +1 -0
  379. package/dist/ai/src/verification/parser-integration.d.ts +137 -0
  380. package/dist/ai/src/verification/parser-integration.d.ts.map +1 -0
  381. package/dist/ai/src/verification/parser-integration.js +273 -0
  382. package/dist/ai/src/verification/parser-integration.js.map +1 -0
  383. package/dist/ai/types/agent-capabilities.d.ts +387 -0
  384. package/dist/ai/types/agent-capabilities.d.ts.map +1 -0
  385. package/dist/ai/types/agent-capabilities.js +32 -0
  386. package/dist/ai/types/agent-capabilities.js.map +1 -0
  387. package/dist/ai/types/delegation-contracts.d.ts +291 -0
  388. package/dist/ai/types/delegation-contracts.d.ts.map +1 -0
  389. package/dist/ai/types/delegation-contracts.js +14 -0
  390. package/dist/ai/types/delegation-contracts.js.map +1 -0
  391. package/dist/ai/types/index.d.ts +4 -1
  392. package/dist/ai/types/index.d.ts.map +1 -1
  393. package/dist/ai/types/index.js +4 -1
  394. package/dist/ai/types/index.js.map +1 -1
  395. package/dist/ai/types/permission-tokens.d.ts +365 -0
  396. package/dist/ai/types/permission-tokens.d.ts.map +1 -0
  397. package/dist/ai/types/permission-tokens.js +13 -0
  398. package/dist/ai/types/permission-tokens.js.map +1 -0
  399. package/dist/ai/types/security-middleware.d.ts +130 -0
  400. package/dist/ai/types/security-middleware.d.ts.map +1 -0
  401. package/dist/ai/types/security-middleware.js +13 -0
  402. package/dist/ai/types/security-middleware.js.map +1 -0
  403. package/dist/ai/utils/storage.d.ts.map +1 -1
  404. package/dist/ai/utils/storage.js +6 -3
  405. package/dist/ai/utils/storage.js.map +1 -1
  406. package/dist/ai/validation/validation-framework.js +1 -1
  407. package/dist/ai/verification/policy-framework.d.ts +161 -0
  408. package/dist/ai/verification/policy-framework.d.ts.map +1 -0
  409. package/dist/ai/verification/policy-framework.js +436 -0
  410. package/dist/ai/verification/policy-framework.js.map +1 -0
  411. package/package.json +36 -8
@@ -0,0 +1,1258 @@
1
+ /**
2
+ * DCYFR Delegation Contract Manager
3
+ * TLP:CLEAR
4
+ *
5
+ * Manages delegation contracts with database persistence, event emission,
6
+ * and lifecycle tracking.
7
+ *
8
+ * @module delegation/contract-manager
9
+ * @version 1.1.0
10
+ * @date 2026-02-15
11
+ */
12
+ import { EventEmitter } from 'events';
13
+ import Database from 'better-sqlite3';
14
+ import { ExecutionMode } from '../types/agent-capabilities.js';
15
+ import { BackgroundSessionQueue, MAX_BACKGROUND_SESSIONS } from './session-queue.js';
16
+ import { SessionCheckpoint } from './session-checkpoint.js';
17
+ import { SessionManager } from './session-manager.js';
18
+ import { SecurityMiddlewareChain } from './security-middleware-chain.js';
19
+ import { IdentityMiddleware } from './middleware/identity-middleware.js';
20
+ import { TLPMiddleware } from './middleware/tlp-middleware.js';
21
+ import { ThreatValidatorMiddleware } from './middleware/threat-validator-middleware.js';
22
+ import { RateLimiterMiddleware } from './middleware/rate-limiter-middleware.js';
23
+ import { ChainDepthMiddleware } from './middleware/chain-depth-middleware.js';
24
+ import { ContentPolicyMiddleware } from './middleware/content-policy-middleware.js';
25
+ import { PermissionsMiddleware } from './middleware/permissions-middleware.js';
26
+ import { ReputationMiddleware } from './middleware/reputation-middleware.js';
27
+ import { CircuitBreaker, CircuitBreakerMiddleware } from './circuit-breaker.js';
28
+ import { ContractTimeoutWatchdog } from './timeout-watchdog.js';
29
+ import { BlastRadiusTracker } from './blast-radius-tracker.js';
30
+ import { TLPEnforcementEngine } from '../src/delegation/tlp-enforcement.js';
31
+ import { FeatureFlagMiddleware } from './middleware/feature-flag-middleware.js';
32
+ import { ChainTrackerMiddleware } from './middleware/chain-tracker-middleware.js';
33
+ import { ResourceLimiterMiddleware } from './middleware/resource-limiter-middleware.js';
34
+ import { FeatureFlagManager, DEFAULT_FEATURE_FLAGS } from './feature-flags.js';
35
+ /**
36
+ * DelegationContractManager - Core delegation contract lifecycle management
37
+ */
38
+ export class DelegationContractManager extends EventEmitter {
39
+ db;
40
+ maxDelegationDepth;
41
+ debug;
42
+ /** In-memory agent name cache (DB may not store names) */
43
+ agentNames = new Map();
44
+ securityThreatEvents = [];
45
+ securityValidationCount = 0;
46
+ securityThreatCount = 0;
47
+ /** Optional registry for manifest-based mode selection. */
48
+ capabilityRegistry;
49
+ /** Background session slot management. */
50
+ backgroundQueue;
51
+ /** Session lifecycle tracking. */
52
+ sessionManager;
53
+ /** Checkpoint persistence. */
54
+ checkpoint;
55
+ /** Pluggable security middleware chain — evaluated on every createContract. */
56
+ securityChain;
57
+ /** Chain depth + fan-out middleware (also manages fan-out counters). */
58
+ chainDepthMiddleware;
59
+ /** Circuit breaker state machine for per-agent failure tracking. */
60
+ circuitBreaker;
61
+ /** Periodic contract timeout watchdog. */
62
+ watchdog;
63
+ /** Optional agent identity registry (enables IdentityMiddleware). */
64
+ agentRegistry;
65
+ /** Blast-radius limiter — caps contract-creation rate per root delegator tree. */
66
+ blastRadiusTracker;
67
+ /** Optional reputation engine (enables ReputationMiddleware + security penalties). */
68
+ reputationEngine;
69
+ /** Optional health monitor wired to live contract stats (8.1). */
70
+ healthMonitor;
71
+ constructor(config = {}) {
72
+ super();
73
+ this.maxDelegationDepth = config.maxDelegationDepth ?? 5;
74
+ this.debug = config.debug ?? false;
75
+ this.capabilityRegistry = config.capabilityRegistry;
76
+ this.agentRegistry = config.agentRegistry;
77
+ this.reputationEngine = config.reputationEngine;
78
+ // 8.1: Wire health monitor to live contract data
79
+ this.healthMonitor = config.healthMonitor;
80
+ if (this.healthMonitor) {
81
+ this.healthMonitor.setContractDataProvider(() => this.getStatistics());
82
+ }
83
+ this.backgroundQueue = new BackgroundSessionQueue(config.maxBackgroundSessions ?? MAX_BACKGROUND_SESSIONS);
84
+ this.sessionManager = new SessionManager({
85
+ archiveBaseDir: config.sessionArchiveDir,
86
+ flushIntervalMs: 60_000,
87
+ });
88
+ this.checkpoint = new SessionCheckpoint(config.checkpointDir);
89
+ // Forward background queue status events upstream
90
+ this.backgroundQueue.on('status', (status) => {
91
+ this.emit('background_queue_status', status);
92
+ });
93
+ const dbPath = config.databasePath ?? ':memory:';
94
+ this.db = new Database(dbPath);
95
+ this.initializeSchema();
96
+ // ── Security middleware chain ──────────────────────────────────────────
97
+ this.blastRadiusTracker = new BlastRadiusTracker();
98
+ this.chainDepthMiddleware = new ChainDepthMiddleware({ maxDepth: this.maxDelegationDepth });
99
+ this.circuitBreaker = new CircuitBreaker();
100
+ this.watchdog = new ContractTimeoutWatchdog();
101
+ this.securityChain = new SecurityMiddlewareChain();
102
+ // 1.3: FeatureFlagMiddleware — kill-switch, must be first in chain.
103
+ // When no featureFlagManager is provided, create a local instance with
104
+ // delegation_enabled=true so existing consumers work out of the box.
105
+ const flagManager = config.featureFlagManager ?? new FeatureFlagManager({
106
+ ...DEFAULT_FEATURE_FLAGS,
107
+ delegation_enabled: true,
108
+ });
109
+ this.securityChain.use(new FeatureFlagMiddleware(flagManager));
110
+ if (this.agentRegistry) {
111
+ this.securityChain.use(new IdentityMiddleware(this.agentRegistry));
112
+ }
113
+ // Build TLP engine with any caller-supplied extra clearances
114
+ const tlpEngine = new TLPEnforcementEngine();
115
+ if (config.additionalTLPClearances) {
116
+ for (const c of config.additionalTLPClearances) {
117
+ tlpEngine.setAgentClearance(c);
118
+ }
119
+ }
120
+ this.securityChain.use(new TLPMiddleware(tlpEngine));
121
+ this.securityChain.use(this.chainDepthMiddleware);
122
+ this.securityChain.use(new ThreatValidatorMiddleware());
123
+ this.securityChain.use(new RateLimiterMiddleware(config.rateLimiterOptions));
124
+ this.securityChain.use(new ContentPolicyMiddleware());
125
+ this.securityChain.use(new PermissionsMiddleware((parentContractId) => {
126
+ const parent = this.getContractById(parentContractId);
127
+ return parent?.permission_tokens ?? null;
128
+ }));
129
+ // 7.1: ReputationMiddleware — block low-reputation agents on TLP:AMBER+ tasks
130
+ if (this.reputationEngine) {
131
+ this.securityChain.use(new ReputationMiddleware(this.reputationEngine));
132
+ }
133
+ this.securityChain.use(new CircuitBreakerMiddleware(this.circuitBreaker));
134
+ // 3.4: ChainTrackerMiddleware — loop detection and depth validation (create-only)
135
+ this.securityChain.use(new ChainTrackerMiddleware(this, { maxChainDepth: this.maxDelegationDepth }));
136
+ // 4.3: ResourceLimiterMiddleware — aggregate resource cap (create-only)
137
+ this.securityChain.use(new ResourceLimiterMiddleware(() => this.queryContracts({ status: 'active' })));
138
+ // Forward chain events upstream for observability
139
+ this.securityChain.on('security_warning', (ev) => this.emit('security_warning', ev));
140
+ this.securityChain.on('security_blocked', (ev) => this.emit('security_blocked', ev));
141
+ this.securityChain.on('chain_evaluated', (ev) => this.emit('chain_evaluated', ev));
142
+ // Forward watchdog timeout events and update contract status
143
+ this.watchdog.on('contract_timeout', (ev) => {
144
+ this.emit('contract_timeout', ev);
145
+ try {
146
+ void this.updateContract({ contract_id: ev.contract_id, status: 'timeout' });
147
+ }
148
+ catch { /* contract may have already completed/been removed */ }
149
+ });
150
+ // Forward circuit breaker open → circuit_breaker_tripped (8.4)
151
+ this.circuitBreaker.on('circuit_opened', (ev) => {
152
+ this.emit('circuit_breaker_tripped', { agent_id: ev.agent_id, failure_count: ev.failure_count });
153
+ });
154
+ // 7.2: Security violation penalty — penalise delegatee reputation on threat detection
155
+ if (this.reputationEngine) {
156
+ const reputationEngine = this.reputationEngine;
157
+ this.on('security_threat_detected', (ev) => {
158
+ const contract = ev.contract_id ? this.getContractById(ev.contract_id) : undefined;
159
+ if (!contract?.delegatee?.agent_id)
160
+ return;
161
+ void reputationEngine.updateReputation({
162
+ contract_id: ev.contract_id ?? 'unknown',
163
+ agent_id: contract.delegatee.agent_id,
164
+ agent_name: contract.delegatee.agent_name ?? contract.delegatee.agent_id,
165
+ task_id: contract.task_id ?? 'unknown',
166
+ success: false,
167
+ completion_time_ms: 0,
168
+ security_violations: 1,
169
+ });
170
+ });
171
+ }
172
+ this.watchdog.start();
173
+ }
174
+ /**
175
+ * Initialize database schema
176
+ */
177
+ initializeSchema() {
178
+ this.db.exec(`
179
+ CREATE TABLE IF NOT EXISTS delegation_contracts (
180
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
181
+ contract_id TEXT NOT NULL UNIQUE,
182
+ delegator_agent_id TEXT NOT NULL,
183
+ delegatee_agent_id TEXT NOT NULL,
184
+ task_id TEXT NOT NULL,
185
+ task_description TEXT NOT NULL,
186
+ verification_policy TEXT NOT NULL,
187
+ success_criteria TEXT NOT NULL,
188
+ timeout_ms INTEGER NOT NULL,
189
+ permission_tokens TEXT,
190
+ priority INTEGER DEFAULT 3,
191
+ metadata TEXT,
192
+ status TEXT NOT NULL DEFAULT 'pending',
193
+ created_at TEXT NOT NULL,
194
+ activated_at TEXT,
195
+ completed_at TEXT,
196
+ verification_result TEXT,
197
+ parent_contract_id TEXT,
198
+ delegation_depth INTEGER DEFAULT 0,
199
+ tlp_classification TEXT
200
+ );
201
+
202
+ CREATE INDEX IF NOT EXISTS idx_delegator ON delegation_contracts(delegator_agent_id);
203
+ CREATE INDEX IF NOT EXISTS idx_delegatee ON delegation_contracts(delegatee_agent_id);
204
+ CREATE INDEX IF NOT EXISTS idx_status ON delegation_contracts(status);
205
+ CREATE INDEX IF NOT EXISTS idx_task_id ON delegation_contracts(task_id);
206
+ CREATE INDEX IF NOT EXISTS idx_parent ON delegation_contracts(parent_contract_id);
207
+ `);
208
+ }
209
+ /** Normalize agents from legacy or current request shapes */
210
+ normalizeContractAgents(request, legacyRequest) {
211
+ const delegator = request.delegator || {
212
+ agent_id: legacyRequest?.delegator_agent_id || legacyRequest?.delegator?.agent_id || 'delegator-agent',
213
+ agent_name: legacyRequest?.delegator?.agent_name || legacyRequest?.delegator?.agent_id || 'Delegator Agent',
214
+ capabilities: legacyRequest?.delegator?.capabilities,
215
+ };
216
+ const delegatee = request.delegatee || {
217
+ agent_id: legacyRequest?.delegatee_agent_id || legacyRequest?.delegatee?.agent_id || 'delegatee-agent',
218
+ agent_name: legacyRequest?.delegatee?.agent_name || legacyRequest?.delegatee?.agent_id || 'Delegatee Agent',
219
+ capabilities: legacyRequest?.delegatee?.capabilities,
220
+ };
221
+ return { delegator, delegatee };
222
+ }
223
+ /** Normalize verification policy from legacy/current values */
224
+ normalizeVerificationPolicy(raw) {
225
+ if (raw === 'manual')
226
+ return 'human_required';
227
+ if (raw === 'automated' || raw === 'capability_match')
228
+ return 'direct_inspection';
229
+ return raw;
230
+ }
231
+ /**
232
+ * 5.3 Sanitize task description text — strip null bytes and Unicode direction
233
+ * override characters while preserving legitimate Unicode (emoji, CJK, etc.).
234
+ */
235
+ sanitizeTaskDescription(text) {
236
+ return text
237
+ // Remove null bytes
238
+ .replace(/\0/g, '')
239
+ // Remove Unicode direction override characters (U+202A–U+202E, U+2066–U+2069)
240
+ .replace(/[\u202A-\u202E\u2066-\u2069]/g, '');
241
+ }
242
+ /**
243
+ * 6.2: Walk the parent chain to find the root delegator agent_id.
244
+ * Falls back to the provided delegator ID if no traceable parent exists.
245
+ */
246
+ getRootDelegatorId(parentContractId, fallbackDelegatorId) {
247
+ if (!parentContractId) {
248
+ return fallbackDelegatorId;
249
+ }
250
+ // Walk up the chain (guard against cycles with a depth cap)
251
+ let current = this.getContractById(parentContractId);
252
+ for (let i = 0; i < 20 && current; i++) {
253
+ if (!current.parent_contract_id) {
254
+ return current.delegator.agent_id;
255
+ }
256
+ current = this.getContractById(current.parent_contract_id);
257
+ }
258
+ return fallbackDelegatorId;
259
+ }
260
+ /** Run security validation, emit threat event and throw if a threat is detected */
261
+ async validateContractSecurity(request, legacyRequest, normalizedPermissionTokens) {
262
+ this.securityValidationCount++;
263
+ // 2.6: Validate PermissionToken holder/issuer identity binding
264
+ if (normalizedPermissionTokens) {
265
+ for (const token of normalizedPermissionTokens) {
266
+ const t = token;
267
+ if (t.holder !== undefined && t.holder !== request.delegatee.agent_id) {
268
+ throw new Error(`Permission token '${token.token_id}': holder '${t.holder}' does not match delegatee '${request.delegatee.agent_id}'`);
269
+ }
270
+ if (t.issuer !== undefined && t.issuer !== request.delegator.agent_id) {
271
+ throw new Error(`Permission token '${token.token_id}': issuer '${t.issuer}' does not match delegator '${request.delegator.agent_id}'`);
272
+ }
273
+ }
274
+ }
275
+ // ── Pre-flight threat guards ───────────────────────────────────────────
276
+ // These three checks mirror the behaviour of the original detectSecurityThreat()
277
+ // whose private helpers were removed in task 1.6. We keep them as inline
278
+ // pre-chain guards because the SecurityMiddlewareChain cannot (a) access
279
+ // permission_token.scopes from the array form, (b) evaluate resource
280
+ // requirements outside the DelegationContract type, or (c) guarantee the
281
+ // same risk-score thresholds as the original contract-level checks.
282
+ // Guard 1: critical permission scopes / actions → permission_escalation
283
+ {
284
+ const allScopes = new Set();
285
+ const allActions = new Set();
286
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
287
+ const legacyPt = legacyRequest?.permission_token;
288
+ if (legacyPt && typeof legacyPt === 'object' && !Array.isArray(legacyPt)) {
289
+ for (const s of legacyPt.scopes ?? [])
290
+ allScopes.add(String(s).toLowerCase());
291
+ for (const a of legacyPt.actions ?? [])
292
+ allActions.add(String(a).toLowerCase());
293
+ }
294
+ for (const token of normalizedPermissionTokens ?? []) {
295
+ for (const s of token.scopes ?? [])
296
+ allScopes.add(String(s).toLowerCase()); // eslint-disable-line @typescript-eslint/no-explicit-any
297
+ for (const a of token.actions ?? [])
298
+ allActions.add(String(a).toLowerCase()); // eslint-disable-line @typescript-eslint/no-explicit-any
299
+ }
300
+ const joined = `${Array.from(allScopes).join(' ')} ${Array.from(allActions).join(' ')}`;
301
+ if (/(root|admin|execute|delete|modify_system|system_admin|root_access|execute_arbitrary)/i.test(joined)) {
302
+ this.securityThreatCount++;
303
+ const te = { contract_id: request.contract_id || `preflight-${Date.now()}`, threat_detected: true, threat_type: 'permission_escalation', severity: 'critical', description: 'Detected high-risk permission scopes or actions.', action: 'block', timestamp: new Date().toISOString() };
304
+ this.securityThreatEvents.push(te);
305
+ this.emit('security_threat_detected', te);
306
+ throw new Error('Security threat detected: permission_escalation');
307
+ }
308
+ }
309
+ // Guard 2: excessive delegation depth in metadata → permission_escalation
310
+ {
311
+ const depth = Number(legacyRequest?.metadata?.delegation_depth ?? 0);
312
+ if (Number.isFinite(depth) && depth >= 6) {
313
+ this.securityThreatCount++;
314
+ const te = { contract_id: request.contract_id || `preflight-${Date.now()}`, threat_detected: true, threat_type: 'permission_escalation', severity: 'critical', description: 'Delegation chain depth exceeds safe limits.', action: 'block', timestamp: new Date().toISOString() };
315
+ this.securityThreatEvents.push(te);
316
+ this.emit('security_threat_detected', te);
317
+ throw new Error('Security threat detected: permission_escalation');
318
+ }
319
+ }
320
+ // Guard 3: excessive per-contract resource requirements → abuse_pattern
321
+ {
322
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
323
+ const rr = legacyRequest?.resource_requirements;
324
+ const memory = Number(rr?.memory_mb ?? 0);
325
+ const cpu = Number(rr?.cpu_cores ?? 0);
326
+ const disk = Number(rr?.disk_space_mb ?? 0);
327
+ if ((Number.isFinite(memory) && memory > 8192) || (Number.isFinite(cpu) && cpu > 8) || (Number.isFinite(disk) && disk > 512000)) {
328
+ this.securityThreatCount++;
329
+ const te = { contract_id: request.contract_id || `preflight-${Date.now()}`, threat_detected: true, threat_type: 'abuse_pattern', severity: 'critical', description: 'Resource requirements indicate possible abuse or exhaustion attempt.', action: 'block', timestamp: new Date().toISOString() };
330
+ this.securityThreatEvents.push(te);
331
+ this.emit('security_threat_detected', te);
332
+ throw new Error('Security threat detected: abuse_pattern');
333
+ }
334
+ }
335
+ // ── SecurityMiddlewareChain ────────────────────────────────────────────
336
+ const rawTlp = request.tlp_classification || legacyRequest?.tlp_classification;
337
+ const tlpLevel = rawTlp ? rawTlp.replace('TLP:', '') : undefined;
338
+ const context = {
339
+ operation: 'create',
340
+ contract: {
341
+ contract_id: request.contract_id,
342
+ delegator: request.delegator,
343
+ delegatee: request.delegatee,
344
+ delegation_depth: 0,
345
+ tlp_classification: tlpLevel,
346
+ permission_tokens: normalizedPermissionTokens,
347
+ parent_contract_id: request.parent_contract_id,
348
+ // Expose these fields so ThreatValidatorMiddleware can run its full checks
349
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
350
+ ...(legacyRequest?.resource_requirements ? { resource_requirements: legacyRequest.resource_requirements } : {}),
351
+ metadata: legacyRequest?.metadata,
352
+ },
353
+ // Provide auth fields so IdentityMiddleware can verify signatures
354
+ delegator_auth: request.delegator,
355
+ delegatee_auth: request.delegatee,
356
+ task_content: legacyRequest?.task_content ??
357
+ (request.task_description ? { instruction: request.task_description } : undefined),
358
+ metadata: legacyRequest?.metadata,
359
+ timestamp_ms: Date.now(),
360
+ // Enable core security gates by default; callers may override via metadata
361
+ feature_flags: {
362
+ security_monitoring: true,
363
+ chain_tracking: true,
364
+ identity_auth: !!(this.agentRegistry),
365
+ content_security: true,
366
+ reputation_tracking: !!(this.reputationEngine),
367
+ ...(legacyRequest?.feature_flags ?? {}),
368
+ },
369
+ };
370
+ const chainResult = await this.securityChain.evaluate(context);
371
+ if (chainResult.action === 'block') {
372
+ this.securityThreatCount++;
373
+ const bv = chainResult.blocking_verdict;
374
+ const threatEvent = {
375
+ contract_id: request.contract_id || request.task_id || `preflight-${Date.now()}`,
376
+ threat_detected: true,
377
+ threat_type: bv.threat_type ?? 'security_chain_block',
378
+ severity: bv.severity ?? 'critical',
379
+ description: bv.reason ?? 'Security middleware chain blocked this contract.',
380
+ action: 'block',
381
+ timestamp: new Date().toISOString(),
382
+ blocked_by: chainResult.blocked_by,
383
+ evidence: bv.evidence,
384
+ };
385
+ this.securityThreatEvents.push(threatEvent);
386
+ this.emit('security_threat_detected', threatEvent);
387
+ throw new Error(`Security threat detected: ${bv.threat_type ?? 'security_chain_block'}`);
388
+ }
389
+ }
390
+ /**
391
+ * Create a new delegation contract
392
+ */
393
+ async createContract(request) {
394
+ const legacyRequest = request;
395
+ const { delegator: normalizedDelegator, delegatee: normalizedDelegatee } = this.normalizeContractAgents(request, legacyRequest);
396
+ const normalizedTaskDescription = this.sanitizeTaskDescription(request.task_description || legacyRequest?.description || request.task_id || 'Delegated task');
397
+ const normalizedTimeout = request.timeout_ms ?? legacyRequest?.timeout_ms ?? 30000;
398
+ const normalizedSuccessCriteria = Array.isArray(request.success_criteria)
399
+ ? { required_checks: request.success_criteria }
400
+ : (request.success_criteria || {});
401
+ const rawVerificationPolicy = request.verification_policy || legacyRequest?.verification_policy || 'direct_inspection';
402
+ const normalizedVerificationPolicy = this.normalizeVerificationPolicy(rawVerificationPolicy);
403
+ const normalizedPermissionTokens = request.permission_tokens ||
404
+ (legacyRequest?.permission_token && typeof legacyRequest.permission_token === 'object' && !Array.isArray(legacyRequest.permission_token)
405
+ ? [{
406
+ token_id: legacyRequest.permission_token.token_id ?? '',
407
+ scopes: legacyRequest.permission_token.scopes || [],
408
+ delegatable: legacyRequest.permission_token.delegatable ?? false,
409
+ max_delegation_depth: legacyRequest.permission_token.max_delegation_depth ?? 0,
410
+ }]
411
+ : undefined);
412
+ await this.validateContractSecurity(request, legacyRequest, normalizedPermissionTokens);
413
+ // Use explicit contract_id if provided (for testing), otherwise generate
414
+ const contract_id = request.contract_id || `contract-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
415
+ const created_at = request.created_at || new Date().toISOString();
416
+ const status = request.status || 'pending';
417
+ // Cache agent names for later retrieval
418
+ this.agentNames.set(normalizedDelegator.agent_id, normalizedDelegator.agent_name);
419
+ this.agentNames.set(normalizedDelegatee.agent_id, normalizedDelegatee.agent_name);
420
+ // Calculate delegation depth
421
+ let delegation_depth = 0;
422
+ if (request.parent_contract_id) {
423
+ const parent = this.getContractById(request.parent_contract_id);
424
+ if (parent) {
425
+ delegation_depth = (parent.delegation_depth ?? 0) + 1;
426
+ }
427
+ }
428
+ // 6.2: Blast radius check — cap contract-creation rate per root delegator tree
429
+ const rootDelegatorId = this.getRootDelegatorId(request.parent_contract_id ?? null, normalizedDelegator.agent_id);
430
+ const blastCheck = this.blastRadiusTracker.check(rootDelegatorId);
431
+ if (!blastCheck.allowed) {
432
+ throw new Error(`Blast radius limit exceeded for root delegator '${rootDelegatorId}': ` +
433
+ `${blastCheck.currentCount}/${blastCheck.limit} contracts in the current window`);
434
+ }
435
+ // Insert contract
436
+ const stmt = this.db.prepare(`
437
+ INSERT INTO delegation_contracts (
438
+ contract_id, delegator_agent_id, delegatee_agent_id,
439
+ task_id, task_description, verification_policy,
440
+ success_criteria, timeout_ms, priority, permission_tokens,
441
+ metadata, parent_contract_id, delegation_depth, tlp_classification,
442
+ status, created_at
443
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
444
+ `);
445
+ // Store execution mode and session ID in metadata (backward-compatible, no schema migration needed)
446
+ const executionMode = request.execution_mode ?? ExecutionMode.INTERACTIVE;
447
+ const sessionId = request.session_id ?? (executionMode !== ExecutionMode.INTERACTIVE
448
+ ? `session-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
449
+ : undefined);
450
+ const initialMetadata = {
451
+ // 8.4: always persist execution_mode so DelegationContract.execution_mode is never derived from default
452
+ execution_mode: executionMode,
453
+ };
454
+ if (sessionId) {
455
+ initialMetadata['session_id'] = sessionId;
456
+ }
457
+ stmt.run(contract_id, normalizedDelegator.agent_id, normalizedDelegatee.agent_id, request.task_id, normalizedTaskDescription, normalizedVerificationPolicy, JSON.stringify(normalizedSuccessCriteria), normalizedTimeout, request.priority ?? 3, normalizedPermissionTokens ? JSON.stringify(normalizedPermissionTokens) : null, Object.keys(initialMetadata).length > 0 ? JSON.stringify(initialMetadata) : null, request.parent_contract_id ?? null, delegation_depth, request.tlp_classification ?? 'TLP:CLEAR', status, created_at);
458
+ const contract = this.getContractById(contract_id);
459
+ // Emit event
460
+ this.emit('contract_created', contract);
461
+ // 6.2: Record contract in blast radius tracker
462
+ this.blastRadiusTracker.record(rootDelegatorId);
463
+ // Track fan-out counter for the delegator
464
+ if (request.parent_contract_id) {
465
+ this.chainDepthMiddleware.incrementFanOut(normalizedDelegator.agent_id);
466
+ }
467
+ // Register contract with timeout watchdog
468
+ this.watchdog.track({
469
+ contract_id,
470
+ created_at,
471
+ timeout_ms: normalizedTimeout,
472
+ status,
473
+ });
474
+ if (this.debug) {
475
+ console.log(`[ContractManager] Created contract ${contract_id}`);
476
+ }
477
+ return contract;
478
+ }
479
+ /**
480
+ * Query contracts with filters
481
+ */
482
+ /** Add status condition (array or single value) */
483
+ addStatusCondition(status, conditions, params) {
484
+ if (!status)
485
+ return;
486
+ if (Array.isArray(status)) {
487
+ conditions.push(`status IN (${status.map(() => '?').join(',')})`);
488
+ params.push(...status);
489
+ }
490
+ else {
491
+ conditions.push('status = ?');
492
+ params.push(status);
493
+ }
494
+ }
495
+ /** Append ORDER BY / LIMIT / OFFSET clauses */
496
+ appendQueryTail(query, options, params) {
497
+ if (options.sort_by) {
498
+ query += ` ORDER BY ${options.sort_by} ${options.sort_order === 'asc' ? 'ASC' : 'DESC'}`;
499
+ }
500
+ if (options.limit !== undefined) {
501
+ query += ' LIMIT ?';
502
+ params.push(options.limit);
503
+ }
504
+ if (options.offset !== undefined) {
505
+ if (options.limit === undefined)
506
+ query += ' LIMIT -1';
507
+ query += ' OFFSET ?';
508
+ params.push(options.offset);
509
+ }
510
+ return query;
511
+ }
512
+ /** Build WHERE clause and params from query options */
513
+ buildQueryFromOptions(options) {
514
+ const conditions = [];
515
+ const params = [];
516
+ const delegatorId = options.delegator_agent_id ?? options.delegator_id;
517
+ const delegateeId = options.delegatee_agent_id ?? options.delegatee_id;
518
+ if (delegatorId) {
519
+ conditions.push('delegator_agent_id = ?');
520
+ params.push(delegatorId);
521
+ }
522
+ if (delegateeId) {
523
+ conditions.push('delegatee_agent_id = ?');
524
+ params.push(delegateeId);
525
+ }
526
+ if (options.task_id) {
527
+ conditions.push('task_id = ?');
528
+ params.push(options.task_id);
529
+ }
530
+ this.addStatusCondition(options.status, conditions, params);
531
+ if (options.delegation_depth !== undefined) {
532
+ conditions.push('delegation_depth = ?');
533
+ params.push(options.delegation_depth);
534
+ }
535
+ if (options.parent_contract_id) {
536
+ conditions.push('parent_contract_id = ?');
537
+ params.push(options.parent_contract_id);
538
+ }
539
+ if (options.priority !== undefined) {
540
+ conditions.push('priority = ?');
541
+ params.push(options.priority);
542
+ }
543
+ let query = 'SELECT * FROM delegation_contracts';
544
+ if (conditions.length > 0)
545
+ query += ' WHERE ' + conditions.join(' AND ');
546
+ query = this.appendQueryTail(query, options, params);
547
+ return { query, params };
548
+ }
549
+ queryContracts(options = {}) {
550
+ const { query, params } = this.buildQueryFromOptions(options);
551
+ const rows = this.db.prepare(query).all(...params);
552
+ return rows.map(row => this.rowToContract(row));
553
+ }
554
+ /** Build SQL fields/params for an updateContract call */
555
+ buildUpdateFields(updates) {
556
+ const fields = [];
557
+ const params = [];
558
+ if (updates.status) {
559
+ fields.push('status = ?');
560
+ params.push(updates.status);
561
+ if (updates.status === 'active' && !updates.activated_at) {
562
+ fields.push('activated_at = ?');
563
+ params.push(new Date().toISOString());
564
+ }
565
+ if ((updates.status === 'completed' || updates.status === 'revoked') && !updates.completed_at) {
566
+ fields.push('completed_at = ?');
567
+ params.push(new Date().toISOString());
568
+ }
569
+ }
570
+ if (updates.activated_at) {
571
+ fields.push('activated_at = ?');
572
+ params.push(updates.activated_at);
573
+ }
574
+ if (updates.completed_at) {
575
+ fields.push('completed_at = ?');
576
+ params.push(updates.completed_at);
577
+ }
578
+ if (updates.verification_result) {
579
+ fields.push('verification_result = ?');
580
+ params.push(JSON.stringify(updates.verification_result));
581
+ }
582
+ if (updates.metadata) {
583
+ fields.push('metadata = ?');
584
+ params.push(JSON.stringify(updates.metadata));
585
+ }
586
+ return { fields, params };
587
+ }
588
+ /**
589
+ * Update contract status and metadata.
590
+ * Accepts a single object with contract_id and fields to update.
591
+ * Automatically sets activated_at when status='active' and completed_at when status='completed'.
592
+ */
593
+ async updateContract(updates) {
594
+ const { contract_id } = updates;
595
+ const existing = this.getContractById(contract_id);
596
+ if (!existing) {
597
+ throw new Error(`Contract not found: ${contract_id}`);
598
+ }
599
+ // 2.4: Caller ownership check
600
+ if (updates.caller_id) {
601
+ const isOwner = existing.delegator.agent_id === updates.caller_id ||
602
+ existing.delegatee.agent_id === updates.caller_id;
603
+ if (!isOwner) {
604
+ throw new Error(`Unauthorized: agent '${updates.caller_id}' is not the delegator or delegatee of contract '${contract_id}'`);
605
+ }
606
+ }
607
+ // 1.5: Run security chain (FeatureFlags + Identity) for update operations.
608
+ // Heavy create-only middleware (TLP, ThreatValidator, etc.) are skipped via appliesTo.
609
+ const updateContext = {
610
+ operation: 'update',
611
+ contract: {
612
+ contract_id: existing.contract_id,
613
+ delegator: existing.delegator,
614
+ delegatee: existing.delegatee,
615
+ },
616
+ timestamp_ms: Date.now(),
617
+ feature_flags: { identity_auth: !!(this.agentRegistry) },
618
+ };
619
+ const updateResult = await this.securityChain.evaluate(updateContext);
620
+ if (updateResult.action === 'block') {
621
+ const bv = updateResult.blocking_verdict;
622
+ throw new Error(`Security check failed for contract update: ${bv.reason ?? bv.threat_type}`);
623
+ }
624
+ // 5.1: State machine — once a contract reaches a terminal state it cannot be changed
625
+ const terminalStates = new Set(['completed', 'failed', 'cancelled', 'revoked', 'timeout']);
626
+ if (updates.status && terminalStates.has(existing.status)) {
627
+ throw new Error(`Invalid state transition: ${existing.status} → ${updates.status} (terminal state cannot be changed)`);
628
+ }
629
+ // 4.6: Non-empty output validation — reject completion without verification_result
630
+ if (updates.status === 'completed' && !updates.verification_result) {
631
+ throw new Error('Cannot complete contract without verification_result');
632
+ }
633
+ // 6.5: Quarantine on failed verification or quality below threshold
634
+ if (updates.status === 'completed' && updates.verification_result) {
635
+ const vr = updates.verification_result;
636
+ const qualityFail = typeof vr.quality_score === 'number' && vr.quality_score < 0.7;
637
+ if (vr.verified === false || qualityFail) {
638
+ const quarantineReason = vr.verified === false ? 'verification_failed' : 'quality_below_threshold';
639
+ return this.updateContract({
640
+ contract_id,
641
+ status: 'failed',
642
+ verification_result: vr,
643
+ metadata: { ...(existing.metadata ?? {}), quarantined: true, quarantine_reason: quarantineReason },
644
+ });
645
+ }
646
+ }
647
+ const { fields, params } = this.buildUpdateFields(updates);
648
+ if (fields.length === 0) {
649
+ return existing;
650
+ }
651
+ params.push(contract_id);
652
+ const query = `UPDATE delegation_contracts SET ${fields.join(', ')} WHERE contract_id = ?`;
653
+ this.db.prepare(query).run(...params);
654
+ const contract = this.getContractById(contract_id);
655
+ if (!contract) {
656
+ throw new Error(`Contract not found: ${contract_id}`);
657
+ }
658
+ // Emit events based on status
659
+ if (updates.status === 'completed') {
660
+ this.emit('contract_completed', contract);
661
+ }
662
+ else if (updates.status === 'failed') {
663
+ this.emit('contract_failed', contract);
664
+ }
665
+ else if (updates.status === 'revoked') {
666
+ this.emit('contract_revoked', contract);
667
+ }
668
+ else if (updates.status === 'cancelled') {
669
+ this.emit('contract_cancelled', contract);
670
+ }
671
+ else if (updates.status === 'timeout') {
672
+ this.emit('contract_timeout_fired', contract);
673
+ }
674
+ // 6.3: Cascading revocation — when a contract is revoked, revoke all non-terminal children
675
+ if (updates.status === 'revoked') {
676
+ const terminalSet = new Set(['completed', 'failed', 'cancelled', 'revoked', 'timeout']);
677
+ const children = this.queryContracts({ parent_contract_id: contract_id });
678
+ for (const child of children) {
679
+ if (!terminalSet.has(child.status)) {
680
+ await this.updateContract({ contract_id: child.contract_id, status: 'revoked' });
681
+ }
682
+ }
683
+ }
684
+ // On terminal status: release fan-out slot + untrack from watchdog
685
+ const terminalStatuses = ['completed', 'failed', 'cancelled', 'revoked', 'timeout'];
686
+ if (updates.status && terminalStatuses.includes(updates.status)) {
687
+ if (contract.parent_contract_id) {
688
+ this.chainDepthMiddleware.decrementFanOut(contract.delegator.agent_id);
689
+ }
690
+ this.watchdog.untrack(contract_id);
691
+ // Record circuit breaker outcome
692
+ if (updates.status === 'completed') {
693
+ this.circuitBreaker.recordSuccess(contract.delegatee.agent_id);
694
+ }
695
+ else if (updates.status === 'failed') {
696
+ this.circuitBreaker.recordFailure(contract.delegatee.agent_id);
697
+ }
698
+ }
699
+ if (this.debug) {
700
+ console.log(`[ContractManager] Updated contract ${contract_id}: status=${updates.status}`);
701
+ }
702
+ return contract;
703
+ }
704
+ /**
705
+ * Soft delete (revoke) a contract
706
+ */
707
+ async deleteContract(contract_id, reason) {
708
+ const contract = this.getContractById(contract_id);
709
+ if (!contract) {
710
+ throw new Error(`Contract not found: ${contract_id}`);
711
+ }
712
+ await this.updateContract({
713
+ contract_id,
714
+ status: 'revoked',
715
+ });
716
+ if (this.debug) {
717
+ console.log(`[ContractManager] Deleted contract ${contract_id}: ${reason ?? 'no reason'}`);
718
+ }
719
+ }
720
+ /**
721
+ * Update contract status (convenience method)
722
+ */
723
+ async updateContractStatus(contract_id, status, options) {
724
+ const updates = { contract_id, status };
725
+ // Add verification_result if provided
726
+ if (options?.verification_result) {
727
+ updates.verification_result = options.verification_result;
728
+ }
729
+ // Merge metadata if provided
730
+ if (options?.metadata) {
731
+ // Get existing contract to merge metadata
732
+ const existing = this.getContractById(contract_id);
733
+ const existingMetadata = existing?.metadata || {};
734
+ updates.metadata = { ...existingMetadata, ...options.metadata };
735
+ }
736
+ return this.updateContract(updates);
737
+ }
738
+ /**
739
+ * Cancel a contract (convenience method for cancellation)
740
+ */
741
+ async cancelContract(contract_id, reason) {
742
+ const contract = this.getContractById(contract_id);
743
+ if (!contract) {
744
+ throw new Error(`Contract not found: ${contract_id}`);
745
+ }
746
+ await this.updateContract({
747
+ contract_id,
748
+ status: 'cancelled',
749
+ metadata: reason ? { cancellation_reason: reason } : undefined,
750
+ });
751
+ if (this.debug) {
752
+ console.log(`[ContractManager] Cancelled contract ${contract_id}: ${reason ?? 'no reason'}`);
753
+ }
754
+ }
755
+ /**
756
+ * Send a heartbeat for a long-running active contract.
757
+ * Extends the timeout watchdog deadline by `heartbeatGraceMs` (default 30 s).
758
+ * The contract's `last_heartbeat_at` is recorded in metadata.
759
+ *
760
+ * @param contract_id - The active contract to keep alive.
761
+ */
762
+ async heartbeat(contract_id) {
763
+ const contract = this.getContractById(contract_id);
764
+ if (!contract)
765
+ throw new Error(`Contract not found: ${contract_id}`);
766
+ if (contract.status !== 'active')
767
+ throw new Error(`Contract ${contract_id} is not active (status: ${contract.status})`);
768
+ const now = new Date().toISOString();
769
+ const metadata = { ...(contract.metadata ?? {}), last_heartbeat_at: now };
770
+ await this.updateContract({ contract_id, metadata });
771
+ this.watchdog.heartbeat(contract_id);
772
+ }
773
+ /**
774
+ * Get a single contract by ID
775
+ */
776
+ getContract(contract_id) {
777
+ const row = this.db
778
+ .prepare('SELECT * FROM delegation_contracts WHERE contract_id = ?')
779
+ .get(contract_id);
780
+ return row ? this.rowToContract(row) : null;
781
+ }
782
+ /**
783
+ * Get contract by ID (alias for getContract)
784
+ */
785
+ getContractById(contract_id) {
786
+ return this.getContract(contract_id);
787
+ }
788
+ /**
789
+ * Get active contracts for an agent
790
+ */
791
+ getActiveContracts(agent_id) {
792
+ return this.queryContracts({
793
+ delegatee_agent_id: agent_id,
794
+ status: ['pending', 'active'],
795
+ });
796
+ }
797
+ /**
798
+ * Get contract statistics
799
+ */
800
+ getStatistics(agent_id) {
801
+ let query = `
802
+ SELECT
803
+ COUNT(*) as total,
804
+ SUM(CASE WHEN status IN ('active', 'pending') THEN 1 ELSE 0 END) as active,
805
+ SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed,
806
+ SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed
807
+ FROM delegation_contracts
808
+ `;
809
+ const params = [];
810
+ if (agent_id) {
811
+ query += ' WHERE delegatee_agent_id = ?';
812
+ params.push(agent_id);
813
+ }
814
+ const stats = this.db.prepare(query).get(...params);
815
+ const total = stats?.total || 0;
816
+ const completed = stats?.completed || 0;
817
+ const failed = stats?.failed || 0;
818
+ const decidedTotal = completed + failed;
819
+ return {
820
+ total,
821
+ active: stats?.active || 0,
822
+ completed,
823
+ failed,
824
+ success_rate: decidedTotal > 0
825
+ ? completed / decidedTotal
826
+ : 0,
827
+ };
828
+ }
829
+ /**
830
+ * Close database connection
831
+ */
832
+ close() {
833
+ this.db.close();
834
+ }
835
+ /**
836
+ * Clear all contracts (for testing)
837
+ */
838
+ clearAll() {
839
+ this.db.prepare('DELETE FROM delegation_contracts').run();
840
+ // Safely attempt to clear audit log if it exists
841
+ try {
842
+ this.db.prepare('DELETE FROM reputation_audit_log').run();
843
+ }
844
+ catch {
845
+ // Table may not exist
846
+ }
847
+ }
848
+ /**
849
+ * Get total contract count (legacy compatibility helper)
850
+ */
851
+ getContractCount() {
852
+ const row = this.db.prepare('SELECT COUNT(*) as count FROM delegation_contracts').get();
853
+ return row?.count ?? 0;
854
+ }
855
+ /**
856
+ * Get security threat statistics (legacy compatibility helper)
857
+ */
858
+ getSecurityThreatStatistics() {
859
+ const threat_types = {};
860
+ const severity_distribution = {};
861
+ const action_distribution = {};
862
+ for (const threat of this.securityThreatEvents) {
863
+ const type = String(threat.threat_type || 'unknown');
864
+ const severity = String(threat.severity || 'warning');
865
+ const action = String(threat.action || 'block');
866
+ threat_types[type] = (threat_types[type] || 0) + 1;
867
+ severity_distribution[severity] = (severity_distribution[severity] || 0) + 1;
868
+ action_distribution[action] = (action_distribution[action] || 0) + 1;
869
+ }
870
+ return {
871
+ total_validations: this.securityValidationCount,
872
+ threats_detected: this.securityThreatCount,
873
+ threat_types,
874
+ severity_distribution,
875
+ action_distribution,
876
+ };
877
+ }
878
+ /**
879
+ * Get recent security threats (legacy compatibility helper)
880
+ */
881
+ getRecentSecurityThreats(limit = 10) {
882
+ return this.securityThreatEvents.slice(-limit).reverse();
883
+ }
884
+ /** Build security recommendations based on threat statistics */
885
+ buildSecurityRecommendations(stats, threatRate) {
886
+ const recommendations = [];
887
+ if (stats.threats_detected > 0) {
888
+ recommendations.push('Review and audit blocked delegation contracts for threat patterns.');
889
+ }
890
+ if (threatRate > 0.25) {
891
+ recommendations.push('Threat detection rate is elevated; consider tightening delegation policies.');
892
+ }
893
+ if (recommendations.length === 0) {
894
+ recommendations.push('Maintain periodic security review of delegation contracts and policies.');
895
+ }
896
+ return recommendations;
897
+ }
898
+ /**
899
+ * Get security status summary (legacy compatibility helper)
900
+ */
901
+ getSecurityStatus() {
902
+ const stats = this.getSecurityThreatStatistics();
903
+ const totalContracts = this.getContractCount();
904
+ const threatRate = stats.total_validations > 0 ? stats.threats_detected / stats.total_validations : 0;
905
+ return {
906
+ tlp_enforcement_enabled: true,
907
+ security_threat_validation_enabled: true,
908
+ contract_security_summary: {
909
+ total_contracts: totalContracts,
910
+ security_validations_performed: stats.total_validations,
911
+ threats_detected: stats.threats_detected,
912
+ threat_detection_rate: threatRate,
913
+ threat_types: stats.threat_types,
914
+ severity_distribution: stats.severity_distribution,
915
+ action_distribution: stats.action_distribution,
916
+ },
917
+ recent_security_events: this.getRecentSecurityThreats(10),
918
+ security_recommendations: this.buildSecurityRecommendations(stats, threatRate),
919
+ };
920
+ }
921
+ // ─────────────────────────────────────────────────────────────────────────
922
+ // Execution Mode: Phase 3 – Selection, Lifecycle Hooks, Handoff
923
+ // ─────────────────────────────────────────────────────────────────────────
924
+ /**
925
+ * Select the execution mode for a delegation request using a 4-tier priority:
926
+ *
927
+ * 1. **Explicit** — `request.execution_mode` field (highest priority)
928
+ * 2. **OpenSpec hint** — `request.metadata?.openspec_execution_mode`
929
+ * 3. **Agent manifest preference** — `delegateeManifest.preferred_execution_mode`
930
+ * 4. **Default** — `ExecutionMode.INTERACTIVE`
931
+ *
932
+ * In addition, the selected mode must be in the agent's `supported_execution_modes`
933
+ * (when declared), and background mode requires available queue capacity.
934
+ *
935
+ * @returns The resolved `ExecutionMode`.
936
+ */
937
+ selectExecutionMode(request, delegateeManifest) {
938
+ const supportedModes = delegateeManifest
939
+ ? new Set(delegateeManifest.supported_execution_modes) // 8.5: always present
940
+ : new Set(Object.values(ExecutionMode)); // no manifest — all modes allowed
941
+ const supportsMode = (m) => supportedModes.has(m);
942
+ // Tier 1: Explicit override
943
+ if (request.execution_mode && supportsMode(request.execution_mode)) {
944
+ return this._applyQueueGuard(request.execution_mode);
945
+ }
946
+ // Tier 2: OpenSpec hint stored in metadata
947
+ const openspecHint = request.metadata?.openspec_execution_mode;
948
+ if (openspecHint && Object.values(ExecutionMode).includes(openspecHint) && supportsMode(openspecHint)) {
949
+ return this._applyQueueGuard(openspecHint);
950
+ }
951
+ // Tier 3: Agent manifest preference
952
+ const manifestPref = delegateeManifest?.preferred_execution_mode;
953
+ if (manifestPref && supportsMode(manifestPref)) {
954
+ return this._applyQueueGuard(manifestPref);
955
+ }
956
+ // Tier 4: Default
957
+ return ExecutionMode.INTERACTIVE;
958
+ }
959
+ /**
960
+ * Degrade BACKGROUND → INTERACTIVE when the queue is at capacity.
961
+ * @private
962
+ */
963
+ _applyQueueGuard(mode) {
964
+ if (mode === ExecutionMode.BACKGROUND && !this.backgroundQueue.hasCapacity()) {
965
+ this.emit('background_queue_full', this.backgroundQueue.getStatus());
966
+ return ExecutionMode.INTERACTIVE;
967
+ }
968
+ return mode;
969
+ }
970
+ /**
971
+ * 7.3 — Rank a list of candidate agent IDs by their reputation reliability_score,
972
+ * highest first. Falls back to the original order when the reputation engine is
973
+ * unavailable or when `featureFlags.reputation_tracking === false`.
974
+ */
975
+ async rankCandidatesByReputation(agentIds, featureFlags) {
976
+ if (!this.reputationEngine || featureFlags?.reputation_tracking === false) {
977
+ return agentIds;
978
+ }
979
+ const scored = await Promise.all(agentIds.map(async (id) => {
980
+ const rep = await this.reputationEngine.getReputation(id);
981
+ return { id, score: rep?.reliability_score ?? 0.5 };
982
+ }));
983
+ return scored.sort((a, b) => b.score - a.score).map((e) => e.id);
984
+ }
985
+ /**
986
+ * Get the current background session queue status.
987
+ */
988
+ getBackgroundQueueStatus() {
989
+ return this.backgroundQueue.getStatus();
990
+ }
991
+ /**
992
+ * Expose the session manager for external lifecycle queries.
993
+ */
994
+ getSessionManager() {
995
+ return this.sessionManager;
996
+ }
997
+ /**
998
+ * Expose the session checkpoint manager.
999
+ */
1000
+ getCheckpoint() {
1001
+ return this.checkpoint;
1002
+ }
1003
+ /**
1004
+ * 8.1 — Expose the optional health monitor so callers can start/stop monitoring
1005
+ * and retrieve live metrics.
1006
+ */
1007
+ getHealthMonitor() {
1008
+ return this.healthMonitor;
1009
+ }
1010
+ // ─────────── Lifecycle Hooks ───────────
1011
+ /**
1012
+ * **Phase 3.2 / 3.4** — Must be called after creating a BACKGROUND contract.
1013
+ * - Acquires a background queue slot (waits if at capacity)
1014
+ * - Registers the session in the session manager
1015
+ * - Optionally records the worktree path returned by `worktree-coordinator`
1016
+ *
1017
+ * Emits: `session.created`
1018
+ */
1019
+ async beforeBackgroundExecution(contractId, sessionId, worktreePath) {
1020
+ // Acquire queue slot
1021
+ await this.backgroundQueue.acquire(sessionId, contractId);
1022
+ // Persist session_id into contract metadata so handoffSession can resolve it
1023
+ try {
1024
+ const existing = this.getContractById(contractId);
1025
+ if (existing) {
1026
+ const updatedMetadata = { ...existing.metadata, session_id: sessionId };
1027
+ await this.updateContract({ contract_id: contractId, metadata: updatedMetadata });
1028
+ }
1029
+ }
1030
+ catch {
1031
+ // Non-fatal — handoff will fall back gracefully
1032
+ }
1033
+ // Register session
1034
+ const sessionState = {
1035
+ status: 'active',
1036
+ conversationMessages: [],
1037
+ lastActivity: new Date().toISOString(),
1038
+ ...(worktreePath !== undefined && { worktreePath }),
1039
+ };
1040
+ this.sessionManager.register(sessionId, contractId, ExecutionMode.BACKGROUND, sessionState);
1041
+ this.emit('session.created', { sessionId, contractId, mode: ExecutionMode.BACKGROUND, worktreePath });
1042
+ }
1043
+ /**
1044
+ * **Phase 3.2 / 3.4** — Must be called when a BACKGROUND contract completes.
1045
+ * - Releases the background queue slot
1046
+ * - Archives the session
1047
+ *
1048
+ * Emits: `session.archived`
1049
+ */
1050
+ afterBackgroundExecution(contractId, sessionId) {
1051
+ this.backgroundQueue.release(sessionId);
1052
+ try {
1053
+ this.sessionManager.archive(sessionId);
1054
+ }
1055
+ catch {
1056
+ // Session may have already been archived via handoff — safe to ignore
1057
+ }
1058
+ this.emit('session.archived', { sessionId, contractId, mode: ExecutionMode.BACKGROUND });
1059
+ }
1060
+ /**
1061
+ * **Phase 3.5** — Must be called after creating an ASYNC contract.
1062
+ * - Registers the session in the session manager
1063
+ * - Optionally records the feature branch name
1064
+ *
1065
+ * Emits: `session.created`
1066
+ */
1067
+ beforeAsyncExecution(contractId, sessionId, branchName) {
1068
+ const sessionState = {
1069
+ status: 'active',
1070
+ conversationMessages: [],
1071
+ lastActivity: new Date().toISOString(),
1072
+ };
1073
+ this.sessionManager.register(sessionId, contractId, ExecutionMode.ASYNC, sessionState);
1074
+ this.emit('session.created', { sessionId, contractId, mode: ExecutionMode.ASYNC, branchName });
1075
+ }
1076
+ /**
1077
+ * **Phase 3.5** — Must be called when an ASYNC contract completes.
1078
+ * - Archives the session
1079
+ * - Optionally records the PR number in session metadata before archiving
1080
+ *
1081
+ * Emits: `session.archived`
1082
+ */
1083
+ afterAsyncExecution(contractId, sessionId, prNumber) {
1084
+ // Record PR number in session state before archiving
1085
+ if (prNumber !== undefined) {
1086
+ try {
1087
+ this.sessionManager.updateState(sessionId, { prNumber });
1088
+ }
1089
+ catch {
1090
+ // Session may not be registered — no-op
1091
+ }
1092
+ }
1093
+ try {
1094
+ this.sessionManager.archive(sessionId);
1095
+ }
1096
+ catch {
1097
+ // Already archived — safe to ignore
1098
+ }
1099
+ this.emit('session.archived', { sessionId, contractId, mode: ExecutionMode.ASYNC, prNumber });
1100
+ }
1101
+ // ─────────── Session Handoff ───────────
1102
+ /**
1103
+ * **Phase 3.6** — Perform an atomic session handoff between execution modes.
1104
+ *
1105
+ * Steps (all-or-nothing; rolls back on failure):
1106
+ * 1. Create a `pre-handoff` checkpoint of the current session state
1107
+ * 2. Create a new contract in the target execution mode
1108
+ * 3. Archive the original session
1109
+ * 4. Emit `session.handoff`
1110
+ *
1111
+ * @param request - Source contract ID, target mode, context snapshot, and reason
1112
+ * @returns The newly created contract (in the target mode)
1113
+ * @throws If the source contract does not exist or the new contract cannot be created
1114
+ */
1115
+ async handoffSession(request) {
1116
+ const { fromContractId, toExecutionMode, contextSnapshot, handoffReason } = request;
1117
+ // 1. Load source contract
1118
+ const sourceContract = this.getContractById(fromContractId);
1119
+ if (!sourceContract) {
1120
+ throw new Error(`handoffSession: source contract not found: ${fromContractId}`);
1121
+ }
1122
+ // 2.5: Delegatee ownership check — only the delegatee may initiate a handoff
1123
+ if (request.caller_id && sourceContract.delegatee.agent_id !== request.caller_id) {
1124
+ throw new Error(`Unauthorized: only delegatee '${sourceContract.delegatee.agent_id}' can initiate handoff from '${fromContractId}'`);
1125
+ }
1126
+ // 1.5: Run security chain (FeatureFlags + Identity) for handoff operations.
1127
+ // Heavy create-only middleware are skipped via appliesTo.
1128
+ const handoffCtx = {
1129
+ operation: 'handoff',
1130
+ contract: {
1131
+ contract_id: sourceContract.contract_id,
1132
+ delegator: sourceContract.delegator,
1133
+ delegatee: sourceContract.delegatee,
1134
+ },
1135
+ timestamp_ms: Date.now(),
1136
+ feature_flags: { identity_auth: !!(this.agentRegistry) },
1137
+ };
1138
+ const handoffResult = await this.securityChain.evaluate(handoffCtx);
1139
+ if (handoffResult.action === 'block') {
1140
+ const bv = handoffResult.blocking_verdict;
1141
+ throw new Error(`Security check failed for handoff: ${bv.reason ?? bv.threat_type}`);
1142
+ }
1143
+ const fromSessionId = sourceContract.session_id
1144
+ ?? this.sessionManager.getActiveSessionForContract(fromContractId)?.sessionId;
1145
+ const fromMode = sourceContract.execution_mode; // 8.4: always present, no fallback needed
1146
+ // 2. Checkpoint current state before handoff
1147
+ const messageCount = Array.isArray(contextSnapshot?.conversationHistory)
1148
+ ? contextSnapshot.conversationHistory.length
1149
+ : 0;
1150
+ let checkpointId;
1151
+ if (fromSessionId) {
1152
+ try {
1153
+ const sessionState = {
1154
+ status: 'active',
1155
+ conversationMessages: contextSnapshot?.conversationHistory ?? [],
1156
+ lastActivity: new Date().toISOString(),
1157
+ };
1158
+ const cp = this.checkpoint.create(fromSessionId, fromContractId, sessionState, 'pre-handoff', messageCount, { toMode: toExecutionMode, reason: handoffReason });
1159
+ checkpointId = cp.id;
1160
+ }
1161
+ catch {
1162
+ // Non-fatal — continue with handoff
1163
+ }
1164
+ }
1165
+ // 3. Create new contract in the target mode
1166
+ let newContract;
1167
+ try {
1168
+ newContract = await this.createContract({
1169
+ delegator: sourceContract.delegator,
1170
+ delegatee: sourceContract.delegatee,
1171
+ task_id: `${sourceContract.task_id}-handoff-${Date.now()}`,
1172
+ task_description: sourceContract.task_description,
1173
+ verification_policy: sourceContract.verification_policy,
1174
+ success_criteria: sourceContract.success_criteria,
1175
+ timeout_ms: sourceContract.timeout_ms,
1176
+ priority: sourceContract.priority,
1177
+ parent_contract_id: fromContractId,
1178
+ tlp_classification: sourceContract.tlp_classification,
1179
+ execution_mode: toExecutionMode,
1180
+ ...(request.newContractOverrides ?? {}),
1181
+ });
1182
+ }
1183
+ catch (err) {
1184
+ // Rollback: restore source contract to active (it was never changed)
1185
+ throw new Error(`handoffSession: failed to create target contract — ${err.message}`);
1186
+ }
1187
+ // 4. Archive original session
1188
+ if (fromSessionId) {
1189
+ try {
1190
+ this.sessionManager.archive(fromSessionId);
1191
+ if (fromMode === ExecutionMode.BACKGROUND) {
1192
+ this.backgroundQueue.release(fromSessionId);
1193
+ }
1194
+ }
1195
+ catch {
1196
+ // Already archived — safe to ignore
1197
+ }
1198
+ }
1199
+ // 5. Record handoff history and emit event
1200
+ const handoffRecord = {
1201
+ fromContractId,
1202
+ toContractId: newContract.contract_id,
1203
+ fromMode,
1204
+ toMode: toExecutionMode,
1205
+ handoffReason,
1206
+ handoffAt: new Date().toISOString(),
1207
+ contextSnapshot: {
1208
+ conversationHistory: contextSnapshot?.conversationHistory ?? [],
1209
+ artifacts: contextSnapshot?.artifacts ?? [],
1210
+ checkpointId,
1211
+ },
1212
+ };
1213
+ this.emit('session.handoff', handoffRecord);
1214
+ return newContract;
1215
+ }
1216
+ /**
1217
+ * Convert database row to DelegationContract
1218
+ */
1219
+ rowToContract(row) {
1220
+ const metadata = row.metadata ? JSON.parse(row.metadata) : {};
1221
+ // Recover execution_mode / session_id stored in metadata (backward-compatible)
1222
+ const executionMode = metadata['execution_mode']
1223
+ ?? ExecutionMode.INTERACTIVE;
1224
+ const sessionId = metadata['session_id'];
1225
+ return {
1226
+ contract_id: row.contract_id,
1227
+ delegator: {
1228
+ agent_id: row.delegator_agent_id,
1229
+ agent_name: this.agentNames.get(row.delegator_agent_id) ?? row.delegator_agent_id,
1230
+ },
1231
+ delegatee: {
1232
+ agent_id: row.delegatee_agent_id,
1233
+ agent_name: this.agentNames.get(row.delegatee_agent_id) ?? row.delegatee_agent_id,
1234
+ },
1235
+ task_id: row.task_id,
1236
+ task_description: row.task_description,
1237
+ verification_policy: row.verification_policy,
1238
+ success_criteria: JSON.parse(row.success_criteria),
1239
+ timeout_ms: row.timeout_ms,
1240
+ priority: row.priority,
1241
+ permission_tokens: row.permission_tokens ? JSON.parse(row.permission_tokens) : undefined,
1242
+ status: row.status,
1243
+ created_at: row.created_at,
1244
+ activated_at: row.activated_at ?? undefined,
1245
+ completed_at: row.completed_at ?? undefined,
1246
+ verification_result: row.verification_result ? JSON.parse(row.verification_result) : undefined,
1247
+ parent_contract_id: row.parent_contract_id ?? undefined,
1248
+ delegation_depth: row.delegation_depth ?? 0,
1249
+ tlp_classification: row.tlp_classification ?? 'CLEAR',
1250
+ execution_mode: executionMode,
1251
+ session_id: sessionId,
1252
+ metadata,
1253
+ };
1254
+ }
1255
+ }
1256
+ // Export aliases for backward compatibility
1257
+ export { DelegationContractManager as ContractManager };
1258
+ //# sourceMappingURL=contract-manager.js.map