@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
@@ -8,7 +8,6 @@ import { finalizeReviewSummaryContent } from './review-artifacts.js';
8
8
  import { inspectDecisionDetailDuplicates } from './decision-details.js';
9
9
  import { resolveTaskRef } from './resolve-ref.js';
10
10
  import { validateLifecycleExecution } from './lifecycle-execution.js';
11
- import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.js';
12
11
  import { getArtifactSchema } from './artifact-schema.js';
13
12
  import { validateQualificationAudit } from './qualification-audit.js';
14
13
  import { canonicalSemanticDigest, inspectArtifactContract, sha256Content } from './artifact-operations.js';
@@ -47,7 +46,7 @@ function preflightFailed(request, code, message, taskId = null, extra = {}) {
47
46
  };
48
47
  }
49
48
  /** Validate the current review draft before any finding-ledger write. */
50
- function preflightReviewSummaryUnlocked(request, options = {}) {
49
+ function preflightReviewSummary(request, options = {}) {
51
50
  const stage = request.stage;
52
51
  const spec = STAGES[stage];
53
52
  if (!spec)
@@ -106,21 +105,6 @@ function preflightReviewSummaryUnlocked(request, options = {}) {
106
105
  status: 'passed', changed: false, error: null
107
106
  };
108
107
  }
109
- function preflightReviewSummary(request, options = {}) {
110
- if (request.dryRun || options.lockAlreadyHeld)
111
- return preflightReviewSummaryUnlocked(request, options);
112
- const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
113
- if (!resolved.ok)
114
- return preflightReviewSummaryUnlocked(request, options);
115
- try {
116
- return withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-review.preflight', () => preflightReviewSummaryUnlocked(request, { ...options, lockAlreadyHeld: true }));
117
- }
118
- catch (error) {
119
- if (!(error instanceof TaskExecutionLockError))
120
- throw error;
121
- return preflightFailed(request, 'REVIEW_PROVENANCE_INVALID', `${error.code}: ${error.message}`, resolved.taskId);
122
- }
123
- }
124
108
  /** Prepare domain validation, summary bytes and provenance before any publication. */
125
109
  function prepareReviewSummaryCandidate(request, artifactContent, options = {}) {
126
110
  let taskId = null;
@@ -208,7 +192,6 @@ function prepareReviewSummaryCandidate(request, artifactContent, options = {}) {
208
192
  operations: transformed.changed ? [{ kind: 'artifact', artifact: request.artifact, operation: 'update' }] : [],
209
193
  error: null
210
194
  },
211
- lockAlreadyHeld: options.lockAlreadyHeld
212
195
  };
213
196
  }
214
197
  function commitReviewSummaryProvenance(prepared, repoRoot, options = {}) {
@@ -230,7 +213,7 @@ function replaceCurrentArtifactAtomically(file, content) {
230
213
  }
231
214
  }
232
215
  }
233
- function finalizeReviewSummaryUnlocked(request, options = {}) {
216
+ function finalizeReviewSummary(request, options = {}) {
234
217
  const spec = STAGES[request.stage];
235
218
  if (!spec || !request.taskRef || !request.artifact)
236
219
  return prepareReviewSummaryCandidate(request, '', options).result;
@@ -267,21 +250,5 @@ function finalizeReviewSummaryUnlocked(request, options = {}) {
267
250
  return failed(request, 'REVIEW_RECOVERY_COMMIT_FAILED', `cannot update current review artifact: ${error instanceof Error ? error.message : String(error)}`, resolved.taskId);
268
251
  }
269
252
  }
270
- function finalizeReviewSummary(request, options = {}) {
271
- const effectiveOptions = options;
272
- if (request.dryRun || options.lockAlreadyHeld)
273
- return finalizeReviewSummaryUnlocked(request, effectiveOptions);
274
- const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
275
- if (!resolved.ok)
276
- return finalizeReviewSummaryUnlocked(request, effectiveOptions);
277
- try {
278
- return withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-review.finalize-summary', () => finalizeReviewSummaryUnlocked(request, { ...effectiveOptions, lockAlreadyHeld: true }));
279
- }
280
- catch (error) {
281
- if (!(error instanceof TaskExecutionLockError))
282
- throw error;
283
- return failed(request, 'REVIEW_PROVENANCE_INVALID', `${error.code}: ${error.message}`, resolved.taskId);
284
- }
285
- }
286
253
  export { finalizeReviewSummary, preflightReviewSummary, prepareReviewSummaryCandidate, commitReviewSummaryProvenance };
287
254
  //# sourceMappingURL=review-finalization.js.map
@@ -23,7 +23,9 @@ export function inspectReviewIdentity(taskDir, reportContent, repositoryRoot) {
23
23
  }
24
24
  try {
25
25
  const metadata = parseTypedTaskFrontmatter(fs.readFileSync(path.join(taskDir, 'task.md'), 'utf8'));
26
- const taskRepositoryRoot = git(taskDir, ['rev-parse', '--show-toplevel']);
26
+ const taskRepositoryRoot = repositoryRoot
27
+ ? fs.realpathSync.native(repositoryRoot)
28
+ : git(taskDir, ['rev-parse', '--show-toplevel']);
27
29
  const branch = String(metadata.branch ?? '').trim();
28
30
  const gitRoot = branch ? resolveBranchWorktree(taskRepositoryRoot, branch) : taskRepositoryRoot;
29
31
  if (!gitRoot)
@@ -1,6 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { parseTypedTaskFrontmatter } from './frontmatter.js';
4
+ import { resolveProjectTaskWorkspaceRoot } from './workspace-root.js';
4
5
  const REGISTRY_NAME = '.short-ids.json';
5
6
  const LOCK_NAME = '.short-ids.json.lock';
6
7
  function normalizeShortIdInput(input, opts) {
@@ -42,7 +43,7 @@ function resolveShortIdReadOnly(input, repoRoot, opts) {
42
43
  return shortIdFailure('SHORT_ID_NOT_FOUND', `short id '${input}' not found in active task registry`);
43
44
  }
44
45
  const key = normalized.value;
45
- const registryPath = path.join(repoRoot, '.agents', 'workspace', 'active', REGISTRY_NAME);
46
+ const registryPath = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active', REGISTRY_NAME);
46
47
  if (!fs.existsSync(registryPath)) {
47
48
  return shortIdFailure('SHORT_ID_REGISTRY_NOT_FOUND', `short id '${key}' not found; active task registry is empty.`);
48
49
  }
@@ -95,8 +96,9 @@ function resolveShortIdReadOnly(input, repoRoot, opts) {
95
96
  : `short id '${key}' not found in task short-id registry.`;
96
97
  return shortIdFailure('SHORT_ID_NOT_FOUND', message);
97
98
  }
98
- const activeTask = path.join(repoRoot, '.agents', 'workspace', 'active', taskId, 'task.md');
99
- const completedTask = path.join(repoRoot, '.agents', 'workspace', 'completed', taskId, 'task.md');
99
+ const workspaceRoot = resolveProjectTaskWorkspaceRoot(repoRoot);
100
+ const activeTask = path.join(workspaceRoot, 'active', taskId, 'task.md');
101
+ const completedTask = path.join(workspaceRoot, 'completed', taskId, 'task.md');
100
102
  let isValidCompletedTask = false;
101
103
  try {
102
104
  const task = parseTypedTaskFrontmatter(fs.readFileSync(completedTask, 'utf8'));
@@ -210,7 +212,7 @@ function writeRegistry(registryPath, registry) {
210
212
  }
211
213
  }
212
214
  function mutateShortIdRegistry(repoRoot, taskId, requested) {
213
- const activeDir = path.join(repoRoot, '.agents', 'workspace', 'active');
215
+ const activeDir = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active');
214
216
  return mutateShortIdRegistryAt(activeDir, configuredShortIdLength(repoRoot), taskId, requested);
215
217
  }
216
218
  function mutateShortIdRegistryAt(activeDir, width, taskId, requested, onlyReleaseWhenInactive = false, pruneOrphans = true) {
@@ -267,7 +269,7 @@ function mutateShortIdRegistryAt(activeDir, width, taskId, requested, onlyReleas
267
269
  });
268
270
  }
269
271
  function releaseStaleShortIdRegistry(repoRoot, taskId) {
270
- const activeDir = path.join(repoRoot, '.agents', 'workspace', 'active');
272
+ const activeDir = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active');
271
273
  return mutateShortIdRegistryAt(activeDir, configuredShortIdLength(repoRoot), taskId, 'release', true, false);
272
274
  }
273
275
  function executeShortIdCommand(request) {
@@ -327,7 +329,7 @@ function executeShortIdCommand(request) {
327
329
  }
328
330
  }
329
331
  function readRegistry(repoRoot) {
330
- const registryPath = path.join(repoRoot, '.agents', 'workspace', 'active', REGISTRY_NAME);
332
+ const registryPath = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active', REGISTRY_NAME);
331
333
  if (!fs.existsSync(registryPath))
332
334
  return null;
333
335
  try {
@@ -342,7 +344,7 @@ function readRegistry(repoRoot) {
342
344
  }
343
345
  }
344
346
  function readBranchFromTaskMd(repoRoot, taskId) {
345
- const taskMdPath = path.join(repoRoot, '.agents', 'workspace', 'active', taskId, 'task.md');
347
+ const taskMdPath = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active', taskId, 'task.md');
346
348
  if (!fs.existsSync(taskMdPath))
347
349
  return null;
348
350
  const content = fs.readFileSync(taskMdPath, 'utf8');
@@ -362,7 +364,7 @@ function loadShortIdByTaskId(repoRoot) {
362
364
  return map;
363
365
  }
364
366
  function inspectShortIdRegistry(repoRoot, shortIdLength = configuredShortIdLength(repoRoot)) {
365
- const registryPath = path.join(repoRoot, '.agents', 'workspace', 'active', REGISTRY_NAME);
367
+ const registryPath = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active', REGISTRY_NAME);
366
368
  if (!fs.existsSync(registryPath)) {
367
369
  return {
368
370
  status: 'missing',
@@ -54,9 +54,7 @@ const DEFAULT_REQUIRED_FIELDS = [
54
54
  "assigned_to"
55
55
  ];
56
56
  const DATE_TIME_PATTERN = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:[+-]\d{2}:\d{2})?$/;
57
- // Start markers (action suffixed with ` [started]`) are excluded from the
58
- // "latest action" / freshness computation so a step's in-flight marker never
59
- // satisfies a skill's expected_action_pattern; the matching done entry does.
57
+ // Started rows do not represent completed lifecycle actions.
60
58
  const ACTIVITY_LOG_STARTED_RE = /\s*\[started\]\s*$/;
61
59
  const BRANCH_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
62
60
  // Review disagreement ledger (see .agents/rules/review-handshake.md).
@@ -322,15 +320,9 @@ function checkTaskMeta({ taskDir, config, repositoryRoot, skillName, artifactFil
322
320
  if (expectedStep && metadata.current_step !== expectedStep) {
323
321
  let validLifecycleArtifact = false;
324
322
  if (currentTask) {
325
- const activityConfig = loadVerificationConfig(repositoryRoot, skillName).checks?.["activity-log"];
326
323
  const { section, invalidEntries } = inspectActivityLog(task.content);
327
- if (activityConfig && section && invalidEntries.length === 0) {
328
- let latestAction = "";
329
- for (const entry of section.entries) {
330
- if (!ACTIVITY_LOG_STARTED_RE.test(entry.step))
331
- latestAction = entry.step;
332
- }
333
- validLifecycleArtifact = checkArtifactLifecycleActivityLog(taskDir, artifactFile, skillName, activityConfig, task, section.entries, latestAction)?.status === "pass";
324
+ if (section && invalidEntries.length === 0) {
325
+ validLifecycleArtifact = checkArtifactLifecycleActivityLog(taskDir, artifactFile, skillName, task, section.entries)?.status === "pass";
334
326
  }
335
327
  }
336
328
  if (!validLifecycleArtifact) {
@@ -634,14 +626,14 @@ function checkImplementationInput({ taskDir, artifactFile }) {
634
626
  return passResult("implementation-input", `${actionDecision} matches Activity Log, report, and task table`);
635
627
  }
636
628
  const ARTIFACT_ACTIVITY_STAGES = {
637
- "analyze-task": { family: "analysis", event: "analyze.completed" },
638
- "plan-task": { family: "plan", event: "plan.completed" },
639
- "review-analysis": { family: "review-analysis", event: "review-analysis.completed" },
640
- "review-plan": { family: "review-plan", event: "review-plan.completed" },
641
- "code-task": { family: "code", event: "code.completed" },
642
- "review-code": { family: "review-code", event: "review-code.completed" }
629
+ "analyze-task": { family: "analysis", event: "analyze.completed", action: "Analyze Task" },
630
+ "plan-task": { family: "plan", event: "plan.completed", action: "Plan Task" },
631
+ "review-analysis": { family: "review-analysis", event: "review-analysis.completed", action: "Review Analysis" },
632
+ "review-plan": { family: "review-plan", event: "review-plan.completed", action: "Review Plan" },
633
+ "code-task": { family: "code", event: "code.completed", action: "Code Task" },
634
+ "review-code": { family: "review-code", event: "review-code.completed", action: "Review Code" }
643
635
  };
644
- function checkArtifactLifecycleActivityLog(taskDir, artifactFile, skillName, config, task, entries, latestAction) {
636
+ function checkArtifactLifecycleActivityLog(taskDir, artifactFile, skillName, task, entries) {
645
637
  const stage = ARTIFACT_ACTIVITY_STAGES[skillName];
646
638
  if (!stage)
647
639
  return null;
@@ -680,26 +672,18 @@ function checkArtifactLifecycleActivityLog(taskDir, artifactFile, skillName, con
680
672
  return failResult("activity-log", `Input '${input.name}' changed or is no longer current; rerun ${skillName} to refresh '${output}'`);
681
673
  }
682
674
  }
683
- const expectedAction = new RegExp(config.expected_action_pattern);
675
+ const roundActionPattern = new RegExp(`^${stage.action} \\(Round ${identity.round}(?:, [^)]+)?\\)$`);
684
676
  const roundAction = entries.find((entry) => {
685
- if (ACTIVITY_LOG_STARTED_RE.test(entry.step))
686
- return false;
687
- if (!expectedAction.test(entry.step))
688
- return false;
689
- expectedAction.lastIndex = 0;
690
- const actionRound = /\(Round (\d+)/.exec(entry.step)?.[1];
691
- return actionRound === String(identity.round) && entry.note.includes(`→ ${output}`);
677
+ return !ACTIVITY_LOG_STARTED_RE.test(entry.step)
678
+ && roundActionPattern.test(entry.step)
679
+ && entry.note.includes(`→ ${output}`);
692
680
  });
693
681
  if (!roundAction) {
694
682
  return failResult("activity-log", `No completed Activity Log row records '${output}' for ${skillName} Round ${identity.round}`);
695
683
  }
696
- if (skillName === "plan-task" && /^(?:Human Decision|Decision)\b/.test(latestAction)
697
- && expectedAction.test(latestAction)) {
698
- return passResult("activity-log", `Plan completion '${output}' is current; latest action '${latestAction}' is a human decision`);
699
- }
700
684
  return passResult("activity-log", `Current ${stage.family} completion '${output}' is valid for Round ${identity.round}`);
701
685
  }
702
- function checkActivityLog({ taskDir, config, skillName, artifactFile }) {
686
+ function checkActivityLog({ taskDir, skillName, artifactFile }) {
703
687
  const task = loadTask(taskDir);
704
688
  if (!task.ok) {
705
689
  return failResult("activity-log", task.message);
@@ -712,37 +696,14 @@ function checkActivityLog({ taskDir, config, skillName, artifactFile }) {
712
696
  const entries = section.entries;
713
697
  if (entries.length === 0)
714
698
  return failResult("activity-log", "Activity Log has no entries");
715
- let latestAction = "";
716
- let latestTimestamp = "";
717
- const doneActions = [];
718
699
  for (const entry of entries) {
719
700
  if (!entry.note.trim())
720
701
  return failResult("activity-log", "Activity Log entry note is required");
721
- const { time: timestamp, step: action } = entry;
722
- // A `[started]` marker is not a terminal action: keep latestAction/latestTimestamp
723
- // on the most recent done entry so expected_action_pattern sees it.
724
- if (!ACTIVITY_LOG_STARTED_RE.test(action)) {
725
- latestTimestamp = timestamp;
726
- latestAction = action;
727
- doneActions.push(action);
728
- }
729
702
  }
730
- const artifactLifecycleResult = checkArtifactLifecycleActivityLog(taskDir, artifactFile, skillName, config, task, entries, latestAction);
703
+ const artifactLifecycleResult = checkArtifactLifecycleActivityLog(taskDir, artifactFile, skillName, task, entries);
731
704
  if (artifactLifecycleResult)
732
705
  return artifactLifecycleResult;
733
- if (config.expected_action_pattern && !new RegExp(config.expected_action_pattern).test(latestAction)) {
734
- const expected = new RegExp(config.expected_action_pattern);
735
- let index = doneActions.length - 1;
736
- while (index >= 0 && doneActions[index] === 'Commit' && !expected.test(doneActions[index]))
737
- index -= 1;
738
- if (index >= 0 && expected.test(doneActions[index])) {
739
- latestAction = doneActions[index];
740
- }
741
- }
742
- if (config.expected_action_pattern && !new RegExp(config.expected_action_pattern).test(latestAction)) {
743
- return failResult("activity-log", `Latest action '${latestAction}' does not match '${config.expected_action_pattern}'`);
744
- }
745
- return passResult("activity-log", `Latest entry '${latestAction}' at ${latestTimestamp}`);
706
+ return passResult("activity-log", "Activity Log is valid");
746
707
  }
747
708
  function checkCompletionChecklist({ taskDir, config }) {
748
709
  const task = loadTask(taskDir);
@@ -932,10 +893,10 @@ async function checkPostReviewCommit({ taskDir, config, repositoryRoot }) {
932
893
  }
933
894
  let gitRoot;
934
895
  try {
935
- gitRoot = execFileSync("git", ["-C", taskDir, "rev-parse", "--show-toplevel"], { encoding: "utf8" }).trim();
896
+ gitRoot = execFileSync("git", ["-C", repositoryRoot, "rev-parse", "--show-toplevel"], { encoding: "utf8" }).trim();
936
897
  }
937
898
  catch {
938
- return blockedResult("post-review-commit", "git unavailable or task directory is not inside a git repository");
899
+ return blockedResult("post-review-commit", "git unavailable or repository root is not inside a git repository");
939
900
  }
940
901
  const task = loadTask(taskDir);
941
902
  if (!task.ok)
@@ -0,0 +1,59 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import { isSandbox } from '../sandbox/environment.js';
5
+ /**
6
+ * Resolve the physical task-workspace boundary from the verified process
7
+ * execution context. Sandbox mode (task-bound / branch-only) does not affect
8
+ * the task workspace mount location.
9
+ */
10
+ export function resolveTaskWorkspaceExecutionBoundary(env = process.env) {
11
+ if (env.AGENT_INFRA_SANDBOX !== '1')
12
+ return 'host';
13
+ const statusMountPath = env.AGENT_INFRA_CONTROL_STATUS_DIR;
14
+ if (!statusMountPath || !isSandbox(env, { statusMountPath })) {
15
+ throw new Error('task workspace boundary requires a verified sandbox execution context');
16
+ }
17
+ return 'container';
18
+ }
19
+ export function resolveTaskWorkspaceLayout(input) {
20
+ const { project, boundary } = input;
21
+ if (!project || project === '.' || project === '..' || /[\\/\u0000-\u001f\u007f]/u.test(project)) {
22
+ throw new TypeError('project must be a safe single path segment');
23
+ }
24
+ let root;
25
+ if (boundary === 'container') {
26
+ root = '/task-workspace';
27
+ }
28
+ else if (boundary === 'host') {
29
+ if (!input.home)
30
+ throw new TypeError('home is required for host task workspace resolution');
31
+ if (!path.isAbsolute(input.home))
32
+ throw new TypeError('home must be an absolute path for host task workspace resolution');
33
+ root = path.join(input.home, '.agent-infra', 'task-workspaces', project);
34
+ }
35
+ else {
36
+ throw new TypeError(`unsupported task workspace boundary: ${String(boundary)}`);
37
+ }
38
+ return {
39
+ projectKey: project,
40
+ boundary,
41
+ root,
42
+ active: path.join(root, 'active'),
43
+ blocked: path.join(root, 'blocked'),
44
+ completed: path.join(root, 'completed'),
45
+ archive: path.join(root, 'archive'),
46
+ shortIds: path.join(root, 'active', '.short-ids.json')
47
+ };
48
+ }
49
+ export function resolveProjectTaskWorkspaceLayout(repoRoot, boundary = resolveTaskWorkspaceExecutionBoundary()) {
50
+ const configPath = path.join(repoRoot, '.agents', '.airc.json');
51
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
52
+ if (typeof config.project !== 'string')
53
+ throw new TypeError(`project is missing from ${configPath}`);
54
+ return resolveTaskWorkspaceLayout({ project: config.project, boundary, home: process.env.HOME || os.homedir() });
55
+ }
56
+ export function resolveProjectTaskWorkspaceRoot(repoRoot) {
57
+ return resolveProjectTaskWorkspaceLayout(repoRoot).root;
58
+ }
59
+ //# sourceMappingURL=workspace-root.js.map
@@ -3,6 +3,7 @@ import fs from 'node:fs';
3
3
  import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { spawnSync } from 'node:child_process';
6
+ import { resolveProjectTaskWorkspaceRoot } from './workspace-root.js';
6
7
  function git(repoRoot, indexFile, args) {
7
8
  const env = indexFile ? { ...process.env, GIT_INDEX_FILE: indexFile } : process.env;
8
9
  const result = spawnSync('git', args, { cwd: repoRoot, env, encoding: 'utf8' });
@@ -32,7 +33,7 @@ function captureWorktreeTree(repoRoot, forcedPath) {
32
33
  }
33
34
  }
34
35
  function taskFileFingerprints(stateRoot, taskId) {
35
- const activeRoot = path.join(stateRoot, '.agents', 'workspace', 'active');
36
+ const activeRoot = path.join(resolveProjectTaskWorkspaceRoot(stateRoot), 'active');
36
37
  const roots = taskId ? [path.join(activeRoot, taskId)] : [activeRoot];
37
38
  const records = [];
38
39
  const visit = (absolute, relative) => {
@@ -45,7 +46,7 @@ function taskFileFingerprints(stateRoot, taskId) {
45
46
  }
46
47
  if (!stat.isFile() && !stat.isSymbolicLink())
47
48
  return;
48
- if (/^\.agents\/workspace\/(?:active|blocked|completed)\/TASK-[0-9]{8}-[0-9]{6}\/\.runtime\/orchestration\.json$/u.test(relative))
49
+ if (/^task-workspace\/(?:active|blocked|completed)\/TASK-[0-9]{8}-[0-9]{6}\/\.runtime\/orchestration\.json$/u.test(relative))
49
50
  return;
50
51
  const content = stat.isSymbolicLink()
51
52
  ? Buffer.from(fs.readlinkSync(absolute))
@@ -60,7 +61,7 @@ function taskFileFingerprints(stateRoot, taskId) {
60
61
  for (const root of roots) {
61
62
  if (!fs.existsSync(root))
62
63
  continue;
63
- const relative = path.posix.join('.agents/workspace/active', path.relative(activeRoot, root).split(path.sep).join('/'));
64
+ const relative = path.posix.join('task-workspace/active', path.relative(activeRoot, root).split(path.sep).join('/'));
64
65
  visit(root, relative.replace(/\/$/, ''));
65
66
  }
66
67
  return records.sort((left, right) => left.path.localeCompare(right.path));
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "protocolVersion": 3,
3
- "packageVersion": "0.11.15",
4
- "sourceInputHash": "2d62f5ec22e0e0024a0e11258cef192b9d4c80764386bc112e4c2a3a03d72a3f",
5
- "internalExecutableBuildHash": "9b88774ed654efea7d31aea3790aa1194f30df1f4487f95664de03f48815123f"
3
+ "packageVersion": "0.12.1",
4
+ "sourceInputHash": "b998fe9d348d3f7f55e1258d2d09793f09240d1d70173d6bce49a9ce6c89429e",
5
+ "internalExecutableBuildHash": "d75b6e06c5ed88b0cd03663d98e2001c3f5c661d9637b8e6b8993580f69a3f16"
6
6
  }
@@ -11,7 +11,7 @@ import { captureTaskWriteMetadata, writeTask } from '../../../task/write.ts';
11
11
  import { parseTypedTaskFrontmatter } from '../../../task/frontmatter.ts';
12
12
  import { resolveTaskRef } from '../../../task/resolve-ref.ts';
13
13
  import {
14
- recoverActivatedOrchestrationDelegationUnderLock,
14
+ recoverActivatedOrchestrationDelegation,
15
15
  readRun
16
16
  } from '../../../task/orchestration.ts';
17
17
  import type { OrchestrationOptions, OrchestrationRun } from '../../../task/orchestration.ts';
@@ -265,7 +265,7 @@ function appendRecoveryLog(
265
265
  });
266
266
  }
267
267
 
268
- function recoverStartedLifecycleUnderLock(
268
+ function recoverStartedLifecycle(
269
269
  request: LifecycleRecoveryRequest,
270
270
  options: LifecycleRecoveryOptions = {}
271
271
  ): LifecycleRecoveryResult {
@@ -372,7 +372,7 @@ function consumeRecoveryEvidence(
372
372
  let consumed = stored;
373
373
  if (stored.consumer === null) {
374
374
  try {
375
- consumed = store.consumeWithinTaskLock(pending.childId!, pending.id, stored.state.startEvidence?.hookDefinitionHash, {
375
+ consumed = store.consume(pending.childId!, pending.id, stored.state.startEvidence?.hookDefinitionHash, {
376
376
  taskId: pending.taskId, runId: pending.runId, receiptId: pending.id
377
377
  });
378
378
  } catch (error) {
@@ -393,7 +393,7 @@ function finishActiveRecovery(
393
393
  row: StepRow,
394
394
  options: LifecycleRecoveryOptions
395
395
  ): LifecycleRecoveryResult {
396
- const recovered = recoverActivatedOrchestrationDelegationUnderLock(taskId, {
396
+ const recovered = recoverActivatedOrchestrationDelegation(taskId, {
397
397
  receiptId: pending.id,
398
398
  stage: pending.stage,
399
399
  round: pending.round,
@@ -411,8 +411,8 @@ function recoverStartedLifecycleFromAdapter(
411
411
  request: LifecycleRecoveryRequest,
412
412
  options: LifecycleRecoveryOptions = {}
413
413
  ): LifecycleRecoveryResult {
414
- return recoverStartedLifecycleUnderLock(request, options);
414
+ return recoverStartedLifecycle(request, options);
415
415
  }
416
416
 
417
- export { recoverStartedLifecycleFromAdapter, recoverStartedLifecycleUnderLock };
417
+ export { recoverStartedLifecycle, recoverStartedLifecycleFromAdapter };
418
418
  export type { LifecycleRecoveryOptions, LifecycleRecoveryRequest, LifecycleRecoveryResult };
@@ -3,7 +3,6 @@ import path from 'node:path';
3
3
 
4
4
  import {
5
5
  mutateDelegationAdapterEvidence,
6
- mutateDelegationAdapterEvidenceWithinTaskLock,
7
6
  readRun
8
7
  } from '../../../task/orchestration.ts';
9
8
  import type { DelegationReceipt } from '../../../task/delegation-receipts.ts';
@@ -195,12 +194,10 @@ function createCodexLifecycleStore(options: CodexLifecycleStoreOptions) {
195
194
  function update(
196
195
  binding: CodexLifecycleTaskBinding,
197
196
  key: string,
198
- mutate: (current: StoredCodexLifecycle | null) => StoredCodexLifecycle,
199
- taskLockHeld = false
197
+ mutate: (current: StoredCodexLifecycle | null) => StoredCodexLifecycle
200
198
  ): StoredCodexLifecycle {
201
199
  let result: StoredCodexLifecycle | null = null;
202
- const updateState = taskLockHeld ? mutateDelegationAdapterEvidenceWithinTaskLock : mutateDelegationAdapterEvidence;
203
- updateState(options.taskId, binding.receiptId, 'codex', (value) => {
200
+ mutateDelegationAdapterEvidence(options.taskId, binding.receiptId, 'codex', (value) => {
204
201
  const currentState = storedEvidence(value);
205
202
  const current = currentState.records[key] ?? null;
206
203
  result = mutate(current);
@@ -304,23 +301,18 @@ function createCodexLifecycleStore(options: CodexLifecycleStoreOptions) {
304
301
  return matches[0]!;
305
302
  }
306
303
 
307
- function consumeWithLockMode(
304
+ function consume(
308
305
  childThreadId: string,
309
306
  consumer: string,
310
- expectedHookDefinitionHash: string | undefined,
311
- expectedTaskBinding: CodexLifecycleTaskBinding | undefined,
312
- taskLockHeld: boolean
307
+ expectedHookDefinitionHash?: string,
308
+ expectedTaskBinding?: CodexLifecycleTaskBinding
313
309
  ): StoredCodexLifecycle {
314
310
  if (!consumer.trim()) throw new Error('Codex lifecycle consumer is required');
315
311
  const current = read(childThreadId);
316
312
  const binding = expectedTaskBinding ?? current.taskBinding;
317
313
  if (!binding) throw new Error('Codex lifecycle task receipt binding is missing');
318
314
  const spawn = current.state.spawn;
319
- if (!spawn) {
320
- throw new Error(taskLockHeld
321
- ? 'Codex lifecycle task receipt binding is missing'
322
- : 'Codex lifecycle spawn evidence is missing');
323
- }
315
+ if (!spawn) throw new Error('Codex lifecycle spawn evidence is missing');
324
316
  const key = recordKey(spawn.sessionId, spawn.turnId, spawn.toolUseId);
325
317
  return update(binding, key, (latest) => {
326
318
  if (!latest || expectedTaskBinding && JSON.stringify(latest.taskBinding) !== JSON.stringify(expectedTaskBinding)) {
@@ -335,25 +327,7 @@ function createCodexLifecycleStore(options: CodexLifecycleStoreOptions) {
335
327
  }
336
328
  if (latest.consumer) return latest;
337
329
  return Object.freeze({ ...latest, revision: latest.revision + 1, consumer, consumedAt: now(), updatedAt: now() });
338
- }, taskLockHeld);
339
- }
340
-
341
- function consume(
342
- childThreadId: string,
343
- consumer: string,
344
- expectedHookDefinitionHash?: string,
345
- expectedTaskBinding?: CodexLifecycleTaskBinding
346
- ): StoredCodexLifecycle {
347
- return consumeWithLockMode(childThreadId, consumer, expectedHookDefinitionHash, expectedTaskBinding, false);
348
- }
349
-
350
- function consumeWithinTaskLock(
351
- childThreadId: string,
352
- consumer: string,
353
- expectedHookDefinitionHash?: string,
354
- expectedTaskBinding?: CodexLifecycleTaskBinding
355
- ): StoredCodexLifecycle {
356
- return consumeWithLockMode(childThreadId, consumer, expectedHookDefinitionHash, expectedTaskBinding, true);
330
+ });
357
331
  }
358
332
 
359
333
  function expireBefore(cutoff: string): number {
@@ -373,7 +347,7 @@ function createCodexLifecycleStore(options: CodexLifecycleStoreOptions) {
373
347
  return changed;
374
348
  }
375
349
 
376
- return Object.freeze({ taskId: options.taskId, root: path.join(taskDir, '.runtime'), apply, applyToSpawn, consume, consumeWithinTaskLock, expireBefore, findByParent, findByTaskBinding, read });
350
+ return Object.freeze({ taskId: options.taskId, root: path.join(taskDir, '.runtime'), apply, applyToSpawn, consume, expireBefore, findByParent, findByTaskBinding, read });
377
351
  }
378
352
 
379
353
  export { createCodexLifecycleStore, hasActiveCodexLifecycleEvidence, readCodexLifecycleActivationEvidence };
@@ -481,7 +481,7 @@ async function sealCodexOrchestrationDelegation(
481
481
  coreOptions(options),
482
482
  () => {
483
483
  try {
484
- const consumed = store.consumeWithinTaskLock(
484
+ const consumed = store.consume(
485
485
  childThreadId,
486
486
  current.receipt.id,
487
487
  existing.state.spawn?.hookDefinitionHash,
package/lib/decide.ts CHANGED
@@ -3,7 +3,6 @@ import { parseTaskScope } from './task/command-options.ts';
3
3
  import { applyHumanDecision } from './task/decision-intents.ts';
4
4
  import { canonicalTimestamp } from './task/write.ts';
5
5
  import { resolveTaskContext } from './task/resolve-ref.ts';
6
- import { TaskExecutionLockError, withTaskExecutionLock } from './task/task-execution-lock.ts';
7
6
 
8
7
  type DecideOptions = {
9
8
  repoRoot?: string;
@@ -70,15 +69,11 @@ export async function decide(args: string[], options: DecideOptions = {}): Promi
70
69
  repoRoot: resolved.repoRoot,
71
70
  metadataProvider: () => ({ timestamp: now, agentInfraVersion: options.version ?? VERSION })
72
71
  };
73
- let result;
74
- const execute = async () => applyHumanDecision(request, writeOptions);
75
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-decision', execute);
72
+ const result = await applyHumanDecision(request, writeOptions);
76
73
  if (result.error) throw new Error(result.error.message);
77
74
  return 0;
78
75
  } catch (error) {
79
- const message = error instanceof TaskExecutionLockError
80
- ? `${error.code}: ${error.message}`
81
- : error instanceof Error ? error.message : String(error);
76
+ const message = error instanceof Error ? error.message : String(error);
82
77
  process.stderr.write(`Error: ${message}\n`);
83
78
  return 1;
84
79
  }
@@ -52,6 +52,7 @@ export const INTERNAL_HANDLER_ROUTE_SELECTORS = Object.freeze({
52
52
  'pr-review-grade': ['decide', 'resolve-host', 'verify-artifact'],
53
53
  'platform-checks': ['inspect', 'watch', 'resolve-run', 'logs'],
54
54
  'task-context': ['resolve'],
55
+ 'task-workspace': ['resolve'],
55
56
  'task-ledger': ['decision-next-id', 'stage-status', 'finding-upsert', 'finding-respond', 'finding-review', 'decision-upsert', 'rework-intent-upsert', 'rework-intent-rebuild'],
56
57
  'task-warning': ['list', 'add', 'set-status'],
57
58
  'task-activity': ['pr-review-inspect', 'pr-review-start', 'pr-review-complete', 'pr-review-terminate'],
@@ -104,6 +105,7 @@ export function internalRouteSelector(command: string, args: readonly string[]):
104
105
  if (['task-ledger', 'task-warning', 'task-activity'].includes(command)) return args[1] ?? '';
105
106
  if (command === 'task-delivery') return args[1] ?? '';
106
107
  if (command === 'task-context') return first(args);
108
+ if (command === 'task-workspace') return first(args);
107
109
  return first(args);
108
110
  }
109
111