@zq-silk/yui 0.15.7 → 0.15.8

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 (281) hide show
  1. package/ARCHITECTURE.md +192 -399
  2. package/README.md +127 -1149
  3. package/dist/agent/adapterCatalog.js +15 -2
  4. package/dist/agent/agent.js +23 -3
  5. package/dist/agent/argumentPolicy.js +7 -1
  6. package/dist/agent/connectionPlan.js +62 -0
  7. package/dist/agent/executionComponents.js +158 -0
  8. package/dist/agent/launchEnvironment.js +31 -3
  9. package/dist/agent/managedRuntimeEnvironment.js +3 -5
  10. package/dist/{turn/turn.js → agentRun/agentRun.js} +166 -109
  11. package/dist/{turn/turnIdentity.js → agentRun/runIdentity.js} +4 -4
  12. package/dist/brief/taskBrief.js +12 -0
  13. package/dist/cli/agentConfigurationPicker.js +13 -0
  14. package/dist/cli/commandCatalog.js +157 -70
  15. package/dist/cli/interactionCandidates.js +5 -5
  16. package/dist/cli/interactionPolicy.js +38 -8
  17. package/dist/cli/invocationRouter.js +1 -1
  18. package/dist/cli/managedDiagnostics.js +28 -0
  19. package/dist/cli/operatorWizard.js +1 -7
  20. package/dist/cli/roleOptionOrder.js +27 -0
  21. package/dist/cli/roleWizard.js +50 -14
  22. package/dist/cli/updateOrchestrator.js +1 -1
  23. package/dist/cli/updatePorts.js +3 -4
  24. package/dist/cli.js +178 -95
  25. package/dist/commands/agentCommands.js +72 -14
  26. package/dist/commands/capabilityCommands.js +9 -6
  27. package/dist/commands/configCommands.js +20 -20
  28. package/dist/commands/deliveryGuardPreflight.js +2 -2
  29. package/dist/commands/executionAuditCommands.js +24 -24
  30. package/dist/commands/globalRoleCommands.js +1 -1
  31. package/dist/commands/grantCommands.js +4 -4
  32. package/dist/commands/operatorCommands.js +1 -7
  33. package/dist/commands/projectCommands.js +4 -4
  34. package/dist/commands/resourcesCommands.js +2 -2
  35. package/dist/commands/roleConfiguration.js +25 -5
  36. package/dist/commands/roleRuntimeGuard.js +4 -5
  37. package/dist/commands/sessionCommands.js +3 -7
  38. package/dist/commands/taskActivationCommands.js +259 -0
  39. package/dist/commands/taskActor.js +28 -49
  40. package/dist/commands/taskCommands.js +1188 -710
  41. package/dist/commands/taskContextCommand.js +39 -583
  42. package/dist/commands/taskExecutionCommands.js +32 -32
  43. package/dist/commands/taskInputCommands.js +40 -104
  44. package/dist/commands/taskIntegrationCommands.js +3 -2
  45. package/dist/commands/taskIntegrationQueueCommands.js +1 -1
  46. package/dist/commands/taskNextActionCommand.js +8 -8
  47. package/dist/commands/taskOverviewCommand.js +33 -45
  48. package/dist/commands/taskRemoteDeliveryCommand.js +2 -2
  49. package/dist/commands/taskRoleRuntimeStatus.js +133 -102
  50. package/dist/commands/telemetryCommands.js +36 -38
  51. package/dist/config/configCatalog.js +4 -4
  52. package/dist/config/yuiConfig.js +8 -8
  53. package/dist/context/contextSnapshot.js +10 -10
  54. package/dist/context/dispatchContext.js +11 -11
  55. package/dist/context/roleSessionContext.js +6 -3
  56. package/dist/context/{turnContextPack.js → runContextPack.js} +146 -81
  57. package/dist/context/{turnInputContract.js → runInputContract.js} +73 -60
  58. package/dist/context/sessionBootstrapManifest.js +21 -2
  59. package/dist/context/sourceRunContext.js +30 -0
  60. package/dist/context/taskContext.js +458 -0
  61. package/dist/context/wakeNotification.js +27 -27
  62. package/dist/controller/agentRuntimeObserver.js +21 -24
  63. package/dist/controller/capabilityBridge.js +17 -6
  64. package/dist/controller/clientRuntime.js +65 -92
  65. package/dist/controller/controller.js +114 -188
  66. package/dist/controller/fileSchedulerStoreAdapter.js +787 -887
  67. package/dist/controller/jobControl.js +54 -85
  68. package/dist/controller/resourceInventory.js +8 -27
  69. package/dist/controller/resourceInventoryLinux.js +12 -13
  70. package/dist/controller/runtime.js +529 -479
  71. package/dist/controller/runtimeEventInbox.js +55 -25
  72. package/dist/controller/runtimeEventProcessor.js +22 -31
  73. package/dist/controller/{runtimeHookTurnFence.js → runtimeHookRunFence.js} +91 -115
  74. package/dist/controller/runtimeLaunchCoordinator.js +80 -426
  75. package/dist/controller/runtimeObservationHook.js +14 -18
  76. package/dist/controller/sessionNotify.js +16 -24
  77. package/dist/controller/sessionOwnerReconciliation.js +168 -50
  78. package/dist/controller/structuredProviderObservation.js +138 -99
  79. package/dist/coordination/workMailbox.js +3 -3
  80. package/dist/coordination/workMailboxQueue.js +36 -33
  81. package/dist/core/boundedRpc.js +8 -1
  82. package/dist/core/controllerClient.js +20 -1
  83. package/dist/core/controllerServer.js +4 -4
  84. package/dist/doctor/doctor.js +13 -2
  85. package/dist/domain/agentResultTransport.js +9 -9
  86. package/dist/execution/codexThreadNaming.js +2 -8
  87. package/dist/execution/executionHealth.js +51 -63
  88. package/dist/execution/reviewMainRun.js +137 -0
  89. package/dist/execution/workItemExecution.js +28 -29
  90. package/dist/execution/workItemExecutionProjection.js +99 -107
  91. package/dist/execution/workItemMainRun.js +141 -0
  92. package/dist/executor/agentAdapter.js +227 -20
  93. package/dist/executor/agentConfigurationCatalog.js +126 -4
  94. package/dist/executor/agentConfigurationProbe.js +162 -4
  95. package/dist/executor/agentExecutor.js +79 -78
  96. package/dist/executor/effectiveLaunch.js +105 -18
  97. package/dist/executor/executorRegistry.js +29 -44
  98. package/dist/executor/fileRoleLaunchPlanner.js +229 -154
  99. package/dist/executor/workspacePreflightClassification.js +16 -16
  100. package/dist/grant/capabilityGrant.js +6 -3
  101. package/dist/input/inputRequest.js +12 -10
  102. package/dist/integration/gitIntegrationService.js +4 -11
  103. package/dist/integration/integrationQueueService.js +4 -4
  104. package/dist/interaction/operatorPresentation.js +1 -1
  105. package/dist/kernel/builtinCapabilities.js +247 -12
  106. package/dist/kernel/capabilityRegistry.js +64 -18
  107. package/dist/kernel/instanceHost.js +12 -1
  108. package/dist/kernel/kernelPorts.js +2 -2
  109. package/dist/lifecycle/canonicalLifecycleEvent.js +44 -49
  110. package/dist/lifecycle/exactRunTerminalization.js +449 -0
  111. package/dist/message/message.js +62 -6
  112. package/dist/message/messageContinuation.js +204 -0
  113. package/dist/observability/executionAudit.js +70 -72
  114. package/dist/observability/faultClassification.js +2 -2
  115. package/dist/observability/orchestrationMetrics.js +8 -8
  116. package/dist/operator/operatorSessionHistory.js +1 -7
  117. package/dist/output/agentConfigurationPresentation.js +8 -3
  118. package/dist/output/agentRunConfigurationPresentation.js +128 -0
  119. package/dist/output/rolePresentation.js +54 -3
  120. package/dist/plugins/pluginChild.js +104 -0
  121. package/dist/plugins/pluginIntent.js +26 -0
  122. package/dist/plugins/pluginInterpreter.js +43 -0
  123. package/dist/plugins/pluginPackage.js +101 -0
  124. package/dist/plugins/pluginProcess.js +112 -0
  125. package/dist/plugins/pluginService.js +380 -0
  126. package/dist/profile/agentProfile.js +1 -1
  127. package/dist/repository/gitWorkspace.js +26 -4
  128. package/dist/repository/project.js +19 -4
  129. package/dist/repository/taskBaseFreshness.js +13 -13
  130. package/dist/repository/taskWorkspaceCoordinator.js +20 -27
  131. package/dist/repository/taskWorkspacePreparer.js +344 -83
  132. package/dist/resources/autoResourceGc.js +3 -3
  133. package/dist/resources/liveReferences.js +3 -3
  134. package/dist/resources/projectResource.js +123 -0
  135. package/dist/resources/projectResourceService.js +421 -0
  136. package/dist/resources/resourceDiscovery.js +6 -6
  137. package/dist/resources/resourceGc.js +1 -1
  138. package/dist/resources/resourceRegistrar.js +1 -1
  139. package/dist/resources/resourceTypes.js +1 -1
  140. package/dist/review/deltaRecheck.js +3 -3
  141. package/dist/review/reviewAcceptance.js +16 -16
  142. package/dist/review/reviewDecision.js +7 -7
  143. package/dist/review/reviewRound.js +21 -20
  144. package/dist/review/reviewerAvailability.js +2 -2
  145. package/dist/role/role.js +51 -7
  146. package/dist/role/taskRoleUpdate.js +30 -0
  147. package/dist/runtime/acpProtocol.js +425 -0
  148. package/dist/runtime/acpSession.js +731 -0
  149. package/dist/runtime/acpSessionConfiguration.js +260 -0
  150. package/dist/runtime/agentDriver.js +30 -11
  151. package/dist/runtime/agentEndpoint.js +278 -0
  152. package/dist/runtime/agentEndpointIdentity.js +86 -0
  153. package/dist/runtime/agentEndpointOwnership.js +239 -0
  154. package/dist/runtime/agentError.js +2 -10
  155. package/dist/runtime/agentHost.js +565 -314
  156. package/dist/runtime/agentRunConfiguration.js +258 -0
  157. package/dist/runtime/builtinAgentDrivers.js +134 -18
  158. package/dist/runtime/builtinAgentErrorMappers.js +55 -3
  159. package/dist/runtime/builtinTranscriptUsage.js +1 -1
  160. package/dist/runtime/claude-process-owner +0 -0
  161. package/dist/runtime/codexAppServerRuntime.js +38 -30
  162. package/dist/runtime/codexInteractiveHost.js +41 -6
  163. package/dist/runtime/continuationManager.js +2 -6
  164. package/dist/runtime/executionEnvironment.js +30 -0
  165. package/dist/runtime/firstProgressAdvisory.js +11 -11
  166. package/dist/runtime/index.js +4 -3
  167. package/dist/runtime/jsonLineChannel.js +109 -0
  168. package/dist/runtime/launchBroker.js +91 -16
  169. package/dist/runtime/launchDiagnostics.js +2 -2
  170. package/dist/runtime/lifecycleReservation.js +10 -18
  171. package/dist/runtime/managedCaller.js +61 -17
  172. package/dist/runtime/nativeSessionControl.js +102 -0
  173. package/dist/runtime/ports.js +6 -21
  174. package/dist/runtime/processExitObservation.js +8 -7
  175. package/dist/runtime/promptEnvelope.js +17 -6
  176. package/dist/runtime/providerContinuation.js +3 -9
  177. package/dist/runtime/providerContinuationReconciliationService.js +4 -13
  178. package/dist/runtime/providerControl.js +2 -7
  179. package/dist/runtime/providerRuntimeIdentity.js +110 -222
  180. package/dist/runtime/providerRuntimeReconciler.js +5 -9
  181. package/dist/runtime/runtimeBinding.js +0 -1
  182. package/dist/runtime/runtimeContinuationProjection.js +4 -7
  183. package/dist/runtime/runtimeDeadlines.js +9 -0
  184. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  185. package/dist/runtime/runtimeObservation.js +29 -65
  186. package/dist/runtime/runtimeProjection.js +43 -51
  187. package/dist/runtime/runtimeSessionCandidate.js +1 -3
  188. package/dist/runtime/sessionLaunchRequest.js +3 -7
  189. package/dist/runtime/sessionOwnerIdentity.js +7 -54
  190. package/dist/runtime/sessionOwnerRegistry.js +22 -17
  191. package/dist/runtime/sessionReconciliation.js +4 -8
  192. package/dist/runtime/sessionTerminationGuard.js +70 -259
  193. package/dist/runtime/sessionTokenMetrics.js +5 -16
  194. package/dist/runtime/structuredProviderHost.js +237 -117
  195. package/dist/runtime/taskRuntimeIsolation.js +39 -122
  196. package/dist/runtime/tmuxAdapters.js +39 -86
  197. package/dist/scheduler/activeRoleRunDelivery.js +354 -0
  198. package/dist/scheduler/leaderWakeupProcessor.js +75 -266
  199. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  200. package/dist/scheduler/ports.js +80 -9
  201. package/dist/scheduler/{roleTurnLiveness.js → roleRunLiveness.js} +26 -30
  202. package/dist/scheduler/{roleTurnStall.js → roleRunStall.js} +128 -139
  203. package/dist/scheduler/taskExecutionProjection.js +120 -124
  204. package/dist/scheduler/taskObservabilityProjection.js +29 -29
  205. package/dist/scheduler/taskWake.js +11 -4
  206. package/dist/scheduler/wakeReason.js +9 -1
  207. package/dist/setup/setupCommand.js +1 -0
  208. package/dist/storage/migrations/agentRunContract.js +159 -0
  209. package/dist/storage/migrations/removeRuntimeGeneration.js +207 -0
  210. package/dist/storage/sqliteSchema.js +431 -5
  211. package/dist/storage/sqliteStore.js +375 -220
  212. package/dist/storage/storageVersions.js +1 -1
  213. package/dist/storage/storeRpc.js +10 -5
  214. package/dist/storage/taskStore.js +13 -11
  215. package/dist/storage/upgrade/upgradeOrchestrator.js +5 -7
  216. package/dist/surface/surfaceContributions.js +102 -0
  217. package/dist/task/completionReadiness.js +32 -6
  218. package/dist/task/deliveryGuard.js +16 -16
  219. package/dist/task/draftPlan.js +72 -12
  220. package/dist/task/nextAction.js +144 -128
  221. package/dist/task/remoteDelivery.js +6 -6
  222. package/dist/task/task.js +184 -18
  223. package/dist/task/taskActivation.js +301 -0
  224. package/dist/task/taskActivationService.js +392 -0
  225. package/dist/task/taskRecordReference.js +5 -4
  226. package/dist/task/taskRecordRetirement.js +1 -1
  227. package/dist/telemetry/sqliteTelemetryStore.js +55 -68
  228. package/dist/telemetry/telemetryConfig.js +14 -14
  229. package/dist/telemetry/telemetryWiring.js +2 -2
  230. package/dist/web/assets/assetManifest.js +2 -0
  231. package/dist/web/assets/client/app.js +120 -20
  232. package/dist/web/assets/client/components.js +87 -54
  233. package/dist/web/assets/client/i18n.js +83 -41
  234. package/dist/web/assets/client/markdown.js +1 -1
  235. package/dist/web/assets/client/taskSurface.js +353 -0
  236. package/dist/web/assets/client/view.js +49 -44
  237. package/dist/web/assets/shell.js +1 -1
  238. package/dist/web/assets/styles/cards.js +22 -4
  239. package/dist/web/controllerWeb.js +60 -0
  240. package/dist/web/webMutation.js +28 -0
  241. package/dist/web/webServer.js +118 -8
  242. package/dist/web/webSnapshot.js +81 -74
  243. package/dist/web/webTaskSurface.js +64 -0
  244. package/dist/workItem/dependencyGate.js +1 -1
  245. package/dist/workItem/workItem.js +80 -48
  246. package/dist/workspace/workItemChangeSetManager.js +16 -9
  247. package/docs/agent-result-consumption.md +94 -0
  248. package/docs/agent-runtime-drivers.md +91 -0
  249. package/docs/architecture/README.md +38 -0
  250. package/docs/architecture/capabilities-and-resources.md +79 -0
  251. package/docs/managed-turn-and-session-runtime.md +222 -0
  252. package/docs/observability/README.md +81 -0
  253. package/docs/plugin-sdk.md +290 -0
  254. package/docs/provider-runtime.md +163 -0
  255. package/docs/release-workflow.md +303 -0
  256. package/docs/roles-and-configuration.md +113 -0
  257. package/docs/sqlite-control-plane-design.md +76 -0
  258. package/docs/task-dag-semantics.md +57 -0
  259. package/docs/task-delivery.md +103 -0
  260. package/docs/task-local-identity.md +6 -6
  261. package/docs/testing/verification-levels.md +86 -0
  262. package/i18n/README.zh-CN.md +98 -739
  263. package/package.json +2 -2
  264. package/skills/yui-leader/SKILL.md +130 -103
  265. package/skills/yui-leader/references/integration.md +39 -0
  266. package/skills/yui-leader/references/replicated-execution.md +42 -0
  267. package/skills/yui-leader/references/task-plugins.md +33 -0
  268. package/skills/yui-operator/SKILL.md +30 -59
  269. package/skills/yui-reviewer/SKILL.md +35 -36
  270. package/skills/yui-runtime/SKILL.md +88 -24
  271. package/skills/yui-runtime/references/publication.md +22 -0
  272. package/skills/yui-runtime/references/recovery.md +64 -0
  273. package/skills/yui-worker/SKILL.md +37 -39
  274. package/dist/cli/roleOptionCatalog.js +0 -68
  275. package/dist/context/sourceTurnContext.js +0 -30
  276. package/dist/execution/reviewMainTurn.js +0 -161
  277. package/dist/execution/workItemMainTurn.js +0 -164
  278. package/dist/lifecycle/exactTurnTerminalization.js +0 -407
  279. package/dist/runtime/preallocatedNativeSession.js +0 -13
  280. package/dist/runtime/runtimeStopReceipt.js +0 -42
  281. package/dist/scheduler/activeRoleTurnDelivery.js +0 -315
@@ -13,4 +13,4 @@
13
13
  * intermediate Yui releases.
14
14
  */
15
15
  export const MIN_SUPPORTED_STORAGE_VERSION = 1;
16
- export const CURRENT_STORAGE_VERSION = 3;
16
+ export const CURRENT_STORAGE_VERSION = 18;
@@ -28,6 +28,9 @@ import { StorageCancelledError, StorageConflictError, StorageRecordError } from
28
28
  * else is routed to the writer connection.
29
29
  */
30
30
  const READ_ONLY_STORE_METHODS = new Set([
31
+ "getPluginIntent", "listPluginIntents",
32
+ "getPluginValidation", "getArtifact", "listArtifacts", "getLocalResource", "listLocalResources",
33
+ "getEnvironmentPreparation", "listEnvironmentPreparations",
31
34
  "rootDirectory",
32
35
  "getConfig",
33
36
  "getHomeIdentity",
@@ -48,6 +51,8 @@ const READ_ONLY_STORE_METHODS = new Set([
48
51
  "readNextActionFacts",
49
52
  "readCompletionReadinessFacts",
50
53
  "listActiveTaskIds",
54
+ "listPlanningDraftTaskIds",
55
+ "listPendingActivationRequestTaskIds",
51
56
  "getTaskBrief",
52
57
  "listChangeSets",
53
58
  "getChangeSet",
@@ -70,13 +75,13 @@ const READ_ONLY_STORE_METHODS = new Set([
70
75
  "getRoleSession",
71
76
  "getWorkItem",
72
77
  "listWorkItems",
73
- "getTurn",
74
- "listTurns",
78
+ "getRun",
79
+ "listRuns",
75
80
  "listPendingProviderRetries",
76
- "peekNextTurnId",
81
+ "peekNextRunId",
77
82
  "getReviewRound",
78
- "getActiveTurn",
79
- "getActiveExecutionLaneTurn",
83
+ "getActiveRun",
84
+ "getActiveExecutionLaneRun",
80
85
  "listMessages",
81
86
  "getInputRequest",
82
87
  "listInputRequests",
@@ -5,14 +5,14 @@ import { isDeepStrictEqual } from "node:util";
5
5
  import { validateCapabilityGrant } from "../grant/capabilityGrant.js";
6
6
  import { validateReleaseWorkflow } from "../release/releaseWorkflow.js";
7
7
  import { validatePublicationReference } from "../task/publicationReference.js";
8
- import { reconciliationIntervalMilliseconds, resolveAgentLaunchInactivityTimeoutSeconds, resolveControllerTaskConcurrency, resolveDeliveryTimeoutSeconds, resolveLeaderNextActionMode, resolveLeaderSemanticBudgetTurns, resolveResourcesGcAutoQuarantine, resolveResourcesGcMode, resolveResourcesQuarantineTtlHours, resolveRuntimeHealth, resolveTelemetryEnabled, resolveTelemetryTurnCap, resolveTelemetryTerminalKeep, resolveTmuxBin, resolveTmuxHistoryLimit } from "../config/yuiConfig.js";
8
+ import { reconciliationIntervalMilliseconds, resolveAgentLaunchInactivityTimeoutSeconds, resolveControllerTaskConcurrency, resolveDeliveryTimeoutSeconds, resolveLeaderNextActionMode, resolveLeaderSemanticBudgetRuns, resolveResourcesGcAutoQuarantine, resolveResourcesGcMode, resolveResourcesQuarantineTtlHours, resolveRuntimeHealth, resolveTelemetryEnabled, resolveTelemetryRunCap, resolveTelemetryTerminalKeep, resolveTmuxBin, resolveTmuxHistoryLimit } from "../config/yuiConfig.js";
9
9
  import { resolveTimeZone } from "../output/timePresentation.js";
10
10
  import { validateReviewConfig } from "../review/reviewConfig.js";
11
11
  import { validateTaskRecordReference } from "../task/taskRecordReference.js";
12
12
  export const CURRENT_CONFIG_SCHEMA_VERSION = 6;
13
13
  /** Current SQLite payload-family versions owned by this storage boundary. */
14
14
  export const CURRENT_CONFIGURED_AGENT_SCHEMA_VERSION = 2;
15
- export const CURRENT_PROJECT_SCHEMA_VERSION = 5;
15
+ export const CURRENT_PROJECT_SCHEMA_VERSION = 6;
16
16
  export const CURRENT_AGENT_PROFILE_SCHEMA_VERSION = 3;
17
17
  export const CURRENT_GLOBAL_ROLE_SCHEMA_VERSION = 3;
18
18
  export const CURRENT_GLOBAL_ROLE_SESSION_SET_SCHEMA_VERSION = 5;
@@ -42,13 +42,13 @@ export const COMPLETION_SHELLS = ["bash", "zsh", "fish"];
42
42
  * makes the two key spaces disjoint even for legal Role names such as
43
43
  * `lane:worker:1`.
44
44
  */
45
- export function executionLaneActiveTurnKey(executionGroupId, executionLaneId) {
45
+ export function executionLaneActiveRunKey(executionGroupId, executionLaneId) {
46
46
  return `/execution-lane/${encodeLaneKeyPart(executionGroupId)}:${encodeLaneKeyPart(executionLaneId)}`;
47
47
  }
48
48
  function encodeLaneKeyPart(value) {
49
49
  return encodeURIComponent(value).replace(/:/gu, "%3A");
50
50
  }
51
- export function executionLaneActiveTurnKeyParts(key) {
51
+ export function executionLaneActiveRunKeyParts(key) {
52
52
  const match = /^\/execution-lane\/([^:]+):([^:]+)$/u.exec(key);
53
53
  if (match === null)
54
54
  return null;
@@ -66,7 +66,7 @@ export function executionLaneActiveTurnKeyParts(key) {
66
66
  * Nested-record versions consumed by the current SQLite payload validators.
67
67
  */
68
68
  export const CURRENT_TASK_ROLE_SESSION_SET_SCHEMA_VERSION = 12;
69
- export const CURRENT_TURN_SCHEMA_VERSION = 5;
69
+ export const CURRENT_RUN_SCHEMA_VERSION = 5;
70
70
  export const CURRENT_INTEGRATION_QUEUE_SCHEMA_VERSION = 1;
71
71
  export class StorageRecordError extends Error {
72
72
  constructor(message) { super(message); this.name = "StorageRecordError"; }
@@ -156,13 +156,13 @@ export function validateYuiConfig(config) {
156
156
  "controllerTaskConcurrency",
157
157
  "agentLaunchInactivityTimeoutSeconds",
158
158
  "deliveryTimeoutSeconds",
159
- "leaderSemanticBudgetTurns",
159
+ "leaderSemanticBudgetRuns",
160
160
  "resourcesQuarantineTtlHours",
161
161
  "tmuxBin",
162
162
  "tmuxHistoryLimit",
163
163
  "telemetryEnabled",
164
164
  "telemetryTerminalKeep",
165
- "telemetryTurnCap",
165
+ "telemetryRunCap",
166
166
  "completionInstallations"
167
167
  ];
168
168
  exact(config, [
@@ -184,12 +184,12 @@ export function validateYuiConfig(config) {
184
184
  resolveControllerTaskConcurrency(config.controllerTaskConcurrency);
185
185
  resolveAgentLaunchInactivityTimeoutSeconds(config.agentLaunchInactivityTimeoutSeconds);
186
186
  resolveDeliveryTimeoutSeconds(config.deliveryTimeoutSeconds);
187
- resolveLeaderSemanticBudgetTurns(config.leaderSemanticBudgetTurns);
187
+ resolveLeaderSemanticBudgetRuns(config.leaderSemanticBudgetRuns);
188
188
  resolveTmuxBin(config.tmuxBin);
189
189
  resolveTmuxHistoryLimit(config.tmuxHistoryLimit);
190
190
  resolveTelemetryEnabled(config.telemetryEnabled);
191
191
  resolveTelemetryTerminalKeep(config.telemetryTerminalKeep);
192
- resolveTelemetryTurnCap(config.telemetryTurnCap);
192
+ resolveTelemetryRunCap(config.telemetryRunCap);
193
193
  }
194
194
  catch (error) {
195
195
  throw new StorageRecordError(error instanceof Error ? error.message : "Yui reconciliation interval is invalid.");
@@ -350,7 +350,8 @@ export function isValidCapabilityGrantTransition(existing, candidate) {
350
350
  }
351
351
  // A use record must advance the counter (compare-and-swap): a stale equal
352
352
  // increment from a concurrent reader is rejected, so two workflows cannot
353
- // spend the same maxUses slot. Reservations are append-only, one per use.
353
+ // spend the same maxUses slot. Existing reservations are append-only;
354
+ // non-resumable uses may advance the counter without adding a reservation.
354
355
  return candidate.usesUsed > existing.usesUsed
355
356
  && reservationsAppendOnly(existing.useReservations, candidate.useReservations)
356
357
  && Date.parse(candidate.updatedAt) >= Date.parse(existing.updatedAt);
@@ -702,7 +703,8 @@ function assertJsonValue(value, label, seen = new Set()) {
702
703
  }
703
704
  function clone(value) { assertJsonValue(value, "Stored value"); return JSON.parse(JSON.stringify(value)); }
704
705
  export function pendingWakeupProjection(mailbox) {
705
- const pending = mailbox?.processing?.owner.startsWith("leader-steer:") === true
706
+ const pending = (mailbox?.processing?.owner.startsWith("leader-steer:") === true
707
+ || mailbox?.processing?.owner.startsWith("leader-notification:") === true)
706
708
  ? mailbox.processing.batch
707
709
  : mailbox?.pending ?? null;
708
710
  if (mailbox === null || mailbox.target.kind !== "role" || mailbox.target.roleName !== "leader"
@@ -6,7 +6,7 @@ import { RUNTIME_PROCESS_EXIT_TASK_EVENT, validateRuntimeProcessExitObservation
6
6
  import { validateAgentProfile } from "../../profile/agentProfile.js";
7
7
  import { validateRoleSessionSet } from "../../executor/agentExecutor.js";
8
8
  import { validateReviewRound } from "../../review/reviewRound.js";
9
- import { validateTurn } from "../../turn/turn.js";
9
+ import { validateRun } from "../../agentRun/agentRun.js";
10
10
  import { validateDurableJob } from "../../job/durableJob.js";
11
11
  import { validateWorkItem } from "../../workItem/workItem.js";
12
12
  import { SqliteTaskStore } from "../sqliteStore.js";
@@ -185,10 +185,8 @@ function validateCurrentStore(home) {
185
185
  validateRoleSessionSet(sessions);
186
186
  }
187
187
  for (const owner of store.listSessionOwners()) {
188
- if (owner.schemaVersion !== 2
189
- || typeof owner.runtimeGenerationId !== "string"
190
- || Object.hasOwn(owner, "launchId")) {
191
- throw new Error("Session owner runtime generation identity is invalid.");
188
+ if (owner.schemaVersion !== 2 || Object.hasOwn(owner, "launchId")) {
189
+ throw new Error("Session owner runtime identity is invalid.");
192
190
  }
193
191
  }
194
192
  for (const taskId of store.listTasks().map(({ id }) => id)) {
@@ -198,8 +196,8 @@ function validateCurrentStore(home) {
198
196
  validateWorkItem(item);
199
197
  for (const round of store.listReviewRounds(taskId))
200
198
  validateReviewRound(round);
201
- for (const turn of store.listTurns(taskId))
202
- validateTurn(turn);
199
+ for (const run of store.listRuns(taskId))
200
+ validateRun(run);
203
201
  for (const sessions of store.listRoleSessionSets(taskId)) {
204
202
  validateRoleSessionSet(sessions);
205
203
  }
@@ -0,0 +1,102 @@
1
+ /** A fresh authorized view, not a second directory or instance ledger.
2
+ * Capabilities naturally contribute CLI commands; queries also get the known
3
+ * JSON renderer unless the provider supplies a controlled panel descriptor. */
4
+ export class SurfaceContributions {
5
+ registry;
6
+ constructor(registry) {
7
+ this.registry = registry;
8
+ }
9
+ listCommands(context) {
10
+ return this.registry.search(context).map((entry) => ({
11
+ ...reference(entry), name: entry.surfaces?.cli?.name ?? entry.name,
12
+ help: entry.surfaces?.cli?.help ?? entry.summary, effect: entry.effect,
13
+ ...(entry.unavailable === undefined ? {} : { unavailable: entry.unavailable })
14
+ }));
15
+ }
16
+ listPanels(context) {
17
+ return this.registry.search(context).flatMap((entry) => {
18
+ const panel = entry.surfaces?.panel
19
+ ?? (entry.effect === "query" ? { kind: "data", title: entry.summary, renderer: "json" } : undefined);
20
+ return panel ? [{
21
+ ...reference(entry), panel, inputSchema: entry.inputSchema,
22
+ ...(entry.unavailable === undefined ? {} : { unavailable: entry.unavailable })
23
+ }] : [];
24
+ });
25
+ }
26
+ /** Query entry used by the Controller-owned Web server. Resolve the current
27
+ * descriptor and exact generation again; the browser never supplies code. */
28
+ readPanel(context, selected, input) {
29
+ const resolved = this.registry.describe(context, {
30
+ name: selected.capability, contractVersion: selected.contractVersion, providerId: selected.provider.id
31
+ });
32
+ if (resolved.kind !== "value")
33
+ return Promise.resolve(resolved);
34
+ const descriptor = resolved.value;
35
+ if (descriptor.provider.generation !== selected.provider.generation || descriptor.effect !== "query") {
36
+ return Promise.resolve({ kind: "unavailable", effect: "none", operations: [],
37
+ detail: "Panel changed or is not a query. Reload current panels." });
38
+ }
39
+ const panel = descriptor.surfaces?.panel;
40
+ if (panel !== undefined && panel.kind !== "data")
41
+ return Promise.resolve({ ...resolved, value: panel });
42
+ return this.registry.call(context, {
43
+ name: descriptor.name, contractVersion: descriptor.contractVersion,
44
+ providerId: descriptor.provider.id, input
45
+ });
46
+ }
47
+ }
48
+ /** Called before a complete capability generation is published. Restrict the
49
+ * entire accepted shape so unchecked HTML or executable fields cannot sneak
50
+ * into the browser's descriptor payload. */
51
+ export function checkSurfaceDescriptors(entry) {
52
+ if (entry.surfaces === undefined)
53
+ return;
54
+ const surfaces = record(entry.surfaces, ["cli", "panel"]);
55
+ if (surfaces.cli !== undefined) {
56
+ const cli = record(surfaces.cli, ["name", "help"]);
57
+ // Command names are the capability's existing namespace, not root commands
58
+ // or a second alias-resolution policy.
59
+ if (cli.name !== entry.name || !text(cli.help))
60
+ throw new Error("Invalid CLI contribution.");
61
+ }
62
+ if (surfaces.panel !== undefined) {
63
+ const panel = record(surfaces.panel, ["kind", "title", "text", "href", "renderer"]);
64
+ if (!text(panel.title))
65
+ throw new Error("Invalid panel title.");
66
+ switch (panel.kind) {
67
+ case "text":
68
+ record(panel, ["kind", "title", "text"]);
69
+ if (typeof panel.text !== "string")
70
+ throw new Error("Invalid text panel.");
71
+ break;
72
+ case "link": {
73
+ record(panel, ["kind", "title", "href"]);
74
+ if (!text(panel.href))
75
+ throw new Error("Invalid link panel.");
76
+ const url = new URL(panel.href);
77
+ if (!["https:", "http:"].includes(url.protocol) || url.username || url.password) {
78
+ throw new Error("Panel links require an HTTP(S) URL without credentials.");
79
+ }
80
+ break;
81
+ }
82
+ case "data":
83
+ record(panel, ["kind", "title", "renderer"]);
84
+ if (entry.effect !== "query" || panel.renderer !== "json")
85
+ throw new Error("Invalid data panel.");
86
+ break;
87
+ default: throw new Error("Unknown panel kind.");
88
+ }
89
+ }
90
+ }
91
+ function reference(entry) {
92
+ return { capability: entry.name, contractVersion: entry.contractVersion, provider: entry.provider };
93
+ }
94
+ function text(value) {
95
+ return typeof value === "string" && value.trim().length > 0;
96
+ }
97
+ function record(value, keys) {
98
+ if (!value || typeof value !== "object" || Array.isArray(value)
99
+ || Object.keys(value).some((key) => !keys.includes(key)))
100
+ throw new Error("Invalid surface descriptor.");
101
+ return value;
102
+ }
@@ -1,4 +1,24 @@
1
1
  import { governingWorkItemDeliveries, integrationAttemptRequiresSettlement, workItemDeliverySettled } from "../integration/deliveryObligation.js";
2
+ import { operationalTaskRecords } from "./taskRecordRetirement.js";
3
+ /** Mailbox refs locate original durable user intent. No separate acknowledgement
4
+ * state is introduced: finish the current native turn and let the existing
5
+ * notification delivery present the new input before declaring completion. */
6
+ export function pendingCompletionMessages(store, taskId) {
7
+ const mailbox = store.getWorkMailbox({ kind: "role", taskId, roleName: "leader" });
8
+ const refs = [...(mailbox?.pending?.refs ?? [])];
9
+ const processing = mailbox?.processing;
10
+ if (processing?.owner.startsWith("leader-notification:")) {
11
+ const native = store.getTaskRoleSessionSet(taskId, "leader")?.providerBinding?.run;
12
+ if (native?.attemptId !== processing.batchId
13
+ || !["accepted", "completed", "failed", "cancelled"].includes(native.status)) {
14
+ refs.push(...processing.batch.refs);
15
+ }
16
+ }
17
+ const ids = new Set(refs.filter(ref => ref.type === "message" && ref.taskId === taskId).map(ref => ref.id));
18
+ return operationalTaskRecords(store.listMessages(taskId), store.listEvents(taskId), "message")
19
+ .filter(message => ids.has(message.id)
20
+ && (message.kind === "user" || message.kind === "operator") && message.wakePolicy !== "none");
21
+ }
2
22
  const ACTIVE_JOB_STATUSES = new Set([
3
23
  "queued",
4
24
  "running",
@@ -15,6 +35,14 @@ export function projectCompletionReadiness(facts) {
15
35
  const blockers = [];
16
36
  const advisories = [];
17
37
  const { task } = facts;
38
+ for (const message of facts.pendingUserMessages ?? []) {
39
+ blockers.push({
40
+ code: "pending-user-input",
41
+ ref: ref("message", message.id),
42
+ reason: `User message ${message.id} is still awaiting Leader delivery.`,
43
+ fix: `finish the current native turn, read the next notification and message ${message.id}, then reconsider completion`
44
+ });
45
+ }
18
46
  // A pending/running Task-final Review must be resumed or blocked first.
19
47
  for (const round of facts.reviewRounds) {
20
48
  if ((round.scope ?? "work-item") !== "task")
@@ -27,7 +55,7 @@ export function projectCompletionReadiness(facts) {
27
55
  reason: `Task-final ReviewRound ${round.id} is ${round.status}.`,
28
56
  fix: round.status === "pending"
29
57
  ? `yui task review retry ${task.id}/${round.id}`
30
- : `wait for Reviewer Turn on ${round.id} to finish`
58
+ : `wait for Reviewer AgentRun on ${round.id} to finish`
31
59
  });
32
60
  }
33
61
  // Open Input requests block protocol convergence.
@@ -41,15 +69,13 @@ export function projectCompletionReadiness(facts) {
41
69
  }
42
70
  // Every Work Item must be terminal (completed or retired).
43
71
  for (const item of facts.workItems) {
44
- if (item.status === "completed" || item.status === "retired")
72
+ if (item.status === "accepted" || item.status === "retired")
45
73
  continue;
46
74
  blockers.push({
47
75
  code: "incomplete-work-item",
48
76
  ref: ref("work-item", item.id),
49
77
  reason: `Work Item ${item.id} is ${item.status}.`,
50
- fix: item.status === "failed"
51
- ? `yui task work update ${task.id}/${item.id} running`
52
- : `complete or retire Work Item ${item.id}`
78
+ fix: `accept or retire Work Item ${item.id}`
53
79
  });
54
80
  }
55
81
  // Active DurableJobs (integration checks, etc.) must settle.
@@ -152,7 +178,7 @@ function workspaceCompletionDisposition(facts, taskId, workspace) {
152
178
  reason: `Work Item ${owner.workItemId} has an isolated workspace that is not disposed.`,
153
179
  fix: `yui task work cleanup ${taskId}/${owner.workItemId} --integrated|--abandon`
154
180
  };
155
- return item !== undefined && (item.status === "completed" || item.status === "retired")
181
+ return item !== undefined && (item.status === "accepted" || item.status === "retired")
156
182
  ? { kind: "advisory", value }
157
183
  : { kind: "blocker", value };
158
184
  }
@@ -1,5 +1,5 @@
1
- import { isCompletedTaskReviewEvidenceFromTurns } from "../review/reviewAcceptance.js";
2
- const OPEN_WORK_ITEM_STATUSES = new Set(["pending", "running", "awaiting_acceptance"]);
1
+ import { isCompletedTaskReviewEvidenceFromRuns } from "../review/reviewAcceptance.js";
2
+ const OPEN_WORK_ITEM_STATUSES = new Set(["open"]);
3
3
  export function detectDeliveryDuplicates(facts, intent) {
4
4
  switch (intent.kind) {
5
5
  case "create-work-item":
@@ -59,7 +59,7 @@ function detectWorkItemDuplicates(facts, scope) {
59
59
  });
60
60
  continue;
61
61
  }
62
- if (sameScope && item.status === "completed") {
62
+ if (sameScope && item.status === "accepted") {
63
63
  duplicates.push({
64
64
  severity: "suspected",
65
65
  reason: `Work Item ${item.id} already delivered the identical scope; re-creating it may be a duplicate successor`,
@@ -127,7 +127,7 @@ function detectReviewDuplicates(facts, intent) {
127
127
  if (!sameCandidate)
128
128
  continue;
129
129
  const ref = { kind: "review-round", id: round.id };
130
- if (isCompletedTaskReviewEvidenceFromTurns(round, facts.reviewOutcomeEvidence?.turns ?? [])) {
130
+ if (isCompletedTaskReviewEvidenceFromRuns(round, facts.reviewOutcomeEvidence?.runs ?? [])) {
131
131
  duplicates.push({
132
132
  severity: "exact",
133
133
  reason: `Task-final Review ${round.id} already attests this exact head`,
@@ -174,29 +174,29 @@ function overlap(left, right) {
174
174
  * Default number of consecutive completed Leader turns that must produce no
175
175
  * durable delivery change before the budget is exhausted.
176
176
  */
177
- export const DEFAULT_SEMANTIC_BUDGET_TURNS = 3;
177
+ export const DEFAULT_SEMANTIC_BUDGET_RUNS = 3;
178
178
  /**
179
179
  * Evaluate the semantic-progress budget from existing records only. The
180
- * budget is exhausted when the last `turns` Leader Turns all completed and no
180
+ * budget is exhausted when the last `runs` Leader AgentRuns all completed and no
181
181
  * WorkItem/ChangeSet/Integration/Review record changed at or after the first
182
- * of those Turns. Active execution (any Turn) never exhausts the budget: a
182
+ * of those AgentRuns. Active execution (any AgentRun) never exhausts the budget: a
183
183
  * slow but progressing Worker or Leader is never interrupted.
184
184
  */
185
- export function evaluateSemanticBudget(facts, turns = DEFAULT_SEMANTIC_BUDGET_TURNS) {
186
- if (facts.activeTurns.length > 0) {
185
+ export function evaluateSemanticBudget(facts, runs = DEFAULT_SEMANTIC_BUDGET_RUNS) {
186
+ if (facts.activeRuns.length > 0) {
187
187
  return {
188
188
  exhausted: false,
189
- reason: "Active execution is in flight; the budget never interrupts a progressing Turn.",
190
- evidence: facts.activeTurns.map((run) => run.id)
189
+ reason: "Active execution is in flight; the budget never interrupts a progressing AgentRun.",
190
+ evidence: facts.activeRuns.map((run) => run.id)
191
191
  };
192
192
  }
193
- const recentLeaderRuns = facts.leaderTurns
193
+ const recentLeaderRuns = facts.leaderRuns
194
194
  .filter((run) => run.status === "completed")
195
- .slice(-turns);
196
- if (recentLeaderRuns.length < turns) {
195
+ .slice(-runs);
196
+ if (recentLeaderRuns.length < runs) {
197
197
  return {
198
198
  exhausted: false,
199
- reason: `Fewer than ${turns} consecutive completed Leader turns.`,
199
+ reason: `Fewer than ${runs} consecutive completed Leader runs.`,
200
200
  evidence: recentLeaderRuns.map((run) => run.id)
201
201
  };
202
202
  }
@@ -211,7 +211,7 @@ export function evaluateSemanticBudget(facts, turns = DEFAULT_SEMANTIC_BUDGET_TU
211
211
  }
212
212
  return {
213
213
  exhausted: true,
214
- reason: `${turns} consecutive Leader turns produced no durable delivery change; record a diagnosis and wait for new facts instead of creating more records.`,
214
+ reason: `${runs} consecutive Leader runs produced no durable delivery change; record a diagnosis and wait for new facts instead of creating more records.`,
215
215
  evidence: recentLeaderRuns.map((run) => run.id)
216
216
  };
217
217
  }
@@ -1,3 +1,25 @@
1
+ import { RUNTIME_OBSERVATION_TASK_EVENT } from "../runtime/runtimeObservation.js";
2
+ import { SYSTEM_LEADER_ROLE } from "../role/systemRoles.js";
3
+ /**
4
+ * Runtime Task-event types that are emitted with a Role but no Turn in their
5
+ * payload. Each one is still only exempted when its `roleName` resolves to the
6
+ * Leader — the `runtime.` prefix is never exempted, and a type absent from this
7
+ * set keeps disqualifying the Draft.
8
+ *
9
+ * Turn lifecycle events are deliberately not listed: they use one generic type
10
+ * per transition and name the Turn in their payload, so the guard resolves that
11
+ * Turn's own purpose instead of trusting the type. Listing invented
12
+ * `turn.planning-*` types would have exempted nothing while silently
13
+ * disqualifying every Draft that ever held a planning conversation.
14
+ */
15
+ export const PLANNING_ROLE_EVENT_TYPES = new Set([
16
+ "runtime.session-stop-requested",
17
+ "runtime.session-termination",
18
+ // Written by the liveness/host-exit paths, which admit a Draft planning Turn.
19
+ // Its payload carries the Role and embeds the Turn only inside the serialized
20
+ // observation, so it is resolved as Role-scoped rather than by that blob.
21
+ "runtime.process-exit-observed"
22
+ ]);
1
23
  export function assertDraftTaskExecutionFree(store, task) {
2
24
  if (task.status !== "draft") {
3
25
  throw new Error(`Task is not a Draft: ${task.id}/${task.status}.`);
@@ -109,13 +131,21 @@ function assertDraftWorkItemDependencyGraph(workItems, onlyItem) {
109
131
  function firstDraftExecutionFact(store, task) {
110
132
  if (task.workspaceIdentity !== undefined || task.cwd !== undefined)
111
133
  return "Task workspace";
112
- const hostOwner = store.listSessionOwners().find(({ owner }) => (owner.scope === "task" && owner.taskId === task.id));
134
+ // Draft planning is a first-class Leader conversation, so its Turns, its
135
+ // Session and its Host are ordinary planning facts rather than execution
136
+ // history. Anything that could only exist after delivery still disqualifies
137
+ // the Draft, and a planning Turn can never carry a WorkItem, ReviewRound,
138
+ // Lane or workspace (validateTurn enforces that), so this stays a narrow
139
+ // exemption rather than a hole.
140
+ const run = store.listRuns(task.id).find(({ purpose }) => purpose !== "planning");
141
+ if (run !== undefined)
142
+ return `AgentRun ${run.id}/${run.purpose}`;
143
+ const hostOwner = store.listSessionOwners().find(({ owner }) => (owner.scope === "task" && owner.taskId === task.id && owner.roleName !== SYSTEM_LEADER_ROLE));
113
144
  if (hostOwner !== undefined)
114
- return `Host owner (${hostOwner.runtimeGenerationId})`;
115
- if (store.listTurns(task.id).length > 0)
116
- return "Turn";
117
- if (store.listRoleSessionSets(task.id).length > 0)
118
- return "Role Session";
145
+ return `Host process (${hostOwner.providerRoot.pid})`;
146
+ const sessionSet = store.listRoleSessionSets(task.id).find(({ owner }) => owner.roleName !== SYSTEM_LEADER_ROLE);
147
+ if (sessionSet !== undefined)
148
+ return `Role Session (${sessionSet.owner.roleName})`;
119
149
  if (store.listDurableJobs(task.id).length > 0)
120
150
  return "DurableJob";
121
151
  if (store.listManagedWorkspaces(task.id).length > 0)
@@ -130,13 +160,43 @@ function firstDraftExecutionFact(store, task) {
130
160
  || item.currentExecutionGroupId !== undefined
131
161
  || item.candidates.length > 0
132
162
  || item.workspaceDisposition !== undefined
133
- || !["pending", "retired"].includes(item.status)));
163
+ || !["open", "retired"].includes(item.status)));
134
164
  if (itemWithExecution !== undefined) {
135
165
  return `Work Item execution (${itemWithExecution.id})`;
136
166
  }
137
- const runtimeEvent = store.listEvents(task.id).find(({ type }) => (type.startsWith("runtime.")
138
- || type.startsWith("turn.")
139
- || type.startsWith("review.")
140
- || type.startsWith("integration.")));
141
- return runtimeEvent === undefined ? undefined : `event ${runtimeEvent.id}/${runtimeEvent.type}`;
167
+ // Runtime observations support planning; they are not a competing source
168
+ // of delivery authority. The domain records above own delivery facts.
169
+ return undefined;
170
+ }
171
+ /**
172
+ * Whether one runtime/Turn Task event belongs to this Draft's own planning
173
+ * conversation.
174
+ *
175
+ * The binding the event carries decides this, never its type prefix:
176
+ *
177
+ * - it names a Turn → that Turn must exist on this Task and be `planning`;
178
+ * - it names no Turn → its exact type must be Role-scoped by construction and
179
+ * its `roleName` must be the Leader, the only Role a Draft may run.
180
+ *
181
+ * Everything else stays disqualifying, so an unrecognized type, a foreign Role
182
+ * or a Turn reference that cannot be resolved fails closed.
183
+ */
184
+ function isDraftPlanningEvent(store, task, event) {
185
+ // Several emitters write an absent Turn as an empty string, so only a
186
+ // non-empty id counts as a reference worth resolving.
187
+ const runId = event.payload["runId"];
188
+ if (typeof runId === "string" && runId !== "") {
189
+ return store.getRun(task.id, runId)?.purpose === "planning";
190
+ }
191
+ // A canonical runtime observation is the event normal delivery writes for
192
+ // session.started/conversation.observed/turn.accepted and every terminal. It
193
+ // names its Turn in the same payload field as everything else and was
194
+ // resolved above; only an unfenced host-level observation reaches here, where
195
+ // the Role still has to prove it. Admitting this one type by its own binding
196
+ // is not the same as admitting the `runtime.` prefix.
197
+ if (event.type !== RUNTIME_OBSERVATION_TASK_EVENT
198
+ && !PLANNING_ROLE_EVENT_TYPES.has(event.type)) {
199
+ return false;
200
+ }
201
+ return event.payload["roleName"] === SYSTEM_LEADER_ROLE;
142
202
  }