@fitlab-ai/agent-infra 0.11.15 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/bin/cli.ts +1 -1
  2. package/dist/bin/cli.js +1 -1
  3. package/dist/bin/internal-cli.js +6 -1
  4. package/dist/lib/agent-clients/adapters/codex-lifecycle/recovery.js +6 -6
  5. package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +8 -18
  6. package/dist/lib/agent-clients/adapters/codex-orchestration.js +1 -1
  7. package/dist/lib/decide.js +2 -7
  8. package/dist/lib/internal/cli-route-inventory.js +3 -0
  9. package/dist/lib/internal/manual-validation.js +19 -33
  10. package/dist/lib/internal/platform-comment.js +59 -9
  11. package/dist/lib/internal/task-activity.js +1 -12
  12. package/dist/lib/internal/task-event.js +1 -12
  13. package/dist/lib/internal/task-ledger.js +1 -12
  14. package/dist/lib/internal/task-operation-registry.js +2 -1
  15. package/dist/lib/internal/task-qualification.js +6 -15
  16. package/dist/lib/internal/task-review.js +3 -16
  17. package/dist/lib/internal/task-short-id.js +2 -1
  18. package/dist/lib/internal/task-verify.js +1 -11
  19. package/dist/lib/internal/task-warning.js +1 -12
  20. package/dist/lib/internal/task-workspace.js +43 -0
  21. package/dist/lib/merge.js +4 -3
  22. package/dist/lib/platform/issue-comments.js +373 -267
  23. package/dist/lib/platform/issue-summary-content.js +112 -0
  24. package/dist/lib/platform/pr-change-report.js +175 -26
  25. package/dist/lib/platform/pr-summary-content.js +54 -0
  26. package/dist/lib/platform/pr-summary.js +321 -296
  27. package/dist/lib/platform/pull-requests.js +3 -15
  28. package/dist/lib/platform/summary-content-pipeline.js +18 -0
  29. package/dist/lib/pr-review/evidence-grading.js +3 -2
  30. package/dist/lib/process-data/index.js +5 -4
  31. package/dist/lib/process-data/sources.js +6 -0
  32. package/dist/lib/run/index.js +3 -2
  33. package/dist/lib/sandbox/commands/create.js +5 -1
  34. package/dist/lib/sandbox/commands/enter.js +1 -1
  35. package/dist/lib/sandbox/commands/list-running.js +2 -1
  36. package/dist/lib/sandbox/control/client.js +8 -13
  37. package/dist/lib/sandbox/control/completed-reentry.js +2 -1
  38. package/dist/lib/sandbox/control/task-view.js +4 -2
  39. package/dist/lib/sandbox/mounts.js +4 -4
  40. package/dist/lib/sandbox/recovery.js +26 -16
  41. package/dist/lib/sandbox/removal.js +62 -12
  42. package/dist/lib/sandbox/task-resolver.js +9 -6
  43. package/dist/lib/sandbox/workspace-identity.js +6 -5
  44. package/dist/lib/sandbox/workspace-view.js +29 -22
  45. package/dist/lib/task/activity-intent.js +2 -12
  46. package/dist/lib/task/artifact-lifecycle.js +17 -11
  47. package/dist/lib/task/artifact-operations.js +41 -49
  48. package/dist/lib/task/capabilities.js +2 -2
  49. package/dist/lib/task/commands/ls.js +4 -3
  50. package/dist/lib/task/commands/status.js +1 -1
  51. package/dist/lib/task/commit-operation.js +6 -6
  52. package/dist/lib/task/control-authority.js +32 -32
  53. package/dist/lib/task/create-service.js +2 -4
  54. package/dist/lib/task/create.js +12 -65
  55. package/dist/lib/task/delegation-receipts.js +1 -1
  56. package/dist/lib/task/delivery.js +2 -8
  57. package/dist/lib/task/events.js +5 -31
  58. package/dist/lib/task/finalization.js +33 -29
  59. package/dist/lib/task/lifecycle.js +9 -48
  60. package/dist/lib/task/local-artifact-finalization.js +1 -2
  61. package/dist/lib/task/orchestration.js +24 -57
  62. package/dist/lib/task/platform-operation-recovery.js +87 -88
  63. package/dist/lib/task/resolve-ref.js +17 -12
  64. package/dist/lib/task/review-finalization.js +2 -35
  65. package/dist/lib/task/review-identity.js +3 -1
  66. package/dist/lib/task/short-id.js +10 -8
  67. package/dist/lib/task/verification-engine.js +19 -58
  68. package/dist/lib/task/workspace-root.js +59 -0
  69. package/dist/lib/task/workspace-snapshot.js +4 -3
  70. package/dist/lifecycle-build-manifest.json +3 -3
  71. package/lib/agent-clients/adapters/codex-lifecycle/recovery.ts +6 -6
  72. package/lib/agent-clients/adapters/codex-lifecycle/store.ts +8 -34
  73. package/lib/agent-clients/adapters/codex-orchestration.ts +1 -1
  74. package/lib/decide.ts +2 -7
  75. package/lib/internal/cli-route-inventory.ts +2 -0
  76. package/lib/internal/manual-validation.ts +20 -37
  77. package/lib/internal/platform-comment.ts +49 -6
  78. package/lib/internal/task-activity.ts +1 -10
  79. package/lib/internal/task-event.ts +1 -10
  80. package/lib/internal/task-ledger.ts +1 -10
  81. package/lib/internal/task-operation-registry.ts +2 -1
  82. package/lib/internal/task-qualification.ts +5 -11
  83. package/lib/internal/task-review.ts +3 -14
  84. package/lib/internal/task-short-id.ts +2 -1
  85. package/lib/internal/task-verify.ts +1 -9
  86. package/lib/internal/task-warning.ts +1 -10
  87. package/lib/internal/task-workspace.ts +39 -0
  88. package/lib/merge.ts +4 -3
  89. package/lib/platform/issue-comments.ts +478 -280
  90. package/lib/platform/issue-summary-content.ts +132 -0
  91. package/lib/platform/pr-change-report.ts +165 -20
  92. package/lib/platform/pr-summary-content.ts +60 -0
  93. package/lib/platform/pr-summary.ts +367 -269
  94. package/lib/platform/pull-requests.ts +3 -24
  95. package/lib/platform/summary-content-pipeline.ts +23 -0
  96. package/lib/pr-review/evidence-grading.ts +3 -2
  97. package/lib/process-data/index.ts +4 -3
  98. package/lib/process-data/sources.ts +6 -0
  99. package/lib/run/index.ts +3 -2
  100. package/lib/sandbox/commands/create.ts +5 -1
  101. package/lib/sandbox/commands/enter.ts +1 -1
  102. package/lib/sandbox/commands/list-running.ts +2 -1
  103. package/lib/sandbox/control/client.ts +7 -12
  104. package/lib/sandbox/control/completed-reentry.ts +2 -1
  105. package/lib/sandbox/control/task-view.ts +4 -2
  106. package/lib/sandbox/mounts.ts +4 -4
  107. package/lib/sandbox/recovery.ts +26 -18
  108. package/lib/sandbox/removal.ts +60 -27
  109. package/lib/sandbox/task-resolver.ts +9 -6
  110. package/lib/sandbox/workspace-identity.ts +6 -5
  111. package/lib/sandbox/workspace-view.ts +28 -20
  112. package/lib/task/activity-intent.ts +3 -17
  113. package/lib/task/artifact-lifecycle.ts +39 -11
  114. package/lib/task/artifact-operations.ts +28 -35
  115. package/lib/task/capabilities.ts +2 -2
  116. package/lib/task/commands/ls.ts +4 -3
  117. package/lib/task/commands/status.ts +1 -1
  118. package/lib/task/commit-operation.ts +5 -6
  119. package/lib/task/control-authority.ts +29 -35
  120. package/lib/task/create-service.ts +2 -4
  121. package/lib/task/create.ts +10 -51
  122. package/lib/task/delegation-receipts.ts +1 -1
  123. package/lib/task/delivery.ts +2 -10
  124. package/lib/task/events.ts +5 -32
  125. package/lib/task/finalization.ts +27 -30
  126. package/lib/task/lifecycle.ts +9 -50
  127. package/lib/task/local-artifact-finalization.ts +1 -4
  128. package/lib/task/orchestration.ts +31 -80
  129. package/lib/task/platform-operation-recovery.ts +70 -82
  130. package/lib/task/resolve-ref.ts +18 -12
  131. package/lib/task/review-finalization.ts +2 -52
  132. package/lib/task/review-identity.ts +3 -1
  133. package/lib/task/short-id.ts +10 -8
  134. package/lib/task/verification-engine.ts +20 -62
  135. package/lib/task/workspace-root.ts +78 -0
  136. package/lib/task/workspace-snapshot.ts +4 -3
  137. package/package.json +1 -1
  138. package/templates/.agents/QUICKSTART.en.md +19 -8
  139. package/templates/.agents/QUICKSTART.zh-CN.md +19 -8
  140. package/templates/.agents/README.en.md +10 -15
  141. package/templates/.agents/README.zh-CN.md +9 -13
  142. package/templates/.agents/rules/issue-sync.en.md +1 -1
  143. package/templates/.agents/rules/issue-sync.zh-CN.md +1 -1
  144. package/templates/.agents/rules/lifecycle-orchestration.en.md +1 -1
  145. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +1 -1
  146. package/templates/.agents/rules/next-step-output.en.md +2 -2
  147. package/templates/.agents/rules/next-step-output.zh-CN.md +2 -2
  148. package/templates/.agents/rules/pr-sync.en.md +5 -3
  149. package/templates/.agents/rules/pr-sync.zh-CN.md +7 -10
  150. package/templates/.agents/rules/release-commands.en.md +3 -0
  151. package/templates/.agents/rules/release-commands.zh-CN.md +3 -0
  152. package/templates/.agents/rules/task-management.en.md +0 -2
  153. package/templates/.agents/rules/task-management.zh-CN.md +0 -2
  154. package/templates/.agents/rules/task-short-id.en.md +2 -2
  155. package/templates/.agents/rules/task-short-id.zh-CN.md +2 -2
  156. package/templates/.agents/scripts/task-short-id.js +2 -8
  157. package/templates/.agents/skills/analyze-task/SKILL.en.md +6 -6
  158. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +6 -6
  159. package/templates/.agents/skills/analyze-task/config/verify.en.json +0 -1
  160. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +0 -1
  161. package/templates/.agents/skills/archive-tasks/SKILL.en.md +5 -5
  162. package/templates/.agents/skills/archive-tasks/SKILL.zh-CN.md +5 -5
  163. package/templates/.agents/skills/archive-tasks/scripts/archive-tasks.sh +10 -2
  164. package/templates/.agents/skills/block-task/SKILL.en.md +4 -4
  165. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +5 -5
  166. package/templates/.agents/skills/block-task/config/verify.json +0 -1
  167. package/templates/.agents/skills/cancel-task/SKILL.en.md +7 -7
  168. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +7 -7
  169. package/templates/.agents/skills/cancel-task/config/verify.json +0 -1
  170. package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
  171. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +3 -3
  172. package/templates/.agents/skills/code-task/config/verify.en.json +0 -1
  173. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +0 -1
  174. package/templates/.agents/skills/code-task/reference/output-template.en.md +1 -1
  175. package/templates/.agents/skills/code-task/reference/output-template.zh-CN.md +1 -1
  176. package/templates/.agents/skills/commit/SKILL.en.md +1 -1
  177. package/templates/.agents/skills/commit/SKILL.zh-CN.md +1 -1
  178. package/templates/.agents/skills/commit/config/verify.json +0 -1
  179. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +2 -2
  180. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +2 -2
  181. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +2 -2
  182. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +2 -2
  183. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +2 -2
  184. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +2 -2
  185. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +0 -1
  186. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +0 -1
  187. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +3 -3
  188. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +3 -3
  189. package/templates/.agents/skills/complete-task/SKILL.en.md +15 -30
  190. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +17 -32
  191. package/templates/.agents/skills/complete-task/config/verify.en.json +0 -1
  192. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +0 -1
  193. package/templates/.agents/skills/create-pr/SKILL.en.md +3 -3
  194. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +3 -3
  195. package/templates/.agents/skills/create-pr/config/verify.json +0 -1
  196. package/templates/.agents/skills/create-pr/reference/change-report.en.md +10 -3
  197. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +10 -3
  198. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +3 -3
  199. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +3 -3
  200. package/templates/.agents/skills/create-release-note/SKILL.en.md +2 -2
  201. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +2 -2
  202. package/templates/.agents/skills/create-task/SKILL.en.md +4 -22
  203. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +4 -22
  204. package/templates/.agents/skills/create-task/config/verify.json +0 -1
  205. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  206. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  207. package/templates/.agents/skills/import-codescan/config/verify.json +0 -1
  208. package/templates/.agents/skills/import-dependabot/SKILL.en.md +3 -3
  209. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +3 -3
  210. package/templates/.agents/skills/import-dependabot/config/verify.json +0 -1
  211. package/templates/.agents/skills/import-issue/SKILL.en.md +5 -5
  212. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +5 -5
  213. package/templates/.agents/skills/import-issue/config/verify.json +0 -1
  214. package/templates/.agents/skills/plan-task/SKILL.en.md +5 -5
  215. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +5 -5
  216. package/templates/.agents/skills/plan-task/config/verify.en.json +0 -1
  217. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +0 -1
  218. package/templates/.agents/skills/restore-task/SKILL.en.md +2 -2
  219. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +3 -3
  220. package/templates/.agents/skills/restore-task/config/verify.json +0 -1
  221. package/templates/.agents/skills/review-analysis/SKILL.en.md +1 -1
  222. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +2 -2
  223. package/templates/.agents/skills/review-analysis/config/verify.en.json +0 -1
  224. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +0 -1
  225. package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +5 -5
  226. package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +5 -5
  227. package/templates/.agents/skills/review-code/SKILL.en.md +2 -2
  228. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +2 -2
  229. package/templates/.agents/skills/review-code/reference/output-templates.en.md +4 -4
  230. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +4 -4
  231. package/templates/.agents/skills/review-plan/SKILL.en.md +1 -1
  232. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +2 -2
  233. package/templates/.agents/skills/review-plan/config/verify.en.json +0 -1
  234. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +0 -1
  235. package/templates/.agents/skills/review-plan/reference/output-templates.en.md +5 -5
  236. package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +5 -5
  237. package/templates/.agents/skills/review-pr/SKILL.en.md +2 -2
  238. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +2 -2
  239. package/templates/.agents/skills/review-pr/config/verify.en.json +0 -1
  240. package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +0 -1
  241. package/templates/.agents/skills/review-pr/reference/output-guidance.en.md +1 -1
  242. package/templates/.agents/skills/review-pr/reference/output-guidance.zh-CN.md +1 -1
  243. package/templates/.agents/skills/run-manual-validation/config/verify.en.json +0 -1
  244. package/templates/.agents/skills/run-manual-validation/config/verify.zh-CN.json +0 -1
  245. package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
  246. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
  247. package/templates/.agents/skills/test/SKILL.en.md +0 -3
  248. package/templates/.agents/skills/test/SKILL.zh-CN.md +0 -3
  249. package/templates/.agents/skills/test-integration/SKILL.en.md +0 -3
  250. package/templates/.agents/skills/test-integration/SKILL.zh-CN.md +0 -3
  251. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +13 -6
  252. package/templates/.agents/skills/upgrade-dependency/SKILL.en.md +0 -3
  253. package/templates/.agents/skills/upgrade-dependency/SKILL.zh-CN.md +0 -3
  254. package/templates/.agents/skills/watch-pr/SKILL.en.md +4 -4
  255. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +4 -4
  256. package/templates/.agents/skills/watch-pr/config/verify.json +0 -1
  257. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +3 -3
  258. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +3 -3
  259. package/templates/.agents/templates/handoff.en.md +1 -1
  260. package/templates/.agents/templates/handoff.zh-CN.md +1 -1
  261. package/templates/.agents/workflows/bug-fix.en.yaml +1 -1
  262. package/templates/.agents/workflows/feature-development.en.yaml +1 -1
  263. package/templates/.agents/workflows/refactoring.en.yaml +1 -1
  264. package/dist/lib/task/task-execution-lock.js +0 -250
  265. package/lib/task/task-execution-lock.ts +0 -320
package/bin/cli.ts CHANGED
@@ -31,7 +31,7 @@ Commands:
31
31
  run Schedule a lifecycle skill in the task sandbox tmux session
32
32
  sandbox, s Manage Docker-based AI sandboxes
33
33
  server Run the local AI collaboration daemon (start/stop/status/logs)
34
- task, t Read-only views of .agents/workspace tasks
34
+ task, t Read-only views of project task workspaces
35
35
  sync Update seed files and sync file registry for an existing project
36
36
  update Update the agent-infra CLI itself
37
37
  version Show version
package/dist/bin/cli.js CHANGED
@@ -31,7 +31,7 @@ Commands:
31
31
  run Schedule a lifecycle skill in the task sandbox tmux session
32
32
  sandbox, s Manage Docker-based AI sandboxes
33
33
  server Run the local AI collaboration daemon (start/stop/status/logs)
34
- task, t Read-only views of .agents/workspace tasks
34
+ task, t Read-only views of project task workspaces
35
35
  sync Update seed files and sync file registry for an existing project
36
36
  update Update the agent-infra CLI itself
37
37
  version Show version
@@ -60,7 +60,7 @@ if (!taskViewGuardFailed && !markerlessHelp && (taskControlCommand || taskWorkfl
60
60
  }
61
61
  case 'direct-host':
62
62
  // The host CLI is the direct-host authority. Domain handlers retain their
63
- // task locks, atomic writes, and operation-specific recovery facts.
63
+ // atomic writes and operation-specific recovery facts.
64
64
  break;
65
65
  case 'sandbox-local': {
66
66
  break;
@@ -185,6 +185,11 @@ if (!controlRouted && !taskViewGuardFailed && internalRouteRegistered)
185
185
  taskContext(process.argv.slice(3));
186
186
  break;
187
187
  }
188
+ case 'task-workspace': {
189
+ const { taskWorkspace } = await import('../lib/internal/task-workspace.js');
190
+ taskWorkspace(process.argv.slice(3));
191
+ break;
192
+ }
188
193
  case 'task-ledger': {
189
194
  const { taskLedger } = await import('../lib/internal/task-ledger.js');
190
195
  await taskLedger(process.argv.slice(3));
@@ -6,7 +6,7 @@ import { locateActivityLog, pairEntries, appendActivityEntry } from '../../../ta
6
6
  import { captureTaskWriteMetadata, writeTask } from '../../../task/write.js';
7
7
  import { parseTypedTaskFrontmatter } from '../../../task/frontmatter.js';
8
8
  import { resolveTaskRef } from '../../../task/resolve-ref.js';
9
- import { recoverActivatedOrchestrationDelegationUnderLock, readRun } from '../../../task/orchestration.js';
9
+ import { recoverActivatedOrchestrationDelegation, readRun } from '../../../task/orchestration.js';
10
10
  const ACTIONS = {
11
11
  analysis: 'Analyze Task',
12
12
  'review-analysis': 'Review Analysis',
@@ -175,7 +175,7 @@ function appendRecoveryLog(request, taskId, section, candidate, repoRoot, writer
175
175
  taskId, receiptId: candidate.receipt.id, childId: candidate.receipt.childId
176
176
  });
177
177
  }
178
- function recoverStartedLifecycleUnderLock(request, options = {}) {
178
+ function recoverStartedLifecycle(request, options = {}) {
179
179
  if (!request || request.intent !== 'recover-started' || request.auto !== true || normalizeAgentToken(request.agent) !== 'codex') {
180
180
  return failure(request, 'conflict', 'RECOVERY_PAYLOAD_INVALID', 'automatic recovery requires a task and the Codex agent');
181
181
  }
@@ -259,7 +259,7 @@ function consumeRecoveryEvidence(request, taskId, repoRoot, pending, options) {
259
259
  let consumed = stored;
260
260
  if (stored.consumer === null) {
261
261
  try {
262
- consumed = store.consumeWithinTaskLock(pending.childId, pending.id, stored.state.startEvidence?.hookDefinitionHash, {
262
+ consumed = store.consume(pending.childId, pending.id, stored.state.startEvidence?.hookDefinitionHash, {
263
263
  taskId: pending.taskId, runId: pending.runId, receiptId: pending.id
264
264
  });
265
265
  }
@@ -272,7 +272,7 @@ function consumeRecoveryEvidence(request, taskId, repoRoot, pending, options) {
272
272
  : { result: failure(request, 'owner-unknown', 'RECOVERY_EVIDENCE_INVALID', 'consumed stop evidence has no timestamp', { taskId, receiptId: pending.id, childId: pending.childId }) };
273
273
  }
274
274
  function finishActiveRecovery(request, taskId, section, repoRoot, pending, row, options) {
275
- const recovered = recoverActivatedOrchestrationDelegationUnderLock(taskId, {
275
+ const recovered = recoverActivatedOrchestrationDelegation(taskId, {
276
276
  receiptId: pending.id,
277
277
  stage: pending.stage,
278
278
  round: pending.round,
@@ -286,7 +286,7 @@ function finishActiveRecovery(request, taskId, section, repoRoot, pending, row,
286
286
  return appendRecoveryLog(request, taskId, section, { receipt: recovered.run.receipts.at(-1), row }, repoRoot, options.writeTask ?? writeTask);
287
287
  }
288
288
  function recoverStartedLifecycleFromAdapter(request, options = {}) {
289
- return recoverStartedLifecycleUnderLock(request, options);
289
+ return recoverStartedLifecycle(request, options);
290
290
  }
291
- export { recoverStartedLifecycleFromAdapter, recoverStartedLifecycleUnderLock };
291
+ export { recoverStartedLifecycle, recoverStartedLifecycleFromAdapter };
292
292
  //# sourceMappingURL=recovery.js.map
@@ -1,6 +1,6 @@
1
1
  import crypto from 'node:crypto';
2
2
  import path from 'node:path';
3
- import { mutateDelegationAdapterEvidence, mutateDelegationAdapterEvidenceWithinTaskLock, readRun } from '../../../task/orchestration.js';
3
+ import { mutateDelegationAdapterEvidence, readRun } from '../../../task/orchestration.js';
4
4
  import { resolveTaskRef } from '../../../task/resolve-ref.js';
5
5
  import { createCodexLifecycleState, expireCodexLifecycleState, reduceCodexLifecycleEvent } from './evidence.js';
6
6
  function readCodexLifecycleActivationEvidence(receipt) {
@@ -111,10 +111,9 @@ function createCodexLifecycleStore(options) {
111
111
  }
112
112
  return matches[0];
113
113
  }
114
- function update(binding, key, mutate, taskLockHeld = false) {
114
+ function update(binding, key, mutate) {
115
115
  let result = null;
116
- const updateState = taskLockHeld ? mutateDelegationAdapterEvidenceWithinTaskLock : mutateDelegationAdapterEvidence;
117
- updateState(options.taskId, binding.receiptId, 'codex', (value) => {
116
+ mutateDelegationAdapterEvidence(options.taskId, binding.receiptId, 'codex', (value) => {
118
117
  const currentState = storedEvidence(value);
119
118
  const current = currentState.records[key] ?? null;
120
119
  result = mutate(current);
@@ -215,7 +214,7 @@ function createCodexLifecycleStore(options) {
215
214
  throw new Error(`Codex lifecycle child '${childThreadId}' was not found uniquely`);
216
215
  return matches[0];
217
216
  }
218
- function consumeWithLockMode(childThreadId, consumer, expectedHookDefinitionHash, expectedTaskBinding, taskLockHeld) {
217
+ function consume(childThreadId, consumer, expectedHookDefinitionHash, expectedTaskBinding) {
219
218
  if (!consumer.trim())
220
219
  throw new Error('Codex lifecycle consumer is required');
221
220
  const current = read(childThreadId);
@@ -223,11 +222,8 @@ function createCodexLifecycleStore(options) {
223
222
  if (!binding)
224
223
  throw new Error('Codex lifecycle task receipt binding is missing');
225
224
  const spawn = current.state.spawn;
226
- if (!spawn) {
227
- throw new Error(taskLockHeld
228
- ? 'Codex lifecycle task receipt binding is missing'
229
- : 'Codex lifecycle spawn evidence is missing');
230
- }
225
+ if (!spawn)
226
+ throw new Error('Codex lifecycle spawn evidence is missing');
231
227
  const key = recordKey(spawn.sessionId, spawn.turnId, spawn.toolUseId);
232
228
  return update(binding, key, (latest) => {
233
229
  if (!latest || expectedTaskBinding && JSON.stringify(latest.taskBinding) !== JSON.stringify(expectedTaskBinding)) {
@@ -244,13 +240,7 @@ function createCodexLifecycleStore(options) {
244
240
  if (latest.consumer)
245
241
  return latest;
246
242
  return Object.freeze({ ...latest, revision: latest.revision + 1, consumer, consumedAt: now(), updatedAt: now() });
247
- }, taskLockHeld);
248
- }
249
- function consume(childThreadId, consumer, expectedHookDefinitionHash, expectedTaskBinding) {
250
- return consumeWithLockMode(childThreadId, consumer, expectedHookDefinitionHash, expectedTaskBinding, false);
251
- }
252
- function consumeWithinTaskLock(childThreadId, consumer, expectedHookDefinitionHash, expectedTaskBinding) {
253
- return consumeWithLockMode(childThreadId, consumer, expectedHookDefinitionHash, expectedTaskBinding, true);
243
+ });
254
244
  }
255
245
  function expireBefore(cutoff) {
256
246
  let changed = 0;
@@ -271,7 +261,7 @@ function createCodexLifecycleStore(options) {
271
261
  }
272
262
  return changed;
273
263
  }
274
- return Object.freeze({ taskId: options.taskId, root: path.join(taskDir, '.runtime'), apply, applyToSpawn, consume, consumeWithinTaskLock, expireBefore, findByParent, findByTaskBinding, read });
264
+ return Object.freeze({ taskId: options.taskId, root: path.join(taskDir, '.runtime'), apply, applyToSpawn, consume, expireBefore, findByParent, findByTaskBinding, read });
275
265
  }
276
266
  export { createCodexLifecycleStore, hasActiveCodexLifecycleEvidence, readCodexLifecycleActivationEvidence };
277
267
  //# sourceMappingURL=store.js.map
@@ -347,7 +347,7 @@ async function sealCodexOrchestrationDelegation(childThreadId, options = {}) {
347
347
  }
348
348
  return sealMatchingOrchestrationDelegation('codex', { nativeAgent: record.state.startEvidence.nativeAgent, childId: childThreadId }, coreOptions(options), () => {
349
349
  try {
350
- const consumed = store.consumeWithinTaskLock(childThreadId, current.receipt.id, existing.state.spawn?.hookDefinitionHash, existing.taskBinding ?? undefined);
350
+ const consumed = store.consume(childThreadId, current.receipt.id, existing.state.spawn?.hookDefinitionHash, existing.taskBinding ?? undefined);
351
351
  return consumed.consumer === current.receipt.id && consumed.consumedAt
352
352
  ? null
353
353
  : bridgeFailure('ORCHESTRATION_CODEX_RECONCILIATION_FAILED', 'Codex lifecycle evidence was not consumed by the active receipt');
@@ -3,7 +3,6 @@ import { parseTaskScope } from './task/command-options.js';
3
3
  import { applyHumanDecision } from './task/decision-intents.js';
4
4
  import { canonicalTimestamp } from './task/write.js';
5
5
  import { resolveTaskContext } from './task/resolve-ref.js';
6
- import { TaskExecutionLockError, withTaskExecutionLock } from './task/task-execution-lock.js';
7
6
  function parseDecisionParts(parts) {
8
7
  const decision = [];
9
8
  let needsImplementation;
@@ -81,17 +80,13 @@ export async function decide(args, options = {}) {
81
80
  repoRoot: resolved.repoRoot,
82
81
  metadataProvider: () => ({ timestamp: now, agentInfraVersion: options.version ?? VERSION })
83
82
  };
84
- let result;
85
- const execute = async () => applyHumanDecision(request, writeOptions);
86
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-decision', execute);
83
+ const result = await applyHumanDecision(request, writeOptions);
87
84
  if (result.error)
88
85
  throw new Error(result.error.message);
89
86
  return 0;
90
87
  }
91
88
  catch (error) {
92
- const message = error instanceof TaskExecutionLockError
93
- ? `${error.code}: ${error.message}`
94
- : error instanceof Error ? error.message : String(error);
89
+ const message = error instanceof Error ? error.message : String(error);
95
90
  process.stderr.write(`Error: ${message}\n`);
96
91
  return 1;
97
92
  }
@@ -49,6 +49,7 @@ export const INTERNAL_HANDLER_ROUTE_SELECTORS = Object.freeze({
49
49
  'pr-review-grade': ['decide', 'resolve-host', 'verify-artifact'],
50
50
  'platform-checks': ['inspect', 'watch', 'resolve-run', 'logs'],
51
51
  'task-context': ['resolve'],
52
+ 'task-workspace': ['resolve'],
52
53
  'task-ledger': ['decision-next-id', 'stage-status', 'finding-upsert', 'finding-respond', 'finding-review', 'decision-upsert', 'rework-intent-upsert', 'rework-intent-rebuild'],
53
54
  'task-warning': ['list', 'add', 'set-status'],
54
55
  'task-activity': ['pr-review-inspect', 'pr-review-start', 'pr-review-complete', 'pr-review-terminate'],
@@ -115,6 +116,8 @@ export function internalRouteSelector(command, args) {
115
116
  return args[1] ?? '';
116
117
  if (command === 'task-context')
117
118
  return first(args);
119
+ if (command === 'task-workspace')
120
+ return first(args);
118
121
  return first(args);
119
122
  }
120
123
  export function isInternalHandlerRoute(command, args) {
@@ -2,10 +2,10 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { locateActivityLog, pairEntries } from '../task/activity-log.js';
4
4
  import { resolveTaskRef } from '../task/resolve-ref.js';
5
+ import { prepareAndRenderPrSummaryContent } from '../platform/pr-summary.js';
5
6
  import { applyTaskEvent } from '../task/events.js';
6
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
7
7
  import { normalizeAgentToken } from '../agent-clients/tokens.js';
8
- import { MANUAL_VALIDATION_RECEIPT_PLACEHOLDER, createManualValidationReceipt, manualValidationFinalSummaryDigest, manualValidationFinalSummaryProjectionMatches, readManualValidationReceipt, writeManualValidationReceiptAtomic } from '../task/manual-validation-receipt.js';
8
+ import { createManualValidationReceipt, manualValidationFinalSummaryDigest, manualValidationFinalSummaryProjectionMatches, readManualValidationReceipt, writeManualValidationReceiptAtomic } from '../task/manual-validation-receipt.js';
9
9
  import { archiveManualValidationGeneration, createManualValidationTransaction, readManualValidationTransaction, retryManualValidationTransaction, summaryPreimageDigest, transitionManualValidationTransaction, validateManualValidationGenerationArchive, writeManualValidationTransactionAtomic } from '../task/manual-validation-transaction.js';
10
10
  import { sha256File } from '../task/artifact-receipts.js';
11
11
  import { summaryCommentState, syncPullRequestSummary } from '../platform/pr-summary.js';
@@ -22,22 +22,14 @@ function printFailure(format, error) {
22
22
  process.stderr.write(`${error.code}: ${error.message}\n`);
23
23
  process.exitCode = 1;
24
24
  }
25
- const MANUAL_VALIDATION_STATUS_HEADING = /^###\s+(?:⚠️\s+(?:需人工校验|Manual Validation Required)|✅\s+(?:人工验证已通过|无需人工校验|Manual Validation Passed|No Manual Validation Required)|⏳\s+(?:人工验证待收尾|Manual Validation Pending))\s*$/mu;
26
25
  function manualSummaryBody(body, phase) {
27
- const chinese = /###\s+(?:⚠️\s+需人工校验|✅\s+(?:人工验证已通过|无需人工校验)|⏳\s+人工验证待收尾)\s*$/mu.test(body);
28
- const heading = phase === 'pending'
29
- ? chinese ? '### ⏳ 人工验证待收尾' : '### ⏳ Manual Validation Pending'
30
- : chinese ? '### ✅ 人工验证已通过' : '### ✅ Manual Validation Passed';
31
- const marker = phase === 'final'
32
- ? `\n\n${MANUAL_VALIDATION_RECEIPT_PLACEHOLDER}`
33
- : '';
34
- if (MANUAL_VALIDATION_STATUS_HEADING.test(body)) {
35
- return `${body.replace(MANUAL_VALIDATION_STATUS_HEADING, `${heading}${marker}`).replace(/\s+$/u, '')}\n`;
36
- }
37
- const fallback = phase === 'pending'
38
- ? chinese ? '人工验证正在等待最终完成。' : 'Manual validation is awaiting final promotion.'
39
- : chinese ? '人工验证已通过。' : 'Manual validation passed.';
40
- return `${body.replace(/\s+$/u, '')}\n\n${heading}${marker}\n\n${fallback}\n`;
26
+ const content = JSON.parse(body);
27
+ const manual = content.manualValidation;
28
+ manual.state = phase === 'pending' ? 'pending' : 'passed';
29
+ return JSON.stringify(content);
30
+ }
31
+ function renderedManualSummaryBody(body, phase, taskContent) {
32
+ return prepareAndRenderPrSummaryContent(JSON.parse(manualSummaryBody(body, phase)), taskContent).rendered;
41
33
  }
42
34
  function openManualValidationStarted(taskMdPath) {
43
35
  let content;
@@ -77,16 +69,9 @@ async function executeManualValidationTransaction(taskRef, values, cwd, options
77
69
  const resolved = resolveTaskRef(taskRef, { repoRoot: cwd });
78
70
  if (!resolved.ok)
79
71
  return result('failed', { code: resolved.code, message: resolved.message });
80
- try {
81
- return await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `manual-validation:${taskRef}`, () => executeManualValidationTransactionLocked(taskRef, values, cwd, resolved, agent, primaryResult, prepareOnly, options));
82
- }
83
- catch (error) {
84
- if (error instanceof TaskExecutionLockError)
85
- return result('failed', { code: error.code, message: error.message });
86
- throw error;
87
- }
72
+ return executeManualValidationTransactionAtResolvedTask(taskRef, values, cwd, resolved, agent, primaryResult, prepareOnly, options);
88
73
  }
89
- async function executeManualValidationTransactionLocked(taskRef, values, cwd, resolved, agent, primaryResult, prepareOnly, options) {
74
+ async function executeManualValidationTransactionAtResolvedTask(taskRef, values, cwd, resolved, agent, primaryResult, prepareOnly, options) {
90
75
  const artifactPath = path.resolve(resolved.taskDir, values.artifact);
91
76
  if (!prepareOnly && !fs.existsSync(artifactPath))
92
77
  return result('failed', { code: 'MANUAL_VALIDATION_ARTIFACT_MISSING', message: `manual-validation artifact is missing: ${values.artifact}` });
@@ -98,6 +83,7 @@ async function executeManualValidationTransactionLocked(taskRef, values, cwd, re
98
83
  const preimage = { commentId: currentState.comment?.id ?? null, body: preimageBody, digest: summaryPreimageDigest(preimageBody) };
99
84
  const summaryPath = path.resolve(cwd, values.summaryFile);
100
85
  const finalBodyWithoutReceipt = fs.readFileSync(summaryPath, 'utf8');
86
+ const taskContent = fs.readFileSync(resolved.taskMdPath, 'utf8');
101
87
  const evidenceDigest = sha256File(summaryPath);
102
88
  const archiveGeneration = options.archiveGeneration ?? archiveManualValidationGeneration;
103
89
  let transactionResult = readManualValidationTransaction(resolved.taskDir, { taskId: resolved.taskId, prNumber: pullRequest.number, prHeadSha: pullRequest.head.sha, evidenceDigest, artifact: values.artifact });
@@ -140,7 +126,7 @@ async function executeManualValidationTransactionLocked(taskRef, values, cwd, re
140
126
  evidenceDigest,
141
127
  summaryPreimage: preimage,
142
128
  pendingSummaryDigest: summaryPreimageDigest(pendingBody),
143
- finalSummaryDigest: manualValidationFinalSummaryDigest(manualSummaryBody(finalBodyWithoutReceipt, 'final')),
129
+ finalSummaryDigest: manualValidationFinalSummaryDigest(renderedManualSummaryBody(finalBodyWithoutReceipt, 'final', taskContent)),
144
130
  artifact: values.artifact,
145
131
  attempt: 1,
146
132
  createdAt: new Date().toISOString(),
@@ -151,7 +137,7 @@ async function executeManualValidationTransactionLocked(taskRef, values, cwd, re
151
137
  let startedEventApplied = false;
152
138
  if (!transactionResult.ok) {
153
139
  transaction = createTransaction();
154
- const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transactionId, reasonCode: 'user-request', transactionId }, { lockAlreadyHeld: true, repoRoot: cwd });
140
+ const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transactionId, reasonCode: 'user-request', transactionId }, { repoRoot: cwd });
155
141
  if (started.status === 'failed')
156
142
  return result('failed', started.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation started event failed' });
157
143
  startedEventApplied = true;
@@ -176,7 +162,7 @@ async function executeManualValidationTransactionLocked(taskRef, values, cwd, re
176
162
  }
177
163
  }
178
164
  if (transaction.phase === 'prepared' && !startedEventApplied) {
179
- const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', transactionId: transaction.transactionId }, { lockAlreadyHeld: true, repoRoot: cwd });
165
+ const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', transactionId: transaction.transactionId }, { repoRoot: cwd });
180
166
  if (started.status === 'failed')
181
167
  return result('failed', started.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation started event failed' });
182
168
  }
@@ -196,7 +182,7 @@ async function executeManualValidationTransactionLocked(taskRef, values, cwd, re
196
182
  if (transaction.phase === 'prepared') {
197
183
  const staged = await syncPullRequestSummary(taskRef, {
198
184
  cwd, client: options.client, agent, body: pendingBody, changeReportFile: path.resolve(cwd, values.changeReportFile), primaryResult: primaryResult, strict: true,
199
- manualValidation: { phase: 'pending', transactionId: transaction.transactionId }, lockAlreadyHeld: true
185
+ manualValidation: { phase: 'pending', transactionId: transaction.transactionId }
200
186
  });
201
187
  if (!['applied', 'no-op'].includes(staged.status))
202
188
  transactionFailure(staged.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'pending summary staging failed' });
@@ -235,7 +221,7 @@ async function executeManualValidationTransactionLocked(taskRef, values, cwd, re
235
221
  transitionAndPersist('receipt-committed', { committedReceipt: receipt.receiptDigest });
236
222
  }
237
223
  if (transaction.phase === 'receipt-committed' && !transaction.eventAppended) {
238
- const completed = applyTaskEvent({ taskRef, event: 'manual-validation.completed', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', artifact: values.artifact, summaryResult: 'human-confirmed validation and committed receipt', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha }, { lockAlreadyHeld: true, repoRoot: cwd });
224
+ const completed = applyTaskEvent({ taskRef, event: 'manual-validation.completed', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', artifact: values.artifact, summaryResult: 'human-confirmed validation and committed receipt', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha }, { repoRoot: cwd });
239
225
  if (completed.status === 'failed')
240
226
  transactionFailure(completed.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation completion event failed' });
241
227
  transitionAndPersist('receipt-committed', { eventAppended: true });
@@ -245,7 +231,7 @@ async function executeManualValidationTransactionLocked(taskRef, values, cwd, re
245
231
  }
246
232
  const promoted = await syncPullRequestSummary(taskRef, {
247
233
  cwd, client: options.client, agent, body: manualSummaryBody(finalBodyWithoutReceipt, 'final'), changeReportFile: path.resolve(cwd, values.changeReportFile), primaryResult, strict: true,
248
- manualValidation: { phase: 'final', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha, authority: 'coordinator' }, lockAlreadyHeld: true
234
+ manualValidation: { phase: 'final', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha, authority: 'coordinator' }
249
235
  });
250
236
  if (!['applied', 'no-op'].includes(promoted.status))
251
237
  transactionFailure(promoted.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_RECOVERY_REQUIRED', message: 'final summary promotion failed' });
@@ -261,7 +247,7 @@ async function executeManualValidationTransactionLocked(taskRef, values, cwd, re
261
247
  try {
262
248
  await syncPullRequestSummary(taskRef, {
263
249
  cwd, client: options.client, agent, body: pendingBody, changeReportFile: path.resolve(cwd, values.changeReportFile), primaryResult: primaryResult, strict: true,
264
- manualValidation: { phase: 'pending', transactionId: transaction.transactionId }, lockAlreadyHeld: true
250
+ manualValidation: { phase: 'pending', transactionId: transaction.transactionId }
265
251
  });
266
252
  }
267
253
  catch {
@@ -1,5 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
+ import { resolveProjectTaskWorkspaceRoot } from '../task/workspace-root.js';
3
4
  import { createHash, randomUUID } from 'node:crypto';
4
5
  import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.js';
5
6
  import { checkPlatformCommentOwner, listPlatformComments, syncPlatformComment } from '../platform/issue-comments.js';
@@ -9,6 +10,9 @@ import { recoverTaskFromComments } from '../platform/task-recovery.js';
9
10
  import { backfillCompletionComments } from '../platform/completion-backfill.js';
10
11
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
11
12
  import { resolveTaskRef } from '../task/resolve-ref.js';
13
+ import { enumerateArtifacts } from '../task/artifacts.js';
14
+ import { parseTaskFrontmatter } from '../task/frontmatter.js';
15
+ import { prepareAndRenderCancelSummaryContent, prepareAndRenderDeliverySummaryContent } from '../platform/issue-summary-content.js';
12
16
  const USAGE = `Usage: agent-infra-internal platform-comment list --issue <token> [--cwd <path>]
13
17
  agent-infra-internal platform-comment recover --issue <token> --task-id <TASK-id> --output <staging-task.md> [--cwd <path>]
14
18
  agent-infra-internal platform-comment owner <task-ref> [--cwd <path>]
@@ -115,14 +119,14 @@ async function platformComment(args = []) {
115
119
  return;
116
120
  }
117
121
  const outputPath = path.resolve(cwd, output);
118
- const workspaceDir = path.resolve(cwd, '.agents', 'workspace');
122
+ const workspaceDir = resolveProjectTaskWorkspaceRoot(cwd);
119
123
  const stagingDir = path.dirname(outputPath);
120
124
  const stagingParent = fs.existsSync(stagingDir) ? path.dirname(fs.realpathSync(stagingDir)) : '';
121
125
  const realWorkspace = fs.existsSync(workspaceDir) ? fs.realpathSync(workspaceDir) : '';
122
126
  if (path.basename(outputPath) !== 'task.md' || stagingParent !== realWorkspace
123
127
  || !path.basename(stagingDir).startsWith('.restore-staging-') || !fs.existsSync(stagingDir)
124
128
  || !fs.lstatSync(stagingDir).isDirectory() || fs.existsSync(outputPath)) {
125
- fail('recover output must be a new task.md inside an existing .agents/workspace/.restore-staging-* directory');
129
+ fail('recover output must be a new task.md inside an existing task-workspace/.restore-staging-* directory');
126
130
  return;
127
131
  }
128
132
  const listed = await listPlatformComments(issue, cwd);
@@ -201,19 +205,34 @@ async function platformComment(args = []) {
201
205
  fail(`unable to read body file: ${error instanceof Error ? error.message : String(error)}`);
202
206
  return;
203
207
  }
204
- const canonical = canonicalizeSummaryBody(body);
205
- if (!canonical.ok) {
206
- fail(`unable to stage summary: ${canonical.error.code}: ${canonical.error.message}`);
207
- return;
208
- }
209
- body = canonical.value;
210
208
  const resolved = resolveTaskRef(taskRef, { repoRoot: cwd });
211
209
  if (!resolved.ok || resolved.state !== 'active') {
212
210
  fail('stage-summary requires an active task');
213
211
  return;
214
212
  }
215
213
  const target = path.join(resolved.taskDir, '.delivery-summary.json');
216
- const value = { taskId: resolved.taskId, body, sha256: createHash('sha256').update(body).digest('hex') };
214
+ let content;
215
+ try {
216
+ const supplied = JSON.parse(body);
217
+ const taskContent = fs.readFileSync(resolved.taskMdPath, 'utf8');
218
+ const title = /^#\s+(.+)$/mu.exec(taskContent)?.[1]?.trim();
219
+ const prepared = prepareAndRenderDeliverySummaryContent(supplied, {
220
+ taskId: resolved.taskId,
221
+ title: title || resolved.taskId,
222
+ artifacts: enumerateArtifacts(resolved.taskDir).filter((artifact) => artifact.name !== 'task.md').map((artifact) => artifact.name),
223
+ verificationFallback: { state: 'not-run', detail: 'Final verification has not run at summary staging.' }
224
+ });
225
+ content = prepared.content;
226
+ const canonical = canonicalizeSummaryBody(prepared.rendered);
227
+ if (!canonical.ok)
228
+ throw new Error(`${canonical.error.code}: ${canonical.error.message}`);
229
+ body = canonical.value;
230
+ }
231
+ catch (error) {
232
+ fail(`unable to stage summary: ${error instanceof Error ? error.message : String(error)}`);
233
+ return;
234
+ }
235
+ const value = { taskId: resolved.taskId, content, contentSha256: createHash('sha256').update(JSON.stringify(content)).digest('hex') };
217
236
  const previous = fs.existsSync(target) ? fs.readFileSync(target, 'utf8') : null;
218
237
  const next = `${JSON.stringify(value)}\n`;
219
238
  if (previous === next) {
@@ -272,6 +291,37 @@ async function platformComment(args = []) {
272
291
  fail(`unable to read body file: ${error instanceof Error ? error.message : String(error)}`);
273
292
  return;
274
293
  }
294
+ if (kind === 'summary' || kind === 'cancel') {
295
+ try {
296
+ const input = JSON.parse(body);
297
+ const resolved = resolveTaskRef(taskRef, { repoRoot: cwd });
298
+ if (!resolved.ok)
299
+ throw new Error(resolved.message);
300
+ const taskContent = fs.readFileSync(resolved.taskMdPath, 'utf8');
301
+ const taskFrontmatter = parseTaskFrontmatter(taskContent);
302
+ const title = /^#\s+(.+)$/mu.exec(taskContent)?.[1]?.trim();
303
+ const artifacts = enumerateArtifacts(resolved.taskDir).filter((artifact) => artifact.name !== 'task.md').map((artifact) => artifact.name);
304
+ const rendered = kind === 'summary'
305
+ ? prepareAndRenderDeliverySummaryContent(input, {
306
+ taskId: resolved.taskId,
307
+ title: title || resolved.taskId,
308
+ artifacts,
309
+ ...(resolved.state === 'active' ? { verificationFallback: { state: 'not-run', detail: 'Final verification has not run at summary staging.' } } : {})
310
+ }).rendered
311
+ : prepareAndRenderCancelSummaryContent(input, {
312
+ taskId: resolved.taskId,
313
+ title: title || resolved.taskId,
314
+ reason: typeof taskFrontmatter.cancel_reason === 'string' ? taskFrontmatter.cancel_reason : '',
315
+ cancelledAt: typeof taskFrontmatter.cancelled_at === 'string' ? taskFrontmatter.cancelled_at : '',
316
+ lastCompletedArtifact: artifacts.at(-1) ?? null
317
+ }).rendered;
318
+ body = rendered;
319
+ }
320
+ catch (error) {
321
+ fail(`invalid ${kind} summary structure: ${error instanceof Error ? error.message : String(error)}`);
322
+ return;
323
+ }
324
+ }
275
325
  finish(await syncPlatformComment(taskRef, {
276
326
  kind: kind,
277
327
  agent: normalizedAgent,
@@ -1,6 +1,5 @@
1
1
  import { applyPrReviewActivityIntent, inspectPrReviewActivity } from '../task/activity-intent.js';
2
2
  import { resolveTaskRef } from '../task/resolve-ref.js';
3
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
4
3
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
5
4
  const USAGE = `Usage: agent-infra-internal task-activity <task-ref> pr-review-inspect
6
5
  agent-infra-internal task-activity <task-ref> pr-review-start --agent <agent> --artifact <canonical.md> --head <40hex> [--dry-run]
@@ -112,17 +111,7 @@ async function taskActivity(args = []) {
112
111
  usageFailure(resolved.message);
113
112
  return;
114
113
  }
115
- let result;
116
- try {
117
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-activity.${kind}`, async () => applyPrReviewActivityIntent(values, { lockAlreadyHeld: true }));
118
- }
119
- catch (error) {
120
- if (!(error instanceof TaskExecutionLockError))
121
- throw error;
122
- process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
123
- process.exitCode = 1;
124
- return;
125
- }
114
+ const result = await applyPrReviewActivityIntent(values);
126
115
  process.stdout.write(`${JSON.stringify(result)}\n`);
127
116
  if (result.status === 'failed')
128
117
  process.exitCode = 1;
@@ -1,7 +1,6 @@
1
1
  import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.js';
2
2
  import { applyTaskEvent, eventCatalog } from '../task/events.js';
3
3
  import { resolveTaskRef } from '../task/resolve-ref.js';
4
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
5
4
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
6
5
  const USAGE = `Usage: agent-infra-internal task-event <N | TASK-id> <event> --agent <agent> [event options] [--orchestrated] [--dry-run]
7
6
 
@@ -93,17 +92,7 @@ async function taskEvent(args = []) {
93
92
  process.exitCode = 1;
94
93
  return;
95
94
  }
96
- let result;
97
- try {
98
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-event.${request.event}`, async () => applyTaskEvent(request, { lockAlreadyHeld: true }));
99
- }
100
- catch (error) {
101
- if (!(error instanceof TaskExecutionLockError))
102
- throw error;
103
- process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
104
- process.exitCode = 1;
105
- return;
106
- }
95
+ const result = await applyTaskEvent(request);
107
96
  process.stdout.write(`${JSON.stringify(result)}\n`);
108
97
  if (result.status === 'failed')
109
98
  process.exitCode = 1;
@@ -2,7 +2,6 @@ import fs from 'node:fs';
2
2
  import { applyLedgerIntent } from '../task/ledger-intents.js';
3
3
  import { LEDGER_SECTION_MISSING_CODE, LEDGER_SECTION_MISSING_MESSAGE, isReviewStage, parseLedgerDocument, summarizeLedgerStage, validateLedgerRows } from '../task/ledger.js';
4
4
  import { resolveTaskRef } from '../task/resolve-ref.js';
5
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
6
5
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
7
6
  const USAGE = `Usage: agent-infra-internal task-ledger <task-ref> <intent> [intent flags] [--dry-run]\n\nIntents: finding-upsert, finding-respond, finding-review, decision-next-id, decision-upsert, rework-intent-upsert, rework-intent-rebuild, stage-status\n`;
8
7
  const FLAGS = {
@@ -148,17 +147,7 @@ async function taskLedger(args = []) {
148
147
  usageFailure(lockResolved.message);
149
148
  return;
150
149
  }
151
- let result;
152
- try {
153
- result = await withTaskExecutionLock(lockResolved.repoRoot, lockResolved.taskId, `task-ledger.${kind}`, async () => applyLedgerIntent(values));
154
- }
155
- catch (error) {
156
- if (!(error instanceof TaskExecutionLockError))
157
- throw error;
158
- process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
159
- process.exitCode = 1;
160
- return;
161
- }
150
+ const result = await applyLedgerIntent(values);
162
151
  process.stdout.write(`${JSON.stringify(result)}\n`);
163
152
  if (result.status === 'failed')
164
153
  process.exitCode = 1;
@@ -77,6 +77,7 @@ function internalTaskRoutes() {
77
77
  descriptor('internal', 'platform-checks', 'resolve-run', 'conditional', 'diagnostic'),
78
78
  descriptor('internal', 'platform-checks', 'logs', 'conditional', 'diagnostic'),
79
79
  descriptor('internal', 'task-context', 'resolve', 'task-bound', 'diagnostic'),
80
+ descriptor('internal', 'task-workspace', 'resolve', 'non-task', 'diagnostic', 'none'),
80
81
  descriptor('internal', 'task-ledger', 'decision-next-id', 'task-bound', 'diagnostic'),
81
82
  descriptor('internal', 'task-ledger', 'stage-status', 'task-bound', 'diagnostic'),
82
83
  descriptor('internal', 'task-ledger', 'finding-upsert', 'task-bound', 'progress'),
@@ -176,7 +177,7 @@ export const INTERNAL_DISPATCHER_ROUTES = Object.freeze([
176
177
  'task-create', 'task-qualification', 'sandbox-control', 'agent-client', 'codex-lifecycle',
177
178
  'git-workflow', 'task-delivery', 'release-workflow', 'platform-release-notes', 'platform-security', 'platform-metadata', 'platform-context',
178
179
  'platform-comment', 'platform-issue', 'platform-pr', 'platform-pr-review', 'pr-review-grade',
179
- 'platform-checks', 'task-context', 'task-ledger', 'task-warning', 'task-activity', 'task-artifact',
180
+ 'platform-checks', 'task-context', 'task-workspace', 'task-ledger', 'task-warning', 'task-activity', 'task-artifact',
180
181
  'task-orchestration', 'task-review', 'task-event', 'task-lifecycle',
181
182
  'task-finalization', 'task-platform-recovery', 'task-short-id', 'task-snapshot', 'task-verify', 'task-validate', 'manual-validation'
182
183
  ]);
@@ -2,7 +2,6 @@ import fs from 'node:fs';
2
2
  import { applyQualificationConfirmation } from '../task/qualification-confirmation.js';
3
3
  import { applyQualificationProposal } from '../task/qualification-intents.js';
4
4
  import { resolveTaskRef } from '../task/resolve-ref.js';
5
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
6
5
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
7
6
  const USAGE = `Usage: agent-infra-internal task-qualification <task-ref> <proposal|confirm|supersede|revoke> --input <json-file> [--dry-run]\n`;
8
7
  function fail(message, code = 'QUALIFICATION_PROPOSAL_INVALID') {
@@ -71,20 +70,12 @@ async function taskQualification(args = []) {
71
70
  fail(resolved.message, resolved.code);
72
71
  return;
73
72
  }
74
- try {
75
- const result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-qualification.${operation}`, () => operation === 'proposal'
76
- ? applyQualificationProposal({ ...payload, taskRef: resolved.taskId, dryRun }, { repoRoot: resolved.repoRoot })
77
- : applyQualificationConfirmation({ ...payload, taskRef: resolved.taskId, operation, dryRun }, { repoRoot: resolved.repoRoot }));
78
- process.stdout.write(`${JSON.stringify(result)}\n`);
79
- if (result.status === 'failed')
80
- process.exitCode = 1;
81
- }
82
- catch (error) {
83
- if (error instanceof TaskExecutionLockError)
84
- fail(`${error.code}: ${error.message}`, error.code);
85
- else
86
- throw error;
87
- }
73
+ const result = await (operation === 'proposal'
74
+ ? applyQualificationProposal({ ...payload, taskRef: resolved.taskId, dryRun }, { repoRoot: resolved.repoRoot })
75
+ : applyQualificationConfirmation({ ...payload, taskRef: resolved.taskId, operation, dryRun }, { repoRoot: resolved.repoRoot }));
76
+ process.stdout.write(`${JSON.stringify(result)}\n`);
77
+ if (result.status === 'failed')
78
+ process.exitCode = 1;
88
79
  }
89
80
  export { taskQualification };
90
81
  //# sourceMappingURL=task-qualification.js.map
@@ -1,7 +1,6 @@
1
1
  import { parseReviewCommand } from '../task/review-command.js';
2
2
  import { finalizeReviewSummary, preflightReviewSummary } from '../task/review-finalization.js';
3
3
  import { resolveTaskRef } from '../task/resolve-ref.js';
4
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
5
4
  import { ensureInternalHandlerRoute } from './cli-route-inventory.js';
6
5
  const USAGE = 'Usage: agent-infra-internal task-review <task-ref> <preflight|finalize-summary> --stage <analysis|plan|code> --artifact <review-*.md> [--orchestrated] [--dry-run]\n';
7
6
  function failUsage(message) {
@@ -36,21 +35,9 @@ async function taskReview(args = []) {
36
35
  failUsage(resolved.message);
37
36
  return;
38
37
  }
39
- let result;
40
- try {
41
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-review.${operation}`, async () => {
42
- return operation === 'preflight'
43
- ? preflightReviewSummary({ taskRef: args[0], stage, artifact, orchestrated, dryRun }, { lockAlreadyHeld: true })
44
- : finalizeReviewSummary({ taskRef: args[0], stage, artifact, orchestrated, dryRun }, { lockAlreadyHeld: true });
45
- });
46
- }
47
- catch (error) {
48
- if (!(error instanceof TaskExecutionLockError))
49
- throw error;
50
- process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
51
- process.exitCode = 1;
52
- return;
53
- }
38
+ const result = operation === 'preflight'
39
+ ? preflightReviewSummary({ taskRef: args[0], stage, artifact, orchestrated, dryRun })
40
+ : finalizeReviewSummary({ taskRef: args[0], stage, artifact, orchestrated, dryRun });
54
41
  process.stdout.write(`${JSON.stringify(result)}\n`);
55
42
  if (result.status === 'failed')
56
43
  process.exitCode = 1;