@noopolis/daimon 0.1.1 → 0.2.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 (404) hide show
  1. package/README.md +307 -45
  2. package/dist/contracts/attentionContract.d.ts +117 -0
  3. package/dist/contracts/attentionContract.d.ts.map +1 -0
  4. package/dist/contracts/attentionContract.js +14 -0
  5. package/dist/contracts/canonicalJson.d.ts +3 -0
  6. package/dist/contracts/canonicalJson.d.ts.map +1 -0
  7. package/dist/contracts/canonicalJson.js +54 -0
  8. package/dist/contracts/grokWorkerContract.d.ts +74 -0
  9. package/dist/contracts/grokWorkerContract.d.ts.map +1 -0
  10. package/dist/contracts/grokWorkerContract.js +88 -0
  11. package/dist/contracts/organizationRuntimeContract.d.ts +765 -0
  12. package/dist/contracts/organizationRuntimeContract.d.ts.map +1 -0
  13. package/dist/contracts/organizationRuntimeContract.js +121 -0
  14. package/dist/contracts/runtimeContractManifest.d.ts +1615 -0
  15. package/dist/contracts/runtimeContractManifest.d.ts.map +1 -0
  16. package/dist/contracts/runtimeContractManifest.js +181 -0
  17. package/dist/core/credentialRedaction.d.ts +4 -0
  18. package/dist/core/credentialRedaction.d.ts.map +1 -0
  19. package/dist/core/credentialRedaction.js +28 -0
  20. package/dist/core/siblingBuildFreshness.d.ts +21 -0
  21. package/dist/core/siblingBuildFreshness.d.ts.map +1 -0
  22. package/dist/core/siblingBuildFreshness.js +25 -0
  23. package/dist/core/types.d.ts +10 -1
  24. package/dist/core/types.d.ts.map +1 -1
  25. package/dist/examples/exampleCausalId.d.ts +3 -0
  26. package/dist/examples/exampleCausalId.d.ts.map +1 -0
  27. package/dist/examples/exampleCausalId.js +8 -0
  28. package/dist/examples/jungian-play-org.js +3 -2
  29. package/dist/examples/jungian-triad-org.js +3 -2
  30. package/dist/examples/jungianPlayAgent.d.ts +1 -1
  31. package/dist/examples/jungianPlayAgent.d.ts.map +1 -1
  32. package/dist/examples/jungianPlayAgent.js +1 -1
  33. package/dist/examples/jungianProfiles.d.ts +1 -1
  34. package/dist/examples/jungianProfiles.d.ts.map +1 -1
  35. package/dist/examples/jungianTriadProfiles.d.ts +1 -1
  36. package/dist/examples/jungianTriadProfiles.d.ts.map +1 -1
  37. package/dist/examples/pi-agent.js +3 -2
  38. package/dist/examples/pi-memory-org.js +6 -5
  39. package/dist/index.d.ts +1 -0
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +1 -0
  42. package/dist/mcp/toolServer.d.ts +31 -0
  43. package/dist/mcp/toolServer.d.ts.map +1 -0
  44. package/dist/mcp/toolServer.js +145 -0
  45. package/dist/observability/causalEvents.d.ts +118 -0
  46. package/dist/observability/causalEvents.d.ts.map +1 -0
  47. package/dist/observability/causalEvents.js +223 -0
  48. package/dist/observability/controlCausal.d.ts +117 -0
  49. package/dist/observability/controlCausal.d.ts.map +1 -0
  50. package/dist/observability/controlCausal.js +107 -0
  51. package/dist/observability/emitCausalFixture.d.ts +25 -0
  52. package/dist/observability/emitCausalFixture.d.ts.map +1 -0
  53. package/dist/observability/emitCausalFixture.js +98 -0
  54. package/dist/observability/index.d.ts +2 -0
  55. package/dist/observability/index.d.ts.map +1 -1
  56. package/dist/observability/index.js +2 -0
  57. package/dist/observability/orgObserver.d.ts.map +1 -1
  58. package/dist/observability/orgObserver.js +3 -3
  59. package/dist/pi/agyHeadlessResult.d.ts +60 -0
  60. package/dist/pi/agyHeadlessResult.d.ts.map +1 -0
  61. package/dist/pi/agyHeadlessResult.js +95 -0
  62. package/dist/pi/cliChildOutput.d.ts +67 -0
  63. package/dist/pi/cliChildOutput.d.ts.map +1 -0
  64. package/dist/pi/cliChildOutput.js +269 -0
  65. package/dist/pi/cliEngineRun.d.ts +16 -0
  66. package/dist/pi/cliEngineRun.d.ts.map +1 -0
  67. package/dist/pi/cliEngineRun.js +27 -0
  68. package/dist/pi/cliEngineSpawn.d.ts +55 -0
  69. package/dist/pi/cliEngineSpawn.d.ts.map +1 -0
  70. package/dist/pi/cliEngineSpawn.js +164 -0
  71. package/dist/pi/cliEnvironment.d.ts +12 -0
  72. package/dist/pi/cliEnvironment.d.ts.map +1 -0
  73. package/dist/pi/cliEnvironment.js +32 -0
  74. package/dist/pi/cliMcpRegistration.d.ts +61 -0
  75. package/dist/pi/cliMcpRegistration.d.ts.map +1 -0
  76. package/dist/pi/cliMcpRegistration.js +75 -0
  77. package/dist/pi/cliProcess.d.ts +7 -0
  78. package/dist/pi/cliProcess.d.ts.map +1 -0
  79. package/dist/pi/cliProcess.js +132 -0
  80. package/dist/pi/cliSession.d.ts +106 -0
  81. package/dist/pi/cliSession.d.ts.map +1 -0
  82. package/dist/pi/cliSession.js +379 -0
  83. package/dist/pi/cliTurnMetering.d.ts +60 -0
  84. package/dist/pi/cliTurnMetering.d.ts.map +1 -0
  85. package/dist/pi/cliTurnMetering.js +60 -0
  86. package/dist/pi/codexFilesystemRules.d.ts +3 -0
  87. package/dist/pi/codexFilesystemRules.d.ts.map +1 -0
  88. package/dist/pi/codexFilesystemRules.js +28 -0
  89. package/dist/pi/codexHeadlessResult.d.ts +68 -0
  90. package/dist/pi/codexHeadlessResult.d.ts.map +1 -0
  91. package/dist/pi/codexHeadlessResult.js +122 -0
  92. package/dist/pi/codexRolloutUsage.d.ts +95 -0
  93. package/dist/pi/codexRolloutUsage.d.ts.map +1 -0
  94. package/dist/pi/codexRolloutUsage.js +221 -0
  95. package/dist/pi/engineWakeLimits.d.ts +39 -0
  96. package/dist/pi/engineWakeLimits.d.ts.map +1 -0
  97. package/dist/pi/engineWakeLimits.js +55 -0
  98. package/dist/pi/grokHeadlessResult.d.ts +36 -0
  99. package/dist/pi/grokHeadlessResult.d.ts.map +1 -0
  100. package/dist/pi/grokHeadlessResult.js +118 -0
  101. package/dist/pi/grokHomeMcpRegistration.d.ts +21 -0
  102. package/dist/pi/grokHomeMcpRegistration.d.ts.map +1 -0
  103. package/dist/pi/grokHomeMcpRegistration.js +57 -0
  104. package/dist/pi/grokSandbox.d.ts +11 -0
  105. package/dist/pi/grokSandbox.d.ts.map +1 -0
  106. package/dist/pi/grokSandbox.js +216 -0
  107. package/dist/pi/grokStreamUsage.d.ts +31 -0
  108. package/dist/pi/grokStreamUsage.d.ts.map +1 -0
  109. package/dist/pi/grokStreamUsage.js +51 -0
  110. package/dist/pi/index.d.ts +5 -0
  111. package/dist/pi/index.d.ts.map +1 -1
  112. package/dist/pi/index.js +5 -0
  113. package/dist/pi/memoryTools.d.ts +55 -1
  114. package/dist/pi/memoryTools.d.ts.map +1 -1
  115. package/dist/pi/memoryTools.js +144 -24
  116. package/dist/pi/modelRegistry.d.ts +13 -0
  117. package/dist/pi/modelRegistry.d.ts.map +1 -0
  118. package/dist/pi/modelRegistry.js +19 -0
  119. package/dist/pi/piAgentHandle.d.ts +46 -0
  120. package/dist/pi/piAgentHandle.d.ts.map +1 -0
  121. package/dist/pi/piAgentHandle.js +351 -0
  122. package/dist/pi/piAgentWakeSupport.d.ts +103 -0
  123. package/dist/pi/piAgentWakeSupport.d.ts.map +1 -0
  124. package/dist/pi/piAgentWakeSupport.js +151 -0
  125. package/dist/pi/piHarness.d.ts +40 -5
  126. package/dist/pi/piHarness.d.ts.map +1 -1
  127. package/dist/pi/piHarness.js +151 -256
  128. package/dist/pi/prompts.d.ts +10 -0
  129. package/dist/pi/prompts.d.ts.map +1 -0
  130. package/dist/pi/prompts.js +63 -0
  131. package/dist/pi/rawTrainingCapture.d.ts +59 -0
  132. package/dist/pi/rawTrainingCapture.d.ts.map +1 -0
  133. package/dist/pi/rawTrainingCapture.js +175 -0
  134. package/dist/pi/turnCausal.d.ts +73 -0
  135. package/dist/pi/turnCausal.d.ts.map +1 -0
  136. package/dist/pi/turnCausal.js +75 -0
  137. package/dist/pi/turnTrace.d.ts +128 -0
  138. package/dist/pi/turnTrace.d.ts.map +1 -0
  139. package/dist/pi/turnTrace.js +138 -0
  140. package/dist/pi/wakeAcceptance.d.ts +49 -0
  141. package/dist/pi/wakeAcceptance.d.ts.map +1 -0
  142. package/dist/pi/wakeAcceptance.js +281 -0
  143. package/dist/pi/wakeAcceptanceFs.d.ts +44 -0
  144. package/dist/pi/wakeAcceptanceFs.d.ts.map +1 -0
  145. package/dist/pi/wakeAcceptanceFs.js +318 -0
  146. package/dist/pi/wakeAcceptanceSchema.d.ts +75 -0
  147. package/dist/pi/wakeAcceptanceSchema.d.ts.map +1 -0
  148. package/dist/pi/wakeAcceptanceSchema.js +265 -0
  149. package/dist/pi/wakeModes.d.ts +9 -0
  150. package/dist/pi/wakeModes.d.ts.map +1 -0
  151. package/dist/pi/wakeModes.js +19 -0
  152. package/dist/pi/worldNudge.d.ts +22 -0
  153. package/dist/pi/worldNudge.d.ts.map +1 -0
  154. package/dist/pi/worldNudge.js +62 -0
  155. package/dist/pi/worldToolProtocol.d.ts +13 -0
  156. package/dist/pi/worldToolProtocol.d.ts.map +1 -0
  157. package/dist/pi/worldToolProtocol.js +49 -0
  158. package/dist/pi/worldTools.d.ts +32 -0
  159. package/dist/pi/worldTools.d.ts.map +1 -0
  160. package/dist/pi/worldTools.js +373 -0
  161. package/dist/pi/worldTrajectory.d.ts +52 -0
  162. package/dist/pi/worldTrajectory.d.ts.map +1 -0
  163. package/dist/pi/worldTrajectory.js +131 -0
  164. package/dist/runtime/agySubscriptionBootstrap.d.ts +16 -0
  165. package/dist/runtime/agySubscriptionBootstrap.d.ts.map +1 -0
  166. package/dist/runtime/agySubscriptionBootstrap.js +80 -0
  167. package/dist/runtime/agySubscriptionRealm.d.ts +38 -0
  168. package/dist/runtime/agySubscriptionRealm.d.ts.map +1 -0
  169. package/dist/runtime/agySubscriptionRealm.js +242 -0
  170. package/dist/runtime/attention.d.ts +21 -0
  171. package/dist/runtime/attention.d.ts.map +1 -0
  172. package/dist/runtime/attention.js +36 -0
  173. package/dist/runtime/attentionDispatcher.d.ts +66 -0
  174. package/dist/runtime/attentionDispatcher.d.ts.map +1 -0
  175. package/dist/runtime/attentionDispatcher.js +271 -0
  176. package/dist/runtime/cli.d.ts +7 -0
  177. package/dist/runtime/cli.d.ts.map +1 -0
  178. package/dist/runtime/cli.js +251 -0
  179. package/dist/runtime/codexSandboxProjection.d.ts +17 -0
  180. package/dist/runtime/codexSandboxProjection.d.ts.map +1 -0
  181. package/dist/runtime/codexSandboxProjection.js +40 -0
  182. package/dist/runtime/contract-manifest.json +1 -0
  183. package/dist/runtime/contract-manifest.sha256 +1 -0
  184. package/dist/runtime/contractManifest.d.ts +8 -0
  185. package/dist/runtime/contractManifest.d.ts.map +1 -0
  186. package/dist/runtime/contractManifest.js +4 -0
  187. package/dist/runtime/engineBrokerCapabilities.d.ts +30 -0
  188. package/dist/runtime/engineBrokerCapabilities.d.ts.map +1 -0
  189. package/dist/runtime/engineBrokerCapabilities.js +59 -0
  190. package/dist/runtime/engineBrokerControlClient.d.ts +44 -0
  191. package/dist/runtime/engineBrokerControlClient.d.ts.map +1 -0
  192. package/dist/runtime/engineBrokerControlClient.js +132 -0
  193. package/dist/runtime/engineBrokerCredentialJournal.d.ts +10 -0
  194. package/dist/runtime/engineBrokerCredentialJournal.d.ts.map +1 -0
  195. package/dist/runtime/engineBrokerCredentialJournal.js +17 -0
  196. package/dist/runtime/engineBrokerInferenceProtocol.d.ts +52 -0
  197. package/dist/runtime/engineBrokerInferenceProtocol.d.ts.map +1 -0
  198. package/dist/runtime/engineBrokerInferenceProtocol.js +65 -0
  199. package/dist/runtime/engineBrokerMcpCallLog.d.ts +160 -0
  200. package/dist/runtime/engineBrokerMcpCallLog.d.ts.map +1 -0
  201. package/dist/runtime/engineBrokerMcpCallLog.js +219 -0
  202. package/dist/runtime/engineBrokerMcpFacade.d.ts +56 -0
  203. package/dist/runtime/engineBrokerMcpFacade.d.ts.map +1 -0
  204. package/dist/runtime/engineBrokerMcpFacade.js +343 -0
  205. package/dist/runtime/engineBrokerNativeClient.d.ts +52 -0
  206. package/dist/runtime/engineBrokerNativeClient.d.ts.map +1 -0
  207. package/dist/runtime/engineBrokerNativeClient.js +151 -0
  208. package/dist/runtime/engineBrokerProtocol.d.ts +135 -0
  209. package/dist/runtime/engineBrokerProtocol.d.ts.map +1 -0
  210. package/dist/runtime/engineBrokerProtocol.js +274 -0
  211. package/dist/runtime/engineBrokerSealLedger.d.ts +70 -0
  212. package/dist/runtime/engineBrokerSealLedger.d.ts.map +1 -0
  213. package/dist/runtime/engineBrokerSealLedger.js +123 -0
  214. package/dist/runtime/engineBrokerService.d.ts +37 -0
  215. package/dist/runtime/engineBrokerService.d.ts.map +1 -0
  216. package/dist/runtime/engineBrokerService.js +138 -0
  217. package/dist/runtime/engineBrokerServiceCli.d.ts +5 -0
  218. package/dist/runtime/engineBrokerServiceCli.d.ts.map +1 -0
  219. package/dist/runtime/engineBrokerServiceCli.js +32 -0
  220. package/dist/runtime/engineBrokerServiceConfig.d.ts +50 -0
  221. package/dist/runtime/engineBrokerServiceConfig.d.ts.map +1 -0
  222. package/dist/runtime/engineBrokerServiceConfig.js +92 -0
  223. package/dist/runtime/engineBrokerSingleflight.d.ts +13 -0
  224. package/dist/runtime/engineBrokerSingleflight.d.ts.map +1 -0
  225. package/dist/runtime/engineBrokerSingleflight.js +24 -0
  226. package/dist/runtime/engineBrokerTurnAccounting.d.ts +76 -0
  227. package/dist/runtime/engineBrokerTurnAccounting.d.ts.map +1 -0
  228. package/dist/runtime/engineBrokerTurnAccounting.js +108 -0
  229. package/dist/runtime/engineBrokerTurnRegistry.d.ts +57 -0
  230. package/dist/runtime/engineBrokerTurnRegistry.d.ts.map +1 -0
  231. package/dist/runtime/engineBrokerTurnRegistry.js +158 -0
  232. package/dist/runtime/engineDispatcher.d.ts +36 -0
  233. package/dist/runtime/engineDispatcher.d.ts.map +1 -0
  234. package/dist/runtime/engineDispatcher.js +216 -0
  235. package/dist/runtime/engineReadiness.d.ts +23 -0
  236. package/dist/runtime/engineReadiness.d.ts.map +1 -0
  237. package/dist/runtime/engineReadiness.js +222 -0
  238. package/dist/runtime/grokAuthenticationError.d.ts +8 -0
  239. package/dist/runtime/grokAuthenticationError.d.ts.map +1 -0
  240. package/dist/runtime/grokAuthenticationError.js +20 -0
  241. package/dist/runtime/grokBrokerCredentialAuthority.d.ts +22 -0
  242. package/dist/runtime/grokBrokerCredentialAuthority.d.ts.map +1 -0
  243. package/dist/runtime/grokBrokerCredentialAuthority.js +124 -0
  244. package/dist/runtime/grokBrokerCredentialReader.d.ts +5 -0
  245. package/dist/runtime/grokBrokerCredentialReader.d.ts.map +1 -0
  246. package/dist/runtime/grokBrokerCredentialReader.js +37 -0
  247. package/dist/runtime/grokBrokerModelPolicy.d.ts +23 -0
  248. package/dist/runtime/grokBrokerModelPolicy.d.ts.map +1 -0
  249. package/dist/runtime/grokBrokerModelPolicy.js +28 -0
  250. package/dist/runtime/grokBrokerProjection.d.ts +106 -0
  251. package/dist/runtime/grokBrokerProjection.d.ts.map +1 -0
  252. package/dist/runtime/grokBrokerProjection.js +94 -0
  253. package/dist/runtime/grokBrokerProxy.d.ts +55 -0
  254. package/dist/runtime/grokBrokerProxy.d.ts.map +1 -0
  255. package/dist/runtime/grokBrokerProxy.js +262 -0
  256. package/dist/runtime/grokBrokerProxyRequest.d.ts +30 -0
  257. package/dist/runtime/grokBrokerProxyRequest.d.ts.map +1 -0
  258. package/dist/runtime/grokBrokerProxyRequest.js +74 -0
  259. package/dist/runtime/grokBrokerRealmLease.d.ts +4 -0
  260. package/dist/runtime/grokBrokerRealmLease.d.ts.map +1 -0
  261. package/dist/runtime/grokBrokerRealmLease.js +33 -0
  262. package/dist/runtime/grokBrokerRefresh.d.ts +2 -0
  263. package/dist/runtime/grokBrokerRefresh.d.ts.map +1 -0
  264. package/dist/runtime/grokBrokerRefresh.js +15 -0
  265. package/dist/runtime/grokBrokerTurnMeter.d.ts +128 -0
  266. package/dist/runtime/grokBrokerTurnMeter.d.ts.map +1 -0
  267. package/dist/runtime/grokBrokerTurnMeter.js +251 -0
  268. package/dist/runtime/grokBrokerWorkerConfig.d.ts +86 -0
  269. package/dist/runtime/grokBrokerWorkerConfig.d.ts.map +1 -0
  270. package/dist/runtime/grokBrokerWorkerConfig.js +135 -0
  271. package/dist/runtime/grokEngineBroker.d.ts +48 -0
  272. package/dist/runtime/grokEngineBroker.d.ts.map +1 -0
  273. package/dist/runtime/grokEngineBroker.js +114 -0
  274. package/dist/runtime/grokEngineBrokerLedger.d.ts +52 -0
  275. package/dist/runtime/grokEngineBrokerLedger.d.ts.map +1 -0
  276. package/dist/runtime/grokEngineBrokerLedger.js +114 -0
  277. package/dist/runtime/grokEngineBrokerMetering.d.ts +51 -0
  278. package/dist/runtime/grokEngineBrokerMetering.d.ts.map +1 -0
  279. package/dist/runtime/grokEngineBrokerMetering.js +34 -0
  280. package/dist/runtime/grokEngineBrokerTurn.d.ts +58 -0
  281. package/dist/runtime/grokEngineBrokerTurn.d.ts.map +1 -0
  282. package/dist/runtime/grokEngineBrokerTurn.js +165 -0
  283. package/dist/runtime/grokInferenceClientConfig.d.ts +41 -0
  284. package/dist/runtime/grokInferenceClientConfig.d.ts.map +1 -0
  285. package/dist/runtime/grokInferenceClientConfig.js +62 -0
  286. package/dist/runtime/grokInferenceGrants.d.ts +77 -0
  287. package/dist/runtime/grokInferenceGrants.d.ts.map +1 -0
  288. package/dist/runtime/grokInferenceGrants.js +116 -0
  289. package/dist/runtime/grokInferenceProxy.d.ts +29 -0
  290. package/dist/runtime/grokInferenceProxy.d.ts.map +1 -0
  291. package/dist/runtime/grokInferenceProxy.js +82 -0
  292. package/dist/runtime/grokInferenceProxyRequest.d.ts +23 -0
  293. package/dist/runtime/grokInferenceProxyRequest.d.ts.map +1 -0
  294. package/dist/runtime/grokInferenceProxyRequest.js +63 -0
  295. package/dist/runtime/grokSlotPreflightReceipt.d.ts +70 -0
  296. package/dist/runtime/grokSlotPreflightReceipt.d.ts.map +1 -0
  297. package/dist/runtime/grokSlotPreflightReceipt.js +101 -0
  298. package/dist/runtime/grokSubscriptionRealm.d.ts +4 -0
  299. package/dist/runtime/grokSubscriptionRealm.d.ts.map +1 -0
  300. package/dist/runtime/grokSubscriptionRealm.js +435 -0
  301. package/dist/runtime/grokSubscriptionRealmTypes.d.ts +26 -0
  302. package/dist/runtime/grokSubscriptionRealmTypes.d.ts.map +1 -0
  303. package/dist/runtime/grokSubscriptionRealmTypes.js +1 -0
  304. package/dist/runtime/grokWorkerAttestation.d.ts +170 -0
  305. package/dist/runtime/grokWorkerAttestation.d.ts.map +1 -0
  306. package/dist/runtime/grokWorkerAttestation.js +266 -0
  307. package/dist/runtime/grokWorkerDenyPlacement.d.ts +80 -0
  308. package/dist/runtime/grokWorkerDenyPlacement.d.ts.map +1 -0
  309. package/dist/runtime/grokWorkerDenyPlacement.js +128 -0
  310. package/dist/runtime/grokWorkerHomeAttestation.d.ts +30 -0
  311. package/dist/runtime/grokWorkerHomeAttestation.d.ts.map +1 -0
  312. package/dist/runtime/grokWorkerHomeAttestation.js +69 -0
  313. package/dist/runtime/grokWorkerSandboxProfile.d.ts +27 -0
  314. package/dist/runtime/grokWorkerSandboxProfile.d.ts.map +1 -0
  315. package/dist/runtime/grokWorkerSandboxProfile.js +44 -0
  316. package/dist/runtime/grokWorkerTmpAttestation.d.ts +55 -0
  317. package/dist/runtime/grokWorkerTmpAttestation.d.ts.map +1 -0
  318. package/dist/runtime/grokWorkerTmpAttestation.js +63 -0
  319. package/dist/runtime/index.d.ts +26 -0
  320. package/dist/runtime/index.d.ts.map +1 -0
  321. package/dist/runtime/index.js +23 -0
  322. package/dist/runtime/inferenceUsageLedger.d.ts +38 -0
  323. package/dist/runtime/inferenceUsageLedger.d.ts.map +1 -0
  324. package/dist/runtime/inferenceUsageLedger.js +53 -0
  325. package/dist/runtime/mcpToolResult.d.ts +127 -0
  326. package/dist/runtime/mcpToolResult.d.ts.map +1 -0
  327. package/dist/runtime/mcpToolResult.js +214 -0
  328. package/dist/runtime/moltnetMachineRead.d.ts +97 -0
  329. package/dist/runtime/moltnetMachineRead.d.ts.map +1 -0
  330. package/dist/runtime/moltnetMachineRead.js +183 -0
  331. package/dist/runtime/native/daimon-engine-broker +0 -0
  332. package/dist/runtime/organizationRuntime.d.ts +165 -0
  333. package/dist/runtime/organizationRuntime.d.ts.map +1 -0
  334. package/dist/runtime/organizationRuntime.js +3 -0
  335. package/dist/runtime/organizationRuntimeControl.d.ts +42 -0
  336. package/dist/runtime/organizationRuntimeControl.d.ts.map +1 -0
  337. package/dist/runtime/organizationRuntimeControl.js +235 -0
  338. package/dist/runtime/organizationRuntimeHost.d.ts +19 -0
  339. package/dist/runtime/organizationRuntimeHost.d.ts.map +1 -0
  340. package/dist/runtime/organizationRuntimeHost.js +359 -0
  341. package/dist/runtime/organizationRuntimeParsing.d.ts +6 -0
  342. package/dist/runtime/organizationRuntimeParsing.d.ts.map +1 -0
  343. package/dist/runtime/organizationRuntimeParsing.js +370 -0
  344. package/dist/runtime/organizationRuntimeReadiness.d.ts +12 -0
  345. package/dist/runtime/organizationRuntimeReadiness.d.ts.map +1 -0
  346. package/dist/runtime/organizationRuntimeReadiness.js +59 -0
  347. package/dist/runtime/physicalReadiness.d.ts +47 -0
  348. package/dist/runtime/physicalReadiness.d.ts.map +1 -0
  349. package/dist/runtime/physicalReadiness.js +142 -0
  350. package/dist/runtime/portableCredentialAuth.d.ts +6 -0
  351. package/dist/runtime/portableCredentialAuth.d.ts.map +1 -0
  352. package/dist/runtime/portableCredentialAuth.js +70 -0
  353. package/dist/runtime/portableCredentialMaterial.d.ts +8 -0
  354. package/dist/runtime/portableCredentialMaterial.d.ts.map +1 -0
  355. package/dist/runtime/portableCredentialMaterial.js +169 -0
  356. package/dist/runtime/productionAgentTools.d.ts +5 -0
  357. package/dist/runtime/productionAgentTools.d.ts.map +1 -0
  358. package/dist/runtime/productionAgentTools.js +328 -0
  359. package/dist/runtime/runtimeHomeLayout.d.ts +48 -0
  360. package/dist/runtime/runtimeHomeLayout.d.ts.map +1 -0
  361. package/dist/runtime/runtimeHomeLayout.js +84 -0
  362. package/dist/runtime/schedule.d.ts +40 -0
  363. package/dist/runtime/schedule.d.ts.map +1 -0
  364. package/dist/runtime/schedule.js +371 -0
  365. package/dist/runtime/storeCoordination.d.ts +23 -0
  366. package/dist/runtime/storeCoordination.d.ts.map +1 -0
  367. package/dist/runtime/storeCoordination.js +94 -0
  368. package/dist/runtime/toolResultSpill.d.ts +152 -0
  369. package/dist/runtime/toolResultSpill.d.ts.map +1 -0
  370. package/dist/runtime/toolResultSpill.js +351 -0
  371. package/dist/runtime/turnRequestLedger.d.ts +160 -0
  372. package/dist/runtime/turnRequestLedger.d.ts.map +1 -0
  373. package/dist/runtime/turnRequestLedger.js +249 -0
  374. package/dist/runtime/turnUsageLedger.d.ts +143 -0
  375. package/dist/runtime/turnUsageLedger.d.ts.map +1 -0
  376. package/dist/runtime/turnUsageLedger.js +203 -0
  377. package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts +17 -0
  378. package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts.map +1 -0
  379. package/dist/runtime/wakeAcceptanceProcessIdentity.js +50 -0
  380. package/dist/runtime/wakeAcceptanceReconciliation.d.ts +211 -0
  381. package/dist/runtime/wakeAcceptanceReconciliation.d.ts.map +1 -0
  382. package/dist/runtime/wakeAcceptanceReconciliation.js +289 -0
  383. package/dist/runtime/wakeAcceptanceRecord.d.ts +23 -0
  384. package/dist/runtime/wakeAcceptanceRecord.d.ts.map +1 -0
  385. package/dist/runtime/wakeAcceptanceRecord.js +56 -0
  386. package/dist/runtime/wakeAcceptanceRetention.d.ts +12 -0
  387. package/dist/runtime/wakeAcceptanceRetention.d.ts.map +1 -0
  388. package/dist/runtime/wakeAcceptanceRetention.js +12 -0
  389. package/dist/runtime/wakeAcceptanceStore.d.ts +113 -0
  390. package/dist/runtime/wakeAcceptanceStore.d.ts.map +1 -0
  391. package/dist/runtime/wakeAcceptanceStore.js +558 -0
  392. package/dist/runtime/wakeAcceptanceTypes.d.ts +179 -0
  393. package/dist/runtime/wakeAcceptanceTypes.d.ts.map +1 -0
  394. package/dist/runtime/wakeAcceptanceTypes.js +95 -0
  395. package/dist/runtime/wakeFuse.d.ts +69 -0
  396. package/dist/runtime/wakeFuse.d.ts.map +1 -0
  397. package/dist/runtime/wakeFuse.js +367 -0
  398. package/package.json +25 -17
  399. package/dist/examples/mixed-engine-org.d.ts +0 -2
  400. package/dist/examples/mixed-engine-org.d.ts.map +0 -1
  401. package/dist/examples/mixed-engine-org.js +0 -351
  402. package/dist/examples/mixedEngineCli.d.ts +0 -15
  403. package/dist/examples/mixedEngineCli.d.ts.map +0 -1
  404. package/dist/examples/mixedEngineCli.js +0 -174
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turnRequestLedger.d.ts","sourceRoot":"","sources":["../../src/runtime/turnRequestLedger.ts"],"names":[],"mappings":"AAGA,OAAO,EAA4B,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC9F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAGlE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,2BAA2B,EAAG,kCAA2C,CAAC;AAEvF;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;;;CAMtB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,EAAG,kCAA2C,CAAC;AAExF,eAAO,MAAM,4BAA4B,GAAI,cAAa,MAAM,CAAC,UAAwB,KAAG,MAG3F,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC,CAAC;AAIH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,gBAAgB,KAAG,MAqBhE,CAAC;AASF,0FAA0F;AAC1F;;;;GAIG;AACH;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AACvQ;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE/M;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,0BAA0B,GAAI,OAAO,oBAAoB,KAAG,MAuBxE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAU,MAAM,MAAM,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,OAAO,CAGpF,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,sBAAsB,GAAU,MAAM,MAAM,EAAE,OAAO,oBAAoB,KAAG,OAAO,CAAC,OAAO,CAGvG,CAAC;AA4BF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAU,MAAM,MAAM,EAAE,OAAO,gBAAgB,KAAG,OAAO,CAAC,OAAO,CAU/F,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GAAU,OAAO,QAAQ,CAAC;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC,KAAG,OAAO,CAAC,OAAO,CAiBnB,CAAC"}
@@ -0,0 +1,249 @@
1
+ import { constants } from "node:fs";
2
+ import { open, rename, stat } from "node:fs/promises";
3
+ import { readCodexRolloutRequests } from "../pi/codexRolloutUsage.js";
4
+ import { TURN_USAGE_LEDGER, TURN_USAGE_MAX_IDENTIFIER_CHARS, TURN_USAGE_ROTATE_BYTES } from "./turnUsageLedger.js";
5
+ /**
6
+ * Per-model-request token accounting, written *beside* the per-wake usage
7
+ * ledger and never inside it.
8
+ *
9
+ * `turnUsageLedger.ts` records one aggregate row per wake. Production measured
10
+ * 55 wakes at 14,890,263 input tokens against 159,726 output — output is 1.06%
11
+ * of the spend — with context per model request flat at 23–32k regardless of
12
+ * how many requests a wake made. That is the signature of a fixed prefix
13
+ * replayed once per request rather than of a conversation that grows, but the
14
+ * aggregate row cannot tell the two apart, and every optimisation worth doing
15
+ * next depends on which one it is. This file is what tells them apart.
16
+ *
17
+ * It is a separate stream, not a wider row, for one specific reason. Spawnfile's
18
+ * reader (`spawnfile/src/runtime/usageLedger.ts`) rejects any line whose `v` is
19
+ * not `noopolis.daimon.turn-usage.v1` and returns `null` for the whole line, so
20
+ * a version bump on the existing ledger would make an unreleased Spawnfile drop
21
+ * every row it can read today. Nothing here changes the shape, version, path, or
22
+ * field list of that ledger; a reader that knows nothing about this file keeps
23
+ * working byte for byte.
24
+ */
25
+ export const TURN_REQUEST_LEDGER_VERSION = "noopolis.daimon.turn-requests.v1";
26
+ /**
27
+ * Default location: the directory Spawnfile already provisions for the usage
28
+ * ledger, under its own filename. No new mount, no new provisioning step.
29
+ */
30
+ export const TURN_REQUEST_LEDGER = {
31
+ version: TURN_REQUEST_LEDGER_VERSION,
32
+ directoryPath: TURN_USAGE_LEDGER.directoryPath,
33
+ filePath: `${TURN_USAGE_LEDGER.directoryPath}/requests.jsonl`,
34
+ rotatedFilePath: `${TURN_USAGE_LEDGER.directoryPath}/requests.jsonl.1`,
35
+ fileMode: TURN_USAGE_LEDGER.fileMode
36
+ };
37
+ /**
38
+ * `DAIMON_TURN_REQUESTS_LEDGER_PATH` relocates the stream, exactly as
39
+ * `DAIMON_TURN_USAGE_LEDGER_PATH` relocates the ledger it sits beside. A
40
+ * relative or empty value is ignored rather than honoured: a ledger written to
41
+ * a process-relative path is a ledger nobody can find again.
42
+ */
43
+ export const TURN_REQUEST_LEDGER_PATH_ENV = "DAIMON_TURN_REQUESTS_LEDGER_PATH";
44
+ export const resolveTurnRequestLedgerPath = (environment = process.env) => {
45
+ const override = environment[TURN_REQUEST_LEDGER_PATH_ENV]?.trim();
46
+ return override !== undefined && override.startsWith("/") ? override : TURN_REQUEST_LEDGER.filePath;
47
+ };
48
+ const bounded = (value) => [...value].slice(0, TURN_USAGE_MAX_IDENTIFIER_CHARS).join("");
49
+ /**
50
+ * One line per model request.
51
+ *
52
+ * `fresh_input` is `input − cached_input`, the split the whole exercise exists
53
+ * to see. It is derived from exactly the relationship Daimon already validates
54
+ * (`cached_input_tokens` is a subset of `input_tokens`, asserted by Codex's own
55
+ * reconciled totals and re-checked when the block is decoded). `cache_write` is
56
+ * emitted raw and never subtracted, because whether Codex counts a cache write
57
+ * inside `input_tokens` has not been verified — a reader that needs that answer
58
+ * has the raw number to work from instead of a guess baked into the row.
59
+ */
60
+ export const renderTurnRequestLines = (entry) => {
61
+ const at = entry.at ?? new Date().toISOString();
62
+ const requests = entry.requests.length;
63
+ return entry.requests.map((request) => `${JSON.stringify({
64
+ v: TURN_REQUEST_LEDGER_VERSION,
65
+ agent: bounded(entry.agent),
66
+ wake: bounded(entry.wake),
67
+ engine: "codex",
68
+ at,
69
+ thread: bounded(entry.thread),
70
+ request: request.index,
71
+ requests,
72
+ input: request.input,
73
+ cached_input: request.cachedInput,
74
+ fresh_input: request.input - request.cachedInput,
75
+ cache_write: request.cacheWrite,
76
+ output: request.output,
77
+ reasoning: request.reasoning,
78
+ total: request.total,
79
+ ...requestClockFields(request)
80
+ })}\n`).join("");
81
+ };
82
+ const TIMESTAMP = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?Z$/u;
83
+ /** Per-request `started_at`/`ended_at`, each only when it was measured; `at` stays the append time. */
84
+ const requestClockFields = (request) => ({
85
+ ...(request.startedAt !== undefined && TIMESTAMP.test(request.startedAt) ? { started_at: request.startedAt } : {}),
86
+ ...(request.endedAt !== undefined && TIMESTAMP.test(request.endedAt) ? { ended_at: request.endedAt } : {})
87
+ });
88
+ /**
89
+ * Grok rows share the Codex row's field meaning: `input` is the whole prompt
90
+ * side the request replayed (`input_tokens + cache_read`), `cached_input` the
91
+ * cache read, `fresh_input` the uncached remainder. Grok does not separate
92
+ * reasoning tokens, so `reasoning` is absent rather than zero. `turn` is the
93
+ * broker idempotency key and `thread` the Grok session id when the stream
94
+ * named one.
95
+ *
96
+ * `tool_calls` is what a turn's rows could not say before: whether the model
97
+ * ever *tried* to call anything. Two live turns ended with correctly mounted
98
+ * tools and no visible attempt, and the rows recorded timings and tokens only,
99
+ * so the question could not be answered after the fact. It is names only —
100
+ * never arguments, never message content, never a bearer — bounded, `[]` for a
101
+ * response that called nothing, and absent for a response that could not be
102
+ * decoded, because a fabricated empty list is byte-identical to a measured one.
103
+ *
104
+ * It is an additive field inside the unchanged
105
+ * `noopolis.daimon.turn-requests.v1` row, deliberately without a version bump:
106
+ * Spawnfile's usage reader (`spawnfile/src/runtime/usageLedger.ts`) drops every
107
+ * line whose `v` it does not recognise while ignoring fields it does not know,
108
+ * and Paideia only relocates this stream's path
109
+ * (`DAIMON_TURN_REQUESTS_LEDGER_PATH`). A bump is what would blind them; a new
110
+ * field is not.
111
+ */
112
+ export const renderGrokTurnRequestLines = (entry) => {
113
+ const at = entry.at ?? new Date().toISOString();
114
+ return entry.requests.map((request) => `${JSON.stringify({
115
+ v: TURN_REQUEST_LEDGER_VERSION,
116
+ agent: bounded(entry.agent),
117
+ wake: bounded(entry.wake),
118
+ engine: "grok",
119
+ at,
120
+ turn: entry.turn,
121
+ ...(entry.session === undefined ? {} : { thread: bounded(entry.session) }),
122
+ model: entry.model,
123
+ request: request.index,
124
+ requests: Math.max(entry.requests.length, entry.requestCount ?? 0),
125
+ input: request.input + request.cacheRead,
126
+ cached_input: request.cacheRead,
127
+ fresh_input: request.input,
128
+ cache_write: request.cacheWrite,
129
+ output: request.output,
130
+ total: request.total,
131
+ ...(request.usageSource === undefined ? {} : { usage_source: request.usageSource }),
132
+ ...(request.toolCalls === undefined ? {} : { tool_calls: request.toolCalls }),
133
+ ...requestClockFields(request)
134
+ })}\n`).join("");
135
+ };
136
+ /**
137
+ * Append already-rendered, newline-terminated ledger lines in one write, with the
138
+ * same rotation and file mode as both ledgers. Advisory: never rejects. The
139
+ * broker uses it to append the exact bytes it sealed into a turn record.
140
+ */
141
+ export const recordLedgerLines = async (file, lines) => {
142
+ if (lines.length === 0)
143
+ return false;
144
+ try {
145
+ await rotate(file);
146
+ await appendLines(file, lines);
147
+ return true;
148
+ }
149
+ catch {
150
+ return false;
151
+ }
152
+ };
153
+ /** Advisory and never rejects, like {@link recordTurnRequests}; an empty turn writes nothing. */
154
+ export const recordGrokTurnRequests = async (file, entry) => {
155
+ if (entry.requests.length === 0)
156
+ return false;
157
+ try {
158
+ await rotate(file);
159
+ await appendLines(file, renderGrokTurnRequestLines(entry));
160
+ return true;
161
+ }
162
+ catch {
163
+ return false;
164
+ }
165
+ };
166
+ const rotate = async (file) => {
167
+ let size;
168
+ try {
169
+ size = (await stat(file)).size;
170
+ }
171
+ catch {
172
+ return;
173
+ }
174
+ if (size >= TURN_USAGE_ROTATE_BYTES)
175
+ await rename(file, `${file}.1`);
176
+ };
177
+ /**
178
+ * One `write(2)` for the whole wake's rows.
179
+ *
180
+ * Turns for different agents run concurrently inside the single broker process.
181
+ * `O_APPEND` makes a single sub-page write atomic against them, so a wake's rows
182
+ * are contiguous and never interleaved with another wake's — which matters more
183
+ * here than in the per-wake ledger, because a row only means something beside
184
+ * the other rows of its own thread. A wake with enough requests to exceed a page
185
+ * is still append-ordered per line; interleaving would cost grouping, not
186
+ * correctness, since every row carries its own thread id.
187
+ */
188
+ const appendLines = async (file, lines) => {
189
+ const bytes = Buffer.from(lines, "utf8");
190
+ const handle = await open(file, constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW, TURN_REQUEST_LEDGER.fileMode);
191
+ try {
192
+ const { bytesWritten } = await handle.write(bytes, 0, bytes.length);
193
+ if (bytesWritten !== bytes.length)
194
+ throw new Error("turn request ledger append was torn");
195
+ }
196
+ finally {
197
+ await handle.close();
198
+ }
199
+ };
200
+ /**
201
+ * Advisory. Never rejects, and never writes an empty wake.
202
+ *
203
+ * A wake whose rollout was absent, unreadable, or undecodable contributes no
204
+ * rows at all rather than a zero row — the same invariant the usage ledger
205
+ * holds, for the same reason: a fabricated zero is byte-identical to a measured
206
+ * one, and this stream exists to be believed.
207
+ */
208
+ export const recordTurnRequests = async (file, entry) => {
209
+ if (entry.requests.length === 0)
210
+ return false;
211
+ try {
212
+ await rotate(file);
213
+ await appendLines(file, renderTurnRequestLines(entry));
214
+ return true;
215
+ }
216
+ catch {
217
+ /* advisory: instrumentation never fails a wake that published */
218
+ return false;
219
+ }
220
+ };
221
+ /**
222
+ * The whole instrumentation path for one Codex wake: find that thread's
223
+ * rollout, decode its per-request usage, append it. Never throws.
224
+ *
225
+ * A wake that produced no rows says so on stderr exactly once. Silence would
226
+ * make a permanently blind instrument indistinguishable from a working one —
227
+ * `--ephemeral`, a relocated `CODEX_HOME`, or a Codex version that renamed the
228
+ * usage frame all end here, and each is worth one line rather than a
229
+ * quietly-empty file nobody questions.
230
+ */
231
+ export const recordCodexTurnRequests = async (input) => {
232
+ try {
233
+ const requests = await readCodexRolloutRequests(input.codexHome, input.threadId);
234
+ const written = await recordTurnRequests(input.file ?? resolveTurnRequestLedgerPath(), {
235
+ agent: input.agent,
236
+ wake: input.wake,
237
+ thread: input.threadId,
238
+ requests
239
+ });
240
+ if (!written) {
241
+ console.error(`daimon: no per-request usage recorded for codex thread ${input.threadId} (${requests.length === 0 ? "no decodable rollout usage" : "ledger append failed"})`);
242
+ }
243
+ return written;
244
+ }
245
+ catch (error) {
246
+ console.error(`daimon: per-request usage instrumentation failed: ${error instanceof Error ? error.message : "unknown error"}`);
247
+ return false;
248
+ }
249
+ };
@@ -0,0 +1,143 @@
1
+ import { type EngineBrokerLimitReason } from "./engineBrokerTurnAccounting.js";
2
+ import type { GrokBrokerModel } from "./grokBrokerModelPolicy.js";
3
+ /**
4
+ * Append-only per-turn token accounting for one container.
5
+ *
6
+ * The record carries no organization: there is one ledger per container and one
7
+ * organization per container, so identity comes from which container was
8
+ * queried. Nothing engine-controlled and non-numeric is ever persisted.
9
+ */
10
+ export declare const TURN_USAGE_LEDGER_VERSION: "noopolis.daimon.turn-usage.v1";
11
+ /**
12
+ * Where the broker writes, and what Spawnfile provisions.
13
+ *
14
+ * Deliberately *not* folded into `RUNTIME_CONTRACT_MANIFEST`. That manifest's
15
+ * canonical bytes are digest-pinned by Spawnfile
16
+ * (`DAIMON_CONTRACT_MANIFEST_SHA256`) and attested against the runtime image
17
+ * selected at compile time, so any new key there makes every pinned image fail
18
+ * to attest and blocks all Daimon compiles until an image is rebuilt and
19
+ * re-pinned. Nothing about metering needs digest attestation: this is a path
20
+ * both sides agree on, mirrored in `spawnfile/src/runtime/daimon/`. Registering
21
+ * the schema in the manifest is bookkeeping that belongs with the next image
22
+ * rebuild.
23
+ */
24
+ export declare const TURN_USAGE_LEDGER: {
25
+ readonly version: "noopolis.daimon.turn-usage.v1";
26
+ readonly directoryPath: "/var/lib/spawnfile/daimon/usage";
27
+ readonly filePath: "/var/lib/spawnfile/daimon/usage/usage.jsonl";
28
+ readonly rotatedFilePath: "/var/lib/spawnfile/daimon/usage/usage.jsonl.1";
29
+ readonly directoryMode: 488;
30
+ readonly fileMode: 416;
31
+ };
32
+ /**
33
+ * `agent` and `wake` are caller-supplied external text (`wake` is `event.id`
34
+ * from the wake request, schema-bounded to 4096 codepoints). They are truncated
35
+ * so one record cannot grow past a size where a single `write(2)` stops being
36
+ * atomic. JSON escaping already prevents line injection.
37
+ */
38
+ export declare const TURN_USAGE_MAX_IDENTIFIER_CHARS = 128;
39
+ /** Rotate to a single `.1` sibling. ~2.5k lines/day observed, so this is months. */
40
+ export declare const TURN_USAGE_ROTATE_BYTES: number;
41
+ export type TurnUsageMeasurement = Readonly<{
42
+ input: number;
43
+ output: number;
44
+ cacheRead: number;
45
+ cacheWrite: number;
46
+ total: number;
47
+ calls: number;
48
+ notionalUsd: number;
49
+ complete: boolean;
50
+ }>;
51
+ /**
52
+ * Every engine whose headless stream reports its own token accounting.
53
+ *
54
+ * Codex, AGY, and Grok all publish decoded terminal-stream accounting here.
55
+ * Spawnfile's reader mirrors this list and is updated separately in packet
56
+ * A1b; until then, a reader that rejects `codex` will drop every Codex line.
57
+ */
58
+ export declare const TURN_USAGE_ENGINES: readonly ["agy", "codex", "grok"];
59
+ /**
60
+ * Whether the wake that spent these tokens went on to succeed.
61
+ *
62
+ * Money is spent by a failed wake exactly as by a successful one, so a row is
63
+ * written whenever the engine actually reported usage — see
64
+ * `../pi/cliSession.ts`. Without this field every failed wake's spend was
65
+ * simply absent from the ledger, and an organization's cost total silently
66
+ * undercounted by however much its failures burned.
67
+ *
68
+ * `reason` is a closed vocabulary, never an engine- or error-supplied string:
69
+ * the record's rule that nothing engine-controlled and non-numeric is
70
+ * persisted still holds, and `renderTurnUsageLine` degrades anything outside
71
+ * the list to `unknown` rather than writing it through.
72
+ */
73
+ export declare const TURN_USAGE_OUTCOMES: readonly ["completed", "failed"];
74
+ /**
75
+ * - `token_ceiling` — the turn's own reported usage crossed the per-wake ceiling.
76
+ * - `request_ceiling` — the broker refused a model request past the turn's request limit.
77
+ * - `wake_timeout` — the wall-clock bound fired before the child finished.
78
+ * - `output_limit` — the retained-output bound was exceeded.
79
+ * - `engine_exit` — the child exited non-zero (or died) after reporting usage.
80
+ * - `turn_rejected` — usage was reported but the decoded turn was not publishable.
81
+ * - `unknown` — any other failure (verification, cleanup, spawn).
82
+ */
83
+ export declare const TURN_USAGE_FAILURE_REASONS: readonly ["token_ceiling", "request_ceiling", "wake_timeout", "output_limit", "engine_exit", "turn_rejected", "unknown"];
84
+ export type TurnUsageFailureReason = typeof TURN_USAGE_FAILURE_REASONS[number];
85
+ export type TurnUsageOutcome = Readonly<{
86
+ status: typeof TURN_USAGE_OUTCOMES[number];
87
+ reason?: TurnUsageFailureReason;
88
+ }>;
89
+ export type TurnUsageEntry = Readonly<{
90
+ agent: string;
91
+ wake: string;
92
+ engine: typeof TURN_USAGE_ENGINES[number];
93
+ usage: TurnUsageMeasurement;
94
+ at?: string;
95
+ outcome?: TurnUsageOutcome;
96
+ /**
97
+ * Broker rows only. `turn` is the idempotency key readers dedupe on (the
98
+ * broker turn id, a sha256 hex); `limitReason` and `model` come from the
99
+ * closed broker vocabularies and are dropped rather than written through
100
+ * when they are not members.
101
+ */
102
+ turn?: string;
103
+ limitReason?: EngineBrokerLimitReason;
104
+ model?: GrokBrokerModel;
105
+ /** Broker rows only: how many of the turn's requests were charged an estimate because their response carried no valid usage. */
106
+ estimatedRequests?: number;
107
+ }>;
108
+ /**
109
+ * Where a metered turn is appended.
110
+ *
111
+ * Production is {@link TURN_USAGE_LEDGER}`.filePath`, which Spawnfile
112
+ * provisions as a non-run-scoped volume. `DAIMON_TURN_USAGE_LEDGER_PATH`
113
+ * redirects it to an absolute path elsewhere; it exists so the wiring between a
114
+ * live engine session and this ledger can be exercised end to end, and so an
115
+ * operator can relocate the ledger without a rebuild. A relative or empty value
116
+ * is ignored rather than honoured, because a ledger written to a
117
+ * process-relative path is a ledger nobody can find again.
118
+ */
119
+ export declare const TURN_USAGE_LEDGER_PATH_ENV: "DAIMON_TURN_USAGE_LEDGER_PATH";
120
+ export declare const resolveTurnUsageLedgerPath: (environment?: NodeJS.ProcessEnv) => string;
121
+ /** One complete line, newline-terminated. `JSON.stringify` escapes any embedded newline. */
122
+ export declare const renderTurnUsageLine: (entry: TurnUsageEntry) => string;
123
+ /**
124
+ * Collapse rows that share a `turn` key to the first one, keeping rows without
125
+ * a key untouched. Every reader that sums the ledger applies this, because a
126
+ * turn key exists precisely so a re-appended turn can never be counted twice.
127
+ */
128
+ export declare const dedupeTurnUsageRows: <T extends Readonly<{
129
+ turn?: unknown;
130
+ }>>(rows: readonly T[]) => T[];
131
+ /**
132
+ * Advisory. Never rejects.
133
+ *
134
+ * The caller runs this inside the broker's turn `try` block, after the turn has
135
+ * already been recorded as *completed*. That block's `catch` calls
136
+ * `finish(..., failed)` unconditionally, and `finish` has no terminal-state
137
+ * guard — it renames over an existing record. An escaping append error would
138
+ * therefore rewrite an already-completed turn as failed. This guard is the only
139
+ * thing preventing that, so it is the one place where getting "advisory" wrong
140
+ * corrupts turn state instead of merely dropping a line.
141
+ */
142
+ export declare const recordTurnUsage: (file: string, entry: TurnUsageEntry) => Promise<void>;
143
+ //# sourceMappingURL=turnUsageLedger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turnUsageLedger.d.ts","sourceRoot":"","sources":["../../src/runtime/turnUsageLedger.ts"],"names":[],"mappings":"AAIA,OAAO,EAA+B,KAAK,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC5G,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,EAAG,+BAAwC,CAAC;AAElF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB;;;;;;;CAOpB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD,oFAAoF;AACpF,eAAO,MAAM,uBAAuB,QAAmB,CAAC;AAExD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,mCAAoC,CAAC;AAEpE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,kCAAmC,CAAC;AAEpE;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,0HAQ7B,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,OAAO,0BAA0B,CAAC,MAAM,CAAC,CAAC;AAE/E,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,MAAM,EAAE,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,sBAAsB,CAAC;CACjC,CAAC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC1C,KAAK,EAAE,oBAAoB,CAAC;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,uBAAuB,CAAC;IACtC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,gIAAgI;IAChI,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,0BAA0B,EAAG,+BAAwC,CAAC;AAEnF,eAAO,MAAM,0BAA0B,GAAI,cAAa,MAAM,CAAC,UAAwB,KAAG,MAGzF,CAAC;AAuBF,4FAA4F;AAC5F,eAAO,MAAM,mBAAmB,GAAI,OAAO,cAAc,KAAG,MAgBtD,CAAC;AASP;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,QAAQ,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EAAE,MAAM,SAAS,CAAC,EAAE,KAAG,CAAC,EAGjG,CAAC;AAuBF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAU,MAAM,MAAM,EAAE,OAAO,cAAc,KAAG,OAAO,CAAC,IAAI,CAOvF,CAAC"}
@@ -0,0 +1,203 @@
1
+ import { constants } from "node:fs";
2
+ import { open, rename, stat } from "node:fs/promises";
3
+ import { GROK_BROKER_MODELS } from "../contracts/grokWorkerContract.js";
4
+ import { ENGINE_BROKER_LIMIT_REASONS } from "./engineBrokerTurnAccounting.js";
5
+ /**
6
+ * Append-only per-turn token accounting for one container.
7
+ *
8
+ * The record carries no organization: there is one ledger per container and one
9
+ * organization per container, so identity comes from which container was
10
+ * queried. Nothing engine-controlled and non-numeric is ever persisted.
11
+ */
12
+ export const TURN_USAGE_LEDGER_VERSION = "noopolis.daimon.turn-usage.v1";
13
+ /**
14
+ * Where the broker writes, and what Spawnfile provisions.
15
+ *
16
+ * Deliberately *not* folded into `RUNTIME_CONTRACT_MANIFEST`. That manifest's
17
+ * canonical bytes are digest-pinned by Spawnfile
18
+ * (`DAIMON_CONTRACT_MANIFEST_SHA256`) and attested against the runtime image
19
+ * selected at compile time, so any new key there makes every pinned image fail
20
+ * to attest and blocks all Daimon compiles until an image is rebuilt and
21
+ * re-pinned. Nothing about metering needs digest attestation: this is a path
22
+ * both sides agree on, mirrored in `spawnfile/src/runtime/daimon/`. Registering
23
+ * the schema in the manifest is bookkeeping that belongs with the next image
24
+ * rebuild.
25
+ */
26
+ export const TURN_USAGE_LEDGER = {
27
+ version: TURN_USAGE_LEDGER_VERSION,
28
+ directoryPath: "/var/lib/spawnfile/daimon/usage",
29
+ filePath: "/var/lib/spawnfile/daimon/usage/usage.jsonl",
30
+ rotatedFilePath: "/var/lib/spawnfile/daimon/usage/usage.jsonl.1",
31
+ directoryMode: 0o750,
32
+ fileMode: 0o640
33
+ };
34
+ /**
35
+ * `agent` and `wake` are caller-supplied external text (`wake` is `event.id`
36
+ * from the wake request, schema-bounded to 4096 codepoints). They are truncated
37
+ * so one record cannot grow past a size where a single `write(2)` stops being
38
+ * atomic. JSON escaping already prevents line injection.
39
+ */
40
+ export const TURN_USAGE_MAX_IDENTIFIER_CHARS = 128;
41
+ /** Rotate to a single `.1` sibling. ~2.5k lines/day observed, so this is months. */
42
+ export const TURN_USAGE_ROTATE_BYTES = 64 * 1024 * 1024;
43
+ /**
44
+ * Every engine whose headless stream reports its own token accounting.
45
+ *
46
+ * Codex, AGY, and Grok all publish decoded terminal-stream accounting here.
47
+ * Spawnfile's reader mirrors this list and is updated separately in packet
48
+ * A1b; until then, a reader that rejects `codex` will drop every Codex line.
49
+ */
50
+ export const TURN_USAGE_ENGINES = ["agy", "codex", "grok"];
51
+ /**
52
+ * Whether the wake that spent these tokens went on to succeed.
53
+ *
54
+ * Money is spent by a failed wake exactly as by a successful one, so a row is
55
+ * written whenever the engine actually reported usage — see
56
+ * `../pi/cliSession.ts`. Without this field every failed wake's spend was
57
+ * simply absent from the ledger, and an organization's cost total silently
58
+ * undercounted by however much its failures burned.
59
+ *
60
+ * `reason` is a closed vocabulary, never an engine- or error-supplied string:
61
+ * the record's rule that nothing engine-controlled and non-numeric is
62
+ * persisted still holds, and `renderTurnUsageLine` degrades anything outside
63
+ * the list to `unknown` rather than writing it through.
64
+ */
65
+ export const TURN_USAGE_OUTCOMES = ["completed", "failed"];
66
+ /**
67
+ * - `token_ceiling` — the turn's own reported usage crossed the per-wake ceiling.
68
+ * - `request_ceiling` — the broker refused a model request past the turn's request limit.
69
+ * - `wake_timeout` — the wall-clock bound fired before the child finished.
70
+ * - `output_limit` — the retained-output bound was exceeded.
71
+ * - `engine_exit` — the child exited non-zero (or died) after reporting usage.
72
+ * - `turn_rejected` — usage was reported but the decoded turn was not publishable.
73
+ * - `unknown` — any other failure (verification, cleanup, spawn).
74
+ */
75
+ export const TURN_USAGE_FAILURE_REASONS = [
76
+ "token_ceiling",
77
+ "request_ceiling",
78
+ "wake_timeout",
79
+ "output_limit",
80
+ "engine_exit",
81
+ "turn_rejected",
82
+ "unknown"
83
+ ];
84
+ /**
85
+ * Where a metered turn is appended.
86
+ *
87
+ * Production is {@link TURN_USAGE_LEDGER}`.filePath`, which Spawnfile
88
+ * provisions as a non-run-scoped volume. `DAIMON_TURN_USAGE_LEDGER_PATH`
89
+ * redirects it to an absolute path elsewhere; it exists so the wiring between a
90
+ * live engine session and this ledger can be exercised end to end, and so an
91
+ * operator can relocate the ledger without a rebuild. A relative or empty value
92
+ * is ignored rather than honoured, because a ledger written to a
93
+ * process-relative path is a ledger nobody can find again.
94
+ */
95
+ export const TURN_USAGE_LEDGER_PATH_ENV = "DAIMON_TURN_USAGE_LEDGER_PATH";
96
+ export const resolveTurnUsageLedgerPath = (environment = process.env) => {
97
+ const override = environment[TURN_USAGE_LEDGER_PATH_ENV]?.trim();
98
+ return override !== undefined && override.startsWith("/") ? override : TURN_USAGE_LEDGER.filePath;
99
+ };
100
+ const bounded = (value) => [...value].slice(0, TURN_USAGE_MAX_IDENTIFIER_CHARS).join("");
101
+ /**
102
+ * `outcome`/`reason` are an additive field pair inside the *unchanged* `v1`
103
+ * record, deliberately not a `v2`.
104
+ *
105
+ * Spawnfile's reader (`spawnfile/src/runtime/usageLedger.ts`) rejects any `v`
106
+ * that is not `noopolis.daimon.turn-usage.v1` and returns `null` for the whole
107
+ * line, while picking only the fields it knows and ignoring the rest. Bumping
108
+ * the version would therefore make an unreleased Spawnfile drop *every* row —
109
+ * strictly worse than the defect being fixed. Reading the pair is opt-in;
110
+ * every historical row lacks it and, since a failed wake previously recorded
111
+ * nothing at all, absent can be read as `completed` without ambiguity.
112
+ */
113
+ const outcomeFields = (outcome) => {
114
+ const status = outcome?.status === "failed" ? "failed" : "completed";
115
+ if (status === "completed")
116
+ return { outcome: status };
117
+ const reason = outcome?.reason;
118
+ return { outcome: status, reason: reason !== undefined && TURN_USAGE_FAILURE_REASONS.includes(reason) ? reason : "unknown" };
119
+ };
120
+ /** One complete line, newline-terminated. `JSON.stringify` escapes any embedded newline. */
121
+ export const renderTurnUsageLine = (entry) => `${JSON.stringify({
122
+ v: TURN_USAGE_LEDGER_VERSION,
123
+ agent: bounded(entry.agent),
124
+ wake: bounded(entry.wake),
125
+ engine: entry.engine,
126
+ at: entry.at ?? new Date().toISOString(),
127
+ input: entry.usage.input,
128
+ output: entry.usage.output,
129
+ cache_read: entry.usage.cacheRead,
130
+ cache_write: entry.usage.cacheWrite,
131
+ total: entry.usage.total,
132
+ calls: entry.usage.calls,
133
+ notional_usd: entry.usage.notionalUsd,
134
+ complete: entry.usage.complete,
135
+ ...outcomeFields(entry.outcome),
136
+ ...brokerFields(entry)
137
+ })}\n`;
138
+ const brokerFields = (entry) => ({
139
+ ...(entry.turn !== undefined && /^[a-f0-9]{64}$/u.test(entry.turn) ? { turn: entry.turn } : {}),
140
+ ...(entry.limitReason !== undefined && ENGINE_BROKER_LIMIT_REASONS.includes(entry.limitReason) ? { limit_reason: entry.limitReason } : {}),
141
+ ...(entry.model !== undefined && GROK_BROKER_MODELS.includes(entry.model) ? { model: entry.model } : {}),
142
+ ...(entry.estimatedRequests !== undefined && Number.isSafeInteger(entry.estimatedRequests) && entry.estimatedRequests > 0 ? { estimated_requests: entry.estimatedRequests } : {})
143
+ });
144
+ /**
145
+ * Collapse rows that share a `turn` key to the first one, keeping rows without
146
+ * a key untouched. Every reader that sums the ledger applies this, because a
147
+ * turn key exists precisely so a re-appended turn can never be counted twice.
148
+ */
149
+ export const dedupeTurnUsageRows = (rows) => {
150
+ const seen = new Set();
151
+ return rows.filter((row) => { if (typeof row.turn !== "string")
152
+ return true; if (seen.has(row.turn))
153
+ return false; seen.add(row.turn); return true; });
154
+ };
155
+ const rotate = async (file) => {
156
+ let size;
157
+ try {
158
+ size = (await stat(file)).size;
159
+ }
160
+ catch {
161
+ return;
162
+ }
163
+ if (size >= TURN_USAGE_ROTATE_BYTES)
164
+ await rename(file, `${file}.1`);
165
+ };
166
+ /**
167
+ * One `write(2)` per complete line. Turns for different agents run concurrently
168
+ * inside the single broker process, and `O_APPEND` makes a single sub-page write
169
+ * atomic against them. The directory is root-provisioned, so this never creates
170
+ * it: a missing directory is a provisioning failure, not something to paper over.
171
+ */
172
+ const appendLine = async (file, line) => {
173
+ const bytes = Buffer.from(line, "utf8");
174
+ const handle = await open(file, constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW, TURN_USAGE_LEDGER.fileMode);
175
+ try {
176
+ const { bytesWritten } = await handle.write(bytes, 0, bytes.length);
177
+ if (bytesWritten !== bytes.length)
178
+ throw new Error("turn usage ledger append was torn");
179
+ }
180
+ finally {
181
+ await handle.close();
182
+ }
183
+ };
184
+ /**
185
+ * Advisory. Never rejects.
186
+ *
187
+ * The caller runs this inside the broker's turn `try` block, after the turn has
188
+ * already been recorded as *completed*. That block's `catch` calls
189
+ * `finish(..., failed)` unconditionally, and `finish` has no terminal-state
190
+ * guard — it renames over an existing record. An escaping append error would
191
+ * therefore rewrite an already-completed turn as failed. This guard is the only
192
+ * thing preventing that, so it is the one place where getting "advisory" wrong
193
+ * corrupts turn state instead of merely dropping a line.
194
+ */
195
+ export const recordTurnUsage = async (file, entry) => {
196
+ try {
197
+ await rotate(file);
198
+ await appendLine(file, renderTurnUsageLine(entry));
199
+ }
200
+ catch {
201
+ /* advisory: a failed append never fails a turn that published */
202
+ }
203
+ };
@@ -0,0 +1,17 @@
1
+ export type TransitionLock = Readonly<{
2
+ owner_id: string;
3
+ generation: string;
4
+ pid: number;
5
+ process_start: string;
6
+ boot_id: string;
7
+ pid_namespace_dev: number;
8
+ pid_namespace_ino: number;
9
+ }>;
10
+ export declare class WakeTransitionLockBlockedError extends Error {
11
+ readonly code: "offline_reconciliation_required";
12
+ constructor();
13
+ }
14
+ export declare function sameNamespace(left: Pick<TransitionLock, "pid_namespace_dev" | "pid_namespace_ino">, right: Pick<TransitionLock, "pid_namespace_dev" | "pid_namespace_ino">): boolean;
15
+ export declare function currentProcessIdentity(): Promise<Omit<TransitionLock, "owner_id" | "generation">>;
16
+ export declare function processIsAlive(lock: TransitionLock): Promise<boolean>;
17
+ //# sourceMappingURL=wakeAcceptanceProcessIdentity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wakeAcceptanceProcessIdentity.d.ts","sourceRoot":"","sources":["../../src/runtime/wakeAcceptanceProcessIdentity.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC3L,qBAAa,8BAA+B,SAAQ,KAAK;IAAG,QAAQ,CAAC,IAAI,EAAG,iCAAiC,CAAU;;CAAmF;AAC1M,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,mBAAmB,GAAG,mBAAmB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,mBAAmB,GAAG,mBAAmB,CAAC,GAAG,OAAO,CAAqH;AAC1S,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC,CAKvG;AACD,wBAAsB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAO3E"}