@fitlab-ai/agent-infra 0.11.15 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) 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 +8 -16
  10. package/dist/lib/internal/platform-comment.js +3 -2
  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/pr-summary.js +6 -15
  23. package/dist/lib/platform/pull-requests.js +3 -15
  24. package/dist/lib/pr-review/evidence-grading.js +3 -2
  25. package/dist/lib/process-data/index.js +5 -4
  26. package/dist/lib/process-data/sources.js +6 -0
  27. package/dist/lib/run/index.js +3 -2
  28. package/dist/lib/sandbox/commands/create.js +5 -1
  29. package/dist/lib/sandbox/commands/enter.js +1 -1
  30. package/dist/lib/sandbox/commands/list-running.js +2 -1
  31. package/dist/lib/sandbox/control/client.js +8 -13
  32. package/dist/lib/sandbox/control/completed-reentry.js +2 -1
  33. package/dist/lib/sandbox/control/task-view.js +4 -2
  34. package/dist/lib/sandbox/mounts.js +4 -4
  35. package/dist/lib/sandbox/recovery.js +26 -16
  36. package/dist/lib/sandbox/removal.js +3 -10
  37. package/dist/lib/sandbox/task-resolver.js +9 -6
  38. package/dist/lib/sandbox/workspace-identity.js +6 -5
  39. package/dist/lib/sandbox/workspace-view.js +29 -22
  40. package/dist/lib/task/activity-intent.js +2 -12
  41. package/dist/lib/task/artifact-lifecycle.js +17 -11
  42. package/dist/lib/task/artifact-operations.js +41 -49
  43. package/dist/lib/task/capabilities.js +2 -2
  44. package/dist/lib/task/commands/ls.js +4 -3
  45. package/dist/lib/task/commands/status.js +1 -1
  46. package/dist/lib/task/commit-operation.js +6 -6
  47. package/dist/lib/task/control-authority.js +32 -32
  48. package/dist/lib/task/create-service.js +2 -4
  49. package/dist/lib/task/create.js +12 -65
  50. package/dist/lib/task/delegation-receipts.js +1 -1
  51. package/dist/lib/task/delivery.js +2 -8
  52. package/dist/lib/task/events.js +5 -31
  53. package/dist/lib/task/finalization.js +17 -22
  54. package/dist/lib/task/lifecycle.js +9 -48
  55. package/dist/lib/task/local-artifact-finalization.js +1 -2
  56. package/dist/lib/task/orchestration.js +24 -57
  57. package/dist/lib/task/platform-operation-recovery.js +1 -2
  58. package/dist/lib/task/resolve-ref.js +17 -12
  59. package/dist/lib/task/review-finalization.js +2 -35
  60. package/dist/lib/task/review-identity.js +3 -1
  61. package/dist/lib/task/short-id.js +10 -8
  62. package/dist/lib/task/verification-engine.js +19 -58
  63. package/dist/lib/task/workspace-root.js +59 -0
  64. package/dist/lib/task/workspace-snapshot.js +4 -3
  65. package/dist/lifecycle-build-manifest.json +3 -3
  66. package/lib/agent-clients/adapters/codex-lifecycle/recovery.ts +6 -6
  67. package/lib/agent-clients/adapters/codex-lifecycle/store.ts +8 -34
  68. package/lib/agent-clients/adapters/codex-orchestration.ts +1 -1
  69. package/lib/decide.ts +2 -7
  70. package/lib/internal/cli-route-inventory.ts +2 -0
  71. package/lib/internal/manual-validation.ts +8 -19
  72. package/lib/internal/platform-comment.ts +3 -2
  73. package/lib/internal/task-activity.ts +1 -10
  74. package/lib/internal/task-event.ts +1 -10
  75. package/lib/internal/task-ledger.ts +1 -10
  76. package/lib/internal/task-operation-registry.ts +2 -1
  77. package/lib/internal/task-qualification.ts +5 -11
  78. package/lib/internal/task-review.ts +3 -14
  79. package/lib/internal/task-short-id.ts +2 -1
  80. package/lib/internal/task-verify.ts +1 -9
  81. package/lib/internal/task-warning.ts +1 -10
  82. package/lib/internal/task-workspace.ts +39 -0
  83. package/lib/merge.ts +4 -3
  84. package/lib/platform/pr-summary.ts +7 -16
  85. package/lib/platform/pull-requests.ts +3 -24
  86. package/lib/pr-review/evidence-grading.ts +3 -2
  87. package/lib/process-data/index.ts +4 -3
  88. package/lib/process-data/sources.ts +6 -0
  89. package/lib/run/index.ts +3 -2
  90. package/lib/sandbox/commands/create.ts +5 -1
  91. package/lib/sandbox/commands/enter.ts +1 -1
  92. package/lib/sandbox/commands/list-running.ts +2 -1
  93. package/lib/sandbox/control/client.ts +7 -12
  94. package/lib/sandbox/control/completed-reentry.ts +2 -1
  95. package/lib/sandbox/control/task-view.ts +4 -2
  96. package/lib/sandbox/mounts.ts +4 -4
  97. package/lib/sandbox/recovery.ts +26 -18
  98. package/lib/sandbox/removal.ts +3 -26
  99. package/lib/sandbox/task-resolver.ts +9 -6
  100. package/lib/sandbox/workspace-identity.ts +6 -5
  101. package/lib/sandbox/workspace-view.ts +28 -20
  102. package/lib/task/activity-intent.ts +3 -17
  103. package/lib/task/artifact-lifecycle.ts +39 -11
  104. package/lib/task/artifact-operations.ts +28 -35
  105. package/lib/task/capabilities.ts +2 -2
  106. package/lib/task/commands/ls.ts +4 -3
  107. package/lib/task/commands/status.ts +1 -1
  108. package/lib/task/commit-operation.ts +5 -6
  109. package/lib/task/control-authority.ts +29 -35
  110. package/lib/task/create-service.ts +2 -4
  111. package/lib/task/create.ts +10 -51
  112. package/lib/task/delegation-receipts.ts +1 -1
  113. package/lib/task/delivery.ts +2 -10
  114. package/lib/task/events.ts +5 -32
  115. package/lib/task/finalization.ts +16 -24
  116. package/lib/task/lifecycle.ts +9 -50
  117. package/lib/task/local-artifact-finalization.ts +1 -4
  118. package/lib/task/orchestration.ts +31 -80
  119. package/lib/task/platform-operation-recovery.ts +1 -2
  120. package/lib/task/resolve-ref.ts +18 -12
  121. package/lib/task/review-finalization.ts +2 -52
  122. package/lib/task/review-identity.ts +3 -1
  123. package/lib/task/short-id.ts +10 -8
  124. package/lib/task/verification-engine.ts +20 -62
  125. package/lib/task/workspace-root.ts +78 -0
  126. package/lib/task/workspace-snapshot.ts +4 -3
  127. package/package.json +1 -1
  128. package/templates/.agents/QUICKSTART.en.md +19 -8
  129. package/templates/.agents/QUICKSTART.zh-CN.md +19 -8
  130. package/templates/.agents/README.en.md +10 -15
  131. package/templates/.agents/README.zh-CN.md +9 -13
  132. package/templates/.agents/rules/issue-sync.en.md +1 -1
  133. package/templates/.agents/rules/issue-sync.zh-CN.md +1 -1
  134. package/templates/.agents/rules/lifecycle-orchestration.en.md +1 -1
  135. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +1 -1
  136. package/templates/.agents/rules/next-step-output.en.md +2 -2
  137. package/templates/.agents/rules/next-step-output.zh-CN.md +2 -2
  138. package/templates/.agents/rules/pr-sync.en.md +1 -1
  139. package/templates/.agents/rules/pr-sync.zh-CN.md +1 -1
  140. package/templates/.agents/rules/release-commands.en.md +3 -0
  141. package/templates/.agents/rules/release-commands.zh-CN.md +3 -0
  142. package/templates/.agents/rules/task-management.en.md +0 -2
  143. package/templates/.agents/rules/task-management.zh-CN.md +0 -2
  144. package/templates/.agents/rules/task-short-id.en.md +2 -2
  145. package/templates/.agents/rules/task-short-id.zh-CN.md +2 -2
  146. package/templates/.agents/scripts/task-short-id.js +2 -8
  147. package/templates/.agents/skills/analyze-task/SKILL.en.md +6 -6
  148. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +6 -6
  149. package/templates/.agents/skills/analyze-task/config/verify.en.json +0 -1
  150. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +0 -1
  151. package/templates/.agents/skills/archive-tasks/SKILL.en.md +5 -5
  152. package/templates/.agents/skills/archive-tasks/SKILL.zh-CN.md +5 -5
  153. package/templates/.agents/skills/archive-tasks/scripts/archive-tasks.sh +10 -2
  154. package/templates/.agents/skills/block-task/SKILL.en.md +4 -4
  155. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +5 -5
  156. package/templates/.agents/skills/block-task/config/verify.json +0 -1
  157. package/templates/.agents/skills/cancel-task/SKILL.en.md +6 -6
  158. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +6 -6
  159. package/templates/.agents/skills/cancel-task/config/verify.json +0 -1
  160. package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
  161. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +3 -3
  162. package/templates/.agents/skills/code-task/config/verify.en.json +0 -1
  163. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +0 -1
  164. package/templates/.agents/skills/code-task/reference/output-template.en.md +1 -1
  165. package/templates/.agents/skills/code-task/reference/output-template.zh-CN.md +1 -1
  166. package/templates/.agents/skills/commit/SKILL.en.md +1 -1
  167. package/templates/.agents/skills/commit/SKILL.zh-CN.md +1 -1
  168. package/templates/.agents/skills/commit/config/verify.json +0 -1
  169. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +2 -2
  170. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +2 -2
  171. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
  172. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
  173. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +2 -2
  174. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +2 -2
  175. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +0 -1
  176. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +0 -1
  177. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +1 -1
  178. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +1 -1
  179. package/templates/.agents/skills/complete-task/SKILL.en.md +7 -7
  180. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +8 -8
  181. package/templates/.agents/skills/complete-task/config/verify.en.json +0 -1
  182. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +0 -1
  183. package/templates/.agents/skills/create-pr/SKILL.en.md +3 -3
  184. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +3 -3
  185. package/templates/.agents/skills/create-pr/config/verify.json +0 -1
  186. package/templates/.agents/skills/create-pr/reference/change-report.en.md +1 -1
  187. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +1 -1
  188. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +1 -1
  189. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +1 -1
  190. package/templates/.agents/skills/create-release-note/SKILL.en.md +2 -2
  191. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +2 -2
  192. package/templates/.agents/skills/create-task/SKILL.en.md +4 -4
  193. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +4 -4
  194. package/templates/.agents/skills/create-task/config/verify.json +0 -1
  195. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  196. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  197. package/templates/.agents/skills/import-codescan/config/verify.json +0 -1
  198. package/templates/.agents/skills/import-dependabot/SKILL.en.md +3 -3
  199. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +3 -3
  200. package/templates/.agents/skills/import-dependabot/config/verify.json +0 -1
  201. package/templates/.agents/skills/import-issue/SKILL.en.md +5 -5
  202. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +5 -5
  203. package/templates/.agents/skills/import-issue/config/verify.json +0 -1
  204. package/templates/.agents/skills/plan-task/SKILL.en.md +5 -5
  205. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +5 -5
  206. package/templates/.agents/skills/plan-task/config/verify.en.json +0 -1
  207. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +0 -1
  208. package/templates/.agents/skills/restore-task/SKILL.en.md +2 -2
  209. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +3 -3
  210. package/templates/.agents/skills/restore-task/config/verify.json +0 -1
  211. package/templates/.agents/skills/review-analysis/SKILL.en.md +1 -1
  212. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +2 -2
  213. package/templates/.agents/skills/review-analysis/config/verify.en.json +0 -1
  214. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +0 -1
  215. package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +5 -5
  216. package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +5 -5
  217. package/templates/.agents/skills/review-code/SKILL.en.md +2 -2
  218. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +2 -2
  219. package/templates/.agents/skills/review-code/reference/output-templates.en.md +4 -4
  220. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +4 -4
  221. package/templates/.agents/skills/review-plan/SKILL.en.md +1 -1
  222. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +2 -2
  223. package/templates/.agents/skills/review-plan/config/verify.en.json +0 -1
  224. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +0 -1
  225. package/templates/.agents/skills/review-plan/reference/output-templates.en.md +5 -5
  226. package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +5 -5
  227. package/templates/.agents/skills/review-pr/SKILL.en.md +2 -2
  228. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +2 -2
  229. package/templates/.agents/skills/review-pr/config/verify.en.json +0 -1
  230. package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +0 -1
  231. package/templates/.agents/skills/review-pr/reference/output-guidance.en.md +1 -1
  232. package/templates/.agents/skills/review-pr/reference/output-guidance.zh-CN.md +1 -1
  233. package/templates/.agents/skills/run-manual-validation/config/verify.en.json +0 -1
  234. package/templates/.agents/skills/run-manual-validation/config/verify.zh-CN.json +0 -1
  235. package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
  236. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
  237. package/templates/.agents/skills/test/SKILL.en.md +0 -3
  238. package/templates/.agents/skills/test/SKILL.zh-CN.md +0 -3
  239. package/templates/.agents/skills/test-integration/SKILL.en.md +0 -3
  240. package/templates/.agents/skills/test-integration/SKILL.zh-CN.md +0 -3
  241. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +13 -6
  242. package/templates/.agents/skills/upgrade-dependency/SKILL.en.md +0 -3
  243. package/templates/.agents/skills/upgrade-dependency/SKILL.zh-CN.md +0 -3
  244. package/templates/.agents/skills/watch-pr/SKILL.en.md +3 -3
  245. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +3 -3
  246. package/templates/.agents/skills/watch-pr/config/verify.json +0 -1
  247. package/templates/.agents/templates/handoff.en.md +1 -1
  248. package/templates/.agents/templates/handoff.zh-CN.md +1 -1
  249. package/templates/.agents/workflows/bug-fix.en.yaml +1 -1
  250. package/templates/.agents/workflows/feature-development.en.yaml +1 -1
  251. package/templates/.agents/workflows/refactoring.en.yaml +1 -1
  252. package/dist/lib/task/task-execution-lock.js +0 -250
  253. package/lib/task/task-execution-lock.ts +0 -320
@@ -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.0",
4
+ "sourceInputHash": "c0a3da802ab0d992591d4ddd191550627992e7f76fea444bab99f342bd59ec18",
5
+ "internalExecutableBuildHash": "536ccdede573b4204982cb184b9b0f5ad8c3f943f3d1e749b42ed05bbcca9ead"
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
 
@@ -4,7 +4,6 @@ import path from 'node:path';
4
4
  import { locateActivityLog, pairEntries } from '../task/activity-log.ts';
5
5
  import { resolveTaskRef } from '../task/resolve-ref.ts';
6
6
  import { applyTaskEvent } from '../task/events.ts';
7
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
8
7
  import { normalizeAgentToken } from '../agent-clients/tokens.ts';
9
8
  import { MANUAL_VALIDATION_RECEIPT_PLACEHOLDER, createManualValidationReceipt, manualValidationFinalSummaryDigest, manualValidationFinalSummaryProjectionMatches, readManualValidationReceipt, writeManualValidationReceiptAtomic } from '../task/manual-validation-receipt.ts';
10
9
  import { archiveManualValidationGeneration, createManualValidationTransaction, readManualValidationTransaction, retryManualValidationTransaction, summaryPreimageDigest, transitionManualValidationTransaction, validateManualValidationGenerationArchive, writeManualValidationTransactionAtomic } from '../task/manual-validation-transaction.ts';
@@ -91,20 +90,10 @@ async function executeManualValidationTransaction(taskRef: string, values: Recor
91
90
  if (!['pr_created', 'pr_reused', 'no_op'].includes(primaryResult)) return result('failed', { code: 'MANUAL_VALIDATION_TRANSACTION_ARGS_INVALID', message: '--result must be pr_created, pr_reused, or no_op' });
92
91
  const resolved = resolveTaskRef(taskRef, { repoRoot: cwd });
93
92
  if (!resolved.ok) return result('failed', { code: resolved.code, message: resolved.message });
94
- try {
95
- return await withTaskExecutionLock(
96
- resolved.repoRoot,
97
- resolved.taskId,
98
- `manual-validation:${taskRef}`,
99
- () => executeManualValidationTransactionLocked(taskRef, values, cwd, resolved, agent, primaryResult as 'pr_created' | 'pr_reused' | 'no_op', prepareOnly, options)
100
- );
101
- } catch (error) {
102
- if (error instanceof TaskExecutionLockError) return result('failed', { code: error.code, message: error.message });
103
- throw error;
104
- }
93
+ return executeManualValidationTransactionAtResolvedTask(taskRef, values, cwd, resolved, agent, primaryResult as 'pr_created' | 'pr_reused' | 'no_op', prepareOnly, options);
105
94
  }
106
95
 
107
- async function executeManualValidationTransactionLocked(
96
+ async function executeManualValidationTransactionAtResolvedTask(
108
97
  taskRef: string,
109
98
  values: Record<string, string>,
110
99
  cwd: string,
@@ -168,7 +157,7 @@ async function executeManualValidationTransactionLocked(
168
157
  let startedEventApplied = false;
169
158
  if (!transactionResult.ok) {
170
159
  transaction = createTransaction();
171
- const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transactionId, reasonCode: 'user-request', transactionId }, { lockAlreadyHeld: true, repoRoot: cwd });
160
+ const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transactionId, reasonCode: 'user-request', transactionId }, { repoRoot: cwd });
172
161
  if (started.status === 'failed') return result('failed', started.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation started event failed' });
173
162
  startedEventApplied = true;
174
163
  if (previousTransaction) {
@@ -186,7 +175,7 @@ async function executeManualValidationTransactionLocked(
186
175
  }
187
176
  }
188
177
  if (transaction.phase === 'prepared' && !startedEventApplied) {
189
- const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', transactionId: transaction.transactionId }, { lockAlreadyHeld: true, repoRoot: cwd });
178
+ const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', transactionId: transaction.transactionId }, { repoRoot: cwd });
190
179
  if (started.status === 'failed') return result('failed', started.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation started event failed' });
191
180
  }
192
181
  if (prepareOnly) return result('applied', null, { transaction, prepared: true, idempotent });
@@ -206,7 +195,7 @@ async function executeManualValidationTransactionLocked(
206
195
  if (transaction.phase === 'prepared') {
207
196
  const staged = await syncPullRequestSummary(taskRef, {
208
197
  cwd, client: options.client, agent, body: pendingBody, changeReportFile: path.resolve(cwd, values.changeReportFile!), primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', strict: true,
209
- manualValidation: { phase: 'pending', transactionId: transaction.transactionId }, lockAlreadyHeld: true
198
+ manualValidation: { phase: 'pending', transactionId: transaction.transactionId }
210
199
  });
211
200
  if (!['applied', 'no-op'].includes(staged.status)) transactionFailure(staged.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'pending summary staging failed' });
212
201
  transitionAndPersist('summary-staged');
@@ -242,7 +231,7 @@ async function executeManualValidationTransactionLocked(
242
231
  transitionAndPersist('receipt-committed', { committedReceipt: receipt.receiptDigest });
243
232
  }
244
233
  if (transaction.phase === 'receipt-committed' && !transaction.eventAppended) {
245
- const completed = applyTaskEvent({ taskRef, event: 'manual-validation.completed', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', artifact: values.artifact, summaryResult: 'human-confirmed validation and committed receipt', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha }, { lockAlreadyHeld: true, repoRoot: cwd });
234
+ const completed = applyTaskEvent({ taskRef, event: 'manual-validation.completed', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', artifact: values.artifact, summaryResult: 'human-confirmed validation and committed receipt', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha }, { repoRoot: cwd });
246
235
  if (completed.status === 'failed') transactionFailure(completed.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation completion event failed' });
247
236
  transitionAndPersist('receipt-committed', { eventAppended: true });
248
237
  }
@@ -251,7 +240,7 @@ async function executeManualValidationTransactionLocked(
251
240
  }
252
241
  const promoted = await syncPullRequestSummary(taskRef, {
253
242
  cwd, client: options.client, agent, body: manualSummaryBody(finalBodyWithoutReceipt, 'final'), changeReportFile: path.resolve(cwd, values.changeReportFile!), primaryResult, strict: true,
254
- manualValidation: { phase: 'final', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha, authority: 'coordinator' }, lockAlreadyHeld: true
243
+ manualValidation: { phase: 'final', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha, authority: 'coordinator' }
255
244
  });
256
245
  if (!['applied', 'no-op'].includes(promoted.status)) transactionFailure(promoted.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_RECOVERY_REQUIRED', message: 'final summary promotion failed' });
257
246
  const postWrite = await summaryCommentState(taskRef, { cwd, client: options.client });
@@ -264,7 +253,7 @@ async function executeManualValidationTransactionLocked(
264
253
  try {
265
254
  await syncPullRequestSummary(taskRef, {
266
255
  cwd, client: options.client, agent, body: pendingBody, changeReportFile: path.resolve(cwd, values.changeReportFile!), primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', strict: true,
267
- manualValidation: { phase: 'pending', transactionId: transaction.transactionId }, lockAlreadyHeld: true
256
+ manualValidation: { phase: 'pending', transactionId: transaction.transactionId }
268
257
  });
269
258
  } catch {
270
259
  // Preserve recovery-required when pending compensation cannot be confirmed.
@@ -1,5 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
+ import { resolveProjectTaskWorkspaceRoot } from '../task/workspace-root.ts';
3
4
  import { createHash, randomUUID } from 'node:crypto';
4
5
 
5
6
  import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.ts';
@@ -98,14 +99,14 @@ async function platformComment(args: string[] = []): Promise<void> {
98
99
  const unexpected = Object.keys(parsed.values).find((key) => !['issue', 'taskId', 'output', 'cwd'].includes(key));
99
100
  if (unexpected) { fail(`recover does not accept '--${unexpected}'`); return; }
100
101
  const outputPath = path.resolve(cwd, output);
101
- const workspaceDir = path.resolve(cwd, '.agents', 'workspace');
102
+ const workspaceDir = resolveProjectTaskWorkspaceRoot(cwd);
102
103
  const stagingDir = path.dirname(outputPath);
103
104
  const stagingParent = fs.existsSync(stagingDir) ? path.dirname(fs.realpathSync(stagingDir)) : '';
104
105
  const realWorkspace = fs.existsSync(workspaceDir) ? fs.realpathSync(workspaceDir) : '';
105
106
  if (path.basename(outputPath) !== 'task.md' || stagingParent !== realWorkspace
106
107
  || !path.basename(stagingDir).startsWith('.restore-staging-') || !fs.existsSync(stagingDir)
107
108
  || !fs.lstatSync(stagingDir).isDirectory() || fs.existsSync(outputPath)) {
108
- fail('recover output must be a new task.md inside an existing .agents/workspace/.restore-staging-* directory');
109
+ fail('recover output must be a new task.md inside an existing task-workspace/.restore-staging-* directory');
109
110
  return;
110
111
  }
111
112
  const listed = await listPlatformComments(issue, cwd);
@@ -7,7 +7,6 @@ import type {
7
7
  PrReviewInspectIntent
8
8
  } from '../task/activity-intent.ts';
9
9
  import { resolveTaskRef } from '../task/resolve-ref.ts';
10
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
11
10
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
12
11
 
13
12
  const USAGE = `Usage: agent-infra-internal task-activity <task-ref> pr-review-inspect
@@ -95,15 +94,7 @@ async function taskActivity(args: string[] = []): Promise<void> {
95
94
  }
96
95
  const resolved = resolveTaskRef(taskRef);
97
96
  if (!resolved.ok) { usageFailure(resolved.message); return; }
98
- let result;
99
- try {
100
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-activity.${kind}`, async () => applyPrReviewActivityIntent(values as PrReviewActivityIntent, { lockAlreadyHeld: true }));
101
- } catch (error) {
102
- if (!(error instanceof TaskExecutionLockError)) throw error;
103
- process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
104
- process.exitCode = 1;
105
- return;
106
- }
97
+ const result = await applyPrReviewActivityIntent(values as PrReviewActivityIntent);
107
98
  process.stdout.write(`${JSON.stringify(result)}\n`);
108
99
  if (result.status === 'failed') process.exitCode = 1;
109
100
  }
@@ -2,7 +2,6 @@ import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.t
2
2
  import { applyTaskEvent, eventCatalog } from '../task/events.ts';
3
3
  import type { TaskEventRequest, Verdict } from '../task/events.ts';
4
4
  import { resolveTaskRef } from '../task/resolve-ref.ts';
5
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
6
5
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
7
6
 
8
7
  const USAGE = `Usage: agent-infra-internal task-event <N | TASK-id> <event> --agent <agent> [event options] [--orchestrated] [--dry-run]
@@ -73,15 +72,7 @@ async function taskEvent(args: string[] = []): Promise<void> {
73
72
  process.exitCode = 1;
74
73
  return;
75
74
  }
76
- let result;
77
- try {
78
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-event.${request.event}`, async () => applyTaskEvent(request, { lockAlreadyHeld: true }));
79
- } catch (error) {
80
- if (!(error instanceof TaskExecutionLockError)) throw error;
81
- process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
82
- process.exitCode = 1;
83
- return;
84
- }
75
+ const result = await applyTaskEvent(request);
85
76
  process.stdout.write(`${JSON.stringify(result)}\n`);
86
77
  if (result.status === 'failed') process.exitCode = 1;
87
78
  }
@@ -4,7 +4,6 @@ import { applyLedgerIntent } from '../task/ledger-intents.ts';
4
4
  import type { LedgerIntent } from '../task/ledger-intents.ts';
5
5
  import { LEDGER_SECTION_MISSING_CODE, LEDGER_SECTION_MISSING_MESSAGE, isReviewStage, parseLedgerDocument, summarizeLedgerStage, validateLedgerRows } from '../task/ledger.ts';
6
6
  import { resolveTaskRef } from '../task/resolve-ref.ts';
7
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
8
7
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
9
8
 
10
9
  const USAGE = `Usage: agent-infra-internal task-ledger <task-ref> <intent> [intent flags] [--dry-run]\n\nIntents: finding-upsert, finding-respond, finding-review, decision-next-id, decision-upsert, rework-intent-upsert, rework-intent-rebuild, stage-status\n`;
@@ -116,15 +115,7 @@ async function taskLedger(args: string[] = []): Promise<void> {
116
115
  }
117
116
  const lockResolved = resolveTaskRef(taskRef);
118
117
  if (!lockResolved.ok) { usageFailure(lockResolved.message); return; }
119
- let result;
120
- try {
121
- result = await withTaskExecutionLock(lockResolved.repoRoot, lockResolved.taskId, `task-ledger.${kind}`, async () => applyLedgerIntent(values as LedgerIntent));
122
- } catch (error) {
123
- if (!(error instanceof TaskExecutionLockError)) throw error;
124
- process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
125
- process.exitCode = 1;
126
- return;
127
- }
118
+ const result = await applyLedgerIntent(values as LedgerIntent);
128
119
  process.stdout.write(`${JSON.stringify(result)}\n`);
129
120
  if (result.status === 'failed') process.exitCode = 1;
130
121
  }
@@ -112,6 +112,7 @@ function internalTaskRoutes(): TaskOperationDescriptor[] {
112
112
  descriptor('internal', 'platform-checks', 'resolve-run', 'conditional', 'diagnostic'),
113
113
  descriptor('internal', 'platform-checks', 'logs', 'conditional', 'diagnostic'),
114
114
  descriptor('internal', 'task-context', 'resolve', 'task-bound', 'diagnostic'),
115
+ descriptor('internal', 'task-workspace', 'resolve', 'non-task', 'diagnostic', 'none'),
115
116
  descriptor('internal', 'task-ledger', 'decision-next-id', 'task-bound', 'diagnostic'),
116
117
  descriptor('internal', 'task-ledger', 'stage-status', 'task-bound', 'diagnostic'),
117
118
  descriptor('internal', 'task-ledger', 'finding-upsert', 'task-bound', 'progress'),
@@ -214,7 +215,7 @@ export const INTERNAL_DISPATCHER_ROUTES = Object.freeze([
214
215
  'task-create', 'task-qualification', 'sandbox-control', 'agent-client', 'codex-lifecycle',
215
216
  'git-workflow', 'task-delivery', 'release-workflow', 'platform-release-notes', 'platform-security', 'platform-metadata', 'platform-context',
216
217
  'platform-comment', 'platform-issue', 'platform-pr', 'platform-pr-review', 'pr-review-grade',
217
- 'platform-checks', 'task-context', 'task-ledger', 'task-warning', 'task-activity', 'task-artifact',
218
+ 'platform-checks', 'task-context', 'task-workspace', 'task-ledger', 'task-warning', 'task-activity', 'task-artifact',
218
219
  'task-orchestration', 'task-review', 'task-event', 'task-lifecycle',
219
220
  'task-finalization', 'task-platform-recovery', 'task-short-id', 'task-snapshot', 'task-verify', 'task-validate', 'manual-validation'
220
221
  ]);
@@ -5,7 +5,6 @@ import type { QualificationConfirmationRequest } from '../task/qualification-con
5
5
  import { applyQualificationProposal } from '../task/qualification-intents.ts';
6
6
  import type { QualificationProposalRequest } from '../task/qualification-intents.ts';
7
7
  import { resolveTaskRef } from '../task/resolve-ref.ts';
8
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
9
8
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
10
9
 
11
10
  const USAGE = `Usage: agent-infra-internal task-qualification <task-ref> <proposal|confirm|supersede|revoke> --input <json-file> [--dry-run]\n`;
@@ -46,16 +45,11 @@ async function taskQualification(args: string[] = []): Promise<void> {
46
45
  if (!payload || typeof payload !== 'object' || Array.isArray(payload)) { fail('qualification input must be an object'); return; }
47
46
  const resolved = resolveTaskRef(taskRef);
48
47
  if (!resolved.ok) { fail(resolved.message, resolved.code); return; }
49
- try {
50
- const result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-qualification.${operation}`, () => operation === 'proposal'
51
- ? applyQualificationProposal({ ...(payload as Record<string, unknown>), taskRef: resolved.taskId, dryRun } as QualificationProposalRequest, { repoRoot: resolved.repoRoot })
52
- : applyQualificationConfirmation({ ...(payload as Record<string, unknown>), taskRef: resolved.taskId, operation, dryRun } as QualificationConfirmationRequest, { repoRoot: resolved.repoRoot }));
53
- process.stdout.write(`${JSON.stringify(result)}\n`);
54
- if (result.status === 'failed') process.exitCode = 1;
55
- } catch (error) {
56
- if (error instanceof TaskExecutionLockError) fail(`${error.code}: ${error.message}`, error.code);
57
- else throw error;
58
- }
48
+ const result = await (operation === 'proposal'
49
+ ? applyQualificationProposal({ ...(payload as Record<string, unknown>), taskRef: resolved.taskId, dryRun } as QualificationProposalRequest, { repoRoot: resolved.repoRoot })
50
+ : applyQualificationConfirmation({ ...(payload as Record<string, unknown>), taskRef: resolved.taskId, operation, dryRun } as QualificationConfirmationRequest, { repoRoot: resolved.repoRoot }));
51
+ process.stdout.write(`${JSON.stringify(result)}\n`);
52
+ if (result.status === 'failed') process.exitCode = 1;
59
53
  }
60
54
 
61
55
  export { taskQualification };
@@ -1,7 +1,6 @@
1
1
  import { parseReviewCommand } from '../task/review-command.ts';
2
2
  import { finalizeReviewSummary, preflightReviewSummary } from '../task/review-finalization.ts';
3
3
  import { resolveTaskRef } from '../task/resolve-ref.ts';
4
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
5
4
  import { ensureInternalHandlerRoute } from './cli-route-inventory.ts';
6
5
 
7
6
  const USAGE = 'Usage: agent-infra-internal task-review <task-ref> <preflight|finalize-summary> --stage <analysis|plan|code> --artifact <review-*.md> [--orchestrated] [--dry-run]\n';
@@ -30,19 +29,9 @@ async function taskReview(args: string[] = []): Promise<void> {
30
29
  const operation = args[1]!;
31
30
  const resolved = resolveTaskRef(args[0]!);
32
31
  if (!resolved.ok) { failUsage(resolved.message); return; }
33
- let result;
34
- try {
35
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-review.${operation}`, async () => {
36
- return operation === 'preflight'
37
- ? preflightReviewSummary({ taskRef: args[0]!, stage, artifact, orchestrated, dryRun }, { lockAlreadyHeld: true })
38
- : finalizeReviewSummary({ taskRef: args[0]!, stage, artifact, orchestrated, dryRun }, { lockAlreadyHeld: true });
39
- });
40
- } catch (error) {
41
- if (!(error instanceof TaskExecutionLockError)) throw error;
42
- process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
43
- process.exitCode = 1;
44
- return;
45
- }
32
+ const result = operation === 'preflight'
33
+ ? preflightReviewSummary({ taskRef: args[0]!, stage, artifact, orchestrated, dryRun })
34
+ : finalizeReviewSummary({ taskRef: args[0]!, stage, artifact, orchestrated, dryRun });
46
35
  process.stdout.write(`${JSON.stringify(result)}\n`);
47
36
  if (result.status === 'failed') process.exitCode = 1;
48
37
  }
@@ -1,6 +1,7 @@
1
1
  import path from 'node:path';
2
2
 
3
3
  import { detectRepoRoot } from '../task/resolve-ref.ts';
4
+ import { resolveProjectTaskWorkspaceRoot } from '../task/workspace-root.ts';
4
5
  import { configuredShortIdLength, executeShortIdCommand } from '../task/short-id.ts';
5
6
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
6
7
 
@@ -50,7 +51,7 @@ function taskShortId(args: string[] = []): void {
50
51
  if (positional.length > (operation === 'list' ? 0 : 1)) { failure('too many positional arguments'); return; }
51
52
  let repoRoot: string | null = null;
52
53
  try { repoRoot = detectRepoRoot(); } catch { /* custom active-dir mode */ }
53
- const resolvedActiveDir = activeDir ?? (repoRoot ? path.join(repoRoot, '.agents', 'workspace', 'active') : null);
54
+ const resolvedActiveDir = activeDir ?? (repoRoot ? path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active') : null);
54
55
  if (!resolvedActiveDir) { failure('cannot determine active task directory'); return; }
55
56
  const width = shortIdLength ?? (repoRoot ? configuredShortIdLength(repoRoot) : 2);
56
57
  const result = executeShortIdCommand({
@@ -1,6 +1,5 @@
1
1
  import { renderTaskVerification, verifyTaskEvent } from '../task/verification.ts';
2
2
  import { resolveTaskRef } from '../task/resolve-ref.ts';
3
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
4
3
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
5
4
 
6
5
  const USAGE = 'Usage: agent-infra-internal task-verify <N | TASK-id> <verification-event> [--artifact <canonical.md>] [--format json|text]\n';
@@ -34,14 +33,7 @@ async function taskVerify(args: string[] = []): Promise<void> {
34
33
  }
35
34
  const resolved = resolveTaskRef(taskRef);
36
35
  if (!resolved.ok) { fail(resolved.message); return; }
37
- let result;
38
- try {
39
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-verify.${event}`, async () => verifyTaskEvent({ taskRef, event, ...(artifact ? { artifact } : {}) }));
40
- } catch (error) {
41
- if (!(error instanceof TaskExecutionLockError)) throw error;
42
- fail(`${error.code}: ${error.message}`);
43
- return;
44
- }
36
+ const result = await verifyTaskEvent({ taskRef, event, ...(artifact ? { artifact } : {}) });
45
37
  process.stdout.write(format === 'text' ? renderTaskVerification(result) : `${JSON.stringify(result)}\n`);
46
38
  process.exitCode = result.status === 'pass' ? 0 : result.status === 'blocked' ? 2 : 1;
47
39
  }
@@ -1,7 +1,6 @@
1
1
  import { applyWorkflowWarningIntent } from '../task/workflow-warning-intents.ts';
2
2
  import type { WorkflowWarningIntent } from '../task/workflow-warning-intents.ts';
3
3
  import { resolveTaskRef } from '../task/resolve-ref.ts';
4
- import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
5
4
  import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
6
5
 
7
6
  const USAGE = `Usage: agent-infra-internal task-warning <task-ref> <add|set-status|list> [intent flags] [--dry-run]\n`;
@@ -52,15 +51,7 @@ async function taskWarning(args: string[] = []): Promise<void> {
52
51
  if (missing) { usageFailure(`${kind} requires '${missing}'`); return; }
53
52
  const resolved = resolveTaskRef(taskRef);
54
53
  if (!resolved.ok) { usageFailure(resolved.message); return; }
55
- let result;
56
- try {
57
- result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-warning.${kind}`, async () => applyWorkflowWarningIntent(values as WorkflowWarningIntent));
58
- } catch (error) {
59
- if (!(error instanceof TaskExecutionLockError)) throw error;
60
- process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
61
- process.exitCode = 1;
62
- return;
63
- }
54
+ const result = await applyWorkflowWarningIntent(values as WorkflowWarningIntent);
64
55
  process.stdout.write(`${JSON.stringify(result)}\n`);
65
56
  if (result.status === 'failed') process.exitCode = 1;
66
57
  }