@fitlab-ai/agent-infra 0.9.13 → 0.9.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/bin/cli.ts +26 -9
  2. package/dist/bin/cli.js +173 -157
  3. package/dist/bin/internal-cli.js +42 -21
  4. package/dist/lib/agent-client.js +5 -0
  5. package/dist/lib/internal/agent-client.js +5 -2
  6. package/dist/lib/internal/cli-route-inventory.js +152 -0
  7. package/dist/lib/internal/codex-lifecycle.js +9 -6
  8. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  9. package/dist/lib/internal/git-workflow.js +10 -6
  10. package/dist/lib/internal/platform-checks.js +16 -4
  11. package/dist/lib/internal/platform-comment.js +16 -4
  12. package/dist/lib/internal/platform-context.js +4 -1
  13. package/dist/lib/internal/platform-issue.js +12 -4
  14. package/dist/lib/internal/platform-metadata.js +88 -0
  15. package/dist/lib/internal/platform-pr-review.js +16 -3
  16. package/dist/lib/internal/platform-pr.js +24 -10
  17. package/dist/lib/internal/platform-release-notes.js +6 -3
  18. package/dist/lib/internal/platform-security.js +93 -0
  19. package/dist/lib/internal/pr-review-grade.js +14 -3
  20. package/dist/lib/internal/release-workflow.js +19 -5
  21. package/dist/lib/internal/sandbox-control.js +22 -5
  22. package/dist/lib/internal/task-activity.js +13 -4
  23. package/dist/lib/internal/task-artifact.js +186 -27
  24. package/dist/lib/internal/task-context.js +4 -1
  25. package/dist/lib/internal/task-create.js +48 -15
  26. package/dist/lib/internal/task-delivery.js +4 -1
  27. package/dist/lib/internal/task-event.js +4 -1
  28. package/dist/lib/internal/task-finalization.js +4 -1
  29. package/dist/lib/internal/task-invalidation.js +4 -1
  30. package/dist/lib/internal/task-ledger.js +12 -1
  31. package/dist/lib/internal/task-lifecycle.js +4 -1
  32. package/dist/lib/internal/task-operation-registry.js +421 -0
  33. package/dist/lib/internal/task-orchestration.js +12 -0
  34. package/dist/lib/internal/task-override.js +10 -3
  35. package/dist/lib/internal/task-qualification.js +90 -0
  36. package/dist/lib/internal/task-review.js +4 -1
  37. package/dist/lib/internal/task-short-id.js +11 -1
  38. package/dist/lib/internal/task-snapshot.js +4 -1
  39. package/dist/lib/internal/task-validate.js +7 -2
  40. package/dist/lib/internal/task-verify.js +5 -1
  41. package/dist/lib/internal/task-warning.js +8 -1
  42. package/dist/lib/platform/comment-safety.js +226 -0
  43. package/dist/lib/platform/github-provider.js +233 -6
  44. package/dist/lib/platform/issue-comments.js +146 -34
  45. package/dist/lib/platform/pr-change-report.js +6 -12
  46. package/dist/lib/platform/pr-summary.js +28 -7
  47. package/dist/lib/platform/provider-contract.d.ts +67 -1
  48. package/dist/lib/platform/provider-contract.js +6 -2
  49. package/dist/lib/platform/provider-validation.js +76 -3
  50. package/dist/lib/platform/pull-requests.js +115 -170
  51. package/dist/lib/platform/repository-metadata.js +377 -0
  52. package/dist/lib/platform/security-alerts.js +155 -0
  53. package/dist/lib/platform/verification-sync.js +33 -26
  54. package/dist/lib/process-data/index.js +7 -0
  55. package/dist/lib/run/index.js +5 -0
  56. package/dist/lib/sandbox/commands/control-status.js +22 -0
  57. package/dist/lib/sandbox/commands/create.js +32 -6
  58. package/dist/lib/sandbox/commands/ls.js +5 -0
  59. package/dist/lib/sandbox/commands/rm.js +827 -120
  60. package/dist/lib/sandbox/commands/show.js +16 -0
  61. package/dist/lib/sandbox/control/client.js +83 -9
  62. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  63. package/dist/lib/sandbox/control/container-identity.js +28 -31
  64. package/dist/lib/sandbox/control/executor.js +149 -14
  65. package/dist/lib/sandbox/control/lifecycle.js +621 -127
  66. package/dist/lib/sandbox/control/native-file-lock.js +177 -0
  67. package/dist/lib/sandbox/control/server.js +305 -35
  68. package/dist/lib/sandbox/control/state.js +5 -3
  69. package/dist/lib/sandbox/control/task-view.js +183 -0
  70. package/dist/lib/sandbox/engines/authority.js +289 -0
  71. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  72. package/dist/lib/sandbox/index.js +5 -0
  73. package/dist/lib/sandbox/recovery.js +21 -1
  74. package/dist/lib/sandbox/workspace-view.js +2 -1
  75. package/dist/lib/sandbox/worktree-safety.js +4 -1
  76. package/dist/lib/server/index.js +8 -0
  77. package/dist/lib/task/artifact-lifecycle.js +42 -13
  78. package/dist/lib/task/artifact-operations.js +520 -0
  79. package/dist/lib/task/artifact-repair-intent.js +59 -0
  80. package/dist/lib/task/artifact-schema.js +135 -0
  81. package/dist/lib/task/capabilities.js +72 -1
  82. package/dist/lib/task/control-authority.js +4 -0
  83. package/dist/lib/task/create-service.js +103 -4
  84. package/dist/lib/task/create.js +25 -0
  85. package/dist/lib/task/events.js +186 -67
  86. package/dist/lib/task/index.js +11 -3
  87. package/dist/lib/task/local-artifact-finalization.js +75 -150
  88. package/dist/lib/task/orchestration.js +192 -52
  89. package/dist/lib/task/qualification-audit.js +490 -0
  90. package/dist/lib/task/qualification-confirmation.js +109 -0
  91. package/dist/lib/task/qualification-intents.js +148 -0
  92. package/dist/lib/task/review-artifacts.js +22 -23
  93. package/dist/lib/task/review-finalization.js +121 -4
  94. package/dist/lib/task/sections.js +6 -4
  95. package/dist/lib/task/verification-config.js +11 -0
  96. package/dist/lib/task/verification-engine.js +54 -4
  97. package/dist/lifecycle-build-manifest.json +3 -3
  98. package/lib/agent-client.ts +9 -0
  99. package/lib/internal/agent-client.ts +4 -2
  100. package/lib/internal/cli-route-inventory.ts +140 -0
  101. package/lib/internal/codex-lifecycle.ts +8 -6
  102. package/lib/internal/codex-sandbox-controller.ts +7 -2
  103. package/lib/internal/git-workflow.ts +9 -6
  104. package/lib/internal/platform-checks.ts +12 -4
  105. package/lib/internal/platform-comment.ts +12 -4
  106. package/lib/internal/platform-context.ts +3 -1
  107. package/lib/internal/platform-issue.ts +11 -4
  108. package/lib/internal/platform-metadata.ts +70 -0
  109. package/lib/internal/platform-pr-review.ts +14 -3
  110. package/lib/internal/platform-pr.ts +23 -10
  111. package/lib/internal/platform-release-notes.ts +5 -3
  112. package/lib/internal/platform-security.ts +83 -0
  113. package/lib/internal/pr-review-grade.ts +10 -3
  114. package/lib/internal/release-workflow.ts +17 -5
  115. package/lib/internal/sandbox-control.ts +19 -5
  116. package/lib/internal/task-activity.ts +12 -4
  117. package/lib/internal/task-artifact.ts +164 -25
  118. package/lib/internal/task-context.ts +3 -1
  119. package/lib/internal/task-create.ts +76 -15
  120. package/lib/internal/task-delivery.ts +3 -1
  121. package/lib/internal/task-event.ts +3 -1
  122. package/lib/internal/task-finalization.ts +3 -1
  123. package/lib/internal/task-invalidation.ts +3 -1
  124. package/lib/internal/task-ledger.ts +11 -1
  125. package/lib/internal/task-lifecycle.ts +3 -1
  126. package/lib/internal/task-operation-registry.ts +482 -0
  127. package/lib/internal/task-orchestration.ts +12 -0
  128. package/lib/internal/task-override.ts +9 -3
  129. package/lib/internal/task-qualification.ts +61 -0
  130. package/lib/internal/task-review.ts +3 -1
  131. package/lib/internal/task-short-id.ts +10 -1
  132. package/lib/internal/task-snapshot.ts +3 -1
  133. package/lib/internal/task-validate.ts +6 -2
  134. package/lib/internal/task-verify.ts +4 -1
  135. package/lib/internal/task-warning.ts +7 -1
  136. package/lib/platform/comment-safety.ts +250 -0
  137. package/lib/platform/github-provider.ts +229 -7
  138. package/lib/platform/issue-comments.ts +160 -35
  139. package/lib/platform/pr-change-report.ts +6 -12
  140. package/lib/platform/pr-summary.ts +27 -6
  141. package/lib/platform/provider-contract.ts +78 -3
  142. package/lib/platform/provider-validation.ts +85 -3
  143. package/lib/platform/pull-requests.ts +126 -178
  144. package/lib/platform/repository-metadata.ts +453 -0
  145. package/lib/platform/security-alerts.ts +191 -0
  146. package/lib/platform/verification-sync.ts +32 -28
  147. package/lib/process-data/index.ts +7 -0
  148. package/lib/run/index.ts +5 -0
  149. package/lib/sandbox/commands/control-status.ts +26 -0
  150. package/lib/sandbox/commands/create.ts +46 -6
  151. package/lib/sandbox/commands/ls.ts +7 -0
  152. package/lib/sandbox/commands/rm.ts +1000 -87
  153. package/lib/sandbox/commands/show.ts +16 -0
  154. package/lib/sandbox/control/client.ts +103 -9
  155. package/lib/sandbox/control/completed-reentry.ts +98 -0
  156. package/lib/sandbox/control/container-identity.ts +27 -43
  157. package/lib/sandbox/control/executor.ts +177 -12
  158. package/lib/sandbox/control/lifecycle.ts +629 -17
  159. package/lib/sandbox/control/native-file-lock.ts +209 -0
  160. package/lib/sandbox/control/protocol.ts +5 -2
  161. package/lib/sandbox/control/server.ts +319 -37
  162. package/lib/sandbox/control/state.ts +6 -3
  163. package/lib/sandbox/control/task-view.ts +240 -0
  164. package/lib/sandbox/engines/authority.ts +365 -0
  165. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  166. package/lib/sandbox/index.ts +7 -0
  167. package/lib/sandbox/recovery.ts +21 -1
  168. package/lib/sandbox/workspace-view.ts +9 -3
  169. package/lib/sandbox/worktree-safety.ts +4 -1
  170. package/lib/server/index.ts +10 -0
  171. package/lib/task/artifact-lifecycle.ts +38 -16
  172. package/lib/task/artifact-operations.ts +626 -0
  173. package/lib/task/artifact-repair-intent.ts +71 -0
  174. package/lib/task/artifact-schema.ts +192 -0
  175. package/lib/task/capabilities.ts +70 -1
  176. package/lib/task/control-authority.ts +11 -1
  177. package/lib/task/create-service.ts +131 -6
  178. package/lib/task/create.ts +27 -0
  179. package/lib/task/events.ts +161 -65
  180. package/lib/task/index.ts +16 -3
  181. package/lib/task/local-artifact-finalization.ts +87 -218
  182. package/lib/task/orchestration.ts +172 -49
  183. package/lib/task/qualification-audit.ts +599 -0
  184. package/lib/task/qualification-confirmation.ts +117 -0
  185. package/lib/task/qualification-intents.ts +150 -0
  186. package/lib/task/review-artifacts.ts +21 -22
  187. package/lib/task/review-finalization.ts +133 -4
  188. package/lib/task/sections.ts +6 -4
  189. package/lib/task/verification-config.ts +12 -0
  190. package/lib/task/verification-engine.ts +55 -4
  191. package/package.json +6 -1
  192. package/templates/.agents/rules/README.en.md +2 -0
  193. package/templates/.agents/rules/README.zh-CN.md +2 -0
  194. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  195. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  196. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  197. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  198. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  199. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  200. package/templates/.agents/rules/local-artifact-repair.en.md +5 -1
  201. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +5 -1
  202. package/templates/.agents/rules/security-alerts.en.md +8 -8
  203. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  204. package/templates/.agents/skills/analyze-task/SKILL.en.md +15 -2
  205. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +19 -2
  206. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  207. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  208. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  209. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  210. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  211. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  212. package/templates/.agents/skills/code-task/SKILL.en.md +14 -1
  213. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +14 -1
  214. package/templates/.agents/skills/code-task/config/verify.en.json +5 -14
  215. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +5 -14
  216. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  217. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  218. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  219. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  220. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  221. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  222. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  223. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  224. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +5 -1
  225. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +5 -1
  226. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
  227. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
  228. package/templates/.agents/skills/complete-task/SKILL.en.md +9 -22
  229. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +9 -22
  230. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  231. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  232. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  233. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  234. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  235. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  236. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  237. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  238. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  239. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  240. package/templates/.agents/skills/plan-task/SKILL.en.md +14 -1
  241. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +16 -1
  242. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  243. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  244. package/templates/.agents/skills/review-analysis/SKILL.en.md +14 -1
  245. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -1
  246. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  247. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  248. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  249. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  250. package/templates/.agents/skills/review-code/SKILL.en.md +14 -1
  251. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +14 -1
  252. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  253. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  254. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  255. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  256. package/templates/.agents/skills/review-plan/SKILL.en.md +14 -1
  257. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -1
  258. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  259. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  260. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  261. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  262. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  263. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  264. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  265. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  266. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +5 -1
  267. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +5 -1
  268. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +3 -1
  269. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +3 -1
  270. package/templates/.agents/skills/test/SKILL.en.md +13 -2
  271. package/templates/.agents/skills/test/SKILL.zh-CN.md +13 -2
  272. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  273. package/templates/.agents/templates/task.en.md +6 -0
  274. package/templates/.agents/templates/task.zh-CN.md +6 -0
  275. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  276. package/templates/.agents/scripts/security-alerts.sh +0 -31
  277. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  278. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  279. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  280. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { randomUUID } from 'node:crypto';
3
+ import { createHash, randomUUID } from 'node:crypto';
4
4
  import { parseTypedTaskFrontmatter } from './frontmatter.js';
5
5
  import { validateCurrentTaskContract } from './current-contract.js';
6
6
  import { parseReviewSummary } from './review-artifacts.js';
@@ -33,10 +33,12 @@ const ORCHESTRATION_STATE_INVALID_MESSAGE = 'orchestration.json does not match t
33
33
  class OrchestrationStateError extends Error {
34
34
  code = 'ORCHESTRATION_STATE_INVALID';
35
35
  taskId;
36
- constructor(taskId = null) {
36
+ reasonCodes;
37
+ constructor(taskId = null, reasonCodes = []) {
37
38
  super(ORCHESTRATION_STATE_INVALID_MESSAGE);
38
39
  this.name = 'OrchestrationStateError';
39
40
  this.taskId = taskId;
41
+ this.reasonCodes = Object.freeze([...reasonCodes]);
40
42
  }
41
43
  }
42
44
  function isRecord(value) {
@@ -117,48 +119,151 @@ const ORCHESTRATION_RUN_KEYS = [
117
119
  'modelPolicySource', 'recoveryHistory', 'baseline', 'pendingDelegation', 'receipts',
118
120
  'pause', 'commitAuthorization', 'completionEvidence', 'createdAt', 'updatedAt'
119
121
  ];
120
- function parseOrchestrationRun(value, expectedTaskId) {
121
- if (!hasExactKeys(value, ORCHESTRATION_RUN_KEYS)
122
- || !exactText(value.taskId)
123
- || (expectedTaskId !== undefined && value.taskId !== expectedTaskId)
124
- || !exactText(value.runId)
125
- || !['running', 'paused', 'completed'].includes(value.status)
126
- || !(value.nextStage === null || ['analysis', 'review-analysis', 'plan', 'review-plan', 'code', 'review-code', 'commit'].includes(value.nextStage))
127
- || !Number.isSafeInteger(value.stepCount) || value.stepCount < 0
128
- || !Number.isSafeInteger(value.maxSteps) || value.maxSteps < 1
129
- || !isModelPolicy(value.modelPolicy)
130
- || !isModelPolicySource(value.modelPolicySource)
131
- || !Array.isArray(value.recoveryHistory) || !value.recoveryHistory.every(isRecovery)
132
- || typeof value.baseline !== 'string'
133
- || !(value.pendingDelegation === null || isDelegationReceipt(value.pendingDelegation))
134
- || !Array.isArray(value.receipts) || !value.receipts.every(isDelegationReceipt)
135
- || !(value.pause === null || isPause(value.pause))
136
- || !hasExactKeys(value.commitAuthorization, ['issuedAt', 'consumedAt'])
137
- || !nullableText(value.commitAuthorization.issuedAt)
138
- || !nullableText(value.commitAuthorization.consumedAt)
139
- || !(value.completionEvidence === null || isCompletionEvidence(value.completionEvidence))
140
- || !exactText(value.createdAt)
141
- || !exactText(value.updatedAt)) {
142
- throw new OrchestrationStateError();
143
- }
144
- const receipts = [...value.receipts, ...(value.pendingDelegation ? [value.pendingDelegation] : [])];
145
- if (receipts.some((receipt) => receipt.taskId !== value.taskId || receipt.runId !== value.runId)) {
146
- throw new OrchestrationStateError();
122
+ function orchestrationStateReasonCodes(value, expectedTaskId) {
123
+ if (!hasExactKeys(value, ORCHESTRATION_RUN_KEYS))
124
+ return ['top-level-keys'];
125
+ const record = value;
126
+ const reasons = [];
127
+ if (!exactText(record.taskId))
128
+ reasons.push('taskId');
129
+ else if (expectedTaskId !== undefined && record.taskId !== expectedTaskId)
130
+ reasons.push('taskId-mismatch');
131
+ if (!exactText(record.runId))
132
+ reasons.push('runId');
133
+ if (!['running', 'paused', 'completed'].includes(record.status))
134
+ reasons.push('status');
135
+ if (!(record.nextStage === null || ['analysis', 'review-analysis', 'plan', 'review-plan', 'code', 'review-code', 'commit'].includes(record.nextStage))) {
136
+ reasons.push('nextStage');
137
+ }
138
+ if (!Number.isSafeInteger(record.stepCount) || record.stepCount < 0)
139
+ reasons.push('stepCount');
140
+ if (!Number.isSafeInteger(record.maxSteps) || record.maxSteps < 1)
141
+ reasons.push('maxSteps');
142
+ if (!isModelPolicy(record.modelPolicy))
143
+ reasons.push('modelPolicy');
144
+ if (!isModelPolicySource(record.modelPolicySource))
145
+ reasons.push('modelPolicySource');
146
+ if (!Array.isArray(record.recoveryHistory) || !record.recoveryHistory.every(isRecovery))
147
+ reasons.push('recoveryHistory');
148
+ if (typeof record.baseline !== 'string')
149
+ reasons.push('baseline');
150
+ if (!(record.pendingDelegation === null || isDelegationReceipt(record.pendingDelegation)))
151
+ reasons.push('pendingDelegation');
152
+ if (!Array.isArray(record.receipts) || !record.receipts.every(isDelegationReceipt))
153
+ reasons.push('receipts');
154
+ if (!(record.pause === null || isPause(record.pause)))
155
+ reasons.push('pause');
156
+ if (!hasExactKeys(record.commitAuthorization, ['issuedAt', 'consumedAt'])) {
157
+ reasons.push('commitAuthorization');
158
+ }
159
+ else {
160
+ if (!nullableText(record.commitAuthorization.issuedAt))
161
+ reasons.push('commitAuthorization.issuedAt');
162
+ if (!nullableText(record.commitAuthorization.consumedAt))
163
+ reasons.push('commitAuthorization.consumedAt');
164
+ }
165
+ if (!(record.completionEvidence === null || isCompletionEvidence(record.completionEvidence)))
166
+ reasons.push('completionEvidence');
167
+ if (!exactText(record.createdAt))
168
+ reasons.push('createdAt');
169
+ if (!exactText(record.updatedAt))
170
+ reasons.push('updatedAt');
171
+ if (Array.isArray(record.receipts) && record.receipts.every(isDelegationReceipt)
172
+ && (record.pendingDelegation === null || isDelegationReceipt(record.pendingDelegation))) {
173
+ const receipts = [...record.receipts, ...(record.pendingDelegation ? [record.pendingDelegation] : [])];
174
+ if (receipts.some((receipt) => receipt.taskId !== record.taskId || receipt.runId !== record.runId)) {
175
+ reasons.push('receipt-identity');
176
+ }
177
+ }
178
+ return reasons;
179
+ }
180
+ function emitDiagnostic(options, event, fields) {
181
+ try {
182
+ options?.diagnosticLog?.(event, fields);
183
+ }
184
+ catch {
185
+ // Diagnostics must never change lifecycle behavior.
186
+ }
187
+ }
188
+ function fileObservation(file) {
189
+ try {
190
+ const stat = fs.lstatSync(file);
191
+ let realpath = null;
192
+ try {
193
+ realpath = fs.realpathSync.native(file);
194
+ }
195
+ catch { /* retain the lstat observation */ }
196
+ return {
197
+ file,
198
+ exists: true,
199
+ fileType: stat.isFile() ? 'file' : stat.isDirectory() ? 'directory' : 'other',
200
+ symbolicLink: stat.isSymbolicLink(),
201
+ bytes: stat.isFile() ? stat.size : null,
202
+ mtimeMs: stat.mtimeMs,
203
+ device: stat.dev,
204
+ inode: stat.ino,
205
+ realpath
206
+ };
207
+ }
208
+ catch (error) {
209
+ return {
210
+ file,
211
+ exists: false,
212
+ fileType: null,
213
+ symbolicLink: null,
214
+ bytes: null,
215
+ mtimeMs: null,
216
+ device: null,
217
+ inode: null,
218
+ realpath: null,
219
+ fsError: error instanceof Error && 'code' in error ? String(error.code) : null
220
+ };
147
221
  }
222
+ }
223
+ function parseOrchestrationRun(value, expectedTaskId) {
224
+ const reasonCodes = orchestrationStateReasonCodes(value, expectedTaskId);
225
+ if (reasonCodes.length > 0)
226
+ throw new OrchestrationStateError(expectedTaskId ?? null, reasonCodes);
148
227
  return value;
149
228
  }
150
- function readRun(taskDir) {
229
+ function readRun(taskDir, options = {}) {
151
230
  const file = orchestrationPath(taskDir);
152
- if (!fs.existsSync(file))
153
- return null;
154
231
  const taskId = path.basename(taskDir);
232
+ const observed = options.diagnosticLog ? fileObservation(file) : {};
233
+ if (!fs.existsSync(file)) {
234
+ emitDiagnostic(options, 'orchestration-state-missing', { taskId, taskDir, ...observed });
235
+ return null;
236
+ }
237
+ emitDiagnostic(options, 'orchestration-state-read-start', { taskId, taskDir, ...observed });
238
+ let rawBytes = null;
239
+ let rawSha256 = null;
155
240
  try {
156
- return parseOrchestrationRun(JSON.parse(fs.readFileSync(file, 'utf8')), taskId);
241
+ const raw = fs.readFileSync(file, 'utf8');
242
+ if (options.diagnosticLog) {
243
+ rawBytes = Buffer.byteLength(raw, 'utf8');
244
+ rawSha256 = createHash('sha256').update(raw, 'utf8').digest('hex');
245
+ }
246
+ const run = parseOrchestrationRun(JSON.parse(raw), taskId);
247
+ emitDiagnostic(options, 'orchestration-state-read-ok', {
248
+ taskId, taskDir, file, rawBytes, rawSha256, status: run.status, runId: run.runId,
249
+ stepCount: run.stepCount, pendingDelegation: run.pendingDelegation !== null
250
+ });
251
+ return run;
157
252
  }
158
253
  catch (error) {
159
- if (error instanceof OrchestrationStateError)
160
- throw new OrchestrationStateError(taskId);
161
- throw new OrchestrationStateError(taskId);
254
+ const reasonCodes = error instanceof OrchestrationStateError && error.reasonCodes.length > 0
255
+ ? error.reasonCodes
256
+ : [error instanceof SyntaxError ? 'json-parse' : 'file-read'];
257
+ emitDiagnostic(options, 'orchestration-state-read-failed', {
258
+ taskId,
259
+ taskDir,
260
+ ...observed,
261
+ rawBytes,
262
+ rawSha256,
263
+ reasonCodes: reasonCodes.join(','),
264
+ errorType: error instanceof Error ? error.name : typeof error,
265
+ });
266
+ throw new OrchestrationStateError(taskId, reasonCodes);
162
267
  }
163
268
  }
164
269
  function atomicWrite(file, value) {
@@ -232,7 +337,7 @@ function beginOrResumeOrchestration(taskRef, options = {}) {
232
337
  }
233
338
  let existing;
234
339
  try {
235
- existing = readRun(resolved.taskDir);
340
+ existing = readRun(resolved.taskDir, options);
236
341
  }
237
342
  catch (error) {
238
343
  return failed('ORCHESTRATION_STATE_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId);
@@ -437,7 +542,7 @@ function routeOrchestration(taskRef, options = {}) {
437
542
  }
438
543
  let run;
439
544
  try {
440
- run = readRun(resolved.taskDir);
545
+ run = readRun(resolved.taskDir, options);
441
546
  }
442
547
  catch (error) {
443
548
  return failed('ORCHESTRATION_STATE_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId);
@@ -543,7 +648,7 @@ function statusOrchestration(taskRef, options = {}) {
543
648
  const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
544
649
  if (!resolved.ok)
545
650
  return failed(resolved.code, resolved.message, resolved.taskId);
546
- const run = readRun(resolved.taskDir);
651
+ const run = readRun(resolved.taskDir, options);
547
652
  if (!run)
548
653
  return failed('ORCHESTRATION_RUN_MISSING', 'no orchestration run exists', resolved.taskId);
549
654
  return { status: run.status, changed: false, taskId: resolved.taskId, run, next: null, error: null };
@@ -555,7 +660,15 @@ function prepareOrchestrationDelegationUnlocked(taskRef, input, options = {}) {
555
660
  if (!(options.supportsLifecycleDelegation ?? supportsLifecycleDelegation)(input.client)) {
556
661
  return failed('ORCHESTRATION_CLIENT_UNSUPPORTED', `client '${input.client}' does not support lifecycle orchestration`, resolved.taskId);
557
662
  }
558
- const run = readRun(resolved.taskDir);
663
+ emitDiagnostic(options, 'orchestration-prepare-start', {
664
+ taskId: resolved.taskId,
665
+ taskDir: resolved.taskDir,
666
+ repoRoot: resolved.repoRoot,
667
+ client: input.client,
668
+ requestedModel: input.requestedModel ?? null,
669
+ requestedReasoningEffort: input.requestedReasoningEffort ?? null
670
+ });
671
+ const run = readRun(resolved.taskDir, options);
559
672
  if (!run || run.status !== 'running')
560
673
  return failed('ORCHESTRATION_RUN_NOT_RUNNING', 'a running orchestration is required', resolved.taskId);
561
674
  if (run.pendingDelegation)
@@ -643,7 +756,7 @@ function dispatchOrchestrationDelegationUnlocked(taskRef, options = {}) {
643
756
  const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
644
757
  if (!resolved.ok)
645
758
  return failed(resolved.code, resolved.message, resolved.taskId);
646
- const run = readRun(resolved.taskDir);
759
+ const run = readRun(resolved.taskDir, options);
647
760
  if (!run?.pendingDelegation)
648
761
  return failed('ORCHESTRATION_DELEGATION_MISSING', 'no pending delegation exists', resolved.taskId);
649
762
  if (run.status !== 'running') {
@@ -677,17 +790,44 @@ function matchingDelegations(predicate, options) {
677
790
  const activeRoot = path.join(repoRoot, '.agents', 'workspace', 'active');
678
791
  if (!fs.existsSync(activeRoot))
679
792
  return [];
680
- return fs.readdirSync(activeRoot, { withFileTypes: true })
793
+ emitDiagnostic(options, 'orchestration-active-scan-start', {
794
+ activeRoot
795
+ });
796
+ const matches = fs.readdirSync(activeRoot, { withFileTypes: true })
681
797
  .filter((entry) => entry.isDirectory())
682
798
  .flatMap((entry) => {
683
- const run = readRun(path.join(activeRoot, entry.name));
799
+ const candidateTaskId = entry.name;
800
+ const candidateTaskDir = path.join(activeRoot, candidateTaskId);
801
+ emitDiagnostic(options, 'orchestration-active-scan-candidate', {
802
+ candidateTaskId,
803
+ candidateTaskDir,
804
+ orchestrationPath: orchestrationPath(candidateTaskDir)
805
+ });
806
+ let run;
807
+ try {
808
+ run = readRun(candidateTaskDir, options);
809
+ }
810
+ catch (error) {
811
+ emitDiagnostic(options, 'orchestration-active-scan-candidate-failed', {
812
+ candidateTaskId,
813
+ candidateTaskDir,
814
+ errorType: error instanceof Error ? error.name : typeof error,
815
+ reasonCodes: error instanceof OrchestrationStateError ? error.reasonCodes.join(',') : null
816
+ });
817
+ throw error;
818
+ }
684
819
  if (!run || run.status !== 'running' || !run.pendingDelegation)
685
820
  return [];
686
821
  const receipt = run.pendingDelegation;
687
822
  return predicate(receipt)
688
- ? [{ taskId: entry.name, run }]
823
+ ? [{ taskId: candidateTaskId, run }]
689
824
  : [];
690
825
  });
826
+ emitDiagnostic(options, 'orchestration-active-scan-finished', {
827
+ activeRoot,
828
+ matchingDelegations: matches.length
829
+ });
830
+ return matches;
691
831
  }
692
832
  function uniqueMatchingDelegation(client, predicate, options) {
693
833
  const matches = matchingDelegations((receipt) => receipt.client === client && predicate(receipt), options);
@@ -838,7 +978,7 @@ function activateOrchestrationDelegation(taskRef, event, options = {}) {
838
978
  const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
839
979
  if (!resolved.ok)
840
980
  return failed(resolved.code, resolved.message, resolved.taskId);
841
- const run = readRun(resolved.taskDir);
981
+ const run = readRun(resolved.taskDir, options);
842
982
  if (!run?.pendingDelegation)
843
983
  return failed('ORCHESTRATION_DELEGATION_MISSING', 'no pending delegation exists', resolved.taskId);
844
984
  if (run.status !== 'running') {
@@ -864,7 +1004,7 @@ async function awaitOrchestrationDelegationActivation(taskRef, event, options =
864
1004
  const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
865
1005
  if (!resolved.ok)
866
1006
  return failed(resolved.code, resolved.message, resolved.taskId);
867
- const run = readRun(resolved.taskDir);
1007
+ const run = readRun(resolved.taskDir, options);
868
1008
  if (!run?.pendingDelegation) {
869
1009
  return failed('ORCHESTRATION_DELEGATION_MISSING', 'no pending delegation exists', resolved.taskId);
870
1010
  }
@@ -901,7 +1041,7 @@ function recoverPreparedOrchestrationDelegation(taskRef, options = {}) {
901
1041
  return failed(resolved.code, resolved.message, resolved.taskId);
902
1042
  try {
903
1043
  return withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-orchestration.recover-prepared', () => {
904
- const run = readRun(resolved.taskDir);
1044
+ const run = readRun(resolved.taskDir, options);
905
1045
  const receipt = run?.pendingDelegation;
906
1046
  if (!run || !receipt) {
907
1047
  return failed('ORCHESTRATION_DELEGATION_MISSING', 'no pending delegation exists', resolved.taskId);
@@ -957,7 +1097,7 @@ function completeOrchestrationStage(taskRef, event, options = {}) {
957
1097
  const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
958
1098
  if (!resolved.ok)
959
1099
  return failed(resolved.code, resolved.message, resolved.taskId);
960
- const run = readRun(resolved.taskDir);
1100
+ const run = readRun(resolved.taskDir, options);
961
1101
  if (!run)
962
1102
  return { status: 'running', changed: false, taskId: resolved.taskId, run: null, next: null, error: null };
963
1103
  if (!run.pendingDelegation)
@@ -975,7 +1115,7 @@ function inspectOrchestrationStage(taskRef, event, options = {}) {
975
1115
  return failed(resolved.code, resolved.message, resolved.taskId);
976
1116
  let run;
977
1117
  try {
978
- run = readRun(resolved.taskDir);
1118
+ run = readRun(resolved.taskDir, options);
979
1119
  }
980
1120
  catch (error) {
981
1121
  return failed('ORCHESTRATION_STATE_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId);
@@ -1023,7 +1163,7 @@ function sealOrchestrationDelegation(taskRef, event, options = {}) {
1023
1163
  const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
1024
1164
  if (!resolved.ok)
1025
1165
  return failed(resolved.code, resolved.message, resolved.taskId);
1026
- const run = readRun(resolved.taskDir);
1166
+ const run = readRun(resolved.taskDir, options);
1027
1167
  if (!run?.pendingDelegation)
1028
1168
  return failed('ORCHESTRATION_DELEGATION_MISSING', 'no pending delegation exists', resolved.taskId);
1029
1169
  const result = sealDelegation(run.pendingDelegation, event, { now: options.now });
@@ -1037,7 +1177,7 @@ function advanceOrchestration(taskRef, options = {}) {
1037
1177
  const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
1038
1178
  if (!resolved.ok)
1039
1179
  return failed(resolved.code, resolved.message, resolved.taskId);
1040
- const run = readRun(resolved.taskDir);
1180
+ const run = readRun(resolved.taskDir, options);
1041
1181
  if (!run?.pendingDelegation)
1042
1182
  return failed('ORCHESTRATION_DELEGATION_MISSING', 'no pending delegation exists', resolved.taskId);
1043
1183
  const result = consumeDelegation(run.pendingDelegation, { now: options.now });
@@ -1060,7 +1200,7 @@ function pauseOrchestration(taskRef, code, message, recoverable, options = {}) {
1060
1200
  const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
1061
1201
  if (!resolved.ok)
1062
1202
  return failed(resolved.code, resolved.message, resolved.taskId);
1063
- const run = readRun(resolved.taskDir);
1203
+ const run = readRun(resolved.taskDir, options);
1064
1204
  if (!run)
1065
1205
  return failed('ORCHESTRATION_RUN_MISSING', 'no orchestration run exists', resolved.taskId);
1066
1206
  const updated = withUpdatedRun(run, { status: 'paused', pause: { code, message, recoverable } });