@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,266 @@
1
+ import { createHash } from "node:crypto";
2
+ import { constants } from "node:fs";
3
+ import { lstat, open } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { assertGrokWorkerDenyPathsPlaceable } from "./grokWorkerDenyPlacement.js";
6
+ import { verifyGrokWorkerHome } from "./grokWorkerHomeAttestation.js";
7
+ import { grokWorkerHomeForProfile, verifyGrokWorkerTmp } from "./grokWorkerTmpAttestation.js";
8
+ import { grokWorkerEventsPathFor } from "./grokWorkerSandboxProfile.js";
9
+ export class GrokWorkerAttestationFailure extends Error {
10
+ failureClass;
11
+ constructor(failureClass) {
12
+ super("Grok worker isolation attestation unavailable");
13
+ this.failureClass = failureClass;
14
+ }
15
+ }
16
+ /**
17
+ * Reads the `deny` list out of a worker sandbox profile, but only after the
18
+ * bytes match `profileSha256` exactly.
19
+ *
20
+ * There is no minimum length, and a populated list is supported. Grok 1.0.13
21
+ * refused to start on any non-empty `deny` (its mode-000 placeholders failed
22
+ * an EACCES "__GROK_INSIDE_BWRAP spoof" check), so deployments rendered
23
+ * `deny = []`. Grok 1.0.34 runs every profile inside bubblewrap and enforces a
24
+ * non-empty list, and since its strict base reads all of `/run`, `/var` and
25
+ * `/tmp`, the deny list is what keeps evaluator and host-bind paths away from
26
+ * the worker. `grokWorkerSandboxProfile.ts` renders these bytes.
27
+ *
28
+ * The integrity guarantee is the hash pin, not the length. `profileSha256`
29
+ * comes from `/etc/daimon-engine-broker/service.json`, which the root
30
+ * provisioning phase writes `0440 root:2100` with `flag: 'wx'` and computes
31
+ * from the same `profileFor()` bytes it writes to the profile; the broker
32
+ * reads that config as uid 2100 and cannot rewrite it. A weaker profile
33
+ * therefore cannot be attested: changing any byte — dropping
34
+ * `restrict_network`, swapping `extends = "strict"` for a permissive base,
35
+ * renaming the profile — changes the digest and fails here. And the deny list
36
+ * this returns is not merely parsed and discarded: it is carried into the
37
+ * snapshot and re-asserted against the kernel's own `ProfileApplied`
38
+ * `deny_paths` by `parseGrokWorkerProfileApplied`, which independently
39
+ * requires `enforced`, `restrict_network`, `platform === "linux/landlock"`
40
+ * and the exact workspace. A length floor would only have caught a Spawnfile
41
+ * rendering bug that produced a trivial profile *and* pinned it consistently
42
+ * — and Spawnfile's own tests pin the rendered bytes.
43
+ */
44
+ export function parseGrokWorkerSandboxProfile(bytes, profileSha256) {
45
+ // Never copy the caller's bytes: `prepareGrokWorkerAttestation` zeroes the
46
+ // buffer it owns, and a private copy here would survive that.
47
+ const buffer = Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
48
+ if (createHash("sha256").update(buffer).digest("hex") !== profileSha256)
49
+ throw new Error("Grok worker isolation attestation unavailable");
50
+ const line = buffer.toString("utf8").split("\n").find((entry) => entry.startsWith("deny = "));
51
+ let parsed;
52
+ try {
53
+ parsed = JSON.parse(line?.slice(7) ?? "null");
54
+ }
55
+ catch {
56
+ throw new Error("Grok worker isolation attestation unavailable");
57
+ }
58
+ if (!Array.isArray(parsed) || parsed.some((entry) => typeof entry !== "string") || new Set(parsed).size !== parsed.length)
59
+ throw new Error("Grok worker isolation attestation unavailable");
60
+ return [...parsed].sort();
61
+ }
62
+ /**
63
+ * Pre-launch half of the per-turn attestation. Besides the pinned profile and
64
+ * the events watermark it requires the 1.0.34 layout: events under
65
+ * `$GROK_HOME/sessions/` (the root `sandbox-events.jsonl` stays empty on
66
+ * 1.0.34), and a root-owned read-only worker home whose `config.toml` hashes to
67
+ * the declared renderer output (`grokWorkerHomeAttestation.ts`).
68
+ *
69
+ * It also refuses a deny list bubblewrap could not materialize
70
+ * (`grokWorkerDenyPlacement.ts`), naming the entry and the ancestor that stops
71
+ * it. Without this the worker dies with a bare `bwrap: Can't create file at
72
+ * …: Permission denied` on *every* turn, because one unplaceable entry makes
73
+ * Grok refuse the whole profile. The broker cannot descend into a directory
74
+ * opened to the worker's group alone (`<runtime home>/tool-state` under a
75
+ * `2000:<worker> 0710` home), so an `EACCES` there is left undecided; root
76
+ * provisioning, which holds `CAP_DAC_READ_SEARCH`, is the authority that
77
+ * decides every entry.
78
+ */
79
+ export async function prepareGrokWorkerAttestation(input, profileOwner = { uid: 0, gid: 0 }) {
80
+ if (input.eventsPath !== grokWorkerEventsPathFor(input.profilePath))
81
+ throw new Error("Grok worker sandbox events must be read from $GROK_HOME/sessions/sandbox-events.jsonl");
82
+ const profile = await secureOpen(input.profilePath, profileOwner.uid, profileOwner.gid, 0o444, 65_536);
83
+ let bytes;
84
+ let denyPaths = [];
85
+ try {
86
+ bytes = await profile.readFile();
87
+ denyPaths = parseGrokWorkerSandboxProfile(bytes, input.profileSha256);
88
+ }
89
+ catch {
90
+ throw new Error("Grok worker isolation attestation unavailable");
91
+ }
92
+ finally {
93
+ bytes?.fill(0);
94
+ await profile.close();
95
+ }
96
+ // The launcher exports TMPDIR=<registered home>/tmp; the profile lives at <home>/.grok/sandbox.toml.
97
+ // Every registered worker's private temp is attested, not only this one's (a sibling's open temp is a shared channel).
98
+ await assertGrokWorkerDenyPathsPlaceable(denyPaths, { uid: input.workerUid, gid: input.workerGid ?? input.workerUid });
99
+ const workers = [{ profilePath: input.profilePath, workerUid: input.workerUid }, ...(input.registeredWorkers ?? [])].map((worker) => ({ home: grokWorkerHomeForProfile(worker.profilePath), uid: worker.workerUid }));
100
+ if (workers.some((worker) => worker.home === undefined))
101
+ throw new Error("Grok worker isolation attestation unavailable");
102
+ await verifyGrokWorkerTmp(workers, profileOwner.tmp);
103
+ await verifyGrokWorkerHome(path.dirname(input.profilePath), input.configSha256);
104
+ const events = await secureOpen(input.eventsPath, input.workerUid, input.brokerGid, 0o640, 16 * 1024 * 1024);
105
+ try {
106
+ const stat = await events.stat();
107
+ return { dev: Number(stat.dev), ino: Number(stat.ino), size: Number(stat.size), denyPaths };
108
+ }
109
+ finally {
110
+ await events.close();
111
+ }
112
+ }
113
+ /** The per-turn attestation input for one registration, carrying every registered worker so sibling temp is attested too. */
114
+ export const grokBrokerAttestationInput = (registration, registrations, configSha256) => ({ ...registration, brokerGid: 2100, configSha256, registeredWorkers: registrations.map((entry) => ({ profilePath: entry.profilePath, workerUid: entry.workerUid })) });
115
+ /**
116
+ * The per-turn isolation guard: every model request of a turn, and the
117
+ * post-turn check, go through the same lock.
118
+ *
119
+ * Why the first verification is trustworthy: the proxy awaits this guard before
120
+ * *every* upstream request, including the first, and the only worker-uid
121
+ * process that exists before request 1 is the Grok the launcher started under
122
+ * the pinned profile — tool children are created only after a model response.
123
+ * So the event accepted at request 1 was written before any tool child could
124
+ * write to the (worker-owned) events file. Later requests must find that exact
125
+ * line, byte for byte, at the same offset: a `ProfileApplied` appended later —
126
+ * which a tool child could forge — is never a substitute, and once a turn has
127
+ * been refused it stays refused.
128
+ */
129
+ export function createGrokWorkerIsolationGuard(input, before) {
130
+ const lock = {};
131
+ return async () => {
132
+ if (lock.refused !== undefined)
133
+ throw new GrokWorkerAttestationFailure(lock.refused);
134
+ try {
135
+ await verifyGrokWorkerAttestation(input, before, lock);
136
+ }
137
+ catch (error) {
138
+ const failure = error instanceof GrokWorkerAttestationFailure ? error : new GrokWorkerAttestationFailure("profile_invalid");
139
+ lock.refused = failure.failureClass;
140
+ throw failure;
141
+ }
142
+ };
143
+ }
144
+ export async function verifyGrokWorkerAttestation(input, before, lock) {
145
+ let handle;
146
+ try {
147
+ handle = await secureOpen(input.eventsPath, input.workerUid, input.brokerGid, 0o640, 16 * 1024 * 1024);
148
+ }
149
+ catch {
150
+ throw new GrokWorkerAttestationFailure("profile_invalid");
151
+ }
152
+ let bytes;
153
+ try {
154
+ const stat = await handle.stat();
155
+ if (Number(stat.dev) !== before.dev || Number(stat.ino) !== before.ino)
156
+ throw new GrokWorkerAttestationFailure("profile_invalid");
157
+ if (Number(stat.size) <= before.size)
158
+ throw new GrokWorkerAttestationFailure("profile_missing");
159
+ const accepted = lock?.accepted;
160
+ const start = accepted === undefined ? before.size : before.size + accepted.offset;
161
+ const length = accepted === undefined ? Number(stat.size) - before.size : accepted.length;
162
+ if (start + length > Number(stat.size))
163
+ throw new GrokWorkerAttestationFailure("profile_invalid");
164
+ bytes = Buffer.alloc(length);
165
+ const read = await handle.read(bytes, 0, bytes.length, start);
166
+ if (read.bytesRead !== bytes.length)
167
+ throw new GrokWorkerAttestationFailure("profile_invalid");
168
+ // The file must not change while it is read: a concurrent writer could
169
+ // otherwise show this check bytes that no single state of the file held.
170
+ const after = await handle.stat();
171
+ if (Number(after.size) !== Number(stat.size) || Number(after.mtimeMs) !== Number(stat.mtimeMs))
172
+ throw new GrokWorkerAttestationFailure("profile_invalid");
173
+ if (accepted !== undefined) {
174
+ if (createHash("sha256").update(bytes).digest("hex") !== accepted.digest)
175
+ throw new GrokWorkerAttestationFailure("profile_invalid");
176
+ return;
177
+ }
178
+ const event = locateGrokWorkerProfileApplied(bytes, input.workspace, before.denyPaths);
179
+ if (lock !== undefined)
180
+ lock.accepted = { offset: event.offset, length: event.length, digest: createHash("sha256").update(bytes.subarray(event.offset, event.offset + event.length)).digest("hex") };
181
+ }
182
+ catch (error) {
183
+ if (error instanceof GrokWorkerAttestationFailure)
184
+ throw error;
185
+ throw new GrokWorkerAttestationFailure("profile_invalid");
186
+ }
187
+ finally {
188
+ bytes?.fill(0);
189
+ await handle.close();
190
+ }
191
+ }
192
+ /**
193
+ * Requires one fully-conforming `ProfileApplied` event *somewhere* in the
194
+ * fresh region — not as its last line.
195
+ *
196
+ * `sandbox-events.jsonl` is not a profile log. Grok (1.0.13 and 1.0.34) writes its whole
197
+ * sandbox event vocabulary there — verified by reading the shipped binary:
198
+ * `ProfileApplied, ApplyFailed, FsViolation, NetViolation, BypassGranted,
199
+ * BypassDenied` (one contiguous enum blob beside the record fields
200
+ * `timestamp, event_type, read_only_paths, deny_paths, operation, target,
201
+ * command, tool_call_id`, emitted from `xai_grok_sandbox::logging`), and its
202
+ * own embedded documentation says so outright: "Sandbox events (profile
203
+ * applied, violations) are logged to `~/.grok/sandbox-events.jsonl`" (1.0.34
204
+ * moved the file to `~/.grok/sessions/`; a 1.0.34 turn logs `ProfileApplied`
205
+ * followed by an `FsViolation` for every denied read).
206
+ *
207
+ * Requiring `ProfileApplied` to be the *last* line therefore failed on the
208
+ * first denied access of any turn: the violation Grok logged next became the
209
+ * last line, this threw, the proxy's per-request isolation guard refused, and
210
+ * the turn died `profile_invalid`. Denials are the normal operating state of
211
+ * a working sandbox, so that check turned the sandbox doing its job into a
212
+ * turn failure.
213
+ *
214
+ * Scanning the region is not weaker. The region is fresh by construction —
215
+ * the caller reads only bytes above the pre-launch dev/ino/size watermark, so
216
+ * nothing here predates this turn and a stale or replayed event below it is
217
+ * unreachable. Both forms are equally forgeable by the same single actor (a
218
+ * worker-uid process, which can only exist by being a Grok that the launcher
219
+ * already started under the pinned profile), and both detect the failure this
220
+ * guard exists for: a Grok that came up without kernel enforcement, which
221
+ * emits no conforming `ProfileApplied` at all.
222
+ */
223
+ export function parseGrokWorkerProfileApplied(bytes, workspace, denyPaths = []) { locateGrokWorkerProfileApplied(bytes, workspace, denyPaths); }
224
+ /** Byte range (within `bytes`) of the first fully-conforming `ProfileApplied` line. */
225
+ export function locateGrokWorkerProfileApplied(bytes, workspace, denyPaths = []) {
226
+ const expected = JSON.stringify([...denyPaths].sort());
227
+ const buffer = Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
228
+ for (let offset = 0; offset < buffer.length;) {
229
+ const newline = buffer.indexOf(0x0a, offset);
230
+ const end = newline === -1 ? buffer.length : newline;
231
+ const line = buffer.subarray(offset, end).toString("utf8");
232
+ const lineOffset = offset;
233
+ offset = end + 1;
234
+ if (line.trim() === "")
235
+ continue;
236
+ let event;
237
+ try {
238
+ const parsed = JSON.parse(line);
239
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
240
+ continue;
241
+ event = parsed;
242
+ }
243
+ catch {
244
+ continue;
245
+ }
246
+ if (event.event_type !== "ProfileApplied")
247
+ continue;
248
+ const observed = Array.isArray(event.deny_paths) ? event.deny_paths.filter((entry) => typeof entry === "string").sort() : [];
249
+ if (event.profile === "daimon-strict" && event.enforced === true && event.restrict_network === true && event.platform === "linux/landlock" && event.workspace === workspace && JSON.stringify(observed) === expected)
250
+ return { offset: lineOffset, length: end - lineOffset };
251
+ }
252
+ throw new Error("Grok worker isolation attestation unavailable");
253
+ }
254
+ async function secureOpen(file, uid, gid, mode, max, links = 1) { try {
255
+ const before = await lstat(file);
256
+ const handle = await open(file, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
257
+ const stat = await handle.stat();
258
+ if (!stat.isFile() || stat.isSymbolicLink() || Number(stat.uid) !== uid || Number(stat.gid) !== gid || (Number(stat.mode) & 0o777) !== mode || Number(stat.nlink) !== links || Number(stat.size) > max || before.dev !== stat.dev || before.ino !== stat.ino) {
259
+ await handle.close();
260
+ throw new Error();
261
+ }
262
+ return handle;
263
+ }
264
+ catch {
265
+ throw new Error("Grok worker isolation attestation unavailable");
266
+ } }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Paths Grok 1.0.34's strict base profile grants read or read-write. A `deny`
3
+ * entry that equals or contains one of them makes Grok refuse the profile
4
+ * outright (verified for `/tmp`, `/var/tmp`, `/run`, `/etc`, `/var` and
5
+ * `sessions`; `/tmp/sub` is accepted), so every entry must sit strictly below
6
+ * each grant it touches.
7
+ */
8
+ export declare const GROK_WORKER_BASE_PROFILE_GRANTS: readonly ["/bin", "/dev", "/etc", "/lib", "/proc", "/run", "/sbin", "/sys", "/tmp", "/usr", "/var", "/var/tmp"];
9
+ export declare class GrokWorkerDenyPlacementError extends Error {
10
+ readonly denyPath: string;
11
+ readonly reason: string;
12
+ constructor(denyPath: string, reason: string);
13
+ }
14
+ /**
15
+ * The shape half of the deny-placement policy: everything decidable without
16
+ * touching a filesystem, so the profile renderer can refuse a bad entry before
17
+ * its bytes are ever pinned or written.
18
+ *
19
+ * `renderGrokWorkerSandboxProfile` already refuses entries that are relative,
20
+ * non-canonical, `/`, trailing-slashed, or carrying a character TOML or Grok
21
+ * would reinterpret; this adds the base-profile grant rule.
22
+ */
23
+ export declare function assertGrokWorkerDenyPathShape(denyPath: string): void;
24
+ /** The subset of `lstat` the placement rules read; pure so every refusal is testable without root. */
25
+ export type GrokWorkerDenyPathEntry = Readonly<{
26
+ uid: number;
27
+ gid: number;
28
+ mode: number;
29
+ isDirectory: () => boolean;
30
+ isSymbolicLink: () => boolean;
31
+ }>;
32
+ /** One resolved path component: the entry, or the errno that stopped the walk. */
33
+ export type GrokWorkerDenyPathStep = Readonly<{
34
+ path: string;
35
+ entry?: GrokWorkerDenyPathEntry;
36
+ code?: string;
37
+ }>;
38
+ export type GrokWorkerDenyPathWorker = Readonly<{
39
+ uid: number;
40
+ gid: number;
41
+ }>;
42
+ /**
43
+ * POSIX search permission: owner bits win, then group, then other. The worker
44
+ * runs with its supplementary groups cleared, so its primary gid is the only
45
+ * group that can apply.
46
+ */
47
+ export declare const grokWorkerCanSearch: (entry: GrokWorkerDenyPathEntry, worker: GrokWorkerDenyPathWorker) => boolean;
48
+ /** The `/`-rooted ancestor chain of `denyPath`, deepest last, followed by the entry itself. */
49
+ export declare const grokWorkerDenyPathChain: (denyPath: string) => readonly string[];
50
+ /**
51
+ * The placement half of the policy, as a pure function of an already-walked
52
+ * chain.
53
+ *
54
+ * Grok 1.0.34 materializes every `deny` entry inside bubblewrap **as the worker
55
+ * uid**, by bind-mounting `$GROK_HOME/sandbox-blocked-{file,dir}` over the
56
+ * target. So bwrap must be able to *resolve* the target as that uid: every
57
+ * ancestor directory needs the search bit for it, and the target must already
58
+ * exist — otherwise bwrap tries to create it and needs write on the parent,
59
+ * which a private parent never grants. A single unplaceable entry makes Grok
60
+ * refuse the whole profile, so every turn of that worker fails, not just that
61
+ * path. Verified matrix: `.runtime/grok-deny-placement/EVIDENCE.md`.
62
+ *
63
+ * The walk may legitimately stop early: a caller that is neither root nor the
64
+ * worker (the broker, uid 2100) cannot descend into a directory the worker's
65
+ * own group opens to it alone — `<runtime home>/tool-state` under a
66
+ * `2000:<worker> 0710` runtime home is exactly that. An `EACCES` below an
67
+ * ancestor the *worker* can search is therefore "not decidable from here", not
68
+ * a refusal; every decidable failure still refuses.
69
+ */
70
+ export declare function assertGrokWorkerDenyPathPlacement(denyPath: string, steps: readonly GrokWorkerDenyPathStep[], worker: GrokWorkerDenyPathWorker): void;
71
+ /** Walks one deny path on the real filesystem, recording what stopped it rather than throwing. */
72
+ export declare function readGrokWorkerDenyPathChain(denyPath: string): Promise<readonly GrokWorkerDenyPathStep[]>;
73
+ /**
74
+ * Fails closed before a worker is ever launched with a profile Grok would
75
+ * refuse. Callers with the widest view run it: root provisioning at container
76
+ * start and on every slot recycle, and the direct (non-broker) path, which runs
77
+ * as the worker uid itself.
78
+ */
79
+ export declare function assertGrokWorkerDenyPathsPlaceable(denyPaths: readonly string[], worker: GrokWorkerDenyPathWorker): Promise<void>;
80
+ //# sourceMappingURL=grokWorkerDenyPlacement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grokWorkerDenyPlacement.d.ts","sourceRoot":"","sources":["../../src/runtime/grokWorkerDenyPlacement.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,iHAEjC,CAAC;AAIZ,qBAAa,4BAA6B,SAAQ,KAAK;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM;gBAAzC,QAAQ,EAAE,MAAM,EAAW,MAAM,EAAE,MAAM;CAI/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAKpE;AAED,sGAAsG;AACtG,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B,cAAc,EAAE,MAAM,OAAO,CAAC;CAC/B,CAAC,CAAC;AAEH,kFAAkF;AAClF,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEhH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE9E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,uBAAuB,EAAE,QAAQ,wBAAwB,KAAG,OAGrE,CAAC;AAEnC,+FAA+F;AAC/F,eAAO,MAAM,uBAAuB,GAAI,UAAU,MAAM,KAAG,SAAS,MAAM,EAGzE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,sBAAsB,EAAE,EACxC,MAAM,EAAE,wBAAwB,GAC/B,IAAI,CAqBN;AAED,kGAAkG;AAClG,wBAAsB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,sBAAsB,EAAE,CAAC,CAa9G;AAED;;;;;GAKG;AACH,wBAAsB,kCAAkC,CACtD,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -0,0 +1,128 @@
1
+ import { lstat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ /**
4
+ * Paths Grok 1.0.34's strict base profile grants read or read-write. A `deny`
5
+ * entry that equals or contains one of them makes Grok refuse the profile
6
+ * outright (verified for `/tmp`, `/var/tmp`, `/run`, `/etc`, `/var` and
7
+ * `sessions`; `/tmp/sub` is accepted), so every entry must sit strictly below
8
+ * each grant it touches.
9
+ */
10
+ export const GROK_WORKER_BASE_PROFILE_GRANTS = Object.freeze([
11
+ "/bin", "/dev", "/etc", "/lib", "/proc", "/run", "/sbin", "/sys", "/tmp", "/usr", "/var", "/var/tmp"
12
+ ]);
13
+ const within = (candidate, root) => candidate === root || candidate.startsWith(`${root}/`);
14
+ export class GrokWorkerDenyPlacementError extends Error {
15
+ denyPath;
16
+ reason;
17
+ constructor(denyPath, reason) {
18
+ super(`Grok worker sandbox deny path ${JSON.stringify(denyPath)} is not placeable: ${reason}`);
19
+ this.denyPath = denyPath;
20
+ this.reason = reason;
21
+ this.name = "GrokWorkerDenyPlacementError";
22
+ }
23
+ }
24
+ /**
25
+ * The shape half of the deny-placement policy: everything decidable without
26
+ * touching a filesystem, so the profile renderer can refuse a bad entry before
27
+ * its bytes are ever pinned or written.
28
+ *
29
+ * `renderGrokWorkerSandboxProfile` already refuses entries that are relative,
30
+ * non-canonical, `/`, trailing-slashed, or carrying a character TOML or Grok
31
+ * would reinterpret; this adds the base-profile grant rule.
32
+ */
33
+ export function assertGrokWorkerDenyPathShape(denyPath) {
34
+ const grant = GROK_WORKER_BASE_PROFILE_GRANTS.find((candidate) => within(candidate, denyPath));
35
+ if (grant !== undefined) {
36
+ throw new GrokWorkerDenyPlacementError(denyPath, `it equals or contains the base profile grant ${grant}, which Grok refuses`);
37
+ }
38
+ }
39
+ /**
40
+ * POSIX search permission: owner bits win, then group, then other. The worker
41
+ * runs with its supplementary groups cleared, so its primary gid is the only
42
+ * group that can apply.
43
+ */
44
+ export const grokWorkerCanSearch = (entry, worker) => entry.uid === worker.uid ? (entry.mode & 0o100) !== 0
45
+ : entry.gid === worker.gid ? (entry.mode & 0o010) !== 0
46
+ : (entry.mode & 0o001) !== 0;
47
+ /** The `/`-rooted ancestor chain of `denyPath`, deepest last, followed by the entry itself. */
48
+ export const grokWorkerDenyPathChain = (denyPath) => {
49
+ const components = denyPath.split("/").slice(1);
50
+ return ["/", ...components.map((_, index) => `/${components.slice(0, index + 1).join("/")}`)];
51
+ };
52
+ /**
53
+ * The placement half of the policy, as a pure function of an already-walked
54
+ * chain.
55
+ *
56
+ * Grok 1.0.34 materializes every `deny` entry inside bubblewrap **as the worker
57
+ * uid**, by bind-mounting `$GROK_HOME/sandbox-blocked-{file,dir}` over the
58
+ * target. So bwrap must be able to *resolve* the target as that uid: every
59
+ * ancestor directory needs the search bit for it, and the target must already
60
+ * exist — otherwise bwrap tries to create it and needs write on the parent,
61
+ * which a private parent never grants. A single unplaceable entry makes Grok
62
+ * refuse the whole profile, so every turn of that worker fails, not just that
63
+ * path. Verified matrix: `.runtime/grok-deny-placement/EVIDENCE.md`.
64
+ *
65
+ * The walk may legitimately stop early: a caller that is neither root nor the
66
+ * worker (the broker, uid 2100) cannot descend into a directory the worker's
67
+ * own group opens to it alone — `<runtime home>/tool-state` under a
68
+ * `2000:<worker> 0710` runtime home is exactly that. An `EACCES` below an
69
+ * ancestor the *worker* can search is therefore "not decidable from here", not
70
+ * a refusal; every decidable failure still refuses.
71
+ */
72
+ export function assertGrokWorkerDenyPathPlacement(denyPath, steps, worker) {
73
+ assertGrokWorkerDenyPathShape(denyPath);
74
+ const chain = grokWorkerDenyPathChain(denyPath);
75
+ if (steps.length !== chain.length || steps.some((step, index) => step.path !== chain[index])) {
76
+ throw new GrokWorkerDenyPlacementError(denyPath, "its resolved path chain does not match the entry");
77
+ }
78
+ for (const [index, step] of steps.entries()) {
79
+ const ancestor = index < steps.length - 1;
80
+ if (step.entry === undefined) {
81
+ if (step.code === "ENOENT")
82
+ throw new GrokWorkerDenyPlacementError(denyPath, `${step.path} does not exist; bubblewrap would have to create it as the worker uid`);
83
+ if (step.code !== "EACCES")
84
+ throw new GrokWorkerDenyPlacementError(denyPath, `${step.path} could not be read (${step.code ?? "unknown error"})`);
85
+ // Undecidable from here, and only after every shallower ancestor passed.
86
+ return;
87
+ }
88
+ if (step.entry.isSymbolicLink())
89
+ throw new GrokWorkerDenyPlacementError(denyPath, `${step.path} is a symlink; bubblewrap refuses to bind over one`);
90
+ if (!ancestor)
91
+ return;
92
+ if (!step.entry.isDirectory())
93
+ throw new GrokWorkerDenyPlacementError(denyPath, `${step.path} is not a directory`);
94
+ if (!grokWorkerCanSearch(step.entry, worker)) {
95
+ throw new GrokWorkerDenyPlacementError(denyPath, `worker uid ${worker.uid} cannot search ${step.path} (${(step.entry.mode & 0o7777).toString(8)} ${step.entry.uid}:${step.entry.gid}); deny that directory itself instead`);
96
+ }
97
+ }
98
+ }
99
+ /** Walks one deny path on the real filesystem, recording what stopped it rather than throwing. */
100
+ export async function readGrokWorkerDenyPathChain(denyPath) {
101
+ const steps = [];
102
+ for (const target of grokWorkerDenyPathChain(denyPath)) {
103
+ try {
104
+ steps.push({ path: target, entry: await lstat(target) });
105
+ }
106
+ catch (error) {
107
+ steps.push({ path: target, code: error.code });
108
+ break;
109
+ }
110
+ }
111
+ const chain = grokWorkerDenyPathChain(denyPath);
112
+ while (steps.length < chain.length)
113
+ steps.push({ path: chain[steps.length], code: steps.at(-1)?.code ?? "EACCES" });
114
+ return steps;
115
+ }
116
+ /**
117
+ * Fails closed before a worker is ever launched with a profile Grok would
118
+ * refuse. Callers with the widest view run it: root provisioning at container
119
+ * start and on every slot recycle, and the direct (non-broker) path, which runs
120
+ * as the worker uid itself.
121
+ */
122
+ export async function assertGrokWorkerDenyPathsPlaceable(denyPaths, worker) {
123
+ for (const denyPath of denyPaths) {
124
+ if (!path.posix.isAbsolute(denyPath))
125
+ throw new GrokWorkerDenyPlacementError(denyPath, "it is not an absolute path");
126
+ assertGrokWorkerDenyPathPlacement(denyPath, await readGrokWorkerDenyPathChain(denyPath), worker);
127
+ }
128
+ }
@@ -0,0 +1,30 @@
1
+ import { type Stats } from "node:fs";
2
+ type Entry = Pick<Stats, "uid" | "mode" | "nlink"> & Partial<Pick<Stats, "dev" | "ino">> & Readonly<{
3
+ isFile(): boolean;
4
+ isDirectory(): boolean;
5
+ isSymbolicLink(): boolean;
6
+ }>;
7
+ /**
8
+ * The worker must not be able to change what Grok reads before its next turn.
9
+ *
10
+ * Grok writes its own state (sessions, hooks, locks, docs) into `$GROK_HOME`,
11
+ * so the directory is worker-group writable — but root-owned and sticky, so a
12
+ * worker can neither rename nor unlink a root-owned file in it. Every file
13
+ * that decides a turn's behaviour is root-owned with no write bit: `config.toml`
14
+ * (model, effort, MCP, skills), `sandbox.toml`, `trusted_folders.toml` (trust
15
+ * would re-enable cwd `AGENTS.md` and project skills), and the managed and
16
+ * requirements layers that can override user config. A missing file fails
17
+ * too: the worker could create it.
18
+ *
19
+ * Pure so every refusal is testable without root.
20
+ */
21
+ export declare function assertGrokWorkerHomeEntries(entries: Readonly<Record<string, Entry | undefined>>, rootUid?: number): void;
22
+ /** The worker's `config.toml` must be exactly the renderer's bytes for the declared policy. */
23
+ export declare function assertGrokWorkerConfigBytes(bytes: Uint8Array, configSha256: string): void;
24
+ /**
25
+ * Attests the worker home layout and that `config.toml` is exactly the
26
+ * renderer's bytes for the declared model policy (`configSha256`).
27
+ */
28
+ export declare function verifyGrokWorkerHome(grokHome: string, configSha256: string, rootUid?: number): Promise<void>;
29
+ export {};
30
+ //# sourceMappingURL=grokWorkerHomeAttestation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grokWorkerHomeAttestation.d.ts","sourceRoot":"","sources":["../../src/runtime/grokWorkerHomeAttestation.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAMhD,KAAK,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC,GAAG,QAAQ,CAAC;IAAE,MAAM,IAAI,OAAO,CAAC;IAAC,WAAW,IAAI,OAAO,CAAC;IAAC,cAAc,IAAI,OAAO,CAAA;CAAE,CAAC,CAAC;AAG9K;;;;;;;;;;;;;GAaG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,SAAS,CAAC,CAAC,EAAE,OAAO,GAAE,MAA2B,GAAG,IAAI,CAS5I;AAED,+FAA+F;AAC/F,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAEzF;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAE,MAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAetI"}
@@ -0,0 +1,69 @@
1
+ import { createHash } from "node:crypto";
2
+ import { constants } from "node:fs";
3
+ import { lstat, open } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { GROK_ENGINE_BROKER } from "../contracts/runtimeContractManifest.js";
6
+ const HOME = GROK_ENGINE_BROKER.worker.home;
7
+ /**
8
+ * The worker must not be able to change what Grok reads before its next turn.
9
+ *
10
+ * Grok writes its own state (sessions, hooks, locks, docs) into `$GROK_HOME`,
11
+ * so the directory is worker-group writable — but root-owned and sticky, so a
12
+ * worker can neither rename nor unlink a root-owned file in it. Every file
13
+ * that decides a turn's behaviour is root-owned with no write bit: `config.toml`
14
+ * (model, effort, MCP, skills), `sandbox.toml`, `trusted_folders.toml` (trust
15
+ * would re-enable cwd `AGENTS.md` and project skills), and the managed and
16
+ * requirements layers that can override user config. A missing file fails
17
+ * too: the worker could create it.
18
+ *
19
+ * Pure so every refusal is testable without root.
20
+ */
21
+ export function assertGrokWorkerHomeEntries(entries, rootUid = HOME.directory.uid) {
22
+ const directory = (entry) => entry !== undefined && entry.isDirectory() && !entry.isSymbolicLink() && entry.uid === rootUid
23
+ && (Number(entry.mode) & 0o002) === 0 && ((Number(entry.mode) & 0o020) === 0 || (Number(entry.mode) & 0o1000) !== 0);
24
+ if (!directory(entries["."]) || !directory(entries[HOME.sessionsDirectory.relativePath]))
25
+ throw unavailable();
26
+ for (const name of HOME.readOnlyFiles.names) {
27
+ const entry = entries[name];
28
+ if (entry === undefined || !entry.isFile() || entry.isSymbolicLink() || entry.uid !== rootUid || entry.nlink !== 1 || (Number(entry.mode) & 0o7222) !== 0)
29
+ throw unavailable();
30
+ }
31
+ }
32
+ /** The worker's `config.toml` must be exactly the renderer's bytes for the declared policy. */
33
+ export function assertGrokWorkerConfigBytes(bytes, configSha256) {
34
+ if (!/^[0-9a-f]{64}$/u.test(configSha256) || createHash("sha256").update(bytes).digest("hex") !== configSha256)
35
+ throw unavailable();
36
+ }
37
+ /**
38
+ * Attests the worker home layout and that `config.toml` is exactly the
39
+ * renderer's bytes for the declared model policy (`configSha256`).
40
+ */
41
+ export async function verifyGrokWorkerHome(grokHome, configSha256, rootUid = HOME.directory.uid) {
42
+ const entries = {};
43
+ for (const name of [".", HOME.sessionsDirectory.relativePath, ...HOME.readOnlyFiles.names]) {
44
+ try {
45
+ entries[name] = await lstat(path.join(grokHome, name));
46
+ }
47
+ catch {
48
+ entries[name] = undefined;
49
+ }
50
+ }
51
+ assertGrokWorkerHomeEntries(entries, rootUid);
52
+ let handle;
53
+ try {
54
+ handle = await open(path.join(grokHome, "config.toml"), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
55
+ const opened = await handle.stat();
56
+ const before = entries["config.toml"];
57
+ // Same inode as the lstat above, as in `secureOpen`: a rename between the two cannot swap in other bytes.
58
+ if (!opened.isFile() || opened.size > 65_536 || opened.dev !== before.dev || opened.ino !== before.ino || opened.uid !== before.uid || opened.mode !== before.mode || opened.nlink !== 1)
59
+ throw unavailable();
60
+ assertGrokWorkerConfigBytes(await handle.readFile(), configSha256);
61
+ }
62
+ catch {
63
+ throw unavailable();
64
+ }
65
+ finally {
66
+ await handle?.close().catch(() => undefined);
67
+ }
68
+ }
69
+ const unavailable = () => new Error("Grok worker isolation attestation unavailable");
@@ -0,0 +1,27 @@
1
+ export declare const GROK_WORKER_SANDBOX_PROFILE: "daimon-strict";
2
+ export declare const GROK_WORKER_SANDBOX_EVENTS_RELATIVE_PATH: "sessions/sandbox-events.jsonl";
3
+ /**
4
+ * The only source of `daimon-strict` sandbox profile bytes.
5
+ *
6
+ * Grok 1.0.34 runs every Landlock profile inside bubblewrap, and there a
7
+ * non-empty `deny` list works: each entry is bind-masked for both the shell
8
+ * tool and in-process `read_file` (P0: `/run/paideia` denied, controls intact).
9
+ * The strict base still reads all of `/run`, `/var`, `/tmp` and `/etc`, so the
10
+ * deny list — not Landlock's allowlist — is what keeps evaluator and host-bind
11
+ * paths away from the worker. Which paths to deny is a registration input
12
+ * supplied by the deployment; Daimon only renders, pins, and attests them.
13
+ *
14
+ * Entries are sorted and deduplicated so equal sets render equal bytes (and the
15
+ * same `profileSha256`). A path that is not absolute and canonical, or that
16
+ * carries a character TOML or Grok would reinterpret, is refused — and so is
17
+ * one that equals or contains a base-profile grant, the first half of the
18
+ * deny-placement policy (`grokWorkerDenyPlacement.ts`). The other half —
19
+ * the entry exists and every ancestor is searchable by the worker uid — needs
20
+ * a filesystem, so it is asserted by whoever provisions the paths and, on the
21
+ * direct path, before every turn.
22
+ */
23
+ export declare function renderGrokWorkerSandboxProfile(denyPaths?: readonly string[]): string;
24
+ export declare const grokWorkerSandboxProfileSha256: (denyPaths?: readonly string[]) => string;
25
+ /** `$GROK_HOME` is the profile's directory; 1.0.34 logs sandbox events under `sessions/`. */
26
+ export declare const grokWorkerEventsPathFor: (profilePath: string) => string;
27
+ //# sourceMappingURL=grokWorkerSandboxProfile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grokWorkerSandboxProfile.d.ts","sourceRoot":"","sources":["../../src/runtime/grokWorkerSandboxProfile.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,2BAA2B,EAAG,eAAwB,CAAC;AACpE,eAAO,MAAM,wCAAwC,EAAG,+BAAwC,CAAC;AAEjG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,8BAA8B,CAAC,SAAS,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,CAexF;AAED,eAAO,MAAM,8BAA8B,GAAI,YAAW,SAAS,MAAM,EAAO,KAAG,MACG,CAAC;AAEvF,6FAA6F;AAC7F,eAAO,MAAM,uBAAuB,GAAI,aAAa,MAAM,KAAG,MAC8B,CAAC"}