@noopolis/daimon 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/README.md +6 -0
  2. package/dist/contracts/attentionContract.d.ts +25 -0
  3. package/dist/contracts/attentionContract.d.ts.map +1 -1
  4. package/dist/contracts/attentionContract.js +8 -1
  5. package/dist/contracts/grokBrokerTaskClock.d.ts +18 -0
  6. package/dist/contracts/grokBrokerTaskClock.d.ts.map +1 -0
  7. package/dist/contracts/grokBrokerTaskClock.js +16 -0
  8. package/dist/contracts/organizationRuntimeContract.d.ts +76 -0
  9. package/dist/contracts/organizationRuntimeContract.d.ts.map +1 -1
  10. package/dist/contracts/organizationRuntimeContract.js +2 -0
  11. package/dist/contracts/runtimeContractManifest.d.ts +222 -15
  12. package/dist/contracts/runtimeContractManifest.d.ts.map +1 -1
  13. package/dist/contracts/runtimeContractManifest.js +35 -10
  14. package/dist/contracts/shellEnvironmentPolicy.d.ts +3 -0
  15. package/dist/contracts/shellEnvironmentPolicy.d.ts.map +1 -0
  16. package/dist/contracts/shellEnvironmentPolicy.js +5 -0
  17. package/dist/contracts/wakeMomentContract.d.ts +61 -0
  18. package/dist/contracts/wakeMomentContract.d.ts.map +1 -0
  19. package/dist/contracts/wakeMomentContract.js +27 -0
  20. package/dist/core/types.d.ts +2 -0
  21. package/dist/core/types.d.ts.map +1 -1
  22. package/dist/examples/jungianPlayAgent.d.ts +1 -0
  23. package/dist/examples/jungianPlayAgent.d.ts.map +1 -1
  24. package/dist/examples/jungianPlayAgent.js +6 -2
  25. package/dist/observability/causalEvents.d.ts +3 -3
  26. package/dist/observability/causalEvents.d.ts.map +1 -1
  27. package/dist/observability/causalEvents.js +4 -4
  28. package/dist/pi/cliEngineSpawn.d.ts +2 -2
  29. package/dist/pi/cliEngineSpawn.d.ts.map +1 -1
  30. package/dist/pi/cliEngineSpawn.js +7 -2
  31. package/dist/pi/cliEnvironment.d.ts.map +1 -1
  32. package/dist/pi/cliEnvironment.js +2 -0
  33. package/dist/pi/cliMcpRegistration.d.ts +1 -1
  34. package/dist/pi/cliMcpRegistration.d.ts.map +1 -1
  35. package/dist/pi/cliMcpRegistration.js +1 -1
  36. package/dist/pi/cliSession.d.ts +2 -0
  37. package/dist/pi/cliSession.d.ts.map +1 -1
  38. package/dist/pi/cliSession.js +3 -80
  39. package/dist/pi/cliSessionMcp.d.ts +9 -0
  40. package/dist/pi/cliSessionMcp.d.ts.map +1 -0
  41. package/dist/pi/cliSessionMcp.js +80 -0
  42. package/dist/pi/engineTaskClock.d.ts +9 -0
  43. package/dist/pi/engineTaskClock.d.ts.map +1 -0
  44. package/dist/pi/engineTaskClock.js +28 -0
  45. package/dist/pi/grokHomeMcpRegistration.d.ts.map +1 -1
  46. package/dist/pi/grokHomeMcpRegistration.js +2 -1
  47. package/dist/pi/grokSandbox.js +1 -1
  48. package/dist/pi/memoryClock.d.ts +25 -0
  49. package/dist/pi/memoryClock.d.ts.map +1 -0
  50. package/dist/pi/memoryClock.js +18 -0
  51. package/dist/pi/piAgentHandle.d.ts +3 -1
  52. package/dist/pi/piAgentHandle.d.ts.map +1 -1
  53. package/dist/pi/piAgentHandle.js +5 -2
  54. package/dist/pi/piHarness.d.ts +8 -2
  55. package/dist/pi/piHarness.d.ts.map +1 -1
  56. package/dist/pi/piHarness.js +28 -12
  57. package/dist/pi/taskClockProcess.d.ts +6 -0
  58. package/dist/pi/taskClockProcess.d.ts.map +1 -0
  59. package/dist/pi/taskClockProcess.js +8 -0
  60. package/dist/pi/turnCausal.d.ts +4 -2
  61. package/dist/pi/turnCausal.d.ts.map +1 -1
  62. package/dist/pi/turnCausal.js +4 -4
  63. package/dist/pi/wakeAcceptance.d.ts +1 -1
  64. package/dist/pi/wakeAcceptance.d.ts.map +1 -1
  65. package/dist/pi/wakeAcceptance.js +2 -2
  66. package/dist/runtime/agySubscriptionBootstrap.js +1 -1
  67. package/dist/runtime/agySubscriptionRealm.js +1 -1
  68. package/dist/runtime/attention.d.ts +5 -0
  69. package/dist/runtime/attention.d.ts.map +1 -1
  70. package/dist/runtime/attention.js +14 -1
  71. package/dist/runtime/attentionDispatcher.d.ts +14 -2
  72. package/dist/runtime/attentionDispatcher.d.ts.map +1 -1
  73. package/dist/runtime/attentionDispatcher.js +127 -33
  74. package/dist/runtime/cli.js +5 -0
  75. package/dist/runtime/contract-manifest.json +1 -1
  76. package/dist/runtime/contract-manifest.sha256 +1 -1
  77. package/dist/runtime/engineBrokerCapabilities.d.ts +10 -0
  78. package/dist/runtime/engineBrokerCapabilities.d.ts.map +1 -1
  79. package/dist/runtime/engineBrokerCapabilities.js +10 -0
  80. package/dist/runtime/engineBrokerControlClient.d.ts +12 -1
  81. package/dist/runtime/engineBrokerControlClient.d.ts.map +1 -1
  82. package/dist/runtime/engineBrokerControlClient.js +139 -43
  83. package/dist/runtime/engineBrokerCredentialJournal.d.ts +2 -0
  84. package/dist/runtime/engineBrokerCredentialJournal.d.ts.map +1 -1
  85. package/dist/runtime/engineBrokerCredentialJournal.js +9 -0
  86. package/dist/runtime/engineBrokerInferenceProtocol.d.ts +3 -2
  87. package/dist/runtime/engineBrokerInferenceProtocol.d.ts.map +1 -1
  88. package/dist/runtime/engineBrokerInferenceProtocol.js +4 -4
  89. package/dist/runtime/engineBrokerMcpCallLog.d.ts +11 -0
  90. package/dist/runtime/engineBrokerMcpCallLog.d.ts.map +1 -1
  91. package/dist/runtime/engineBrokerMcpCallLog.js +13 -1
  92. package/dist/runtime/engineBrokerMcpFacade.d.ts +5 -2
  93. package/dist/runtime/engineBrokerMcpFacade.d.ts.map +1 -1
  94. package/dist/runtime/engineBrokerMcpFacade.js +5 -2
  95. package/dist/runtime/engineBrokerNativeClient.js +2 -2
  96. package/dist/runtime/engineBrokerProtocol.d.ts +42 -10
  97. package/dist/runtime/engineBrokerProtocol.d.ts.map +1 -1
  98. package/dist/runtime/engineBrokerProtocol.js +97 -14
  99. package/dist/runtime/engineBrokerSealLedger.d.ts.map +1 -1
  100. package/dist/runtime/engineBrokerSealLedger.js +9 -0
  101. package/dist/runtime/engineBrokerService.d.ts +8 -2
  102. package/dist/runtime/engineBrokerService.d.ts.map +1 -1
  103. package/dist/runtime/engineBrokerService.js +95 -37
  104. package/dist/runtime/engineBrokerServiceCli.js +1 -1
  105. package/dist/runtime/engineBrokerServiceConfig.d.ts +5 -0
  106. package/dist/runtime/engineBrokerServiceConfig.d.ts.map +1 -1
  107. package/dist/runtime/engineBrokerServiceConfig.js +47 -9
  108. package/dist/runtime/engineBrokerTurnRegistry.d.ts +1 -1
  109. package/dist/runtime/engineBrokerTurnRegistry.d.ts.map +1 -1
  110. package/dist/runtime/engineBrokerTurnRegistry.js +7 -6
  111. package/dist/runtime/engineDispatcher.d.ts +2 -0
  112. package/dist/runtime/engineDispatcher.d.ts.map +1 -1
  113. package/dist/runtime/engineDispatcher.js +14 -2
  114. package/dist/runtime/engineReadiness.js +1 -1
  115. package/dist/runtime/grokBrokerCredentialAuthority.d.ts +1 -0
  116. package/dist/runtime/grokBrokerCredentialAuthority.d.ts.map +1 -1
  117. package/dist/runtime/grokBrokerCredentialAuthority.js +48 -22
  118. package/dist/runtime/grokBrokerCredentialReader.d.ts +1 -0
  119. package/dist/runtime/grokBrokerCredentialReader.d.ts.map +1 -1
  120. package/dist/runtime/grokBrokerCredentialReader.js +2 -1
  121. package/dist/runtime/grokBrokerProjection.d.ts +9 -1
  122. package/dist/runtime/grokBrokerProjection.d.ts.map +1 -1
  123. package/dist/runtime/grokBrokerProjection.js +11 -4
  124. package/dist/runtime/grokBrokerProviderClock.d.ts +26 -0
  125. package/dist/runtime/grokBrokerProviderClock.d.ts.map +1 -0
  126. package/dist/runtime/grokBrokerProviderClock.js +133 -0
  127. package/dist/runtime/grokBrokerProxy.d.ts +17 -3
  128. package/dist/runtime/grokBrokerProxy.d.ts.map +1 -1
  129. package/dist/runtime/grokBrokerProxy.js +73 -9
  130. package/dist/runtime/grokBrokerProxyJson.d.ts +10 -0
  131. package/dist/runtime/grokBrokerProxyJson.d.ts.map +1 -0
  132. package/dist/runtime/grokBrokerProxyJson.js +31 -0
  133. package/dist/runtime/grokBrokerProxyRequest.d.ts.map +1 -1
  134. package/dist/runtime/grokBrokerProxyRequest.js +17 -6
  135. package/dist/runtime/grokBrokerRealmLease.js +1 -1
  136. package/dist/runtime/grokBrokerRefresh.js +1 -1
  137. package/dist/runtime/grokBrokerRunBudget.d.ts +20 -0
  138. package/dist/runtime/grokBrokerRunBudget.d.ts.map +1 -0
  139. package/dist/runtime/grokBrokerRunBudget.js +85 -0
  140. package/dist/runtime/grokBrokerSlot.d.ts +6 -0
  141. package/dist/runtime/grokBrokerSlot.d.ts.map +1 -0
  142. package/dist/runtime/grokBrokerSlot.js +21 -0
  143. package/dist/runtime/grokBrokerTaskClock.d.ts +32 -0
  144. package/dist/runtime/grokBrokerTaskClock.d.ts.map +1 -0
  145. package/dist/runtime/grokBrokerTaskClock.js +120 -0
  146. package/dist/runtime/grokBrokerTurnMeter.d.ts +55 -3
  147. package/dist/runtime/grokBrokerTurnMeter.d.ts.map +1 -1
  148. package/dist/runtime/grokBrokerTurnMeter.js +90 -4
  149. package/dist/runtime/grokBrokerWorkerConfig.d.ts +5 -2
  150. package/dist/runtime/grokBrokerWorkerConfig.d.ts.map +1 -1
  151. package/dist/runtime/grokBrokerWorkerConfig.js +22 -3
  152. package/dist/runtime/grokEngineBroker.d.ts +43 -3
  153. package/dist/runtime/grokEngineBroker.d.ts.map +1 -1
  154. package/dist/runtime/grokEngineBroker.js +159 -71
  155. package/dist/runtime/grokEngineBrokerTurn.d.ts +32 -8
  156. package/dist/runtime/grokEngineBrokerTurn.d.ts.map +1 -1
  157. package/dist/runtime/grokEngineBrokerTurn.js +204 -21
  158. package/dist/runtime/grokEngineBrokerTurnEnd.d.ts +88 -0
  159. package/dist/runtime/grokEngineBrokerTurnEnd.d.ts.map +1 -0
  160. package/dist/runtime/grokEngineBrokerTurnEnd.js +148 -0
  161. package/dist/runtime/grokInferenceProxy.d.ts.map +1 -1
  162. package/dist/runtime/grokInferenceProxy.js +3 -0
  163. package/dist/runtime/grokSubscriptionRealm.js +1 -1
  164. package/dist/runtime/grokWorkerAttestation.d.ts +9 -4
  165. package/dist/runtime/grokWorkerAttestation.d.ts.map +1 -1
  166. package/dist/runtime/grokWorkerAttestation.js +2 -2
  167. package/dist/runtime/grokWorkerHomeAttestation.d.ts +4 -2
  168. package/dist/runtime/grokWorkerHomeAttestation.d.ts.map +1 -1
  169. package/dist/runtime/grokWorkerHomeAttestation.js +10 -4
  170. package/dist/runtime/index.d.ts +7 -2
  171. package/dist/runtime/index.d.ts.map +1 -1
  172. package/dist/runtime/index.js +5 -1
  173. package/dist/runtime/native/daimon-engine-broker +0 -0
  174. package/dist/runtime/organizationRuntime.d.ts +3 -0
  175. package/dist/runtime/organizationRuntime.d.ts.map +1 -1
  176. package/dist/runtime/organizationRuntimeAdmission.d.ts +6 -0
  177. package/dist/runtime/organizationRuntimeAdmission.d.ts.map +1 -0
  178. package/dist/runtime/organizationRuntimeAdmission.js +22 -0
  179. package/dist/runtime/organizationRuntimeControl.d.ts +9 -0
  180. package/dist/runtime/organizationRuntimeControl.d.ts.map +1 -1
  181. package/dist/runtime/organizationRuntimeControl.js +72 -24
  182. package/dist/runtime/organizationRuntimeHost.d.ts.map +1 -1
  183. package/dist/runtime/organizationRuntimeHost.js +13 -4
  184. package/dist/runtime/organizationRuntimeParsing.d.ts.map +1 -1
  185. package/dist/runtime/organizationRuntimeParsing.js +4 -1
  186. package/dist/runtime/organizationRuntimeReadiness.d.ts.map +1 -1
  187. package/dist/runtime/organizationRuntimeReadiness.js +8 -0
  188. package/dist/runtime/organizationRuntimeRecording.d.ts +7 -0
  189. package/dist/runtime/organizationRuntimeRecording.d.ts.map +1 -0
  190. package/dist/runtime/organizationRuntimeRecording.js +58 -0
  191. package/dist/runtime/physicalReadiness.d.ts +12 -0
  192. package/dist/runtime/physicalReadiness.d.ts.map +1 -1
  193. package/dist/runtime/physicalReadiness.js +43 -9
  194. package/dist/runtime/productionAgentTools.d.ts.map +1 -1
  195. package/dist/runtime/productionAgentTools.js +13 -5
  196. package/dist/runtime/relocateRuntimeConfig.d.ts +14 -0
  197. package/dist/runtime/relocateRuntimeConfig.d.ts.map +1 -0
  198. package/dist/runtime/relocateRuntimeConfig.js +38 -0
  199. package/dist/runtime/schedule.d.ts.map +1 -1
  200. package/dist/runtime/schedule.js +12 -7
  201. package/dist/runtime/storeCoordination.d.ts +10 -0
  202. package/dist/runtime/storeCoordination.d.ts.map +1 -1
  203. package/dist/runtime/storeCoordination.js +23 -0
  204. package/dist/runtime/taskClock.d.ts +42 -0
  205. package/dist/runtime/taskClock.d.ts.map +1 -0
  206. package/dist/runtime/taskClock.js +102 -0
  207. package/dist/runtime/taskClockProcess.d.ts +17 -0
  208. package/dist/runtime/taskClockProcess.d.ts.map +1 -0
  209. package/dist/runtime/taskClockProcess.js +58 -0
  210. package/dist/runtime/turnRequestLedger.d.ts +0 -5
  211. package/dist/runtime/turnRequestLedger.d.ts.map +1 -1
  212. package/dist/runtime/turnRequestLedger.js +23 -21
  213. package/dist/runtime/wakeAcceptanceClaimDiagnostics.d.ts +34 -0
  214. package/dist/runtime/wakeAcceptanceClaimDiagnostics.d.ts.map +1 -0
  215. package/dist/runtime/wakeAcceptanceClaimDiagnostics.js +79 -0
  216. package/dist/runtime/wakeAcceptanceIndex.d.ts +55 -0
  217. package/dist/runtime/wakeAcceptanceIndex.d.ts.map +1 -0
  218. package/dist/runtime/wakeAcceptanceIndex.js +158 -0
  219. package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts +9 -1
  220. package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts.map +1 -1
  221. package/dist/runtime/wakeAcceptanceProcessIdentity.js +5 -1
  222. package/dist/runtime/wakeAcceptanceRecord.d.ts +2 -0
  223. package/dist/runtime/wakeAcceptanceRecord.d.ts.map +1 -1
  224. package/dist/runtime/wakeAcceptanceRecord.js +4 -2
  225. package/dist/runtime/wakeAcceptanceRetention.d.ts +25 -1
  226. package/dist/runtime/wakeAcceptanceRetention.d.ts.map +1 -1
  227. package/dist/runtime/wakeAcceptanceRetention.js +28 -2
  228. package/dist/runtime/wakeAcceptanceStore.d.ts +8 -8
  229. package/dist/runtime/wakeAcceptanceStore.d.ts.map +1 -1
  230. package/dist/runtime/wakeAcceptanceStore.js +66 -63
  231. package/dist/runtime/wakeFuse.d.ts +58 -3
  232. package/dist/runtime/wakeFuse.d.ts.map +1 -1
  233. package/dist/runtime/wakeFuse.js +106 -7
  234. package/dist/runtime/wakeMomentFs.d.ts +27 -0
  235. package/dist/runtime/wakeMomentFs.d.ts.map +1 -0
  236. package/dist/runtime/wakeMomentFs.js +223 -0
  237. package/dist/runtime/wakeMomentHistory.d.ts +26 -0
  238. package/dist/runtime/wakeMomentHistory.d.ts.map +1 -0
  239. package/dist/runtime/wakeMomentHistory.js +109 -0
  240. package/dist/runtime/wakeMomentIo.d.ts +22 -0
  241. package/dist/runtime/wakeMomentIo.d.ts.map +1 -0
  242. package/dist/runtime/wakeMomentIo.js +114 -0
  243. package/dist/runtime/wakeMomentRecorder.d.ts +33 -0
  244. package/dist/runtime/wakeMomentRecorder.d.ts.map +1 -0
  245. package/dist/runtime/wakeMomentRecorder.js +81 -0
  246. package/dist/runtime/wakeMomentRetention.d.ts +7 -0
  247. package/dist/runtime/wakeMomentRetention.d.ts.map +1 -0
  248. package/dist/runtime/wakeMomentRetention.js +143 -0
  249. package/dist/runtime/wakeMomentRows.d.ts +8 -0
  250. package/dist/runtime/wakeMomentRows.d.ts.map +1 -0
  251. package/dist/runtime/wakeMomentRows.js +66 -0
  252. package/dist/runtime/wakeMomentSnapshot.d.ts +56 -0
  253. package/dist/runtime/wakeMomentSnapshot.d.ts.map +1 -0
  254. package/dist/runtime/wakeMomentSnapshot.js +248 -0
  255. package/package.json +4 -4
@@ -5,6 +5,7 @@ import { grokWorkerEventsPathFor } from "./grokWorkerSandboxProfile.js";
5
5
  import { TURN_REQUEST_LEDGER } from "./turnRequestLedger.js";
6
6
  import { TURN_USAGE_LEDGER } from "./turnUsageLedger.js";
7
7
  export const ENGINE_BROKER_SERVICE_V1 = "noopolis.daimon.engine-broker-service.v1";
8
+ export const ENGINE_BROKER_SERVICE_V3 = "noopolis.daimon.engine-broker-service.v3";
8
9
  export const ENGINE_BROKER_SERVICE_V2 = "noopolis.daimon.engine-broker-service.v2";
9
10
  const V1_REGISTRATION = ["agentId", "slot", "workerUid", "workspace", "profilePath", "eventsPath", "profileSha256"];
10
11
  const V2_REGISTRATION = [...V1_REGISTRATION, "usageLedgerPath", "limits", "model"];
@@ -29,6 +30,8 @@ export const engineBrokerSealLedgerPathFor = (usageLedgerPath) => path.posix.joi
29
30
  /**
30
31
  * Strict `service.json` parser.
31
32
  *
33
+ * v3 retains seven-field registrations and binds slotPolicies by slot; agent IDs
34
+ * may repeat, while worker UIDs, slots and ledger streams must be distinct.
32
35
  * v2 requires every registration to declare its usage ledger, limits and model
33
36
  * (`model.id`/`model.reasoningEffort` from the closed lists); unknown keys at
34
37
  * any level are refused. v1 is still accepted and receives today's defaults:
@@ -38,39 +41,74 @@ export const engineBrokerSealLedgerPathFor = (usageLedgerPath) => path.posix.joi
38
41
  export function parseEngineBrokerServiceConfig(value) {
39
42
  if (!plain(value))
40
43
  throw invalid();
41
- const v2 = value.version === ENGINE_BROKER_SERVICE_V2;
44
+ const v3 = value.version === ENGINE_BROKER_SERVICE_V3;
45
+ const v2 = v3 || value.version === ENGINE_BROKER_SERVICE_V2;
42
46
  if (!v2 && value.version !== ENGINE_BROKER_SERVICE_V1)
43
47
  throw invalid();
44
- const top = ["version", "credentialHome", "turnStore", "registrations"];
48
+ const top = ["version", "credentialHome", "turnStore", "registrations", ...(v3 ? ["slotPolicies"] : [])];
49
+ if (v3 && Object.hasOwn(value, "maxRunRequests")) {
50
+ if (!Number.isSafeInteger(value.maxRunRequests) || value.maxRunRequests < 1)
51
+ throw invalid();
52
+ top.push("maxRunRequests");
53
+ }
54
+ if (v3 && Object.hasOwn(value, "runRequestStore")) {
55
+ if (!absolute(value.runRequestStore) || value.maxRunRequests === undefined)
56
+ throw invalid();
57
+ top.push("runRequestStore");
58
+ }
45
59
  exact(value, v2 && Object.hasOwn(value, "inferenceLedgerPath") ? [...top, "inferenceLedgerPath"] : top);
46
60
  if (!absolute(value.credentialHome) || !absolute(value.turnStore) || !Array.isArray(value.registrations) || value.registrations.length === 0)
47
61
  throw invalid();
48
- const seen = new Set(), slots = new Set();
62
+ const policies = new Map();
63
+ if (v3) {
64
+ if (!Array.isArray(value.slotPolicies) || value.slotPolicies.length !== value.registrations.length)
65
+ throw invalid();
66
+ for (const policy of value.slotPolicies) {
67
+ if (!plain(policy))
68
+ throw invalid();
69
+ exact(policy, ["slot", "usageLedgerPath", "limits", "model"]);
70
+ if (!Number.isSafeInteger(policy.slot) || policy.slot < 0 || policies.has(policy.slot))
71
+ throw invalid();
72
+ policies.set(policy.slot, policy);
73
+ }
74
+ }
75
+ const seen = new Set(), slots = new Set(), workers = new Set();
76
+ const ledgers = new Set();
49
77
  const registrations = value.registrations.map((entry) => {
50
78
  if (!plain(entry))
51
79
  throw invalid();
52
- exact(entry, v2 ? V2_REGISTRATION : V1_REGISTRATION);
80
+ exact(entry, v2 && !v3 ? V2_REGISTRATION : V1_REGISTRATION);
53
81
  const { agentId, slot, workerUid, workspace, profilePath, eventsPath, profileSha256 } = entry;
54
- if (typeof agentId !== "string" || !agentId.trim() || seen.has(agentId) || !Number.isSafeInteger(slot) || slot < 0 || slots.has(slot) || !Number.isSafeInteger(workerUid) || workerUid < 2200 || !absolute(workspace) || !absolute(profilePath) || !absolute(eventsPath) || typeof profileSha256 !== "string" || !/^[a-f0-9]{64}$/u.test(profileSha256) || eventsPath !== grokWorkerEventsPathFor(profilePath) || !profilePath.endsWith("/sandbox.toml"))
82
+ if (typeof agentId !== "string" || !agentId.trim() || (!v3 && seen.has(agentId)) || !Number.isSafeInteger(slot) || slot < 0 || slots.has(slot) || !Number.isSafeInteger(workerUid) || workerUid < 2200 || workers.has(workerUid) || !absolute(workspace) || !absolute(profilePath) || !absolute(eventsPath) || typeof profileSha256 !== "string" || !/^[a-f0-9]{64}$/u.test(profileSha256) || eventsPath !== grokWorkerEventsPathFor(profilePath) || !profilePath.endsWith("/sandbox.toml"))
55
83
  throw invalid();
56
84
  seen.add(agentId);
57
85
  slots.add(slot);
86
+ workers.add(workerUid);
58
87
  const base = { agentId, slot: slot, workerUid: workerUid, workspace, profilePath, eventsPath, profileSha256 };
59
88
  if (!v2)
60
89
  return { ...base, usageLedgerPath: TURN_USAGE_LEDGER.filePath, limits: DEFAULT_GROK_BROKER_TURN_LIMITS, model: DEFAULT_GROK_BROKER_MODEL_POLICY };
61
- const usageLedgerPath = entry.usageLedgerPath;
90
+ const policy = v3 ? policies.get(slot) : entry;
91
+ if (policy === undefined)
92
+ throw invalid();
93
+ const usageLedgerPath = policy.usageLedgerPath;
62
94
  if (!ledgerPath(usageLedgerPath) || usageLedgerPath === engineBrokerRequestLedgerPathFor(usageLedgerPath) || usageLedgerPath === engineBrokerSealLedgerPathFor(usageLedgerPath))
63
95
  throw invalid();
96
+ const streams = [usageLedgerPath, engineBrokerRequestLedgerPathFor(usageLedgerPath), engineBrokerSealLedgerPathFor(usageLedgerPath)];
97
+ if (v3 && streams.some((file) => ledgers.has(file)))
98
+ throw invalid();
99
+ streams.forEach((file) => ledgers.add(file));
64
100
  let limits;
65
101
  try {
66
- limits = parseEngineBrokerTurnLimits(entry.limits);
102
+ limits = parseEngineBrokerTurnLimits(policy.limits);
67
103
  }
68
104
  catch {
69
105
  throw invalid();
70
106
  }
71
- return { ...base, usageLedgerPath, limits, model: parseServiceModel(entry.model) };
107
+ return { ...base, usageLedgerPath, limits, model: parseServiceModel(policy.model) };
72
108
  });
73
- const base = { credentialHome: value.credentialHome, turnStore: value.turnStore, registrations };
109
+ const base = { credentialHome: value.credentialHome, turnStore: value.turnStore, registrations,
110
+ ...(value.runRequestStore === undefined ? {} : { runRequestStore: value.runRequestStore }),
111
+ ...(value.maxRunRequests === undefined ? {} : { maxRunRequests: value.maxRunRequests }) };
74
112
  if (!Object.hasOwn(value, "inferenceLedgerPath"))
75
113
  return base;
76
114
  const inferenceLedgerPath = value.inferenceLedgerPath;
@@ -48,7 +48,7 @@ export declare class EngineBrokerTurnRegistry {
48
48
  }
49
49
  /**
50
50
  * Strict record parser. v2 accepts exactly `{version,digest,state,bootId}`
51
- * plus `response` and its sealed `ledger` bytes when terminal, and the response must be a v2 terminal frame.
51
+ * plus `response` and its sealed `ledger` bytes when terminal, and the response may be a v2, v3 or v4 terminal frame (older frames upgrade on read).
52
52
  * v1 records keep their historical looser shape and are upgraded on read: no
53
53
  * usage (`null`), zero requests, `limitReason: "none"`, the declared model.
54
54
  */
@@ -1 +1 @@
1
- {"version":3,"file":"engineBrokerTurnRegistry.d.ts","sourceRoot":"","sources":["../../src/runtime/engineBrokerTurnRegistry.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkE,KAAK,mBAAmB,EAAE,KAAK,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AACxK,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAwD,KAAK,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAE/H,KAAK,KAAK,GAAG,OAAO,CAAC,mBAAmB,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC;AAClE,KAAK,QAAQ,GAAG,4BAA4B,CAAC;AAC7C,eAAO,MAAM,4BAA4B,EAAG,uCAAgD,CAAC;AAC7F,eAAO,MAAM,4BAA4B,EAAG,uCAAgD,CAAC;AAK7F,KAAK,QAAQ,GAAG,QAAQ,CAAC;IAAE,OAAO,EAAE,OAAO,4BAA4B,GAAG,OAAO,4BAA4B,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,QAAQ,GAAG,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,qBAAqB,CAAA;CAAE,CAAC,CAAC;AAEpO;;;;;GAKG;AACH,qBAAa,wBAAwB;IAEvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAS,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAqB,OAAO,CAAC,QAAQ,CAAC,eAAe;IADtH,yGAAyG;gBAC5E,IAAI,EAAE,MAAM,EAAkB,MAAM,GAAC,MAAmB,EAAkB,eAAe,GAAC,CAAC,SAAS,EAAC,MAAM,KAAG,OAAO,CAAC,IAAI,CAAe;IACtK,gGAAgG;IAC1F,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,GAAG;QAAE,MAAM,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,qBAAqB,CAAA;KAAE,CAAC;IAW3H;;;;;;;;;OASG;IACG,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAE,qBAAgD,GAAG,OAAO,CAAC,QAAQ,CAAC;QAAE,eAAe,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAO5J;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,QAAQ,CAyB1F"}
1
+ {"version":3,"file":"engineBrokerTurnRegistry.d.ts","sourceRoot":"","sources":["../../src/runtime/engineBrokerTurnRegistry.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmK,KAAK,mBAAmB,EAAE,KAAK,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AACzQ,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAwD,KAAK,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAE/H,KAAK,KAAK,GAAG,OAAO,CAAC,mBAAmB,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC;AAClE,KAAK,QAAQ,GAAG,4BAA4B,CAAC;AAC7C,eAAO,MAAM,4BAA4B,EAAG,uCAAgD,CAAC;AAC7F,eAAO,MAAM,4BAA4B,EAAG,uCAAgD,CAAC;AAM7F,KAAK,QAAQ,GAAG,QAAQ,CAAC;IAAE,OAAO,EAAE,OAAO,4BAA4B,GAAG,OAAO,4BAA4B,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,QAAQ,GAAG,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,qBAAqB,CAAA;CAAE,CAAC,CAAC;AAEpO;;;;;GAKG;AACH,qBAAa,wBAAwB;IAEvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAS,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAqB,OAAO,CAAC,QAAQ,CAAC,eAAe;IADtH,yGAAyG;gBAC5E,IAAI,EAAE,MAAM,EAAkB,MAAM,GAAC,MAAmB,EAAkB,eAAe,GAAC,CAAC,SAAS,EAAC,MAAM,KAAG,OAAO,CAAC,IAAI,CAAe;IACtK,gGAAgG;IAC1F,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,GAAG;QAAE,MAAM,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,qBAAqB,CAAA;KAAE,CAAC;IAW3H;;;;;;;;;OASG;IACG,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAE,qBAAgD,GAAG,OAAO,CAAC,QAAQ,CAAC;QAAE,eAAe,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAO5J;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,QAAQ,CAyB1F"}
@@ -2,13 +2,14 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import { constants } from "node:fs";
3
3
  import { mkdir, open, readFile, rename, unlink } from "node:fs/promises";
4
4
  import path from "node:path";
5
- import { parseEngineBrokerResponse, parseEngineBrokerV1TerminalResponse } from "./engineBrokerProtocol.js";
5
+ import { ENGINE_BROKER_VERSION, parseEngineBrokerResponse, parseEngineBrokerV1TerminalResponse, parseEngineBrokerV2TerminalResponse, parseEngineBrokerV3TerminalResponse } from "./engineBrokerProtocol.js";
6
6
  import { EMPTY_BROKER_TURN_LEDGER, parseBrokerTurnLedgerLines } from "./grokEngineBrokerLedger.js";
7
7
  export const ENGINE_BROKER_TURN_RECORD_V1 = "noopolis.daimon.engine-broker-turn.v1";
8
8
  export const ENGINE_BROKER_TURN_RECORD_V2 = "noopolis.daimon.engine-broker-turn.v2";
9
9
  // The digest deliberately excludes `limits` and the protocol version, so a v1
10
- // record written before the upgrade still identifies the same turn.
11
- const digest = (request) => createHash("sha256").update(JSON.stringify([request.turnId, request.agentId, request.wakeId, request.prompt, request.mcpEndpoint])).digest("hex");
10
+ // record written before the upgrade still identifies the same unclocked turn.
11
+ // A supplied process clock changes execution and must conflict with any other value.
12
+ const digest = (request) => createHash("sha256").update(JSON.stringify([request.turnId, request.agentId, request.wakeId, request.prompt, request.mcpEndpoint, ...(request.processClock === undefined ? [] : [request.processClock])])).digest("hex");
12
13
  const safe = (turnId) => `${createHash("sha256").update(turnId).digest("hex")}.json`;
13
14
  /**
14
15
  * Durable per-turn state. Record v2 stores the terminal response *with* its
@@ -97,7 +98,7 @@ export class EngineBrokerTurnRegistry {
97
98
  }
98
99
  /**
99
100
  * Strict record parser. v2 accepts exactly `{version,digest,state,bootId}`
100
- * plus `response` and its sealed `ledger` bytes when terminal, and the response must be a v2 terminal frame.
101
+ * plus `response` and its sealed `ledger` bytes when terminal, and the response may be a v2, v3 or v4 terminal frame (older frames upgrade on read).
101
102
  * v1 records keep their historical looser shape and are upgraded on read: no
102
103
  * usage (`null`), zero requests, `limitReason: "none"`, the declared model.
103
104
  */
@@ -126,7 +127,7 @@ export function parseEngineBrokerTurnRecord(text, model) {
126
127
  throw new Error("broker turn registry unavailable");
127
128
  }
128
129
  const accounting = { outcome: legacy.kind, usage: null, model, requests: 0, limitReason: "none" };
129
- const response = { ...legacy, ...accounting, version: "noopolis.daimon.engine-broker.v2" };
130
+ const response = { ...legacy, ...accounting, version: ENGINE_BROKER_VERSION };
130
131
  return { version: ENGINE_BROKER_TURN_RECORD_V1, ...base, response };
131
132
  }
132
133
  if (input.version !== ENGINE_BROKER_TURN_RECORD_V2)
@@ -138,7 +139,7 @@ export function parseEngineBrokerTurnRecord(text, model) {
138
139
  return { version: ENGINE_BROKER_TURN_RECORD_V2, ...base };
139
140
  let response;
140
141
  try {
141
- response = parseEngineBrokerResponse(input.response);
142
+ response = input.response?.version === "noopolis.daimon.engine-broker.v2" ? parseEngineBrokerV2TerminalResponse(input.response) : input.response?.version === "noopolis.daimon.engine-broker.v3" ? parseEngineBrokerV3TerminalResponse(input.response) : parseEngineBrokerResponse(input.response);
142
143
  }
143
144
  catch {
144
145
  throw new Error("broker turn registry unavailable");
@@ -11,6 +11,8 @@ export declare function startOrganizationRuntimeEngine(agent: OrganizationRuntim
11
11
  export declare function grokSandboxProtectedPaths(currentAgentId: string, organizationAgents: readonly OrganizationRuntimeAgentConfig[], sharedProtectedPaths?: readonly string[]): readonly string[];
12
12
  export declare function codexSandboxProtectedPaths(currentAgentId: string, currentAgent: OrganizationRuntimeAgentConfig, currentEngineHomePath: string, organizationAgents: readonly OrganizationRuntimeAgentConfig[], sharedProtectedPaths?: readonly string[]): readonly string[];
13
13
  export declare function codexSandboxReadablePaths(currentAgent: OrganizationRuntimeAgentConfig): readonly string[];
14
+ /** @internal The same callback used by the production session; no native process clock enters the engine environment. */
15
+ export declare function grokBrokerTurnFor(agent: OrganizationRuntimeAgentConfig, grokBroker: EngineBrokerTurnClient, wakeEnvironmentContext: import("../pi/piAgentWakeSupport.js").PiWakeEnvironmentContextRef): (prompt: string, endpoint: string, signal: AbortSignal) => Promise<string>;
14
16
  /**
15
17
  * CLI engines do not consume Pi's resource loader. Frame the same immutable
16
18
  * identity in JSON so arbitrary names/instructions cannot change its shape.
@@ -1 +1 @@
1
- {"version":3,"file":"engineDispatcher.d.ts","sourceRoot":"","sources":["../../src/runtime/engineDispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAQpD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,wBAAwB,CAAC;AAE/E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAM7E;;;GAGG;AACH,wBAAsB,8BAA8B,CAClD,KAAK,EAAE,8BAA8B,EACrC,eAAe,EAAE,MAAM,EACvB,KAAK,CAAC,EAAE,UAAU,CAAC,gCAAgC,CAAC,UAAU,CAAC,CAAC,EAChE,aAAa,CAAC,EAAE,MAAM,EACtB,UAAU,CAAC,EAAE,sBAAsB,EACnC,kBAAkB,CAAC,EAAE,SAAS,8BAA8B,EAAE,EAC9D,oBAAoB,GAAE,SAAS,MAAM,EAAO,EAC5C,SAAS,CAAC,EAAE,iBAAiB,GAC5B,OAAO,CAAC,WAAW,CAAC,CA8CtB;AAED,wBAAgB,yBAAyB,CACvC,cAAc,EAAE,MAAM,EACtB,kBAAkB,EAAE,SAAS,8BAA8B,EAAE,EAC7D,oBAAoB,GAAE,SAAS,MAAM,EAAO,GAC3C,SAAS,MAAM,EAAE,CAYnB;AAED,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,8BAA8B,EAC5C,qBAAqB,EAAE,MAAM,EAC7B,kBAAkB,EAAE,SAAS,8BAA8B,EAAE,EAC7D,oBAAoB,GAAE,SAAS,MAAM,EAAO,GAC3C,SAAS,MAAM,EAAE,CAQnB;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,8BAA8B,GAC3C,SAAS,MAAM,EAAE,CAEnB;AAwDD;;;GAGG;AACH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,8BAA8B,EAAE,gBAAgB,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,CAkBxH"}
1
+ {"version":3,"file":"engineDispatcher.d.ts","sourceRoot":"","sources":["../../src/runtime/engineDispatcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAQpD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,wBAAwB,CAAC;AAE/E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAM7E;;;GAGG;AACH,wBAAsB,8BAA8B,CAClD,KAAK,EAAE,8BAA8B,EACrC,eAAe,EAAE,MAAM,EACvB,KAAK,CAAC,EAAE,UAAU,CAAC,gCAAgC,CAAC,UAAU,CAAC,CAAC,EAChE,aAAa,CAAC,EAAE,MAAM,EACtB,UAAU,CAAC,EAAE,sBAAsB,EACnC,kBAAkB,CAAC,EAAE,SAAS,8BAA8B,EAAE,EAC9D,oBAAoB,GAAE,SAAS,MAAM,EAAO,EAC5C,SAAS,CAAC,EAAE,iBAAiB,GAC5B,OAAO,CAAC,WAAW,CAAC,CAiDtB;AAED,wBAAgB,yBAAyB,CACvC,cAAc,EAAE,MAAM,EACtB,kBAAkB,EAAE,SAAS,8BAA8B,EAAE,EAC7D,oBAAoB,GAAE,SAAS,MAAM,EAAO,GAC3C,SAAS,MAAM,EAAE,CAYnB;AAED,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,8BAA8B,EAC5C,qBAAqB,EAAE,MAAM,EAC7B,kBAAkB,EAAE,SAAS,8BAA8B,EAAE,EAC7D,oBAAoB,GAAE,SAAS,MAAM,EAAO,GAC3C,SAAS,MAAM,EAAE,CAQnB;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,8BAA8B,GAC3C,SAAS,MAAM,EAAE,CAEnB;AAkDD,yHAAyH;AACzH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,8BAA8B,EAAE,UAAU,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,OAAO,6BAA6B,EAAE,2BAA2B,IAG5L,QAAQ,MAAM,EAAE,UAAU,MAAM,EAAE,QAAQ,WAAW,qBAI9D;AAED;;;GAGG;AACH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,8BAA8B,EAAE,gBAAgB,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,CAkBxH"}
@@ -1,4 +1,8 @@
1
+ import { brokerProcessClock } from "./grokBrokerTaskClock.js";
2
+ import { reportEngineTaskClockGap } from "../pi/engineTaskClock.js";
1
3
  import { attentionTools } from "./attention.js";
4
+ import { readTaskClock } from "./taskClock.js";
5
+ import { memoryClockOptions } from "../pi/memoryClock.js";
2
6
  import { grokDaimonToolName, grokMountedToolNamingRule } from "../contracts/grokWorkerContract.js";
3
7
  import path from "node:path";
4
8
  import { AGY_MAX_TOOL_TURNS, createCliSessionFactory, resolveCodexWakeTimeoutMs, resolveCodexWakeTokenCeiling, resolveEngineWakeLimitOverrides } from "../pi/cliSession.js";
@@ -14,6 +18,10 @@ import { recordCodexTurnRequests } from "./turnRequestLedger.js";
14
18
  * existing one-agent harness. Configuration never carries a command or env.
15
19
  */
16
20
  export async function startOrganizationRuntimeEngine(agent, controlTokenEnv, paths, agyBusAddress, grokBroker, organizationAgents, sharedProtectedPaths = [], attention) {
21
+ const clock = readTaskClock();
22
+ reportEngineTaskClockGap(agent.engine.kind);
23
+ if (agent.memory !== undefined)
24
+ memoryClockOptions(clock);
17
25
  // A declared Grok model is enforced by the broker proxy and worker config;
18
26
  // the direct path has neither, so it refuses rather than silently ignoring it.
19
27
  if (agent.engine.kind === "grok" && agent.engine.model !== undefined && grokBroker === undefined)
@@ -137,10 +145,14 @@ function adapterFor(agent, controlTokenEnv, verifyExecutable, executablePath, en
137
145
  } : {}) });
138
146
  return cliHarness(agent, sessionFactory, [controlTokenEnv], productionTools, wakeEnvironmentContext);
139
147
  }
140
- function grokBrokerTurnFor(agent, grokBroker, wakeEnvironmentContext) {
148
+ /** @internal The same callback used by the production session; no native process clock enters the engine environment. */
149
+ export function grokBrokerTurnFor(agent, grokBroker, wakeEnvironmentContext) {
141
150
  const limits = resolveEngineWakeLimitOverrides();
142
151
  const options = { ...(limits === undefined ? {} : { limits }), ...(agent.engine.model === undefined ? {} : { model: agent.engine.model }) };
143
- return (prompt, endpoint, signal) => grokBroker.turn(agent.id, wakeEnvironmentContext.current ?? "wake", prompt, endpoint, signal, options);
152
+ return (prompt, endpoint, signal) => {
153
+ const processClock = brokerProcessClock();
154
+ return grokBroker.turn(agent.id, wakeEnvironmentContext.current ?? "wake", prompt, endpoint, signal, { ...options, ...(processClock === undefined ? {} : { processClock }) });
155
+ };
144
156
  }
145
157
  /**
146
158
  * CLI engines do not consume Pi's resource loader. Frame the same immutable
@@ -1,7 +1,7 @@
1
1
  import { constants } from "node:fs";
2
2
  import { lstat, open, realpath, stat } from "node:fs/promises";
3
3
  import path from "node:path";
4
- import { spawn } from "node:child_process";
4
+ import { spawnRealTime as spawn } from "./taskClockProcess.js";
5
5
  import { createHash } from "node:crypto";
6
6
  import { cliChildEnvironment } from "../pi/cliEnvironment.js";
7
7
  import { hasRefreshablePortableCredential, portableCredentialSecretValues } from "./portableCredentialAuth.js";
@@ -9,6 +9,7 @@ export declare class DurableGrokBrokerCredentialAuthority {
9
9
  private staleWrite;
10
10
  private lastDigest;
11
11
  private generation;
12
+ private ancestorDigests;
12
13
  constructor(command: string, home: string, authFile?: string);
13
14
  initialize(): Promise<void>;
14
15
  accessToken(forceRefresh: boolean): Promise<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"grokBrokerCredentialAuthority.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerCredentialAuthority.ts"],"names":[],"mappings":"AAUA,qBAAa,oCAAoC;IAEnC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAU,OAAO,CAAC,QAAQ,CAAC,QAAQ;IADtG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAAC,OAAO,CAAC,KAAK,CAAS;IAAA,OAAO,CAAC,WAAW,CAAO;IAAA,OAAO,CAAC,UAAU,CAAyB;IAAA,OAAO,CAAC,UAAU,CAAkB;IAAA,OAAO,CAAC,UAAU,CAAG;gBACrP,OAAO,EAAE,MAAM,EAAmB,IAAI,EAAE,MAAM,EAAmB,QAAQ,SAA+B;IAC/H,UAAU,IAAG,OAAO,CAAC,IAAI,CAAC;IAC1B,WAAW,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAInD,qBAAqB,CAAC,mBAAmB,EAAC,MAAM,GAAE,OAAO,CAAC,MAAM,CAAC;IACvE,OAAO,CAAC,OAAO;IAOT,YAAY,CAAC,mBAAmB,CAAC,EAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAC9D,OAAO,IAAG,OAAO;IACjB,OAAO,CAAC,SAAS;YACH,KAAK;CAKpB"}
1
+ {"version":3,"file":"grokBrokerCredentialAuthority.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerCredentialAuthority.ts"],"names":[],"mappings":"AAUA,qBAAa,oCAAoC;IAGnC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAU,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAFtG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAAC,OAAO,CAAC,KAAK,CAAS;IAAA,OAAO,CAAC,WAAW,CAAO;IAAA,OAAO,CAAC,UAAU,CAAyB;IAAA,OAAO,CAAC,UAAU,CAAkB;IAAA,OAAO,CAAC,UAAU,CAAG;IAClR,OAAO,CAAC,eAAe,CAAyB;gBACnB,OAAO,EAAE,MAAM,EAAmB,IAAI,EAAE,MAAM,EAAmB,QAAQ,SAA+B;IAC/H,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC3B,WAAW,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAInD,qBAAqB,CAAC,mBAAmB,EAAC,MAAM,GAAE,OAAO,CAAC,MAAM,CAAC;IACvE,OAAO,CAAC,OAAO;IAYT,YAAY,CAAC,mBAAmB,CAAC,EAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAC9D,OAAO,IAAG,OAAO;IACjB,OAAO,CAAC,SAAS;YACH,KAAK;CAKpB"}
@@ -6,7 +6,7 @@ import path from "node:path";
6
6
  import { readGrokBrokerCredential } from "./grokBrokerCredentialReader.js";
7
7
  import { refreshGrokBrokerCredential } from "./grokBrokerRefresh.js";
8
8
  import { EngineBrokerGenerationFence, EngineBrokerSingleflight } from "./engineBrokerSingleflight.js";
9
- import { parseBrokerCredentialJournal, recoverBrokerCredentialJournal } from "./engineBrokerCredentialJournal.js";
9
+ import { BROKER_CREDENTIAL_MAX_ANCESTORS, parseBrokerCredentialJournal, recoverBrokerCredentialJournal } from "./engineBrokerCredentialJournal.js";
10
10
  export class DurableGrokBrokerCredentialAuthority {
11
11
  command;
12
12
  home;
@@ -18,33 +18,52 @@ export class DurableGrokBrokerCredentialAuthority {
18
18
  staleWrite;
19
19
  lastDigest;
20
20
  generation = 0;
21
+ ancestorDigests = [];
21
22
  constructor(command, home, authFile = path.join(home, "auth.json")) {
22
23
  this.command = command;
23
24
  this.home = home;
24
25
  this.authFile = authFile;
25
26
  }
26
- async initialize() { if (this.initialized)
27
- return; const credential = await readGrokBrokerCredential(this.authFile); this.lastDigest = credential.digest; const file = path.join(this.home, ".daimon-broker", "credential-journal.json"); let handle; try {
28
- handle = await open(file, constants.O_RDONLY | constants.O_NOFOLLOW);
29
- const stat = await handle.stat();
30
- if (!stat.isFile() || stat.uid !== process.getuid?.() || (stat.mode & 0o777) !== 0o600 || stat.size > 4096)
31
- throw unavailable();
32
- const journal = parseBrokerCredentialJournal(JSON.parse(await handle.readFile("utf8")));
33
- if (recoverBrokerCredentialJournal(journal, credential.digest) === "stale") {
27
+ async initialize() {
28
+ if (this.initialized)
29
+ return;
30
+ const credential = await readGrokBrokerCredential(this.authFile);
31
+ this.lastDigest = credential.digest;
32
+ const file = path.join(this.home, ".daimon-broker", "credential-journal.json");
33
+ let handle;
34
+ try {
35
+ handle = await open(file, constants.O_RDONLY | constants.O_NOFOLLOW);
36
+ const stat = await handle.stat();
37
+ if (!stat.isFile() || stat.uid !== process.getuid?.() || (stat.mode & 0o777) !== 0o600 || stat.size > 65536)
38
+ throw unavailable();
39
+ const journal = parseBrokerCredentialJournal(JSON.parse(await handle.readFile("utf8")));
34
40
  this.generation = journal.generation;
35
- await this.markStale();
36
- throw unavailable();
41
+ if (recoverBrokerCredentialJournal(journal, credential.digest) === "stale") {
42
+ await this.markStale();
43
+ throw unavailable();
44
+ }
45
+ this.ancestorDigests = [...new Set([...(journal.ancestorDigests ?? []), journal.sourceDigest])]
46
+ .filter((digest) => digest !== credential.digest);
47
+ if (journal.state === "refreshing") {
48
+ // The durable credential still matches the pre-exchange source. Settle
49
+ // before serving it so writeback and drain need no subsequent refresh.
50
+ // No exchange completed: preserve the generation and existing lineage.
51
+ await this.write({ state: "promoted", generation: journal.generation,
52
+ sourceDigest: credential.digest, promotedDigest: credential.digest });
53
+ }
54
+ this.fence.restore(journal.generation);
37
55
  }
38
- this.generation = journal.generation;
39
- this.fence.restore(journal.generation);
40
- }
41
- catch (error) {
42
- if (error.code !== "ENOENT")
43
- throw unavailable();
56
+ catch (error) {
57
+ // Only a missing journal on open is an unjournaled bootstrap. A failed
58
+ // recovery write (including ENOENT) must never publish readiness.
59
+ if (handle !== undefined || error.code !== "ENOENT")
60
+ throw unavailable();
61
+ }
62
+ finally {
63
+ await handle?.close().catch(() => undefined);
64
+ }
65
+ this.initialized = true;
44
66
  }
45
- finally {
46
- await handle?.close().catch(() => undefined);
47
- } this.initialized = true; }
48
67
  async accessToken(forceRefresh) {
49
68
  if (!this.initialized)
50
69
  await this.initialize();
@@ -64,6 +83,11 @@ export class DurableGrokBrokerCredentialAuthority {
64
83
  const before = await readGrokBrokerCredential(this.authFile);
65
84
  if (rejectedTokenDigest !== undefined && createHash("sha256").update(before.accessToken).digest("hex") !== rejectedTokenDigest)
66
85
  return before.accessToken;
86
+ // Never spend a refresh whose lineage cannot be persisted. Advancing expiry
87
+ // normally clears the history, so this bound applies to one expiry epoch.
88
+ const ancestors = [...new Set([...this.ancestorDigests, before.digest])];
89
+ if (ancestors.length > BROKER_CREDENTIAL_MAX_ANCESTORS)
90
+ throw unavailable();
67
91
  try {
68
92
  await this.write({ state: "refreshing", generation, sourceDigest: before.digest });
69
93
  await refreshGrokBrokerCredential(this.command, this.home);
@@ -72,7 +96,9 @@ export class DurableGrokBrokerCredentialAuthority {
72
96
  throw unavailable();
73
97
  const next = this.fence.promote(generation);
74
98
  this.generation = next;
75
- await this.write({ state: "promoted", generation: next, sourceDigest: before.digest, promotedDigest: after.digest });
99
+ const ancestorDigests = before.expiresAt !== undefined && after.expiresAt !== undefined && after.expiresAt > before.expiresAt ? [] : ancestors;
100
+ await this.write({ state: "promoted", generation: next, sourceDigest: before.digest, promotedDigest: after.digest, ancestorDigests });
101
+ this.ancestorDigests = ancestorDigests;
76
102
  this.lastDigest = after.digest;
77
103
  return after.accessToken;
78
104
  }
@@ -100,7 +126,7 @@ export class DurableGrokBrokerCredentialAuthority {
100
126
  const temporary = `${file}.${process.pid}.${randomUUID()}.tmp`;
101
127
  const handle = await open(temporary, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY, 0o600);
102
128
  try {
103
- await handle.writeFile(`${JSON.stringify({ version: "noopolis.daimon.broker-credential-journal.v1", ...value })}\n`);
129
+ await handle.writeFile(`${JSON.stringify({ version: "noopolis.daimon.broker-credential-journal.v1", ancestorDigests: this.ancestorDigests, ...value })}\n`);
104
130
  await handle.sync();
105
131
  }
106
132
  finally {
@@ -1,5 +1,6 @@
1
1
  export declare function readGrokBrokerCredential(file: string): Promise<Readonly<{
2
2
  accessToken: string;
3
3
  digest: string;
4
+ expiresAt?: number;
4
5
  }>>;
5
6
  //# sourceMappingURL=grokBrokerCredentialReader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"grokBrokerCredentialReader.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerCredentialReader.ts"],"names":[],"mappings":"AAIA,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAUvH"}
1
+ {"version":3,"file":"grokBrokerCredentialReader.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerCredentialReader.ts"],"names":[],"mappings":"AAIA,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAW3I"}
@@ -22,7 +22,8 @@ export async function readGrokBrokerCredential(file) {
22
22
  const rows = Object.values(root).filter((value) => value !== null && typeof value === "object" && !Array.isArray(value));
23
23
  if (rows.length !== 1 || typeof rows[0].key !== "string" || rows[0].key.length < 32 || typeof rows[0].refresh_token !== "string" || rows[0].refresh_token.length < 16)
24
24
  throw new Error();
25
- return { accessToken: rows[0].key, digest: createHash("sha256").update(bytes).digest("hex") };
25
+ const expiresAt = typeof rows[0].expires_at === "string" ? Date.parse(rows[0].expires_at) : NaN;
26
+ return { accessToken: rows[0].key, digest: createHash("sha256").update(bytes).digest("hex"), ...(Number.isFinite(expiresAt) ? { expiresAt } : {}) };
26
27
  }
27
28
  catch {
28
29
  throw new Error("Grok broker credential authority unavailable");
@@ -1,8 +1,9 @@
1
+ import { GROK_BROKER_TASK_CLOCK, type GrokWorkerConfigVariant } from "../contracts/grokBrokerTaskClock.js";
1
2
  import { type EngineBrokerServiceRegistration } from "./engineBrokerServiceConfig.js";
2
3
  import { type EngineBrokerTurnLimits } from "./engineBrokerTurnAccounting.js";
3
4
  import type { GrokBrokerModel, GrokBrokerReasoningEffort } from "./grokBrokerModelPolicy.js";
4
5
  import { GROK_WORKER_SANDBOX_PROFILE } from "./grokWorkerSandboxProfile.js";
5
- export declare const GROK_BROKER_PROJECTION_VERSION: "noopolis.daimon.grok-broker-projection.v1";
6
+ export declare const GROK_BROKER_PROJECTION_VERSION: "noopolis.daimon.grok-broker-projection.v3";
6
7
  /**
7
8
  * Everything a consumer (Spawnfile provisioning, Paideia's native adapter, the
8
9
  * root slot supervisor) needs to know about one brokered Grok agent's slot,
@@ -20,6 +21,11 @@ export type OrganizationGrokBrokerProjection = Readonly<{
20
21
  profileSha256: string;
21
22
  denyPaths: readonly string[];
22
23
  workerConfigSha256: string;
24
+ workerConfigVariant: GrokWorkerConfigVariant;
25
+ taskClock?: Omit<typeof GROK_BROKER_TASK_CLOCK, "directoryPath" | "timestampFilePath"> & Readonly<{
26
+ directoryPath: string;
27
+ timestampFilePath: string;
28
+ }>;
23
29
  systemPromptSha256: string;
24
30
  grokCliVersion: string;
25
31
  grokExecutableSha256: string;
@@ -40,6 +46,8 @@ export type OrganizationGrokBrokerProjection = Readonly<{
40
46
  }>;
41
47
  }>;
42
48
  export type OrganizationGrokBrokerProjectionOptions = Readonly<{
49
+ /** Clocked configs require an isolated clock directory per slot. Defaults to the unchanged production bytes. */
50
+ workerConfigVariant?: GrokWorkerConfigVariant;
43
51
  /** Deployment-assigned slot identity. */
44
52
  slot: number;
45
53
  workerUid: number;
@@ -1 +1 @@
1
- {"version":3,"file":"grokBrokerProjection.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerProjection.ts"],"names":[],"mappings":"AAOA,OAAO,EAAkC,KAAK,+BAA+B,EAAE,MAAM,gCAAgC,CAAC;AACtH,OAAO,EAA+B,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAE3G,OAAO,KAAK,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC7F,OAAO,EAAE,2BAA2B,EAA2F,MAAM,+BAA+B,CAAC;AAGrK,eAAO,MAAM,8BAA8B,6CAAuC,CAAC;AAEnF;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CAAC;IACtD,OAAO,EAAE,OAAO,8BAA8B,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,eAAe,EAAE,yBAAyB,CAAC;IAC3C,MAAM,EAAE,sBAAsB,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,yHAAyH;IACzH,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,QAAQ,CAAC;QAAE,QAAQ,EAAE,gBAAgB,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAC;QAAC,eAAe,EAAE,IAAI,CAAC;QAAC,WAAW,EAAE,OAAO,2BAA2B,CAAC;QAAC,cAAc,EAAE,YAAY,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjM,CAAC,CAAC;AAEH,MAAM,MAAM,uCAAuC,GAAG,QAAQ,CAAC;IAC7D,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,GAAG,KAAK,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,sBAAsB,CAAC;IAC/B;;;;;;;;;;;;;;OAcG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,gFAAgF;IAChF,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uCAAuC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,uCAAuC,GAAG,gCAAgC,CA8B5K;AAED,wFAAwF;AACxF,eAAO,MAAM,0BAA0B,GAAI,YAAY,gCAAgC,KAAG,MACpB,CAAC;AAEvE,4HAA4H;AAC5H,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,gCAAgC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAQhI;AAED;;;;GAIG;AACH,wBAAgB,6CAA6C,CAAC,YAAY,EAAE,+BAA+B,EAAE,UAAU,EAAE,gCAAgC,GAAG,IAAI,CAG/J"}
1
+ {"version":3,"file":"grokBrokerProjection.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerProjection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAQ3G,OAAO,EAAkC,KAAK,+BAA+B,EAAE,MAAM,gCAAgC,CAAC;AACtH,OAAO,EAA+B,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAE3G,OAAO,KAAK,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC7F,OAAO,EAAE,2BAA2B,EAA2F,MAAM,+BAA+B,CAAC;AAGrK,eAAO,MAAM,8BAA8B,6CAAuC,CAAC;AAEnF;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CAAC;IACtD,OAAO,EAAE,OAAO,8BAA8B,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,uBAAuB,CAAC;IAC7C,SAAS,CAAC,EAAE,IAAI,CAAC,OAAO,sBAAsB,EAAE,eAAe,GAAG,mBAAmB,CAAC,GAAG,QAAQ,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxJ,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,eAAe,EAAE,yBAAyB,CAAC;IAC3C,MAAM,EAAE,sBAAsB,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,yHAAyH;IACzH,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,QAAQ,CAAC;QAAE,QAAQ,EAAE,gBAAgB,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAC;QAAC,eAAe,EAAE,IAAI,CAAC;QAAC,WAAW,EAAE,OAAO,2BAA2B,CAAC;QAAC,cAAc,EAAE,YAAY,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjM,CAAC,CAAC;AAEH,MAAM,MAAM,uCAAuC,GAAG,QAAQ,CAAC;IAC7D,gHAAgH;IAChH,mBAAmB,CAAC,EAAE,uBAAuB,CAAC;IAC9C,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,GAAG,KAAK,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,sBAAsB,CAAC;IAC/B;;;;;;;;;;;;;;OAcG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,gFAAgF;IAChF,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uCAAuC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,uCAAuC,GAAG,gCAAgC,CAkC5K;AAED,wFAAwF;AACxF,eAAO,MAAM,0BAA0B,GAAI,YAAY,gCAAgC,KAAG,MACpB,CAAC;AAEvE,4HAA4H;AAC5H,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,gCAAgC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAQhI;AAED;;;;GAIG;AACH,wBAAgB,6CAA6C,CAAC,YAAY,EAAE,+BAA+B,EAAE,UAAU,EAAE,gCAAgC,GAAG,IAAI,CAG/J"}
@@ -1,3 +1,5 @@
1
+ import { brokerTaskClockFileFor } from "./grokBrokerSlot.js";
2
+ import { GROK_BROKER_TASK_CLOCK } from "../contracts/grokBrokerTaskClock.js";
1
3
  import { createHash } from "node:crypto";
2
4
  import path from "node:path";
3
5
  import { canonicalJson } from "../contracts/canonicalJson.js";
@@ -6,7 +8,7 @@ import { GROK_ENGINE_BROKER } from "../contracts/runtimeContractManifest.js";
6
8
  import { grokSandboxProtectedPaths } from "./engineDispatcher.js";
7
9
  import { parseEngineBrokerServiceConfig } from "./engineBrokerServiceConfig.js";
8
10
  import { parseEngineBrokerTurnLimits } from "./engineBrokerTurnAccounting.js";
9
- import { grokBrokerWorkerConfigSha256 } from "./grokBrokerWorkerConfig.js";
11
+ import { grokBrokerWorkerConfigPins, grokBrokerWorkerConfigSha256 } from "./grokBrokerWorkerConfig.js";
10
12
  import { GROK_WORKER_SANDBOX_PROFILE, grokWorkerEventsPathFor, renderGrokWorkerSandboxProfile, grokWorkerSandboxProfileSha256 } from "./grokWorkerSandboxProfile.js";
11
13
  import { parseOrganizationRuntimeConfig } from "./organizationRuntime.js";
12
14
  export const GROK_BROKER_PROJECTION_VERSION = GROK_ENGINE_BROKER.projectionVersion;
@@ -50,8 +52,12 @@ export function resolveOrganizationGrokBrokerProjection(config, agentId, options
50
52
  const profileSha256 = grokWorkerSandboxProfileSha256(denyPaths);
51
53
  if (options.profileSha256 !== undefined && options.profileSha256 !== profileSha256)
52
54
  throw new Error("Grok broker projection profile digest mismatch");
53
- const workerConfigSha256 = grokBrokerWorkerConfigSha256({ model, reasoningEffort });
54
- if (workerConfigSha256 !== GROK_ENGINE_BROKER.worker.configSha256[model][reasoningEffort])
55
+ const workerConfigVariant = options.workerConfigVariant ?? "unclocked";
56
+ const workerConfigSha256 = grokBrokerWorkerConfigSha256({ model, reasoningEffort }, workerConfigVariant, options.slot);
57
+ const pin = grokBrokerWorkerConfigPins({ model, reasoningEffort }, options.slot)[workerConfigVariant];
58
+ if (workerConfigVariant === "clocked" && denyPaths.some((denied) => [brokerTaskClockFileFor(options.slot), GROK_BROKER_TASK_CLOCK.preloadPath].some((file) => file === denied || file.startsWith(`${denied}/`))))
59
+ throw new Error("Grok broker task clock path is denied");
60
+ if (workerConfigSha256 !== pin)
55
61
  throw new Error("Grok broker projection worker config drifted from the manifest");
56
62
  if (createHash("sha256").update(DAIMON_GROK_SYSTEM_PROMPT).digest("hex") !== GROK_ENGINE_BROKER.worker.systemPromptSha256)
57
63
  throw new Error("Grok broker projection system prompt drifted from the manifest");
@@ -61,7 +67,8 @@ export function resolveOrganizationGrokBrokerProjection(config, agentId, options
61
67
  const profilePath = path.posix.join(options.workerHomePath, ".grok", "sandbox.toml");
62
68
  const projection = {
63
69
  version: GROK_BROKER_PROJECTION_VERSION, agentId, workspacePath: agent.workspacePath, runtimeHomePath: agent.runtimeHomePath,
64
- workerUid: options.workerUid, slot: options.slot, profilePath, profileSha256, denyPaths, workerConfigSha256,
70
+ workerUid: options.workerUid, slot: options.slot, profilePath, profileSha256, denyPaths, workerConfigSha256, workerConfigVariant,
71
+ ...(workerConfigVariant === "clocked" ? { taskClock: { ...GROK_BROKER_TASK_CLOCK, directoryPath: path.posix.dirname(brokerTaskClockFileFor(options.slot)), timestampFilePath: brokerTaskClockFileFor(options.slot) } } : {}),
65
72
  systemPromptSha256: GROK_ENGINE_BROKER.worker.systemPromptSha256, grokCliVersion: GROK_ENGINE_BROKER.grokCliVersion, grokExecutableSha256: artifact.sha256,
66
73
  nativeAbiVersion: GROK_ENGINE_BROKER.nativeAbiVersion, model, reasoningEffort, limits: parseEngineBrokerTurnLimits(options.limits), usageLedgerPath: options.usageLedgerPath, seccompProfileSha256: options.seccompProfileSha256,
67
74
  attestation: { platform: "linux/landlock", enforced: true, restrictNetwork: true, profileName: GROK_WORKER_SANDBOX_PROFILE, sandboxRuntime: "bubblewrap", eventsPath: grokWorkerEventsPathFor(profilePath) }
@@ -0,0 +1,26 @@
1
+ export type GrokBrokerProviderClockObservation = Readonly<{
2
+ requests: number;
3
+ linesRewritten: number;
4
+ requestsWithoutDateLine: number;
5
+ /** Date-like message lines outside the injected block; absent on older seals. */
6
+ linesIgnored?: number;
7
+ /** The last rewritten line's dates; null until a line is rewritten. */
8
+ injectedDate: string | null;
9
+ taskDate: string | null;
10
+ }>;
11
+ export declare class GrokBrokerProviderClockRefusal extends Error {
12
+ readonly reason: "task_clock_date_format" | "task_clock_date_range" | "request_body_rejected";
13
+ constructor(reason: "task_clock_date_format" | "task_clock_date_range" | "request_body_rejected");
14
+ }
15
+ /** One processClock, owned by one turn; never reads the broker's ambient TZ. */
16
+ export declare class GrokBrokerProviderClock {
17
+ private readonly now;
18
+ private readonly offsetMs;
19
+ private observation;
20
+ constructor(processClock: string, now?: () => number);
21
+ rewrite(body: Uint8Array): Uint8Array;
22
+ snapshot(): GrokBrokerProviderClockObservation;
23
+ }
24
+ /** Closed, dates-only observation on the v3 terminal frame and durable seal. */
25
+ export declare function parseGrokBrokerProviderClockObservation(value: unknown): GrokBrokerProviderClockObservation;
26
+ //# sourceMappingURL=grokBrokerProviderClock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grokBrokerProviderClock.d.ts","sourceRoot":"","sources":["../../src/runtime/grokBrokerProviderClock.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,kCAAkC,GAAG,QAAQ,CAAC;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB,EAAE,MAAM,CAAC;IAChC,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC,CAAC;AAEH,qBAAa,8BAA+B,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,wBAAwB,GAAG,uBAAuB,GAAG,uBAAuB;gBAApF,MAAM,EAAE,wBAAwB,GAAG,uBAAuB,GAAG,uBAAuB;CAG1G;AAOD,gFAAgF;AAChF,qBAAa,uBAAuB;IAOA,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,WAAW,CAGjB;gBAEU,YAAY,EAAE,MAAM,EAAmB,GAAG,GAAE,MAAM,MAAyB;IAIvF,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU;IAuErC,QAAQ,IAAI,kCAAkC;CAG/C;AAKD,gFAAgF;AAChF,wBAAgB,uCAAuC,CAAC,KAAK,EAAE,OAAO,GAAG,kCAAkC,CAuB1G"}