@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
@@ -4,13 +4,13 @@ import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { isValidAgentInfraVersion, VERSION } from '../version.js';
6
6
  import { loadShortIdByTaskId, mutateShortIdRegistry } from './short-id.js';
7
- import { TaskExecutionLockError, withRepositoryMutationLock, withTaskExecutionLock } from './task-execution-lock.js';
8
7
  import { readDeliveryDefaults, validateBaseRef, validateRemote } from './delivery-target.js';
9
8
  import { buildUnboundFact, encodePrDeliveryFact } from './pr-delivery-fact.js';
10
9
  import { CANDIDATE_COLUMNS, CONSTRAINT_COLUMNS, parseTaskQualification } from './qualification-audit.js';
11
10
  import { enumerateAllTaskDirs } from './resolve-ref.js';
12
11
  import { parseTaskFrontmatter } from './frontmatter.js';
13
12
  import { AGENT_TOKEN_VALUES } from '../agent-clients/tokens.js';
13
+ import { resolveProjectTaskWorkspaceRoot } from './workspace-root.js';
14
14
  const TYPES = ['feature', 'bugfix', 'refactor', 'docs', 'chore'];
15
15
  const PRIORITIES = ['Urgent', 'High', 'Medium', 'Low'];
16
16
  const EFFORTS = ['High', 'Medium', 'Low'];
@@ -295,49 +295,6 @@ function ensureRealDirectory(directory, code) {
295
295
  }
296
296
  fs.mkdirSync(directory, { mode: 0o700 });
297
297
  }
298
- function createLockRoot(project) {
299
- const root = path.join(os.homedir(), '.agent-infra');
300
- const directories = [root, path.join(root, 'run'), path.join(root, 'run', project), path.join(root, 'run', project, 'task-create-locks')];
301
- for (const directory of directories) {
302
- if (fs.existsSync(directory)) {
303
- assertRealDirectory(directory, 'TASK_CREATE_LOCK_FAILED');
304
- continue;
305
- }
306
- try {
307
- fs.mkdirSync(directory, { mode: 0o700 });
308
- }
309
- catch (error) {
310
- if (error.code !== 'EEXIST')
311
- throw error;
312
- assertRealDirectory(directory, 'TASK_CREATE_LOCK_FAILED');
313
- }
314
- }
315
- return directories.at(-1);
316
- }
317
- function withCreateLock(repoRoot, project, operation) {
318
- const lockRoot = createLockRoot(project);
319
- let callbackError;
320
- try {
321
- return withTaskExecutionLock(repoRoot, 'task-create', 'task-create', () => {
322
- try {
323
- return operation();
324
- }
325
- catch (error) {
326
- callbackError = error;
327
- throw error;
328
- }
329
- }, { lockRoot, identityScope: `task-create\0${project}` });
330
- }
331
- catch (error) {
332
- if (callbackError !== undefined)
333
- throw callbackError;
334
- if (error instanceof TaskExecutionLockError && error.code === 'ORCHESTRATION_LOCK_BUSY') {
335
- throw new Error('TASK_CREATE_LOCK_TIMEOUT');
336
- }
337
- const message = error instanceof Error ? error.message : String(error);
338
- throw new Error(`TASK_CREATE_LOCK_FAILED: ${message}`);
339
- }
340
- }
341
298
  function recoverPublishedTask(repoRoot, keyDigest, candidateDigest) {
342
299
  for (const task of enumerateAllTaskDirs(repoRoot)) {
343
300
  const taskMd = path.join(task.taskDir, 'task.md');
@@ -366,16 +323,24 @@ function createLocalTask(value, options) {
366
323
  throw new Error('TASK_CREATE_VERSION_INVALID: agentInfraVersion must be a valid v-prefixed semver');
367
324
  }
368
325
  const repoRoot = fs.realpathSync.native(options.repoRoot);
369
- const workspaceRoot = path.join(repoRoot, '.agents', 'workspace');
326
+ const workspaceRoot = resolveProjectTaskWorkspaceRoot(repoRoot);
370
327
  const activeRoot = path.join(workspaceRoot, 'active');
371
328
  ensureRealDirectory(path.join(repoRoot, '.agents'), 'TASK_CREATE_WORKSPACE_INVALID');
329
+ const home = path.resolve(process.env.HOME || os.homedir());
330
+ const managedRoots = [path.join(home, '.agent-infra'), path.join(home, '.agent-infra', 'task-workspaces')];
331
+ for (const root of managedRoots) {
332
+ if (fs.existsSync(root))
333
+ assertRealDirectory(root, 'TASK_CREATE_WORKSPACE_INVALID');
334
+ else
335
+ fs.mkdirSync(root, { mode: 0o700 });
336
+ }
372
337
  ensureRealDirectory(workspaceRoot, 'TASK_CREATE_WORKSPACE_INVALID');
373
338
  ensureRealDirectory(activeRoot, 'TASK_CREATE_WORKSPACE_INVALID');
374
339
  const projectConfig = readProject(repoRoot);
375
340
  const canonical = canonicalTaskCreateCandidate(candidate);
376
341
  const candidateDigest = sha256(canonical);
377
342
  const keyDigest = sha256(candidate.idempotencyKey);
378
- function createUnderRepositoryLock() {
343
+ function createOnce() {
379
344
  const recovered = recoverPublishedTask(repoRoot, keyDigest, candidateDigest);
380
345
  if (recovered) {
381
346
  return { status: 'no-op', changed: false, task: { id: recovered.taskId, shortId: recovered.shortId, state: recovered.state } };
@@ -407,25 +372,7 @@ function createLocalTask(value, options) {
407
372
  throw new Error('TASK_CREATE_SHORT_ID_FAILED');
408
373
  return { status: 'applied', changed: true, task: { id: taskId, shortId: allocated.shortId, state: 'active' } };
409
374
  }
410
- return withCreateLock(repoRoot, projectConfig.project, () => {
411
- let callbackError;
412
- try {
413
- return withRepositoryMutationLock(repoRoot, () => {
414
- try {
415
- return createUnderRepositoryLock();
416
- }
417
- catch (error) {
418
- callbackError = error;
419
- throw error;
420
- }
421
- });
422
- }
423
- catch (error) {
424
- if (callbackError !== undefined)
425
- throw callbackError;
426
- throw error;
427
- }
428
- });
375
+ return createOnce();
429
376
  }
430
377
  export { canonicalTaskCreateCandidate, createLocalTask, validateTaskCreateCandidate };
431
378
  //# sourceMappingURL=create.js.map
@@ -195,7 +195,7 @@ function validateSealRequest(receipt, event) {
195
195
  function validateReviewerSealPaths(receipt, changedPaths) {
196
196
  if (receipt.role !== 'reviewer')
197
197
  return null;
198
- const taskRoot = `.agents/workspace/active/${receipt.taskId}/`;
198
+ const taskRoot = `task-workspace/active/${receipt.taskId}/`;
199
199
  const allowed = new Set([
200
200
  `${taskRoot}${receipt.artifact}`,
201
201
  `${taskRoot}task.md`,
@@ -5,7 +5,6 @@ import { parseTaskFrontmatter } from './frontmatter.js';
5
5
  import { resolveTaskRef } from './resolve-ref.js';
6
6
  import { resolveDeliveryTarget, validateBaseRef, validateRemote } from './delivery-target.js';
7
7
  import { captureTaskWriteMetadata, writeTask } from './write.js';
8
- import { withRepositoryMutationLock, withTaskExecutionLock } from './task-execution-lock.js';
9
8
  function classifyDeliveryState(localHead, remoteHead, lastDelivered) {
10
9
  if (remoteHead === null)
11
10
  return { state: 'absent', shouldPush: true };
@@ -29,7 +28,7 @@ function validateBranch(cwd, branch) {
29
28
  function failure(taskId, code, message, retryable = false, status = retryable ? 'blocked' : 'failed') {
30
29
  return { status, changed: false, taskId, remoteHead: null, localHead: null, state: null, error: { code, message, retryable } };
31
30
  }
32
- function deliverUnlocked(taskId, taskDir, repoRoot, options) {
31
+ function deliverTaskBranchCore(taskId, taskDir, repoRoot, options) {
33
32
  let frontmatter;
34
33
  try {
35
34
  frontmatter = parseTaskFrontmatter(fs.readFileSync(path.join(taskDir, 'task.md'), 'utf8'));
@@ -100,12 +99,7 @@ function deliverTaskBranch(taskRef, options) {
100
99
  const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
101
100
  if (!resolved.ok)
102
101
  return failure(resolved.taskId, resolved.code, resolved.message);
103
- try {
104
- return withRepositoryMutationLock(resolved.repoRoot, () => withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-delivery', () => deliverUnlocked(resolved.taskId, resolved.taskDir, resolved.repoRoot, options)));
105
- }
106
- catch (error) {
107
- return failure(resolved.taskId, 'DELIVERY_LOCK_FAILED', error instanceof Error ? error.message : String(error), true, 'blocked');
108
- }
102
+ return deliverTaskBranchCore(resolved.taskId, resolved.taskDir, resolved.repoRoot, options);
109
103
  }
110
104
  export { classifyDeliveryState, deliverTaskBranch };
111
105
  //# sourceMappingURL=delivery.js.map
@@ -15,7 +15,6 @@ import { resolveTaskRef } from './resolve-ref.js';
15
15
  import { findSectionHeading } from './sections.js';
16
16
  import { validateLifecycleExecution } from './lifecycle-execution.js';
17
17
  import { commitOrchestrationStageCompletion } from './orchestration.js';
18
- import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.js';
19
18
  import { captureTaskWriteMetadata, writeTask } from './write.js';
20
19
  import { validateLocalArtifact } from './local-artifact-finalization.js';
21
20
  import { buildLifecycleFacts, canStart, effectiveReworkTarget } from './capabilities.js';
@@ -456,11 +455,11 @@ function reworkIntentMutationForCompletion(content, taskDir, family, artifact, t
456
455
  }
457
456
  return { mutation: JSON.stringify(next) === JSON.stringify(parsed.intents) ? null : reworkIntentMutation(content, next) };
458
457
  }
459
- function buildCompletionReceipt(content, taskDir, family, artifact, completedAt, frontmatter, request) {
458
+ function buildCompletionReceipt(content, taskDir, repositoryRoot, family, artifact, completedAt, frontmatter, request) {
460
459
  if (!['analyze', 'plan', 'code'].includes(family) && !family.startsWith('review-'))
461
460
  return null;
462
461
  if (family === 'review-code') {
463
- const identity = inspectReviewIdentity(taskDir, fs.readFileSync(artifact.path, 'utf8'));
462
+ const identity = inspectReviewIdentity(taskDir, fs.readFileSync(artifact.path, 'utf8'), repositoryRoot);
464
463
  if (identity.status !== 'matched')
465
464
  return { ok: false, message: `review-code identity is ${identity.status}: ${identity.message}` };
466
465
  }
@@ -566,7 +565,7 @@ function sameCompletionFact(left, right) {
566
565
  function replaceCompletionFact(facts, next) {
567
566
  return [...facts.filter((fact) => !(fact.event === next.event && fact.output === next.output)), next];
568
567
  }
569
- function applyTaskEventUnlocked(request, options = {}) {
568
+ function applyTaskEvent(request, options = {}) {
570
569
  const invalid = validateTaskEventRequest(request);
571
570
  if (invalid)
572
571
  return failed(request, invalid);
@@ -718,7 +717,7 @@ function applyTaskEventUnlocked(request, options = {}) {
718
717
  }
719
718
  if (eventIdentity.phase === 'started') {
720
719
  const trigger = eventTrigger(normalized, eventIdentity.family);
721
- const facts = buildLifecycleFacts(resolved.taskDir, content, resolved.state);
720
+ const facts = buildLifecycleFacts(resolved.taskDir, content, resolved.state, false, resolved.repoRoot);
722
721
  if (!facts.ok)
723
722
  return failed(normalized, { code: 'EVENT_TRANSITION_INVALID', message: `${facts.code}: ${facts.message}` }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
724
723
  const capability = canStart(lifecycleAction(eventIdentity.family), facts.facts, trigger);
@@ -766,7 +765,7 @@ function applyTaskEventUnlocked(request, options = {}) {
766
765
  let currentFact = null;
767
766
  let completionRework = null;
768
767
  if (eventIdentity.phase === 'completed' && completedArtifact) {
769
- const receipt = buildCompletionReceipt(content, resolved.taskDir, eventIdentity.family, completedArtifact, metadata.timestamp, frontmatter, normalized);
768
+ const receipt = buildCompletionReceipt(content, resolved.taskDir, resolved.repoRoot, eventIdentity.family, completedArtifact, metadata.timestamp, frontmatter, normalized);
770
769
  if (receipt && !receipt.ok) {
771
770
  return failed(normalized, { code: 'EVENT_ARTIFACT_CONFLICT', message: receipt.message }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
772
771
  }
@@ -938,31 +937,6 @@ function applyTaskEventUnlocked(request, options = {}) {
938
937
  agentInfraVersion: result.agentInfraVersion, operations: result.operations, error: null
939
938
  };
940
939
  }
941
- function applyTaskEvent(request, options = {}) {
942
- const invalid = validateTaskEventRequest(request);
943
- if (invalid)
944
- return failed(request, invalid);
945
- const parts = eventParts(request.event);
946
- if (options.lockAlreadyHeld)
947
- return applyTaskEventUnlocked(request, options);
948
- if (request.dryRun || !['started', 'completed'].includes(parts.phase)) {
949
- return applyTaskEventUnlocked(request, options);
950
- }
951
- const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
952
- if (!resolved.ok)
953
- return applyTaskEventUnlocked(request, options);
954
- try {
955
- return withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-event.${request.event}`, () => applyTaskEventUnlocked(request, { ...options, lockAlreadyHeld: true }));
956
- }
957
- catch (error) {
958
- if (!(error instanceof TaskExecutionLockError))
959
- throw error;
960
- return failed(request, {
961
- code: 'EVENT_TRANSITION_INVALID',
962
- message: `${error.code}: ${error.message}`
963
- }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
964
- }
965
- }
966
940
  function successNoOp(request, taskId, taskMdPath, currentStep, eventIdentity, timestamp, frontmatter, artifactContext) {
967
941
  return {
968
942
  ...failed(request, { code: 'EVENT_LOG_CONFLICT', message: '' }), status: 'no-op', error: null,
@@ -9,15 +9,15 @@ import { inspectPlatformIssue, syncPlatformIssue } from '../platform/issues.js';
9
9
  import { resourceIdentityEquals } from '../platform/resource-identity.js';
10
10
  import { parseTaskFrontmatter } from './frontmatter.js';
11
11
  import { recoverPlatformOperations } from './platform-operation-recovery.js';
12
- import { applyTaskLifecycle, applyTaskLifecycleWithinTaskLock, inspectTaskLifecycleProgress, previewTaskCompletion } from './lifecycle.js';
12
+ import { applyTaskLifecycle, inspectTaskLifecycleProgress, previewTaskCompletion } from './lifecycle.js';
13
13
  import { enumerateAllTaskDirs, resolveTaskRef } from './resolve-ref.js';
14
14
  import { inspectShortIdRegistry } from './short-id.js';
15
- import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.js';
16
15
  import { verifyTaskEvent } from './verification.js';
17
16
  import { projectFinalizationWarning } from './workflow-warning-intents.js';
18
17
  import { mergeOperationWarnings } from './operation-outcome.js';
19
18
  import { readSandboxControlManifest } from '../sandbox/control/lifecycle.js';
20
19
  import { validateSandboxControlIdentity } from '../sandbox/control/identity-sentinel.js';
20
+ import { parseDeliverySummaryContent, renderDeliverySummaryContent } from '../platform/issue-summary-content.js';
21
21
  const RECEIPT_VERSION = 4;
22
22
  const FINALIZATION_STEPS = ['lifecycle', 'task-comment', 'verification', 'summary'];
23
23
  export function resolveTaskFinalizationDirectory(repoRoot, taskId) {
@@ -442,7 +442,7 @@ function mutationPatch(current, mutation) {
442
442
  ? { warningProjection: 'done', lastError: null }
443
443
  : { warningProjection: 'pending', lastError: mutation.error };
444
444
  }
445
- function applyFinalizationReceiptMutationUnderLock(repoRoot, receipt, capability, mutation, consumed) {
445
+ function mutateFinalizationReceipt(repoRoot, receipt, capability, mutation, consumed) {
446
446
  if (!hasFinalizationTaskDocument(repoRoot, receipt.taskId)) {
447
447
  throw capabilityError('FINALIZATION_SCOPE_INVALID', 'finalization capability requires an active task or a completed task');
448
448
  }
@@ -459,7 +459,7 @@ function applyFinalizationReceiptMutation(repoRoot, receipt, capability, mutatio
459
459
  if (!hasFinalizationTaskDocument(repoRoot, receipt.taskId)) {
460
460
  throw capabilityError('FINALIZATION_SCOPE_INVALID', 'finalization capability requires an active task or a completed task');
461
461
  }
462
- return withTaskExecutionLock(repoRoot, receipt.taskId, 'task-finalization.receipt-mutation', () => applyFinalizationReceiptMutationUnderLock(repoRoot, receipt, capability, mutation, new Set()));
462
+ return mutateFinalizationReceipt(repoRoot, receipt, capability, mutation, new Set());
463
463
  }
464
464
  function warningKey(warning) {
465
465
  return `${warning.step}\0${warning.code}\0${warning.target}`;
@@ -479,14 +479,14 @@ function reconcileWarningProjection(repoRoot, taskId, receipt, consumed) {
479
479
  retryable: true
480
480
  };
481
481
  const capability = issueCapability(receipt, 'warning-projection');
482
- return applyFinalizationReceiptMutationUnderLock(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'failed', error: detail }, consumed);
482
+ return mutateFinalizationReceipt(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'failed', error: detail }, consumed);
483
483
  }
484
484
  }
485
485
  catch (error) {
486
486
  const detail = errorOf(error, 'FINALIZATION_WARNING_PROJECTION_FAILED', true);
487
487
  try {
488
488
  const capability = issueCapability(receipt, 'warning-projection');
489
- return applyFinalizationReceiptMutationUnderLock(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'failed', error: detail }, consumed);
489
+ return mutateFinalizationReceipt(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'failed', error: detail }, consumed);
490
490
  }
491
491
  catch {
492
492
  return receipt;
@@ -495,7 +495,7 @@ function reconcileWarningProjection(repoRoot, taskId, receipt, consumed) {
495
495
  }
496
496
  try {
497
497
  const capability = issueCapability(receipt, 'warning-projection');
498
- return applyFinalizationReceiptMutationUnderLock(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'succeeded' }, consumed);
498
+ return mutateFinalizationReceipt(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'succeeded' }, consumed);
499
499
  }
500
500
  catch {
501
501
  return receipt;
@@ -526,7 +526,7 @@ async function syncPendingTaskComment(input) {
526
526
  if (result.status === 'applied' || result.status === 'no-op') {
527
527
  const skipped = result.error?.code === 'ISSUE_NOT_LINKED';
528
528
  const capability = issueCapability(receipt, 'task-comment');
529
- receipt = applyFinalizationReceiptMutationUnderLock(repoRoot, receipt, capability, {
529
+ receipt = mutateFinalizationReceipt(repoRoot, receipt, capability, {
530
530
  scope: 'task-comment', operation: 'succeeded', state: skipped ? 'skipped' : 'done'
531
531
  }, consumedCapabilities);
532
532
  receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
@@ -542,7 +542,7 @@ async function syncPendingTaskComment(input) {
542
542
  }
543
543
  const detail = step.error ?? { code: 'COMMENT_SYNC_FAILED', message: 'task comment synchronization failed', retryable: true };
544
544
  const capability = issueCapability(receipt, 'task-comment');
545
- receipt = applyFinalizationReceiptMutationUnderLock(repoRoot, receipt, capability, {
545
+ receipt = mutateFinalizationReceipt(repoRoot, receipt, capability, {
546
546
  scope: 'task-comment', operation: 'failed', error: detail
547
547
  }, consumedCapabilities);
548
548
  receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
@@ -552,7 +552,7 @@ async function syncPendingTaskComment(input) {
552
552
  const detail = errorOf(error, 'COMMENT_SYNC_FAILED', true);
553
553
  try {
554
554
  const capability = issueCapability(receipt, 'task-comment');
555
- receipt = applyFinalizationReceiptMutationUnderLock(repoRoot, receipt, capability, {
555
+ receipt = mutateFinalizationReceipt(repoRoot, receipt, capability, {
556
556
  scope: 'task-comment', operation: 'failed', error: detail
557
557
  }, consumedCapabilities);
558
558
  receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
@@ -570,17 +570,25 @@ function readDeliverySummary(taskDir, taskId) {
570
570
  catch {
571
571
  throw Object.assign(new Error('delivery summary staging record is unavailable'), { code: 'SUMMARY_STAGING_INVALID' });
572
572
  }
573
- if (value.taskId !== taskId || typeof value.body !== 'string' || typeof value.sha256 !== 'string') {
573
+ if (value.taskId !== taskId || !value.content || typeof value.contentSha256 !== 'string') {
574
574
  throw Object.assign(new Error('delivery summary staging record is invalid'), { code: 'SUMMARY_STAGING_INVALID' });
575
575
  }
576
- const canonical = canonicalizeSummaryBody(value.body);
577
- if (!canonical.ok || canonical.value !== value.body) {
578
- throw Object.assign(new Error('delivery summary staging body is not canonical'), { code: 'SUMMARY_STAGING_INVALID' });
576
+ let content;
577
+ try {
578
+ content = parseDeliverySummaryContent(value.content);
579
+ }
580
+ catch {
581
+ throw Object.assign(new Error('delivery summary staging payload is invalid'), { code: 'SUMMARY_STAGING_INVALID' });
579
582
  }
583
+ if (content.taskId !== taskId || createHash('sha256').update(JSON.stringify(content)).digest('hex') !== value.contentSha256) {
584
+ throw Object.assign(new Error('delivery summary staging digest does not match payload'), { code: 'SUMMARY_STAGING_INVALID' });
585
+ }
586
+ const body = renderDeliverySummaryContent(content);
587
+ const canonical = canonicalizeSummaryBody(body);
588
+ if (!canonical.ok)
589
+ throw Object.assign(new Error('delivery summary staging body is not canonical'), { code: 'SUMMARY_STAGING_INVALID' });
580
590
  const digest = createHash('sha256').update(canonical.value).digest('hex');
581
- if (digest !== value.sha256)
582
- throw Object.assign(new Error('delivery summary staging digest does not match body'), { code: 'SUMMARY_STAGING_INVALID' });
583
- return { body: canonical.value, sha256: value.sha256 };
591
+ return { body: canonical.value, sha256: digest };
584
592
  }
585
593
  async function syncPendingSummary(input) {
586
594
  let { receipt } = input;
@@ -682,9 +690,9 @@ function preparedResult(taskId, receipt, steps, changed) {
682
690
  result: 'prepared', warnings: openWarnings(receipt), error: null
683
691
  };
684
692
  }
685
- async function prepareUnderLock(request, taskId, options) {
693
+ async function prepareTaskFinalizationCore(request, taskId, options) {
686
694
  const repoRoot = path.resolve(options.repoRoot);
687
- const lifecycle = options.lifecycle ?? ((lifecycleRequest, lifecycleOptions) => (applyTaskLifecycleWithinTaskLock(lifecycleRequest, lifecycleOptions ?? { repoRoot }, taskId)));
695
+ const lifecycle = options.lifecycle ?? ((lifecycleRequest, lifecycleOptions) => (applyTaskLifecycle(lifecycleRequest, lifecycleOptions ?? { repoRoot })));
688
696
  const backfill = options.backfill ?? backfillCompletionComments;
689
697
  const commentSync = options.commentSync ?? syncPlatformComment;
690
698
  const issueSync = options.issueSync ?? syncPlatformIssue;
@@ -966,12 +974,10 @@ async function prepareTaskFinalization(request, options) {
966
974
  if (!resolved.ok)
967
975
  return failed(resolved.taskId, { code: resolved.code, message: resolved.message, retryable: false });
968
976
  try {
969
- return await withTaskExecutionLock(repoRoot, resolved.taskId, 'task-finalization.prepare', () => prepareUnderLock(request, resolved.taskId, options));
977
+ return await prepareTaskFinalizationCore(request, resolved.taskId, options);
970
978
  }
971
979
  catch (error) {
972
- const detail = error instanceof TaskExecutionLockError
973
- ? { code: error.code, message: error.message, retryable: error.code === 'ORCHESTRATION_LOCK_BUSY' }
974
- : errorOf(error, 'TASK_FINALIZATION_FAILED');
980
+ const detail = errorOf(error, 'TASK_FINALIZATION_FAILED');
975
981
  return failed(resolved.taskId, detail);
976
982
  }
977
983
  }
@@ -984,7 +990,7 @@ async function commitPreparedTaskFinalization(request, options) {
984
990
  if (!resolved.ok)
985
991
  return failed(resolved.taskId, { code: resolved.code, message: resolved.message, retryable: false });
986
992
  try {
987
- return await withTaskExecutionLock(repoRoot, resolved.taskId, 'task-finalization.commit', async () => {
993
+ return await (async () => {
988
994
  if (options.controlBinding && options.manifestPath) {
989
995
  try {
990
996
  const manifest = readSandboxControlManifest(options.manifestPath);
@@ -1051,7 +1057,7 @@ async function commitPreparedTaskFinalization(request, options) {
1051
1057
  };
1052
1058
  const result = options.lifecycle
1053
1059
  ? options.lifecycle(lifecycleRequest, lifecycleOptions)
1054
- : applyTaskLifecycleWithinTaskLock(lifecycleRequest, lifecycleOptions, resolved.taskId);
1060
+ : applyTaskLifecycle(lifecycleRequest, lifecycleOptions);
1055
1061
  const step = lifecycleStep(result);
1056
1062
  if (result.status !== 'applied' && result.status !== 'no-op') {
1057
1063
  const updated = updateReceipt(repoRoot, receipt, { lifecycle: 'pending', lastError: step.error });
@@ -1131,12 +1137,10 @@ async function commitPreparedTaskFinalization(request, options) {
1131
1137
  });
1132
1138
  }
1133
1139
  return terminalResult(resolved.taskId, updated, { lifecycle: step, verification }, result.changed, detail);
1134
- });
1140
+ })();
1135
1141
  }
1136
1142
  catch (error) {
1137
- const detail = error instanceof TaskExecutionLockError
1138
- ? { code: error.code, message: error.message, retryable: error.code === 'ORCHESTRATION_LOCK_BUSY' }
1139
- : errorOf(error, 'TASK_FINALIZATION_FAILED');
1143
+ const detail = errorOf(error, 'TASK_FINALIZATION_FAILED');
1140
1144
  return failed(resolved.taskId, detail);
1141
1145
  }
1142
1146
  }
@@ -13,7 +13,7 @@ import { validateCurrentTaskContract } from './current-contract.js';
13
13
  import { isValidAgentInfraVersion } from '../version.js';
14
14
  import { taskIssueIdentity } from '../platform/task-identities.js';
15
15
  import { resourceIdentityEquals } from '../platform/resource-identity.js';
16
- import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.js';
16
+ import { resolveProjectTaskWorkspaceRoot } from './workspace-root.js';
17
17
  const lifecycleIntentCatalog = [
18
18
  'block', 'activate', 'cancel', 'complete', 'close-codescan', 'close-dependabot', 'restore', 'recover-started'
19
19
  ];
@@ -61,7 +61,7 @@ const DEFAULT_IO = {
61
61
  };
62
62
  function isVirtiofsMountPoint(directory, mountInfo) {
63
63
  const decodeMountInfoPath = (value) => value.replace(/\\([0-7]{3})/gu, (_match, octal) => String.fromCharCode(Number.parseInt(octal, 8)));
64
- const expected = path.resolve(directory);
64
+ const expected = fs.realpathSync.native(directory);
65
65
  return mountInfo.split('\n').some((line) => {
66
66
  if (!line)
67
67
  return false;
@@ -371,7 +371,7 @@ function validateRestoreStaging(request, repoRoot, taskId) {
371
371
  let workspace;
372
372
  let stagingDir;
373
373
  try {
374
- workspace = fs.realpathSync.native(path.resolve(repoRoot, '.agents', 'workspace'));
374
+ workspace = fs.realpathSync.native(resolveProjectTaskWorkspaceRoot(repoRoot));
375
375
  stagingDir = fs.realpathSync.native(path.resolve(request.stagingDir));
376
376
  }
377
377
  catch (error) {
@@ -379,7 +379,7 @@ function validateRestoreStaging(request, repoRoot, taskId) {
379
379
  }
380
380
  const relative = path.relative(workspace, stagingDir);
381
381
  if (!relative || relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative) || path.basename(stagingDir) === taskId) {
382
- return { code: 'LIFECYCLE_STAGING_INVALID', message: 'restore staging must be a non-final directory inside .agents/workspace' };
382
+ return { code: 'LIFECYCLE_STAGING_INVALID', message: 'restore staging must be a non-final directory inside the project task workspace' };
383
383
  }
384
384
  let entries;
385
385
  try {
@@ -594,7 +594,7 @@ export function inspectTaskLifecycleProgress(repoRoot, taskId, agent) {
594
594
  return 'unknown';
595
595
  }
596
596
  }
597
- function applyTaskLifecycleUnlocked(requestInput, options = {}) {
597
+ function applyTaskLifecycle(requestInput, options = {}) {
598
598
  if (requestInput.intent === 'recover-started') {
599
599
  return failed(requestInput, { code: 'LIFECYCLE_RECOVERY_REQUIRES_AUTHORITY', message: 'recover-started must be dispatched through task control authority' });
600
600
  }
@@ -649,7 +649,7 @@ function applyTaskLifecycleUnlocked(requestInput, options = {}) {
649
649
  else {
650
650
  return failed(request, { code: 'LIFECYCLE_TASK_NOT_FOUND', message: `task ${taskId} has no lifecycle source` }, { taskId });
651
651
  }
652
- const targetPath = path.join(repoRoot, '.agents', 'workspace', spec.target, taskId);
652
+ const targetPath = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), spec.target, taskId);
653
653
  const requiredSteps = stepsForIntent(request.intent);
654
654
  const movingTaskDirectory = sourcePath !== targetPath;
655
655
  const currentTaskFile = path.join(sourcePath, 'task.md');
@@ -695,7 +695,7 @@ function applyTaskLifecycleUnlocked(requestInput, options = {}) {
695
695
  return failed(request, { code: 'LIFECYCLE_DOCUMENT_INVALID', message: contract.message }, { taskId, sourceState, targetState: spec.target, sourcePath, targetPath });
696
696
  }
697
697
  const registryRequest = executeShortIdCommand({
698
- operation: 'list', activeDir: path.join(repoRoot, '.agents', 'workspace', 'active'),
698
+ operation: 'list', activeDir: path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active'),
699
699
  shortIdLength: configuredShortIdLength(repoRoot)
700
700
  });
701
701
  if (registryRequest.status === 'failed') {
@@ -905,7 +905,7 @@ function applyTaskLifecycleUnlocked(requestInput, options = {}) {
905
905
  }
906
906
  }
907
907
  }
908
- const activeTaskPath = path.join(repoRoot, '.agents', 'workspace', 'active', taskId);
908
+ const activeTaskPath = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active', taskId);
909
909
  if (request.intent === 'complete' && fs.existsSync(activeTaskPath)) {
910
910
  try {
911
911
  let sourceIsVirtiofsMount = false;
@@ -967,44 +967,5 @@ function applyTaskLifecycleUnlocked(requestInput, options = {}) {
967
967
  journalPath, completedSteps: [...completed], pendingSteps: []
968
968
  };
969
969
  }
970
- function applyTaskLifecycle(request, options = {}) {
971
- const normalized = normalizedRequest(request);
972
- if ('code' in normalized)
973
- return applyTaskLifecycleUnlocked(request, options);
974
- const repoRoot = path.resolve(options.repoRoot ?? process.cwd());
975
- const taskId = normalized.intent === 'restore'
976
- ? normalized.taskRef
977
- : (() => {
978
- const resolved = resolveTaskRef(normalized.taskRef, { repoRoot });
979
- return resolved.ok ? resolved.taskId : null;
980
- })();
981
- if (!taskId)
982
- return applyTaskLifecycleUnlocked(request, options);
983
- try {
984
- return withTaskExecutionLock(repoRoot, taskId, 'task-lifecycle.move', () => applyTaskLifecycleUnlocked(request, options));
985
- }
986
- catch (error) {
987
- if (error instanceof TaskExecutionLockError) {
988
- return failed(request, { code: error.code, message: error.message }, { taskId });
989
- }
990
- throw error;
991
- }
992
- }
993
- function applyTaskLifecycleWithinTaskLock(request, options, lockedTaskId) {
994
- const normalized = normalizedRequest(request);
995
- if ('code' in normalized)
996
- return failed(request, normalized);
997
- const repoRoot = path.resolve(options.repoRoot ?? process.cwd());
998
- const resolved = normalized.intent === 'restore'
999
- ? { ok: true, taskId: normalized.taskRef }
1000
- : resolveTaskRef(normalized.taskRef, { repoRoot });
1001
- if (!resolved.ok || resolved.taskId !== lockedTaskId) {
1002
- return failed(request, {
1003
- code: 'LIFECYCLE_LOCK_SCOPE_MISMATCH',
1004
- message: 'task lifecycle request does not match the held task lock'
1005
- }, { taskId: resolved.ok ? resolved.taskId : resolved.taskId });
1006
- }
1007
- return applyTaskLifecycleUnlocked(request, options);
1008
- }
1009
- export { lifecycleIntentCatalog, lifecycleFailureCatalog, lifecycleProducerCatalog, applyTaskLifecycle, applyTaskLifecycleWithinTaskLock, previewTaskCompletion };
970
+ export { lifecycleIntentCatalog, lifecycleFailureCatalog, lifecycleProducerCatalog, applyTaskLifecycle, previewTaskCompletion };
1010
971
  //# sourceMappingURL=lifecycle.js.map
@@ -110,8 +110,7 @@ function prepareLocalArtifact(request, candidate) {
110
110
  return {
111
111
  result: validation.ok && !qualificationError ? { ...result, status: 'passed', error: null } : result,
112
112
  content,
113
- repoRoot: resolved.repoRoot,
114
- lockAlreadyHeld: request.lockAlreadyHeld
113
+ repoRoot: resolved.repoRoot
115
114
  };
116
115
  }
117
116
  function commitLocalArtifactProvenance(prepared) {