@zq-silk/yui 0.15.11 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/ARCHITECTURE.md +11 -6
  2. package/ARCHITECTURE.zh-CN.md +8 -4
  3. package/README.md +13 -5
  4. package/dist/agentRun/agentRun.js +3 -0
  5. package/dist/artifacts/artifactCommitLock.js +16 -55
  6. package/dist/artifacts/taskArtifactRepository.js +3 -3
  7. package/dist/cli/agentConfigurationPicker.js +1 -1
  8. package/dist/cli/commandCatalog.js +92 -48
  9. package/dist/cli/completion.js +18 -18
  10. package/dist/cli/completionWizard.js +1 -1
  11. package/dist/cli/dynamicCompletion.js +1 -1
  12. package/dist/cli/interactionPolicy.js +11 -3
  13. package/dist/cli/invocationAuthority.js +64 -0
  14. package/dist/cli/managedDiagnostics.js +2 -2
  15. package/dist/cli/parseRepeatable.js +35 -0
  16. package/dist/cli/updatePorts.js +26 -5
  17. package/dist/cli.js +1303 -1235
  18. package/dist/commands/agentCommands.js +4 -4
  19. package/dist/commands/capabilityCommands.js +1 -1
  20. package/dist/commands/configCommands.js +6 -57
  21. package/dist/commands/configOverview.js +2 -2
  22. package/dist/commands/durableJobCommands.js +12 -6
  23. package/dist/commands/executionAuditCommands.js +10 -0
  24. package/dist/commands/globalRoleCommands.js +78 -29
  25. package/dist/commands/grantCommands.js +0 -3
  26. package/dist/commands/jobCommands.js +1 -4
  27. package/dist/commands/operatorCommands.js +3 -3
  28. package/dist/commands/projectCommands.js +45 -25
  29. package/dist/commands/resourcesCommands.js +10 -40
  30. package/dist/commands/roleConfiguration.js +2 -6
  31. package/dist/commands/taskActivationCommands.js +4 -8
  32. package/dist/commands/taskAgentCapabilities.js +9 -0
  33. package/dist/commands/taskCommandSupport.js +155 -0
  34. package/dist/commands/taskCommandTypes.js +1 -0
  35. package/dist/commands/taskCommands.js +355 -732
  36. package/dist/commands/taskCompletionGate.js +1 -1
  37. package/dist/commands/taskExecutionCommands.js +1 -1
  38. package/dist/commands/taskFactCommands.js +325 -0
  39. package/dist/commands/taskInputCommands.js +12 -42
  40. package/dist/commands/taskIntegrationCommands.js +20 -58
  41. package/dist/commands/taskNextActionCommand.js +7 -6
  42. package/dist/commands/taskPublicationAdoptCommand.js +127 -0
  43. package/dist/commands/taskPublicationCommands.js +12 -3
  44. package/dist/commands/taskPublicationVerifyCommand.js +24 -40
  45. package/dist/commands/taskRemoteDeliveryCommand.js +5 -86
  46. package/dist/commands/taskUpstreamCommands.js +19 -8
  47. package/dist/commands/workflowCommands.js +6 -1
  48. package/dist/completion/completionInstaller.js +26 -26
  49. package/dist/completion/completionState.js +26 -26
  50. package/dist/completion/fileCompletionManager.js +6 -11
  51. package/dist/config/configCatalog.js +0 -2
  52. package/dist/config/timeZone.js +14 -0
  53. package/dist/config/yuiConfig.js +0 -29
  54. package/dist/context/runContextPack.js +5 -3
  55. package/dist/context/taskCatalog.js +185 -0
  56. package/dist/context/taskContext.js +152 -151
  57. package/dist/context/wakeRunReferences.js +11 -0
  58. package/dist/controller/agentCapabilities.js +58 -0
  59. package/dist/controller/agentRuntimeObserver.js +6 -11
  60. package/dist/controller/clientRuntime.js +22 -14
  61. package/dist/controller/controller.js +20 -24
  62. package/dist/controller/fileSchedulerStoreAdapter.js +191 -225
  63. package/dist/controller/globalInputDelivery.js +13 -0
  64. package/dist/controller/jobClient.js +4 -4
  65. package/dist/controller/jobControl.js +60 -25
  66. package/dist/controller/jobSupervisor.js +4 -4
  67. package/dist/controller/providerRetryAdmission.js +100 -0
  68. package/dist/controller/providerRetryDelivery.js +218 -0
  69. package/dist/controller/runtime.js +85 -43
  70. package/dist/controller/runtimeEventProcessor.js +0 -5
  71. package/dist/controller/sessionOwnerReconciliation.js +5 -0
  72. package/dist/controller/taskAgentError.js +35 -0
  73. package/dist/coordination/workMailboxQueue.js +2 -24
  74. package/dist/core/controllerClient.js +2 -2
  75. package/dist/core/fileLockOwner.js +74 -0
  76. package/dist/decision/decision.js +17 -0
  77. package/dist/doctor/doctor.js +18 -9
  78. package/dist/event/taskEvent.js +12 -0
  79. package/dist/execution/workItemExecutionProjection.js +2 -2
  80. package/dist/executor/agentCapabilityConfig.js +43 -0
  81. package/dist/executor/agentConfigurationCatalog.js +49 -11
  82. package/dist/executor/agentExecutor.js +5 -8
  83. package/dist/executor/fileRoleLaunchPlanner.js +11 -53
  84. package/dist/executor/taskAgentCapabilities.js +64 -0
  85. package/dist/integration/deliveryObligation.js +1 -69
  86. package/dist/integration/gitIntegrationService.js +79 -90
  87. package/dist/integration/integrationAttempt.js +3 -14
  88. package/dist/integration/integrationSourceApplication.js +4 -12
  89. package/dist/integration/manifestTags.js +2 -2
  90. package/dist/job/durableJob.js +4 -25
  91. package/dist/job/jobAssignmentScope.js +22 -0
  92. package/dist/job/jobOperation.js +16 -0
  93. package/dist/job/jobRunner.js +2 -1
  94. package/dist/job/stepDirectory.js +15 -0
  95. package/dist/kernel/builtinCapabilities.js +15 -11
  96. package/dist/kernel/kernelPorts.js +1 -17
  97. package/dist/lifecycle/exactRunTerminalization.js +5 -10
  98. package/dist/message/globalProviderRetry.js +15 -0
  99. package/dist/message/inputControlResolution.js +3 -4
  100. package/dist/message/message.js +17 -20
  101. package/dist/message/messageContinuation.js +1 -1
  102. package/dist/milestone/milestone.js +11 -0
  103. package/dist/observability/executionAudit.js +19 -0
  104. package/dist/observability/orchestrationMetrics.js +24 -1
  105. package/dist/observability/runtimeIdentity.js +1 -17
  106. package/dist/output/agentConfigurationPresentation.js +2 -0
  107. package/dist/output/timePresentation.js +1 -14
  108. package/dist/plugins/pluginService.js +12 -4
  109. package/dist/release/releaseWorkflowPorts.js +45 -96
  110. package/dist/release/runtimeRelease.js +9 -15
  111. package/dist/repository/gitWorkspace.js +371 -105
  112. package/dist/repository/projectMaintenanceLock.js +98 -82
  113. package/dist/repository/taskBaseFreshness.js +1 -1
  114. package/dist/repository/taskWorkspaceCoordinator.js +82 -144
  115. package/dist/repository/taskWorkspacePreparer.js +113 -47
  116. package/dist/repository/workspaceCleanupInspection.js +187 -0
  117. package/dist/resources/autoResourceGc.js +4 -77
  118. package/dist/resources/liveReferences.js +7 -54
  119. package/dist/resources/resourceDiscovery.js +5 -118
  120. package/dist/resources/resourceGc.js +233 -181
  121. package/dist/resources/resourceRegistrar.js +5 -4
  122. package/dist/resources/resourceRegistry.js +3 -37
  123. package/dist/resources/resourceRegistryStore.js +13 -36
  124. package/dist/resources/sqliteResourceRegistry.js +43 -26
  125. package/dist/review/deltaRecheck.js +1 -1
  126. package/dist/review/reviewAcceptance.js +1 -1
  127. package/dist/review/reviewDecision.js +1 -1
  128. package/dist/review/reviewRound.js +8 -7
  129. package/dist/review/taskFinalReviewContractResolution.js +1 -1
  130. package/dist/runtime/acpProtocol.js +4 -51
  131. package/dist/runtime/acpSession.js +10 -75
  132. package/dist/runtime/acpSessionConfiguration.js +1 -8
  133. package/dist/runtime/agentEndpoint.js +3 -2
  134. package/dist/runtime/agentError.js +5 -3
  135. package/dist/runtime/agentFailureContext.js +43 -0
  136. package/dist/runtime/agentHost.js +42 -25
  137. package/dist/runtime/builtinAgentErrorMappers.js +91 -0
  138. package/dist/runtime/codexAppServerRuntime.js +34 -3
  139. package/dist/runtime/codexInteractiveHost.js +2 -2
  140. package/dist/runtime/index.js +0 -1
  141. package/dist/runtime/managedCaller.js +21 -1
  142. package/dist/runtime/providerControl.js +5 -1
  143. package/dist/runtime/providerErrors.js +38 -0
  144. package/dist/runtime/providerRetry.js +198 -0
  145. package/dist/runtime/providerRuntimeIdentity.js +28 -2
  146. package/dist/runtime/runtimeObservation.js +0 -5
  147. package/dist/runtime/runtimeSessionCandidate.js +2 -3
  148. package/dist/runtime/sessionOwnerIdentity.js +1 -1
  149. package/dist/runtime/sessionTokenMetrics.js +15 -5
  150. package/dist/runtime/structuredProviderHost.js +10 -43
  151. package/dist/runtime/taskUsageMetrics.js +275 -0
  152. package/dist/runtime/tmuxAdapters.js +6 -8
  153. package/dist/scheduler/activeRoleRunDelivery.js +19 -7
  154. package/dist/scheduler/leaderWakeupProcessor.js +24 -6
  155. package/dist/scheduler/operatorEvent.js +12 -20
  156. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  157. package/dist/scheduler/ports.js +5 -8
  158. package/dist/scheduler/roleRunLiveness.js +4 -4
  159. package/dist/scheduler/roleRunStall.js +16 -23
  160. package/dist/scheduler/taskExecutionProjection.js +49 -36
  161. package/dist/scheduler/taskObservabilityProjection.js +6 -45
  162. package/dist/scheduler/taskWake.js +5 -10
  163. package/dist/scheduler/wakeReason.js +2 -0
  164. package/dist/scheduler/wakeupQueue.js +2 -4
  165. package/dist/setup/setupCommand.js +1 -1
  166. package/dist/storage/contextRecords.js +106 -0
  167. package/dist/storage/currentTaskStore.js +1 -1
  168. package/dist/storage/homeLayout.js +13 -17
  169. package/dist/storage/migrations/agentFailureContext.js +22 -0
  170. package/dist/storage/migrations/currentInputContract.js +86 -0
  171. package/dist/storage/migrations/currentRuntimeContract.js +228 -0
  172. package/dist/storage/migrations/historicalVerificationPlan.js +35 -0
  173. package/dist/storage/migrations/integrationContinuation.js +5 -4
  174. package/dist/storage/migrations/narrowAgentFailureContext.js +65 -0
  175. package/dist/storage/migrations/notificationOnlyWakes.js +74 -0
  176. package/dist/storage/migrations/verificationPlanV1.js +162 -0
  177. package/dist/storage/migrations/verificationPolicy.js +74 -0
  178. package/dist/storage/migrations/workItemHistory.js +46 -0
  179. package/dist/storage/persistenceWorker.js +12 -4
  180. package/dist/storage/recordValidation.js +87 -0
  181. package/dist/storage/sqliteSchema.js +173 -1
  182. package/dist/storage/sqliteStore.js +172 -161
  183. package/dist/storage/storageSchema.js +2 -14
  184. package/dist/storage/storageVersions.js +1 -1
  185. package/dist/storage/storeRpc.js +16 -7
  186. package/dist/storage/taskCatalog.js +123 -0
  187. package/dist/storage/taskStore.js +5 -7
  188. package/dist/storage/upgrade/upgradeOrchestrator.js +25 -37
  189. package/dist/task/archiveDiagnostics.js +1 -0
  190. package/dist/task/archivePreflight.js +124 -0
  191. package/dist/task/completionReadiness.js +5 -24
  192. package/dist/task/draftPlan.js +0 -53
  193. package/dist/task/nextAction.js +7 -13
  194. package/dist/task/publicationAdoption.js +56 -0
  195. package/dist/task/publicationReference.js +10 -0
  196. package/dist/task/remoteDelivery.js +31 -16
  197. package/dist/task/remoteDeliveryService.js +89 -0
  198. package/dist/task/taskActivation.js +2 -25
  199. package/dist/task/taskActivationService.js +0 -2
  200. package/dist/task/taskRecordReference.js +0 -1
  201. package/dist/task/taskSubmission.js +3 -14
  202. package/dist/telemetry/sqliteTelemetryBatch.js +29 -0
  203. package/dist/telemetry/sqliteTelemetryStore.js +49 -49
  204. package/dist/telemetry/telemetryWiring.js +4 -3
  205. package/dist/tmux/tmuxManager.js +29 -20
  206. package/dist/verification/gateArtifact.js +15 -24
  207. package/dist/verification/gateArtifactStore.js +14 -7
  208. package/dist/verification/verificationGateService.js +29 -88
  209. package/dist/verification/verificationPlan.js +27 -72
  210. package/dist/web/assets/client/app.js +92 -17
  211. package/dist/web/assets/client/components.js +55 -13
  212. package/dist/web/assets/client/i18n.js +72 -4
  213. package/dist/web/assets/client/taskSurface.js +6 -5
  214. package/dist/web/assets/client/view.js +35 -7
  215. package/dist/web/assets/shell.js +6 -0
  216. package/dist/web/assets/styles/layout.js +7 -0
  217. package/dist/web/webServer.js +12 -3
  218. package/dist/web/webSnapshot.js +14 -85
  219. package/dist/web/webTaskSurface.js +17 -46
  220. package/dist/workItem/workItem.js +1 -12
  221. package/dist/workspace/cleanupInspection.js +63 -0
  222. package/dist/workspace/workItemChangeSetManager.js +110 -50
  223. package/docs/agent-result-consumption.md +4 -0
  224. package/docs/agent-result-consumption.zh-CN.md +3 -0
  225. package/docs/agent-runtime-drivers.md +7 -0
  226. package/docs/agent-runtime-drivers.zh-CN.md +5 -0
  227. package/docs/architecture/README.md +2 -0
  228. package/docs/architecture/README.zh-CN.md +3 -1
  229. package/docs/architecture/capabilities-and-resources.md +42 -5
  230. package/docs/architecture/capabilities-and-resources.zh-CN.md +33 -3
  231. package/docs/managed-turn-and-session-runtime.md +121 -1
  232. package/docs/managed-turn-and-session-runtime.zh-CN.md +96 -2
  233. package/docs/observability/README.md +62 -0
  234. package/docs/observability/README.zh-CN.md +47 -0
  235. package/docs/plugin-sdk.md +4 -2
  236. package/docs/project-refresh.md +77 -0
  237. package/docs/project-refresh.zh-CN.md +59 -0
  238. package/docs/provider-retry.md +70 -0
  239. package/docs/provider-runtime.md +3 -1
  240. package/docs/provider-runtime.zh-CN.md +4 -2
  241. package/docs/release-workflow.md +190 -7
  242. package/docs/release-workflow.zh-CN.md +139 -5
  243. package/docs/roles-and-configuration.md +29 -0
  244. package/docs/roles-and-configuration.zh-CN.md +21 -0
  245. package/docs/sqlite-control-plane-design.md +16 -3
  246. package/docs/sqlite-control-plane-design.zh-CN.md +13 -2
  247. package/docs/task-dag-semantics.md +3 -3
  248. package/docs/task-dag-semantics.zh-CN.md +2 -2
  249. package/docs/task-delivery.md +223 -17
  250. package/docs/task-delivery.zh-CN.md +171 -14
  251. package/docs/task-discovery.md +101 -0
  252. package/docs/task-discovery.zh-CN.md +85 -0
  253. package/docs/testing/verification-levels.md +161 -9
  254. package/docs/testing/verification-levels.zh-CN.md +116 -9
  255. package/i18n/README.zh-CN.md +13 -7
  256. package/package.json +1 -1
  257. package/skills/yui-leader/SKILL.md +5 -0
  258. package/skills/yui-leader/references/execution.md +3 -2
  259. package/skills/yui-leader/references/integration.md +9 -5
  260. package/skills/yui-leader/references/planning.md +9 -3
  261. package/skills/yui-operator/SKILL.md +24 -8
  262. package/skills/yui-reviewer/SKILL.md +4 -0
  263. package/skills/yui-runtime/SKILL.md +17 -2
  264. package/skills/yui-runtime/references/publication.md +26 -4
  265. package/skills/yui-runtime/references/recovery.md +71 -0
  266. package/dist/agent/agentRegistry.js +0 -10
  267. package/dist/agentRun/runIdentity.js +0 -22
  268. package/dist/commands/deliveryGuardPreflight.js +0 -30
  269. package/dist/commands/taskIntegrationQueueCommands.js +0 -226
  270. package/dist/commands/taskOverviewCommand.js +0 -376
  271. package/dist/completion/completionWizard.js +0 -125
  272. package/dist/context/dispatchContext.js +0 -110
  273. package/dist/context/wakeNotification.js +0 -144
  274. package/dist/integration/integrationCheckEvidenceReuse.js +0 -53
  275. package/dist/integration/integrationQueueEntry.js +0 -191
  276. package/dist/integration/integrationQueueService.js +0 -810
  277. package/dist/release/fakeReleasePorts.js +0 -55
  278. package/dist/runtime/sessionOwnerRegistry.js +0 -137
  279. package/dist/task/deliveryGuard.js +0 -226
  280. /package/dist/{commands/taskActor.js → task/taskAuthority.js} +0 -0
package/ARCHITECTURE.md CHANGED
@@ -93,8 +93,9 @@ meaning of the report. See [result consumption](docs/agent-result-consumption.md
93
93
  ## Planning, workspaces and resources
94
94
 
95
95
  Draft contains planning facts and Project bindings, not an adopted delivery
96
- workspace. Its private planning directory is outside the control Home and
97
- delivery trees. Planning Sessions capture `planning` authority. The Leader can
96
+ workspace. Its private planning directory is under
97
+ `<YUI_HOME>/runtime/task-runtimes/planning`, separate from durable control data
98
+ and delivery trees. Planning Sessions capture `planning` authority. The Leader can
98
99
  persist an activation request during a Run or ordinary discussion and return;
99
100
  native quiescence releases the intent for current-authority and resource checks.
100
101
 
@@ -169,8 +170,9 @@ Leader management is limited to its Task; executable code still requires exact
169
170
  Operator-issued grants. Plugin validation is not a security certification.
170
171
 
171
172
  CLI contributions and controlled Web panels are projections of the Registry.
172
- Web is loopback-only and Controller-owned; browser credentials do not become
173
- Operator authority. See [Plugin SDK](docs/plugin-sdk.md) and
173
+ Web is loopback-only and Controller-owned. Its authenticated local-user controls
174
+ share CLI domain operations; query panels remain read-only and cannot borrow
175
+ that user authority for mutations or plugin management. See [Plugin SDK](docs/plugin-sdk.md) and
174
176
  [capabilities and resources](docs/architecture/capabilities-and-resources.md).
175
177
 
176
178
  ## Persistence, completion and operation
@@ -181,8 +183,11 @@ Homes; malformed state is diagnosed, not automatically repaired.
181
183
 
182
184
  Completion freezes the delivery result and checks applicable acceptance,
183
185
  integration and review contracts. It is distinct from publication, verified
184
- remote merge, physical quiescence and archive. Archive requires settled work
185
- and clean removable managed resources, preserves Task history, and cannot reopen.
186
+ remote merge, physical quiescence and archive. Ordinary archive requires settled
187
+ work and clean removable managed resources. Explicitly authorized force archive
188
+ can retain unresolved evidence and unsafe resources without claiming delivery or
189
+ quiescence. Both preserve Task history and cannot reopen.
190
+ See [Task delivery and archive](docs/task-delivery.md#archive).
186
191
 
187
192
  Runtime health and cost are observations, not semantic verdicts. The Agent reads
188
193
  exact faults and current intent to choose retry, repair or abandonment. Yui does
@@ -72,8 +72,9 @@ Reviewer 输出留在那个 Run 上。审查策略和显式的 Task-final 合同
72
72
 
73
73
  ## 规划、工作区与资源
74
74
 
75
- Draft 包含规划事实和 Project 绑定,而不是一个已采用的交付工作区。它私有的规划目录在
76
- 控制 Home 和交付树之外。规划 Session 捕获 `planning` 权限。Leader 可以在一个 Run 或
75
+ Draft 包含规划事实和 Project 绑定,而不是一个已采用的交付工作区。它私有的规划目录位于
76
+ `<YUI_HOME>/runtime/task-runtimes/planning`,与持久控制数据和交付树分开。
77
+ 规划 Session 捕获 `planning` 权限。Leader 可以在一个 Run 或
77
78
  普通讨论中持久化一个激活请求并返回;原生静止会把该意图释放出来,进行当前权限和资源
78
79
  检查。
79
80
 
@@ -132,7 +133,8 @@ Registry 暴露 context、消息、artifact、环境、插件以及部分 Task/J
132
133
  由 Operator 签发的 grant。插件验证不是安全认证。
133
134
 
134
135
  CLI 贡献和受控的 Web 面板是 Registry 的投影。Web 仅本地回环、由 Controller 拥有;浏览器
135
- 凭据不会变成 Operator 权限。参见[插件 SDK](docs/plugin-sdk.zh-CN.md)和
136
+ 凭据认证本地用户控制,这些控制复用 CLI 领域操作;查询面板仍只读,不能借用该用户权限
137
+ 执行修改或插件管理。参见[插件 SDK](docs/plugin-sdk.zh-CN.md)和
136
138
  [能力与资源](docs/architecture/capabilities-and-resources.zh-CN.md)。
137
139
 
138
140
  ## 持久化、完成与运维
@@ -141,7 +143,9 @@ Home 有一条只追加的存储迁移链。普通运行时只接受当前记录
141
143
  有效 Home;畸形状态被诊断,而不是自动修复。
142
144
 
143
145
  完成会冻结交付结果,并检查适用的验收、集成和审查合同。它区别于发布、已验证的远程合并、
144
- 物理静止和归档。归档要求工作已了结、受管资源干净可移除,保留 Task 历史,且不可重开。
146
+ 物理静止和归档。普通归档要求工作已了结、受管资源干净可移除。明确授权的 force 归档
147
+ 可以保留未解决证据与不安全资源,但不宣称交付或物理静止。两者都保留 Task 历史且不可
148
+ 重开。参见[Task 交付与归档](docs/task-delivery.zh-CN.md#归档)。
145
149
 
146
150
  运行时健康度和成本是观察,而不是语义判定。Agent 读取精确的故障和当前意图,以选择重试、
147
151
  修复或放弃。Yui 不会自动创建救援 Worker 或选择另一个模型。
package/README.md CHANGED
@@ -30,7 +30,7 @@ not from terminal windows you juggle or details you have to remember.
30
30
  - **Bring your own Agent** — Codex CLI, Claude Code CLI and ACP peers run behind
31
31
  one boundary and stay replaceable without losing the Task.
32
32
  - **Local-first and private** — everything runs on your machine for one trusted
33
- user; the Web view is loopback and read-only.
33
+ user; Web is loopback-only, with read-only views and authenticated user controls.
34
34
  - **Isolated by default** — repository work happens in managed Git worktrees;
35
35
  the stable checkout stays read-only.
36
36
 
@@ -137,7 +137,11 @@ when necessary. A failed process does not erase the Task, and an uncertain
137
137
  submission is not silently repeated.
138
138
 
139
139
  For a visual overview, run `yui web` in another terminal. The local Web view
140
- shows the same tasks and pending questions; it is not a separate task system.
140
+ shows the same tasks and pending questions and lets you send messages, answer
141
+ questions and explicitly queue, steer or interrupt Task input. These authenticated
142
+ Task controls use the same operations as the CLI; Web is not a separate task system.
143
+ See [Web permissions](docs/architecture/capabilities-and-resources.md#cli-and-web)
144
+ and [input timing](docs/managed-turn-and-session-runtime.md#input-timing-queue-steer-and-interrupt).
141
145
 
142
146
  ## Architecture
143
147
 
@@ -243,7 +247,7 @@ the Controller are what touch the store:
243
247
  it moves work and records facts — it never judges an answer
244
248
 
245
249
  Agents work in Projects: read-only checkout + isolated worktrees.
246
- Web view (yui web): a loopback, read-only projection of the store.
250
+ Web (yui web): loopback views + authenticated user controls.
247
251
  ```
248
252
 
249
253
  ### Layered design
@@ -253,7 +257,7 @@ never a fixed workflow:
253
257
 
254
258
  ```text
255
259
  Experience — how you interact
256
- CLI (Operator) · Web (loopback, read-only) · native Agent sessions
260
+ CLI (Operator) · Web (loopback, authenticated) · native Agent sessions
257
261
  collect input · show facts · confirm actions · invoke capabilities
258
262
 
259
263
  Intelligence — who decides
@@ -290,9 +294,13 @@ extra states:
290
294
  WorkItem open ─▶ accepted ─▶ retired
291
295
 
292
296
  Draft holds planning only; activation adopts a delivery workspace.
293
- Archive needs settled work and clean worktrees; it cannot reopen.
297
+ Ordinary archive needs settled work and clean worktrees; it cannot reopen.
294
298
  ```
295
299
 
300
+ Explicitly authorized force archive can retain unresolved evidence and unsafe
301
+ resources; it does not prove delivery or permission to delete them.
302
+ See the [archive contract](docs/task-delivery.md#archive).
303
+
296
304
  ## Design principles
297
305
 
298
306
  ### Agents make decisions; Yui makes work durable
@@ -2,6 +2,7 @@ import { validateEffectiveLaunchSnapshot } from "../executor/effectiveLaunch.js"
2
2
  import { validateTaskRecordReference } from "../task/taskRecordReference.js";
3
3
  import { validateManagedWorkspace } from "../worktree/managedWorkspace.js";
4
4
  import { createRunInput, createRunInputEnvelope, validateRunInput } from "../context/runInputContract.js";
5
+ import { providerRetryProjection } from "../runtime/providerRetry.js";
5
6
  import { boundedRunFailureDiagnostic, MAX_RUN_FAILURE_DIAGNOSTIC_BYTES, MAX_RUN_RESULT_OUTPUT_BYTES } from "../domain/agentResultTransport.js";
6
7
  export { boundedRunFailureDiagnostic, MAX_RUN_FAILURE_DIAGNOSTIC_BYTES, MAX_RUN_RESULT_OUTPUT_BYTES, transportAgentResult } from "../domain/agentResultTransport.js";
7
8
  /** Record lifecycle and observed delivery are separate read-only facts. */
@@ -17,6 +18,8 @@ export function runExecutionObservation(run, binding, events = []) {
17
18
  return {
18
19
  recordStatus: run.status,
19
20
  delivery,
21
+ retry: binding?.retry?.previousRunId === run.id || binding?.retry?.successorRunId === run.id
22
+ ? providerRetryProjection(binding) : null,
20
23
  ...(current === undefined ? {} : {
21
24
  attemptId: current.attemptId, observedAt: current.updatedAt,
22
25
  ...(current.nativeTurnId === undefined ? {} : { nativeTurnId: current.nativeTurnId })
@@ -1,5 +1,6 @@
1
1
  import { mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { currentFileLockOwner, fileLockOwnerIsLive } from "../core/fileLockOwner.js";
3
4
  /**
4
5
  * Short per-Task commit fence for artifact repositories.
5
6
  *
@@ -9,9 +10,9 @@ import { join } from "node:path";
9
10
  * into the wrong commit, or race the expected-HEAD check. This fence serializes
10
11
  * the commit critical section for one Task.
11
12
  *
12
- * Unlike the Project maintenance fence (which guards long operations and fails
13
- * fast so the CLI is not blocked), an artifact save is a short operation, so a
14
- * contended fence briefly RETRIES before giving up. It is otherwise the same
13
+ * The Project maintenance fence waits asynchronously for longer operations.
14
+ * An artifact save is short, so this synchronous critical section briefly
15
+ * retries a contended fence before giving up. It otherwise shares the same
15
16
  * crash-safe design: an exclusive directory under the Home's `locks/` area
16
17
  * (O_EXCL via mkdir), an owner file recording PID + process start time so a
17
18
  * recycled PID can never pass for the original holder, and reclaim of a stale
@@ -47,12 +48,13 @@ export function artifactCommitLockPath(home, taskId) {
47
48
  */
48
49
  export function acquireArtifactCommitLock(home, taskId) {
49
50
  const lock = artifactCommitLockPath(home, taskId);
51
+ const ownerIdentity = currentFileLockOwner();
50
52
  mkdirSync(join(home, "locks", "task-artifacts"), { recursive: true, mode: 0o700 });
51
53
  const deadline = Date.now() + ARTIFACT_COMMIT_LOCK_TIMEOUT_MS;
52
54
  while (true) {
53
55
  try {
54
56
  mkdirSync(lock, { mode: 0o700 });
55
- const ownerIdentity = writeOwnerIdentity(lock);
57
+ writeOwnerIdentity(lock, ownerIdentity);
56
58
  let released = false;
57
59
  return () => {
58
60
  if (released)
@@ -72,8 +74,7 @@ export function acquireArtifactCommitLock(home, taskId) {
72
74
  }
73
75
  }
74
76
  /** Write this process's owner identity and return the exact bytes recorded. */
75
- function writeOwnerIdentity(lock) {
76
- const identity = `${process.pid}:${processStartIdentity() ?? ""}`;
77
+ function writeOwnerIdentity(lock, identity = currentFileLockOwner()) {
77
78
  writeFileSync(join(lock, "owner"), `${identity}\n`, { mode: 0o600 });
78
79
  return identity;
79
80
  }
@@ -109,8 +110,8 @@ function reclaimStaleArtifactCommitLock(lock) {
109
110
  catch (error) {
110
111
  if (!isEnoent(error))
111
112
  throw error;
112
- // Ownerless lock: a crash between mkdir and owner publication. Reclaim only
113
- // when old enough that the creator is not still initializing.
113
+ // Allow publication its initial grace period; an older missing owner is
114
+ // diagnosed as unverified below, never treated as a dead creator.
114
115
  try {
115
116
  if (Date.now() - statSync(lock).mtimeMs < STALE_ARTIFACT_COMMIT_LOCK_AGE_MS)
116
117
  return;
@@ -131,7 +132,7 @@ function reclaimStaleArtifactCommitLock(lock) {
131
132
  return;
132
133
  throw error;
133
134
  }
134
- if (expectedOwner !== null && lockOwnerIsAlive(lock))
135
+ if (fileLockOwnerIsLive(lock))
135
136
  return;
136
137
  const reclaimLock = `${lock}.reclaim`;
137
138
  for (let attempt = 0; attempt < 2; attempt += 1) {
@@ -171,7 +172,7 @@ function reclaimStaleArtifactCommitLock(lock) {
171
172
  }
172
173
  if (currentOwner !== expectedOwner)
173
174
  return;
174
- if (currentOwner !== null && lockOwnerIsAlive(lock))
175
+ if (fileLockOwnerIsLive(lock))
175
176
  return;
176
177
  rmSync(lock, { recursive: true, force: true });
177
178
  }
@@ -182,63 +183,23 @@ function reclaimStaleArtifactCommitLock(lock) {
182
183
  }
183
184
  }
184
185
  /**
185
- * Reclaim a reclaim-lock directory only when provably orphaned: dead (or
186
- * unrecorded) owner AND older than the age bound. Returns true when it removed
186
+ * Reclaim a reclaim-lock directory only with a proven dead generation and
187
+ * after the age bound. Returns true when it removed
187
188
  * the lock (caller retries), false otherwise.
188
189
  */
189
190
  function reclaimOrphanedReclaimLock(reclaimLock) {
190
191
  try {
191
192
  if (Date.now() - statSync(reclaimLock).mtimeMs < STALE_ARTIFACT_COMMIT_LOCK_AGE_MS)
192
193
  return false;
193
- if (lockOwnerIsAlive(reclaimLock))
194
+ if (fileLockOwnerIsLive(reclaimLock))
194
195
  return false;
195
196
  rmSync(reclaimLock, { recursive: true, force: true });
196
197
  return true;
197
198
  }
198
- catch (error) {
199
- return isEnoent(error);
200
- }
201
- }
202
- function lockOwnerIsAlive(lock) {
203
- let owner;
204
- try {
205
- owner = readFileSync(join(lock, "owner"), "utf8").trim();
206
- }
207
199
  catch (error) {
208
200
  if (isEnoent(error))
209
- return false;
210
- return true; // Unreadable owner fails closed: treat the fence as held.
211
- }
212
- const separator = owner.indexOf(":");
213
- const pid = Number.parseInt(separator < 0 ? owner : owner.slice(0, separator), 10);
214
- if (!Number.isInteger(pid) || pid <= 0)
215
- return false;
216
- const recordedIdentity = separator < 0 ? "" : owner.slice(separator + 1);
217
- const currentIdentity = processStartIdentity(pid);
218
- if (currentIdentity !== undefined) {
219
- return recordedIdentity !== "" && currentIdentity === recordedIdentity;
220
- }
221
- return processIsAlive(pid);
222
- }
223
- /** Linux process start time (clock ticks since boot) for a PID; undefined off /proc. */
224
- function processStartIdentity(pid = process.pid) {
225
- try {
226
- const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
227
- const close = stat.lastIndexOf(")");
228
- const fields = stat.slice(close + 2).split(" ");
229
- return fields[19] ?? "0"; // field 22: starttime
230
- }
231
- catch {
232
- return undefined;
233
- }
234
- }
235
- function processIsAlive(pid) {
236
- try {
237
- process.kill(pid, 0);
238
- return true;
239
- }
240
- catch (error) {
241
- return error instanceof Error && "code" in error && error.code === "EPERM";
201
+ return true;
202
+ throw error;
242
203
  }
243
204
  }
244
205
  function isEnoent(error) {
@@ -1,10 +1,10 @@
1
- import { mkdir, writeFile } from "node:fs/promises";
2
- import { existsSync } from "node:fs";
3
1
  import { createHash } from "node:crypto";
2
+ import { existsSync } from "node:fs";
3
+ import { mkdir, writeFile } from "node:fs/promises";
4
4
  import { dirname, join } from "node:path";
5
- import { ManagedGitError, externalProgramConfigViolations, managedGit, managedGitBuffer, managedGitSucceeds, requireCommitId } from "./managedGit.js";
6
5
  import { acquireArtifactCommitLock } from "./artifactCommitLock.js";
7
6
  import { resolveContainedArtifactPath, safeRelativeArtifactPath, taskArtifactRepoPath } from "./artifactPaths.js";
7
+ import { ManagedGitError, externalProgramConfigViolations, managedGit, managedGitBuffer, managedGitSucceeds, requireCommitId } from "./managedGit.js";
8
8
  /**
9
9
  * Per-Task local-only Git artifact repository.
10
10
  *
@@ -106,7 +106,7 @@ export async function selectAgentPermission(resolved, io, current) {
106
106
  export function renderAgentConfigurationResolutionNotice(resolved) {
107
107
  const lines = [];
108
108
  if (resolved.source === "cache") {
109
- lines.push(`! Runtime capability request failed (${resolved.failure?.message ?? "unknown failure"}). `
109
+ lines.push((resolved.failure === undefined ? "" : `! Runtime capability request failed (${resolved.failure.message}). `)
110
110
  + `Showing cached options from ${resolved.fetchedAt ?? "an earlier request"}; they may be stale.`);
111
111
  }
112
112
  else if (resolved.source === "fallback") {
@@ -116,7 +116,8 @@ const agentChildren = [
116
116
  {
117
117
  name: "capabilities",
118
118
  summary: "Probe one Agent CLI for runtime configuration options.",
119
- usage: "yui config agent capabilities <id>"
119
+ usage: "yui config agent capabilities <id> [--refresh]",
120
+ options: ["--refresh"]
120
121
  },
121
122
  {
122
123
  name: "update",
@@ -215,6 +216,11 @@ const globalSessionChildren = [
215
216
  summary: "Reconcile durable Session owners with native sessions.",
216
217
  usage: "yui session reconcile [--report] [--cleanup]",
217
218
  options: ["--report", "--cleanup"]
219
+ },
220
+ {
221
+ name: "retry",
222
+ summary: "Inspect or control bounded Provider recovery for this Global Session.",
223
+ usage: "yui session retry <role> [show|cancel|disable|enable]"
218
224
  }
219
225
  ];
220
226
  const profileChildren = [
@@ -288,7 +294,7 @@ const taskChildren = [
288
294
  "--type": ["feature", "bugfix"]
289
295
  }
290
296
  },
291
- { name: "activate", summary: "Activate a Draft Task.", usage: "yui task activate <id>" },
297
+ { name: "activate", summary: "Adopt an existing Activation request for a Draft Task.", usage: "yui task activate <id>" },
292
298
  {
293
299
  name: "activation",
294
300
  summary: "Request, cancel or inspect explicit Task Activation.",
@@ -373,9 +379,9 @@ const taskChildren = [
373
379
  },
374
380
  {
375
381
  name: "list",
376
- summary: "List unarchived Task overviews.",
377
- usage: "yui task list [--all] [--verbose]",
378
- options: ["--all", "--verbose"]
382
+ summary: "Discover Tasks through a bounded, filterable catalog.",
383
+ usage: "yui task list [--all] [--status <status>] [--project <id>] [--search <text>] [--attention <category>] [--limit <1..100>] [--cursor <cursor>]",
384
+ options: ["--all", "--status", "--project", "--search", "--attention", "--limit", "--cursor"]
379
385
  },
380
386
  { name: "show", summary: "Show a Task.", usage: "yui task show <id>" },
381
387
  {
@@ -406,6 +412,12 @@ const taskChildren = [
406
412
  usage: "yui task remote-delivery <task> [--json]",
407
413
  options: ["--json"]
408
414
  },
415
+ {
416
+ name: "archive-preflight",
417
+ summary: "Inspect current archive and exact-owner cleanup blockers without changing state or authorizing removal.",
418
+ usage: "yui task archive-preflight <id> (--integrated|--abandon) [--force] [--json]",
419
+ options: ["--integrated", "--abandon", "--force", "--json"]
420
+ },
409
421
  {
410
422
  name: "archive",
411
423
  summary: "Archive a terminal Task; explicit --force commits despite delivery/cleanup warnings, retaining unsafe resources.",
@@ -421,8 +433,8 @@ const taskChildren = [
421
433
  {
422
434
  name: "integrate",
423
435
  summary: "Rebase Task changes onto the remote development head through Integration.",
424
- usage: "yui task upstream integrate <task> (--latest|--project <project>) [--check <command> ...]",
425
- options: ["--latest", "--project", "--check"]
436
+ usage: "yui task upstream integrate <task> (--latest|--project <project>) [--check <command> ...] [--rerun-checks]",
437
+ options: ["--latest", "--project", "--check", "--rerun-checks"]
426
438
  }
427
439
  ]
428
440
  },
@@ -446,18 +458,17 @@ const taskChildren = [
446
458
  {
447
459
  name: "send",
448
460
  summary: "Send a Task message. An unaddressed user/operator message carries a submission intent (record|discuss|develop) and an optional idempotency key.",
449
- usage: "yui task message send <id> (<body>|--body-file <path|->) [--intent record|discuss|develop] [--request-id <key>] [--wake-policy leader|none] [--to <role> --work-item <id>|--review-round <id>]",
450
- options: ["--body-file", "--intent", "--request-id", "--wake-policy", "--to", "--work-item", "--review-round"],
461
+ usage: "yui task message send <id> (<body>|--body-file <path|->) [--intent record|discuss|develop] [--request-id <key>] [--to <role> --work-item <id>|--review-round <id>]",
462
+ options: ["--body-file", "--intent", "--request-id", "--to", "--work-item", "--review-round"],
451
463
  optionValues: {
452
- "--intent": ["record", "discuss", "develop"],
453
- "--wake-policy": ["leader", "none"]
464
+ "--intent": ["record", "discuss", "develop"]
454
465
  },
455
466
  fileOptions: ["--body-file"]
456
467
  },
457
468
  {
458
469
  name: "queue",
459
- summary: "Queue an input for delivery at the recipient's next legal opportunity (idempotent by request id).",
460
- usage: "yui task message queue <id> (<body>|--body-file <path|->) --request-id <id> [--to <role> --work-item <id>|--review-round <id>]",
470
+ summary: "Queue ordinary Leader input without --to; an explicit Role requires an existing WorkItem/ReviewRound Assignment. Idempotent by request id.",
471
+ usage: "yui task message queue <id> (<body>|--body-file <path|->) --request-id <id> [--to <role> (--work-item <id>|--review-round <id>)]",
461
472
  options: ["--body-file", "--request-id", "--to", "--work-item", "--review-round"],
462
473
  fileOptions: ["--body-file"]
463
474
  },
@@ -481,12 +492,9 @@ const taskChildren = [
481
492
  },
482
493
  {
483
494
  name: "update",
484
- summary: "Replace the mutable body and wake policy of a Draft user/operator Message.",
485
- usage: "yui task message update <task>/<message> (<body>|--body-file <path|->) [--wake-policy leader|none]",
486
- options: ["--body-file", "--wake-policy"],
487
- optionValues: {
488
- "--wake-policy": ["leader", "none"]
489
- },
495
+ summary: "Edit unkeyed Draft context without changing intent; inputs with request identities require a new Message.",
496
+ usage: "yui task message update <task>/<message> (<body>|--body-file <path|->)",
497
+ options: ["--body-file"],
490
498
  fileOptions: ["--body-file"]
491
499
  },
492
500
  {
@@ -606,17 +614,29 @@ const taskChildren = [
606
614
  {
607
615
  name: "publication",
608
616
  summary: "Create or update external PR/MR publication evidence for a Task.",
609
- sections: [{ id: "manage", title: "Commands", entries: ["upsert", "verify", "list", "show"] }],
617
+ sections: [{ id: "manage", title: "Commands", entries: ["upsert", "diff", "adopt", "verify", "list", "show"] }],
610
618
  children: [
611
619
  {
612
620
  name: "upsert",
613
621
  summary: "Create or immutably update an external PR/MR and its publication state.",
614
- usage: "yui task publication upsert <task> --project <project> --provider <github|gitlab> --repository <owner/name> --kind <pull-request|merge-request> --id <external-id> [--url <url>] [--title <text>] [--source-branch <branch>] [--target-branch <branch>] [--local-commit <sha>] [--remote-commit <sha>] [--state <open|merged|closed>] [--reported|--verified] [--evidence <text>] [--merged-at <iso-timestamp>]",
615
- options: ["--project", "--provider", "--repository", "--kind", "--id", "--url", "--title", "--source-branch", "--target-branch", "--local-commit", "--remote-commit", "--state", "--reported", "--verified", "--evidence", "--merged-at"]
622
+ usage: "yui task publication upsert <task> --project <project> --provider <github|gitlab> --repository <owner/name> --kind <pull-request|merge-request> --id <external-id> [--url <url>] [--title <text>] [--source-branch <branch>] [--target-branch <branch>] [--local-commit <sha>] [--head-commit <sha>] [--remote-commit <sha>] [--state <open|merged|closed>] [--reported|--verified] [--evidence <text>] [--merged-at <iso-timestamp>]",
623
+ options: ["--project", "--provider", "--repository", "--kind", "--id", "--url", "--title", "--source-branch", "--target-branch", "--local-commit", "--head-commit", "--remote-commit", "--state", "--reported", "--verified", "--evidence", "--merged-at"]
624
+ },
625
+ {
626
+ name: "diff",
627
+ summary: "Read a completed Task's fixed acceptance-to-publication candidate diff using local Git only.",
628
+ usage: "yui task publication diff <task>/<publication> [--integration <id>]",
629
+ options: ["--integration"]
630
+ },
631
+ {
632
+ name: "adopt",
633
+ summary: "Explicitly accept the reviewed publication candidate as covering the original completion.",
634
+ usage: "yui task publication adopt <task>/<publication> --reviewed-diff <sha256> --acceptance <text> [--integration <id>]",
635
+ options: ["--reviewed-diff", "--acceptance", "--integration"]
616
636
  },
617
637
  {
618
638
  name: "verify",
619
- summary: "Verify one current GitHub PR against the exact Task delivery head through gh.",
639
+ summary: "Observe the current PR/MR head and merge through its provider; record verification separately from Task coverage.",
620
640
  usage: "yui task publication verify (<task>/<publication-id> | <task> <publication-id>)"
621
641
  },
622
642
  {
@@ -636,7 +656,7 @@ const taskChildren = [
636
656
  summary: "Manage Roles within a Task.",
637
657
  sections: [{ id: "manage", title: "Commands", entries: [
638
658
  "add", "list", "status", "show", "update", "remove", "bind", "unbind",
639
- "session", "interrupt", "view", "takeover", "release"
659
+ "capabilities", "session", "interrupt", "view", "takeover", "release"
640
660
  ] }],
641
661
  children: [
642
662
  {
@@ -653,6 +673,9 @@ const taskChildren = [
653
673
  usage: "yui task role status <task> <role>"
654
674
  },
655
675
  { name: "show", summary: "Show one Task Role.", usage: "yui task role show <task> <role>" },
676
+ { name: "capabilities", summary: "Read native options using this Role's desired or exact failed launch configuration.",
677
+ usage: "yui task role capabilities <task> <role> [--error <event-id>] [--refresh]",
678
+ options: ["--error", "--refresh"] },
656
679
  {
657
680
  name: "update",
658
681
  summary: "Update a Task Role; Agent settings target the named or active binding without switching it.",
@@ -668,8 +691,13 @@ const taskChildren = [
668
691
  name: "session",
669
692
  summary: "Inspect, stop or explicitly select a new Task Role Session.",
670
693
  executable: true,
671
- sections: [{ id: "manage", title: "Commands", entries: ["inspect", "stop", "new"] }],
694
+ sections: [{ id: "manage", title: "Commands", entries: ["inspect", "retry", "stop", "new"] }],
672
695
  children: [
696
+ {
697
+ name: "retry",
698
+ summary: "Inspect or control Provider recovery without stopping an admitted Turn.",
699
+ usage: "yui task role session retry <task> <role> [show|cancel|disable|enable]"
700
+ },
673
701
  {
674
702
  name: "inspect",
675
703
  summary: "Read the current Session, Host process, and AgentRun facts.",
@@ -919,13 +947,13 @@ const taskChildren = [
919
947
  {
920
948
  name: "integration",
921
949
  summary: "Integrate WorkItem results and upstream commits with Leader-owned decisions.",
922
- sections: [{ id: "manage", title: "Commands", entries: ["start", "continue", "resolve", "abort", "supersede", "list", "show", "cleanup", "queue"] }],
950
+ sections: [{ id: "manage", title: "Commands", entries: ["start", "continue", "resolve", "abort", "supersede", "list", "show", "cleanup"] }],
923
951
  children: [
924
952
  {
925
953
  name: "start",
926
954
  summary: "Build, validate, and CAS-commit an integration candidate.",
927
- usage: "yui task integration start <task> --work-item <id> --strategy <ff|cherry-pick|merge|manual> [--project <project>] [--target <ref>] [--check <command> ...]",
928
- options: ["--work-item", "--strategy", "--project", "--target", "--check"],
955
+ usage: "yui task integration start <task> --work-item <id> --strategy <ff|cherry-pick|merge|manual> [--project <project>] [--target <ref>] [--check <command> ...] [--rerun-checks]",
956
+ options: ["--work-item", "--strategy", "--project", "--target", "--check", "--rerun-checks"],
929
957
  optionValues: { "--strategy": ["ff", "cherry-pick", "merge", "manual"] }
930
958
  },
931
959
  {
@@ -954,21 +982,7 @@ const taskChildren = [
954
982
  },
955
983
  { name: "list", summary: "List Integration Attempts.", usage: "yui task integration list <task>" },
956
984
  { name: "show", summary: "Show one Integration Attempt.", usage: "yui task integration show <task>/<integration>" },
957
- { name: "cleanup", summary: "Remove a terminal Integration worktree and branch.", usage: "yui task integration cleanup <task>/<integration>" },
958
- {
959
- name: "queue",
960
- summary: "Manage the serialized integration queue.",
961
- sections: [{ id: "queue", title: "Commands", entries: ["enqueue", "list", "show", "process", "supersede", "requeue", "reconcile"] }],
962
- children: [
963
- { name: "enqueue", summary: "Enqueue a ChangeSet for serialized integration.", usage: "yui task integration queue enqueue <task> --project <project> --change-set <id> [--target <ref>] [--check <command> ...]", options: ["--project", "--change-set", "--target", "--check"] },
964
- { name: "list", summary: "List integration queue entries.", usage: "yui task integration queue list <task> [--project <project>]", options: ["--project"] },
965
- { name: "show", summary: "Show one integration queue entry.", usage: "yui task integration queue show <task>/<entry>" },
966
- { name: "process", summary: "Process queued integration entries.", usage: "yui task integration queue process <task> [--project <project>] [--limit <n>]", options: ["--project", "--limit"] },
967
- { name: "supersede", summary: "Supersede a queued entry.", usage: "yui task integration queue supersede <task>/<entry> --reason <text>", options: ["--reason"] },
968
- { name: "requeue", summary: "Requeue a conflicted entry.", usage: "yui task integration queue requeue <task>/<entry>" },
969
- { name: "reconcile", summary: "Reconcile a blocked entry.", usage: "yui task integration queue reconcile <task>/<entry>" }
970
- ]
971
- }
985
+ { name: "cleanup", summary: "Remove a terminal Integration worktree and branch.", usage: "yui task integration cleanup <task>/<integration>" }
972
986
  ]
973
987
  },
974
988
  {
@@ -1057,10 +1071,12 @@ const taskChildren = [
1057
1071
  {
1058
1072
  name: "wake",
1059
1073
  summary: "Inspect the durable Leader wake ledger and its delta content.",
1060
- sections: [{ id: "manage", title: "Commands", entries: ["list", "show", "resolve"] }],
1074
+ sections: [{ id: "manage", title: "Commands", entries: ["list", "show", "retry", "resolve"] }],
1061
1075
  children: [
1062
1076
  { name: "list", summary: "List recorded Leader wakes.", usage: "yui task wake list <task>" },
1063
1077
  { name: "show", summary: "Show one wake and its delta content.", usage: "yui task wake show <task> <wake>" },
1078
+ { name: "retry", summary: "Retry a rejected notification after correcting its cause; preserve original input.",
1079
+ usage: "yui task wake retry <task> <wake> --reason <correction>", options: ["--reason"] },
1064
1080
  { name: "resolve", summary: "Release an unknown notification claim after explicit quiescence evidence, without replay.",
1065
1081
  usage: "yui task wake resolve <task> <wake> --reason <quiescence-evidence>", options: ["--reason"] }
1066
1082
  ]
@@ -1089,13 +1105,41 @@ export const ROOT_COMMAND = buildNode({
1089
1105
  { id: "general", title: "General", entries: [
1090
1106
  "help", "version", "update", "upgrade", "setup", "doctor"
1091
1107
  ] },
1092
- { id: "workflow", title: "Workflow", entries: ["operator", "project", "task"] },
1108
+ { id: "workflow", title: "Workflow", entries: ["operator", "role", "project", "task"] },
1093
1109
  { id: "configuration", title: "Configuration", entries: ["config"] },
1094
1110
  { id: "operations", title: "Operations", entries: ["web", "controller", "session", "execution", "capability", "job", "jobs", "telemetry", "release"] },
1095
1111
  { id: "resources", title: "Resources", entries: ["resources"] },
1096
1112
  { id: "internal", title: "Internal", entries: ["internal"] }
1097
1113
  ],
1098
1114
  children: [
1115
+ {
1116
+ name: "role",
1117
+ summary: "Queue input or control an exact current Global Role Turn.",
1118
+ sections: [{ id: "input", title: "Input control", entries: ["message", "interrupt"] }],
1119
+ children: [
1120
+ {
1121
+ name: "message", summary: "Send durable input to a Global Role.",
1122
+ sections: [{ id: "input", title: "Input control", entries: ["queue", "steer"] }],
1123
+ children: [
1124
+ {
1125
+ name: "queue", summary: "Queue input for the next legal delivery opportunity.",
1126
+ usage: "yui role message queue <role> (<text>|--body-file <path|->) --request-id <id>",
1127
+ options: ["--request-id", "--body-file"], fileOptions: ["--body-file"]
1128
+ },
1129
+ {
1130
+ name: "steer", summary: "Steer the exact current native Turn.",
1131
+ usage: "yui role message steer <role> (<text>|--body-file <path|->) --request-id <id> --expected-target <turn>",
1132
+ options: ["--request-id", "--expected-target", "--body-file"], fileOptions: ["--body-file"]
1133
+ }
1134
+ ]
1135
+ },
1136
+ {
1137
+ name: "interrupt", summary: "Request cancellation of the exact current native Turn.",
1138
+ usage: "yui role interrupt <role> --expected-target <turn> [--request-id <id>] [--then-message <message>]",
1139
+ options: ["--request-id", "--expected-target", "--then-message"]
1140
+ }
1141
+ ]
1142
+ },
1099
1143
  { name: "help", summary: "Show root or scoped command help.", usage: "yui help [command ...]", commandPathArguments: true },
1100
1144
  { name: "version", summary: "Print the installed Yui version." },
1101
1145
  { name: "update", summary: "Install the latest published Yui package globally." },
@@ -1481,7 +1525,7 @@ export const ROOT_COMMAND = buildNode({
1481
1525
  sections: [
1482
1526
  { id: "global", title: "Global Role sessions", entries: ["context", "enter", "record", "replace"] },
1483
1527
  { id: "maintenance", title: "Maintenance", entries: ["stop"] },
1484
- { id: "recovery", title: "Recovery", entries: ["reconcile"] }
1528
+ { id: "recovery", title: "Recovery", entries: ["reconcile", "retry"] }
1485
1529
  ],
1486
1530
  children: globalSessionChildren
1487
1531
  },
@@ -1489,7 +1533,7 @@ export const ROOT_COMMAND = buildNode({
1489
1533
  name: "task",
1490
1534
  summary: "Manage Tasks, WorkItems, AgentRuns, and integration.",
1491
1535
  sections: [
1492
- { id: "lifecycle", title: "Lifecycle", entries: ["create", "project", "base", "update", "activate", "activation", "execution", "complete", "cancel", "reopen", "retire", "list", "show", "context", "next-action", "remote-delivery", "archive", "replace", "reconcile", "upstream", "artifact"] },
1536
+ { id: "lifecycle", title: "Lifecycle", entries: ["create", "project", "base", "update", "activate", "activation", "execution", "complete", "cancel", "reopen", "retire", "list", "show", "context", "next-action", "remote-delivery", "archive-preflight", "archive", "replace", "reconcile", "upstream", "artifact"] },
1493
1537
  { id: "collaboration", title: "Collaboration", entries: ["message", "input", "grant", "workflow", "publication", "work", "run", "review", "integration", "role", "overlap", "change-set"] },
1494
1538
  { id: "knowledge", title: "Task Knowledge", entries: ["brief", "decision", "milestone", "event", "continuation", "wake"] }
1495
1539
  ],
@@ -1512,7 +1556,7 @@ export const ROOT_COMMAND = buildNode({
1512
1556
  summary: "Start, inspect, cancel, or acknowledge a Controller-managed DurableJob.",
1513
1557
  sections: [{ id: "manage", title: "Commands", entries: ["start", "get", "cancel", "acknowledge"] }],
1514
1558
  children: [
1515
- { name: "start", summary: "Start a DurableJob for build, test, package, or Integration checks.", usage: "yui job start --task <id> --project <project> --head <sha> --workspace <dir> --step <name>=<command> [--step ...] [--owner task|work-item:<id>|integration-attempt:<id>] [--env <k=v>...]" },
1559
+ { name: "start", summary: "Start a DurableJob under an explicit request identity.", usage: "yui job start --request-id <id> --task <id> --project <project> --head <sha> --workspace <dir> --step <name>=<command> [--step ...] [--owner task|work-item:<id>|integration-attempt:<id>] [--env <k=v>...]" },
1516
1560
  { name: "get", summary: "Show a DurableJob record and its terminal result.", usage: "yui job get --task <id> --job <job-id>" },
1517
1561
  { name: "cancel", summary: "Request cancellation of a running or queued DurableJob.", usage: "yui job cancel --task <id> --job <job-id>" },
1518
1562
  { name: "acknowledge", summary: "Acknowledge an unknown-needs-attention DurableJob so Task lifecycle gates can proceed.", usage: "yui job acknowledge --task <id> --job <job-id>" }