@fitlab-ai/agent-infra 0.12.0 → 0.12.2

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 (331) hide show
  1. package/README.md +0 -2
  2. package/README.zh-CN.md +0 -2
  3. package/dist/bin/internal-cli.js +2 -17
  4. package/dist/lib/agent-clients/adapter.js +0 -13
  5. package/dist/lib/agent-clients/adapters/antigravity-cli.js +0 -5
  6. package/dist/lib/agent-clients/adapters/claude-code-credentials.js +0 -17
  7. package/dist/lib/agent-clients/adapters/claude-code.js +0 -9
  8. package/dist/lib/agent-clients/adapters/codex.js +0 -52
  9. package/dist/lib/agent-clients/adapters/opencode.js +0 -5
  10. package/dist/lib/agent-clients/adapters/traecli.js +0 -5
  11. package/dist/lib/agent-clients/config.js +19 -54
  12. package/dist/lib/agent-clients/registry.js +1 -12
  13. package/dist/lib/agent-clients/schema.js +0 -18
  14. package/dist/lib/agent-clients/tokens.js +1 -2
  15. package/dist/lib/agent-clients/types.js +0 -1
  16. package/dist/lib/decide.js +2 -0
  17. package/dist/lib/git/worktree-identity.js +1 -9
  18. package/dist/lib/internal/agent-client.js +2 -62
  19. package/dist/lib/internal/cli-route-inventory.js +1 -5
  20. package/dist/lib/internal/manual-validation.js +29 -27
  21. package/dist/lib/internal/platform-comment.js +56 -7
  22. package/dist/lib/internal/task-create.js +1 -1
  23. package/dist/lib/internal/task-event.js +1 -8
  24. package/dist/lib/internal/task-finalization.js +0 -1
  25. package/dist/lib/internal/task-lifecycle.js +2 -2
  26. package/dist/lib/internal/task-operation-registry.js +4 -20
  27. package/dist/lib/internal/task-review.js +4 -4
  28. package/dist/lib/platform/comment-safety.js +1 -7
  29. package/dist/lib/platform/in-label-sync.js +1 -14
  30. package/dist/lib/platform/issue-comments.js +373 -282
  31. package/dist/lib/platform/issue-summary-content.js +112 -0
  32. package/dist/lib/platform/issues.js +1 -1
  33. package/dist/lib/platform/operation-coordinator.js +4 -2
  34. package/dist/lib/platform/pr-change-report.js +176 -30
  35. package/dist/lib/platform/pr-checks.js +2 -8
  36. package/dist/lib/platform/pr-summary-content.js +54 -0
  37. package/dist/lib/platform/pr-summary.js +318 -284
  38. package/dist/lib/platform/provider-validation.js +0 -20
  39. package/dist/lib/platform/pull-requests.js +73 -84
  40. package/dist/lib/platform/releases.js +1 -43
  41. package/dist/lib/platform/summary-content-pipeline.js +18 -0
  42. package/dist/lib/platform/verification-required.js +0 -2
  43. package/dist/lib/platform/verification-sync.js +1 -79
  44. package/dist/lib/process-data/normalize.js +1 -185
  45. package/dist/lib/process-data/privacy.js +1 -16
  46. package/dist/lib/process-data/sources.js +2 -279
  47. package/dist/lib/render.js +0 -12
  48. package/dist/lib/run/index.js +15 -10
  49. package/dist/lib/run/skills.js +0 -3
  50. package/dist/lib/sandbox/commands/create.js +40 -53
  51. package/dist/lib/sandbox/commands/list-running.js +0 -18
  52. package/dist/lib/sandbox/commands/start.js +7 -8
  53. package/dist/lib/sandbox/constants.js +0 -6
  54. package/dist/lib/sandbox/control/client.js +0 -1
  55. package/dist/lib/sandbox/control/container-identity.js +1 -16
  56. package/dist/lib/sandbox/control/executor.js +0 -4
  57. package/dist/lib/sandbox/control/identity-sentinel.js +0 -7
  58. package/dist/lib/sandbox/control/lifecycle.js +21 -37
  59. package/dist/lib/sandbox/control/native-file-lock.js +0 -3
  60. package/dist/lib/sandbox/control/server.js +18 -38
  61. package/dist/lib/sandbox/control/state.js +1 -9
  62. package/dist/lib/sandbox/dockerfile.js +0 -6
  63. package/dist/lib/sandbox/engine.js +0 -14
  64. package/dist/lib/sandbox/engines/docker-exact-discovery.js +1 -4
  65. package/dist/lib/sandbox/engines/wsl2-paths.js +0 -3
  66. package/dist/lib/sandbox/recovery.js +24 -26
  67. package/dist/lib/sandbox/removal.js +67 -518
  68. package/dist/lib/sandbox/task-resolver.js +0 -41
  69. package/dist/lib/sandbox/tools.js +1 -4
  70. package/dist/lib/sandbox/workspace-view.js +1 -2
  71. package/dist/lib/server/display.js +0 -6
  72. package/dist/lib/task/activity-intent.js +45 -40
  73. package/dist/lib/task/activity-log.js +9 -16
  74. package/dist/lib/task/artifact-command.js +1 -1
  75. package/dist/lib/task/artifact-lifecycle.js +61 -63
  76. package/dist/lib/task/artifact-name.js +0 -6
  77. package/dist/lib/task/artifact-operations.js +3 -3
  78. package/dist/lib/task/capabilities.js +4 -5
  79. package/dist/lib/task/commands/log.js +0 -6
  80. package/dist/lib/task/commands/status.js +17 -60
  81. package/dist/lib/task/commit-operation.js +28 -39
  82. package/dist/lib/task/completion-facts.js +56 -43
  83. package/dist/lib/task/control-authority.js +23 -256
  84. package/dist/lib/task/control-recovery.js +3 -5
  85. package/dist/lib/task/create.js +2 -4
  86. package/dist/lib/task/decision-intents.js +8 -9
  87. package/dist/lib/task/delivery-target.js +1 -40
  88. package/dist/lib/task/events.js +84 -107
  89. package/dist/lib/task/finalization.js +60 -15
  90. package/dist/lib/task/ledger-intents.js +1 -1
  91. package/dist/lib/task/lifecycle-execution.js +38 -33
  92. package/dist/lib/task/lifecycle.js +49 -41
  93. package/dist/lib/task/local-artifact-finalization.js +1 -4
  94. package/dist/lib/task/manual-validation-evidence.js +1 -37
  95. package/dist/lib/task/platform-operation-recovery.js +151 -108
  96. package/dist/lib/task/pr-delivery-fact.js +2 -5
  97. package/dist/lib/task/qualification-confirmation.js +5 -7
  98. package/dist/lib/task/resolve-ref.js +1 -25
  99. package/dist/lib/task/review-command.js +2 -2
  100. package/dist/lib/task/review-finalization.js +1 -21
  101. package/dist/lib/task/review-fingerprint.js +0 -4
  102. package/dist/lib/task/secure-fs.js +0 -56
  103. package/dist/lib/task/short-id.js +1 -39
  104. package/dist/lib/task/skill-scope.js +0 -1
  105. package/dist/lib/task/verification-engine.js +58 -282
  106. package/dist/lib/task/verification.js +6 -3
  107. package/dist/lib/task/write.js +11 -1
  108. package/lib/agent-clients/adapter.ts +0 -76
  109. package/lib/agent-clients/adapters/antigravity-cli.ts +0 -5
  110. package/lib/agent-clients/adapters/claude-code-credentials.ts +0 -19
  111. package/lib/agent-clients/adapters/claude-code.ts +0 -9
  112. package/lib/agent-clients/adapters/codex.ts +0 -56
  113. package/lib/agent-clients/adapters/opencode.ts +0 -5
  114. package/lib/agent-clients/adapters/traecli.ts +0 -5
  115. package/lib/agent-clients/config.ts +20 -61
  116. package/lib/agent-clients/registry.ts +1 -34
  117. package/lib/agent-clients/schema.ts +0 -18
  118. package/lib/agent-clients/tokens.ts +1 -2
  119. package/lib/agent-clients/types.ts +0 -15
  120. package/lib/decide.ts +1 -0
  121. package/lib/git/worktree-identity.ts +0 -10
  122. package/lib/internal/agent-client.ts +2 -70
  123. package/lib/internal/cli-route-inventory.ts +1 -4
  124. package/lib/internal/manual-validation.ts +28 -27
  125. package/lib/internal/platform-comment.ts +46 -4
  126. package/lib/internal/task-create.ts +0 -1
  127. package/lib/internal/task-event.ts +1 -5
  128. package/lib/internal/task-finalization.ts +0 -1
  129. package/lib/internal/task-lifecycle.ts +3 -5
  130. package/lib/internal/task-operation-registry.ts +3 -19
  131. package/lib/internal/task-review.ts +4 -4
  132. package/lib/platform/comment-safety.ts +0 -10
  133. package/lib/platform/github-provider.ts +0 -2
  134. package/lib/platform/in-label-sync.ts +0 -16
  135. package/lib/platform/issue-comments.ts +478 -301
  136. package/lib/platform/issue-summary-content.ts +132 -0
  137. package/lib/platform/issues.ts +0 -2
  138. package/lib/platform/operation-coordinator.ts +4 -2
  139. package/lib/platform/pr-change-report.ts +165 -25
  140. package/lib/platform/pr-checks.ts +1 -10
  141. package/lib/platform/pr-review.ts +1 -1
  142. package/lib/platform/pr-summary-content.ts +60 -0
  143. package/lib/platform/pr-summary.ts +364 -257
  144. package/lib/platform/provider-bridge.ts +0 -1
  145. package/lib/platform/provider-loader.ts +1 -5
  146. package/lib/platform/provider-validation.ts +1 -49
  147. package/lib/platform/pull-requests.ts +64 -99
  148. package/lib/platform/releases.ts +1 -40
  149. package/lib/platform/summary-content-pipeline.ts +23 -0
  150. package/lib/platform/verification-required.ts +0 -2
  151. package/lib/platform/verification-sync.ts +0 -94
  152. package/lib/process-data/normalize.ts +1 -186
  153. package/lib/process-data/privacy.ts +2 -19
  154. package/lib/process-data/sources.ts +3 -283
  155. package/lib/render.ts +0 -15
  156. package/lib/run/index.ts +13 -7
  157. package/lib/run/skills.ts +0 -4
  158. package/lib/sandbox/commands/create.ts +37 -74
  159. package/lib/sandbox/commands/list-running.ts +0 -19
  160. package/lib/sandbox/commands/start.ts +7 -10
  161. package/lib/sandbox/constants.ts +0 -8
  162. package/lib/sandbox/control/client.ts +0 -1
  163. package/lib/sandbox/control/container-identity.ts +1 -16
  164. package/lib/sandbox/control/executor.ts +1 -5
  165. package/lib/sandbox/control/identity-sentinel.ts +0 -8
  166. package/lib/sandbox/control/lifecycle.ts +18 -51
  167. package/lib/sandbox/control/native-file-lock.ts +0 -8
  168. package/lib/sandbox/control/protocol.ts +0 -2
  169. package/lib/sandbox/control/server.ts +13 -39
  170. package/lib/sandbox/control/state.ts +1 -10
  171. package/lib/sandbox/dockerfile.ts +0 -11
  172. package/lib/sandbox/engine.ts +0 -17
  173. package/lib/sandbox/engines/docker-exact-discovery.ts +1 -5
  174. package/lib/sandbox/engines/wsl2-paths.ts +0 -4
  175. package/lib/sandbox/recovery.ts +24 -26
  176. package/lib/sandbox/removal.ts +58 -687
  177. package/lib/sandbox/shell.ts +1 -1
  178. package/lib/sandbox/task-resolver.ts +0 -48
  179. package/lib/sandbox/tools.ts +1 -5
  180. package/lib/sandbox/workspace-view.ts +2 -4
  181. package/lib/server/display.ts +0 -14
  182. package/lib/server/process-control.ts +1 -1
  183. package/lib/task/activity-intent.ts +36 -44
  184. package/lib/task/activity-log.ts +9 -22
  185. package/lib/task/artifact-command.ts +1 -1
  186. package/lib/task/artifact-lifecycle.ts +58 -67
  187. package/lib/task/artifact-name.ts +0 -7
  188. package/lib/task/artifact-operations.ts +3 -3
  189. package/lib/task/capabilities.ts +5 -6
  190. package/lib/task/commands/log.ts +0 -7
  191. package/lib/task/commands/status.ts +14 -79
  192. package/lib/task/commit-operation.ts +29 -51
  193. package/lib/task/completion-facts.ts +45 -42
  194. package/lib/task/control-authority.ts +27 -317
  195. package/lib/task/control-recovery.ts +2 -5
  196. package/lib/task/create.ts +2 -5
  197. package/lib/task/decision-intents.ts +5 -5
  198. package/lib/task/delivery-target.ts +0 -40
  199. package/lib/task/events.ts +89 -123
  200. package/lib/task/finalization.ts +52 -15
  201. package/lib/task/ledger-intents.ts +1 -1
  202. package/lib/task/lifecycle-execution.ts +37 -89
  203. package/lib/task/lifecycle.ts +48 -44
  204. package/lib/task/local-artifact-finalization.ts +0 -7
  205. package/lib/task/manual-validation-evidence.ts +1 -47
  206. package/lib/task/platform-operation-recovery.ts +117 -104
  207. package/lib/task/pr-delivery-fact.ts +2 -11
  208. package/lib/task/qualification-confirmation.ts +6 -6
  209. package/lib/task/resolve-ref.ts +0 -23
  210. package/lib/task/review-command.ts +2 -2
  211. package/lib/task/review-finalization.ts +1 -27
  212. package/lib/task/review-fingerprint.ts +0 -8
  213. package/lib/task/secure-fs.ts +0 -42
  214. package/lib/task/short-id.ts +0 -43
  215. package/lib/task/skill-scope.ts +0 -1
  216. package/lib/task/verification-engine.ts +56 -287
  217. package/lib/task/verification.ts +5 -5
  218. package/lib/task/write.ts +12 -1
  219. package/package.json +2 -2
  220. package/templates/.agents/README.en.md +1 -3
  221. package/templates/.agents/README.zh-CN.md +0 -2
  222. package/templates/.agents/rules/README.en.md +0 -1
  223. package/templates/.agents/rules/README.zh-CN.md +0 -1
  224. package/templates/.agents/rules/commit-and-pr.en.md +1 -1
  225. package/templates/.agents/rules/commit-and-pr.zh-CN.md +1 -1
  226. package/templates/.agents/rules/no-mid-flow-questions.en.md +0 -10
  227. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +0 -10
  228. package/templates/.agents/rules/pr-sync.en.md +4 -2
  229. package/templates/.agents/rules/pr-sync.zh-CN.md +6 -9
  230. package/templates/.agents/rules/task-management.en.md +3 -3
  231. package/templates/.agents/rules/task-management.zh-CN.md +3 -3
  232. package/templates/.agents/skills/analyze-task/SKILL.en.md +3 -3
  233. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +3 -3
  234. package/templates/.agents/skills/cancel-task/SKILL.en.md +2 -2
  235. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +2 -2
  236. package/templates/.agents/skills/code-task/SKILL.en.md +2 -2
  237. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +4 -4
  238. package/templates/.agents/skills/commit/SKILL.en.md +2 -2
  239. package/templates/.agents/skills/commit/SKILL.zh-CN.md +2 -2
  240. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +6 -6
  241. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +6 -6
  242. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
  243. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
  244. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +2 -2
  245. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +2 -2
  246. package/templates/.agents/skills/complete-task/SKILL.en.md +10 -25
  247. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +11 -26
  248. package/templates/.agents/skills/create-pr/SKILL.en.md +1 -1
  249. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +1 -1
  250. package/templates/.agents/skills/create-pr/reference/change-report.en.md +9 -2
  251. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +9 -2
  252. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +2 -2
  253. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +2 -2
  254. package/templates/.agents/skills/create-task/SKILL.en.md +0 -18
  255. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +0 -18
  256. package/templates/.agents/skills/plan-task/SKILL.en.md +2 -2
  257. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +2 -2
  258. package/templates/.agents/skills/review-analysis/SKILL.en.md +3 -3
  259. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +3 -3
  260. package/templates/.agents/skills/review-code/SKILL.en.md +5 -5
  261. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +5 -5
  262. package/templates/.agents/skills/review-plan/SKILL.en.md +3 -3
  263. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +3 -3
  264. package/templates/.agents/skills/review-pr/SKILL.en.md +4 -4
  265. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +4 -4
  266. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +1 -1
  267. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +1 -1
  268. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +3 -75
  269. package/templates/.agents/skills/watch-pr/SKILL.en.md +1 -1
  270. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +1 -1
  271. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +3 -3
  272. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +3 -3
  273. package/templates/.agents/templates/task.en.md +1 -0
  274. package/templates/.agents/templates/task.zh-CN.md +1 -0
  275. package/templates/.claude/settings.json +0 -24
  276. package/templates/.codex/hooks.json +0 -50
  277. package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +0 -582
  278. package/dist/lib/agent-clients/adapters/codex-lifecycle/binding.js +0 -114
  279. package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +0 -237
  280. package/dist/lib/agent-clients/adapters/codex-lifecycle/cli.js +0 -443
  281. package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +0 -236
  282. package/dist/lib/agent-clients/adapters/codex-lifecycle/recovery.js +0 -292
  283. package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +0 -267
  284. package/dist/lib/agent-clients/adapters/codex-orchestration.js +0 -466
  285. package/dist/lib/internal/task-orchestration.js +0 -71
  286. package/dist/lib/platform/verification.js +0 -6
  287. package/dist/lib/run/prompt.js +0 -2
  288. package/dist/lib/sandbox/engines/authority.js +0 -289
  289. package/dist/lib/task/delegation-receipts.js +0 -410
  290. package/dist/lib/task/orchestration.js +0 -1233
  291. package/dist/lib/task/verification-checks.js +0 -9
  292. package/dist/lib/task/workspace-snapshot.js +0 -121
  293. package/dist/lifecycle-build-manifest.json +0 -6
  294. package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +0 -688
  295. package/lib/agent-clients/adapters/codex-lifecycle/binding.ts +0 -147
  296. package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +0 -349
  297. package/lib/agent-clients/adapters/codex-lifecycle/cli.ts +0 -506
  298. package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +0 -385
  299. package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +0 -41
  300. package/lib/agent-clients/adapters/codex-lifecycle/recovery.ts +0 -418
  301. package/lib/agent-clients/adapters/codex-lifecycle/store.ts +0 -354
  302. package/lib/agent-clients/adapters/codex-orchestration.ts +0 -630
  303. package/lib/internal/task-orchestration.ts +0 -74
  304. package/lib/platform/verification.ts +0 -11
  305. package/lib/run/prompt.ts +0 -1
  306. package/lib/sandbox/engines/authority.ts +0 -365
  307. package/lib/task/delegation-receipts.ts +0 -547
  308. package/lib/task/orchestration.ts +0 -1651
  309. package/lib/task/verification-checks.ts +0 -10
  310. package/lib/task/workspace-snapshot.ts +0 -144
  311. package/templates/.agents/hooks/lifecycle-delegation.js +0 -140
  312. package/templates/.agents/rules/lifecycle-orchestration.en.md +0 -44
  313. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +0 -44
  314. package/templates/.agents/skills/run-task/SKILL.en.md +0 -29
  315. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +0 -29
  316. package/templates/.agents/skills/run-task/config/verify.en.json +0 -10
  317. package/templates/.agents/skills/run-task/config/verify.zh-CN.json +0 -10
  318. package/templates/.agents/skills/run-task/reference/host-validation.en.md +0 -24
  319. package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +0 -24
  320. package/templates/.claude/agents/agent-infra-lifecycle-executor.en.md +0 -6
  321. package/templates/.claude/agents/agent-infra-lifecycle-executor.zh-CN.md +0 -6
  322. package/templates/.claude/agents/agent-infra-lifecycle-reviewer.en.md +0 -6
  323. package/templates/.claude/agents/agent-infra-lifecycle-reviewer.zh-CN.md +0 -6
  324. package/templates/.claude/commands/run-task.en.md +0 -8
  325. package/templates/.claude/commands/run-task.zh-CN.md +0 -8
  326. package/templates/.codex/agents/agent-infra-lifecycle-executor.en.toml +0 -3
  327. package/templates/.codex/agents/agent-infra-lifecycle-executor.zh-CN.toml +0 -3
  328. package/templates/.codex/agents/agent-infra-lifecycle-reviewer.en.toml +0 -3
  329. package/templates/.codex/agents/agent-infra-lifecycle-reviewer.zh-CN.toml +0 -3
  330. package/templates/.opencode/commands/run-task.en.md +0 -11
  331. package/templates/.opencode/commands/run-task.zh-CN.md +0 -11
@@ -2,7 +2,8 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { execFileSync } from 'node:child_process';
4
4
  import { resolveBranchWorktree } from '../git/branch-worktree.js';
5
- import { appendActivityEntry, locateActivityLog, pairEntries, startedBackedRows } from './activity-log.js';
5
+ import { appendActivityEntry, inspectActivityLog } from './activity-log.js';
6
+ import { lifecycleExecutions, serializeLifecycleExecution } from './lifecycle-execution.js';
6
7
  import { buildArtifactLinkSection, inspectArtifactDirectory, resolveArtifactContext, validateCompletedArtifact } from './artifact-lifecycle.js';
7
8
  import { artifactName, parseArtifactName } from './artifact-name.js';
8
9
  import { ArtifactReceiptError, parseArtifactReceipts, sha256File, upsertArtifactReceipts } from './artifact-receipts.js';
@@ -13,8 +14,6 @@ import { parseReviewSummary, resolveCanonicalVerdict } from './review-artifacts.
13
14
  import { extractReviewBaseline, extractReviewedHead, extractReviewedSnapshotTree } from './review-fingerprint.js';
14
15
  import { resolveTaskRef } from './resolve-ref.js';
15
16
  import { findSectionHeading } from './sections.js';
16
- import { validateLifecycleExecution } from './lifecycle-execution.js';
17
- import { commitOrchestrationStageCompletion } from './orchestration.js';
18
17
  import { captureTaskWriteMetadata, writeTask } from './write.js';
19
18
  import { validateLocalArtifact } from './local-artifact-finalization.js';
20
19
  import { buildLifecycleFacts, canStart, effectiveReworkTarget } from './capabilities.js';
@@ -23,7 +22,7 @@ import { parseTaskQualification } from './qualification-audit.js';
23
22
  import { getArtifactSchema } from './artifact-schema.js';
24
23
  import { canonicalSemanticDigest, inspectArtifactContract } from './artifact-operations.js';
25
24
  import { inspectReviewIdentity } from './review-identity.js';
26
- import { parseCompletionFacts } from './completion-facts.js';
25
+ import { hasValidArtifactCompletion, parseCompletionFacts } from './completion-facts.js';
27
26
  import { readManualValidationCompletion } from './manual-validation-completion.js';
28
27
  import { parseLifecyclePathDecision } from './lifecycle-path.js';
29
28
  const eventCatalog = [
@@ -69,17 +68,17 @@ const BASE_FIELDS = new Set(['taskRef', 'event', 'agent', 'dryRun', 'initiator',
69
68
  const SCHEMAS = {
70
69
  'analyze.started': { optional: ['round'] },
71
70
  'analyze.awaiting-input': { required: ['question'] },
72
- 'analyze.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round', 'orchestrated'] },
71
+ 'analyze.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round'] },
73
72
  'review-analysis.started': { optional: ['round'] },
74
- 'review-analysis.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round', 'orchestrated'] },
73
+ 'review-analysis.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round'] },
75
74
  'plan.started': { optional: ['round'] },
76
- 'plan.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round', 'orchestrated'] },
75
+ 'plan.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round'] },
77
76
  'review-plan.started': { optional: ['round'] },
78
- 'review-plan.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round', 'orchestrated'] },
77
+ 'review-plan.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round'] },
79
78
  'code.started': { optional: ['round', 'fixFor', 'implementationInput'] },
80
- 'code.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round', 'fixFor', 'implementationInput', 'filesModified', 'testsPassed', 'blockers', 'major', 'minor', 'manualValidation', 'orchestrated'] },
79
+ 'code.completed': { required: ['artifact', 'artifactSha256', 'semanticDigest'], optional: ['round', 'fixFor', 'implementationInput', 'filesModified', 'testsPassed', 'blockers', 'major', 'minor', 'manualValidation'] },
81
80
  'review-code.started': { optional: ['round'] },
82
- 'review-code.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round', 'orchestrated'] },
81
+ 'review-code.completed': { required: ['artifact', 'verdict', 'blockers', 'major', 'minor', 'manualValidation'], optional: ['round'] },
83
82
  'manual-validation.started': { optional: ['round', 'transactionId'] },
84
83
  'manual-validation.completed': { required: ['artifact', 'summaryResult', 'transactionId', 'receiptDigest', 'prHeadSha'], optional: ['round'] },
85
84
  'validation-run.started': { optional: ['round'] },
@@ -107,7 +106,7 @@ function validateTaskEventRequest(request) {
107
106
  }
108
107
  if (request.verdict && !['approved', 'changes-requested', 'rejected'].includes(request.verdict))
109
108
  return { code: 'EVENT_PAYLOAD_INVALID', message: 'verdict is invalid' };
110
- if (request.initiator && !['human', 'model', 'orchestrator'].includes(request.initiator))
109
+ if (request.initiator && !['human', 'model'].includes(request.initiator))
111
110
  return { code: 'EVENT_PAYLOAD_INVALID', message: 'initiator is invalid' };
112
111
  if (request.requestId !== undefined && (!request.requestId.trim() || /[\r\n]/.test(request.requestId)))
113
112
  return { code: 'EVENT_PAYLOAD_INVALID', message: 'requestId must be a non-empty single line' };
@@ -331,21 +330,12 @@ function validateManualValidationCompletion(taskDir, taskId, request, artifactPa
331
330
  return null;
332
331
  }
333
332
  function openStartedIdentity(rows, family) {
334
- const spec = FAMILY[family];
333
+ const matches = rows.filter((item) => item.family === family);
335
334
  if (family === 'manual-validation') {
336
- const row = rows.filter((item) => item.step === spec.label && item.started && !item.done).at(-1);
337
- const completed = rows.filter((item) => item.step === spec.label && item.done).length;
338
- return row ? { row, round: completed + 1, fixFor: undefined, implementationInput: undefined } : null;
339
- }
340
- const escaped = spec.label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
341
- const pattern = new RegExp(`^${escaped} \\(Round (\\d+)(?:(?:, fix for (review-code(?:-r\\d+)?\\.md))|(?:, decision (II-[1-9]\\d*)))?\\)$`);
342
- const matches = rows.flatMap((row) => {
343
- if (!row.started || row.done)
344
- return [];
345
- const match = pattern.exec(row.step);
346
- return match ? [{ row, round: Number(match[1]), fixFor: match[2], implementationInput: match[3] }] : [];
347
- });
348
- return matches.length === 1 ? matches[0] : matches.length > 1 ? { conflict: true } : null;
335
+ const row = matches.at(-1);
336
+ return row ? { row, round: row.round, fixFor: undefined, implementationInput: undefined } : null;
337
+ }
338
+ return matches.length === 1 ? { row: matches[0], round: matches[0].round, fixFor: matches[0].fixFor, implementationInput: matches[0].implementationInput } : matches.length > 1 ? { conflict: true } : null;
349
339
  }
350
340
  function repairMissingCodeFixQualifier(request, family, open, repoRoot) {
351
341
  if (family !== 'code' || open.fixFor !== undefined || !request.fixFor || request.implementationInput !== undefined) {
@@ -369,7 +359,7 @@ function resolveOpenStartedEvent(request, family, open, repoRoot) {
369
359
  if (open.row.agent !== request.agent)
370
360
  return { status: 'error', error: { code: 'EVENT_LOG_CONFLICT', message: 'open started event has a different agent' } };
371
361
  if (family === 'manual-validation' && request.transactionId !== undefined) {
372
- const existingTransactionId = /(?:^|;\s*)transaction=([A-Za-z0-9][A-Za-z0-9._-]{0,127})(?:;|$)/u.exec(open.row.note)?.[1];
362
+ const existingTransactionId = open.row.transactionId;
373
363
  if (existingTransactionId !== undefined && existingTransactionId !== request.transactionId) {
374
364
  return { status: 'error', error: { code: 'EVENT_LOG_CONFLICT', message: 'open manual-validation started event has a different transactionId' } };
375
365
  }
@@ -383,7 +373,7 @@ function resolveOpenStartedEvent(request, family, open, repoRoot) {
383
373
  return { status: 'error', error: { code: 'EVENT_ARTIFACT_CONFLICT', message: `fixFor '${request.fixFor}' conflicts with open event` } };
384
374
  if ('error' in repair)
385
375
  return { status: 'error', error: repair.error, context: repair.context };
386
- return { status: 'repair', repair: repair.request, context: repair.context, superseded: { action: open.row.step } };
376
+ return { status: 'repair', repair: repair.request, context: repair.context, superseded: { action: `${FAMILY[family].label} (Round ${open.round})`, family: open.row.family, round: open.row.round } };
387
377
  }
388
378
  if (request.implementationInput !== open.implementationInput) {
389
379
  return { status: 'error', error: { code: 'EVENT_ARTIFACT_CONFLICT', message: `implementationInput '${request.implementationInput ?? ''}' conflicts with open event` } };
@@ -397,14 +387,11 @@ function resolveOpenStartedEvent(request, family, open, repoRoot) {
397
387
  fixFor: open.fixFor,
398
388
  implementationInput: open.implementationInput
399
389
  },
400
- startedAt: open.row.started
390
+ startedAt: open.row.startedAt
401
391
  };
402
392
  }
403
- function hasOtherOpenStarted(rows, allowedAction) {
404
- return rows.some((row) => row.started && !row.done && row.step !== allowedAction);
405
- }
406
393
  function hasConflictingOpenStarted(rows, recovery) {
407
- return recovery ? hasOtherOpenStarted(rows, recovery.action) : rows.some((row) => row.started && !row.done);
394
+ return rows.some((row) => !recovery || row.family !== recovery.family || row.round !== recovery.round);
408
395
  }
409
396
  function reviewInputFamily(family) {
410
397
  return family === 'review-analysis' ? 'analysis' : family === 'review-plan' ? 'plan' : 'code';
@@ -414,7 +401,7 @@ function lifecycleAction(family) {
414
401
  }
415
402
  function eventTrigger(request, family) {
416
403
  return {
417
- initiator: request.initiator ?? (request.orchestrated ? 'orchestrator' : request.agent === 'human' ? 'human' : 'model'),
404
+ initiator: request.initiator ?? (request.agent === 'human' ? 'human' : 'model'),
418
405
  requestId: request.requestId ?? `${request.taskRef}:${request.event}:${request.round ?? 1}`,
419
406
  requestedAction: lifecycleAction(family),
420
407
  reasonCode: request.reasonCode ?? (request.fixFor || request.implementationInput ? 'review-finding' : 'user-request'),
@@ -422,7 +409,7 @@ function eventTrigger(request, family) {
422
409
  ...(request.sourceArtifact ? { sourceArtifact: request.sourceArtifact } : {}),
423
410
  ...(request.sourceSha256 ? { sourceSha256: request.sourceSha256 } : {}),
424
411
  ...(request.implementationInput ? { implementationInput: request.implementationInput } : {}),
425
- explicitRequest: request.requestId !== undefined || request.reasonCode !== undefined || request.initiator !== undefined || request.orchestrated === true
412
+ explicitRequest: request.requestId !== undefined || request.reasonCode !== undefined || request.initiator !== undefined
426
413
  };
427
414
  }
428
415
  function reworkIntentMutationForCompletion(content, taskDir, family, artifact, timestamp) {
@@ -589,10 +576,14 @@ function applyTaskEvent(request, options = {}) {
589
576
  catch (error) {
590
577
  return failed(request, { code: 'TASK_DOCUMENT_INVALID', message: error instanceof Error ? error.message : String(error) }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
591
578
  }
592
- const section = locateActivityLog(content);
593
- if (!section)
594
- return failed(request, { code: 'EVENT_LOG_MISSING', message: 'task has no unique Activity Log section' }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
595
- const rows = startedBackedRows(pairEntries(section.entries));
579
+ const section = inspectActivityLog(content).section;
580
+ let rows;
581
+ try {
582
+ rows = lifecycleExecutions(content);
583
+ }
584
+ catch (error) {
585
+ return failed(request, { code: 'EVENT_TRANSITION_INVALID', message: error instanceof Error ? error.message : String(error) }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
586
+ }
596
587
  let normalized = request;
597
588
  let artifactContext = null;
598
589
  let supersededOpenStart = null;
@@ -631,10 +622,11 @@ function applyTaskEvent(request, options = {}) {
631
622
  }
632
623
  const eventIdentity = identity(normalized);
633
624
  const currentStep = typeof frontmatter.current_step === 'string' ? frontmatter.current_step : '';
634
- const matchingRows = rows.filter((item) => item.step === eventIdentity.action);
635
625
  const manual = eventIdentity.family === 'manual-validation';
636
- const openRows = matchingRows.filter((item) => item.started && !item.done);
637
- const completedRows = matchingRows.filter((item) => item.done);
626
+ const openRows = rows.filter((item) => item.family === eventIdentity.family && (manual || (item.round === normalized.round && item.fixFor === normalized.fixFor && item.implementationInput === normalized.implementationInput)));
627
+ const completionRecorded = normalized.artifact !== undefined && parseCompletionFacts(frontmatter.completion_facts)
628
+ .some((fact) => fact.event === normalized.event && fact.output === normalized.artifact);
629
+ const hasStartedIdentity = openRows.length > 0;
638
630
  if (!manual && openRows.length > 1)
639
631
  return failed(normalized, { code: 'EVENT_LOG_CONFLICT', message: 'event identity has more than one open attempt' }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase, artifactContext });
640
632
  const row = openRows.at(-1);
@@ -644,14 +636,22 @@ function applyTaskEvent(request, options = {}) {
644
636
  if (row.agent !== normalized.agent)
645
637
  return failed(normalized, { code: 'EVENT_LOG_CONFLICT', message: 'open started event has a different agent' }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
646
638
  if (manual && normalized.transactionId !== undefined) {
647
- const existingTransactionId = /(?:^|;\s*)transaction=([A-Za-z0-9][A-Za-z0-9._-]{0,127})(?:;|$)/u.exec(row.note)?.[1];
639
+ const existingTransactionId = row.transactionId;
648
640
  if (existingTransactionId !== undefined && existingTransactionId !== normalized.transactionId) {
649
641
  return failed(normalized, { code: 'EVENT_LOG_CONFLICT', message: 'open manual-validation started event has a different transactionId' }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
650
642
  }
651
643
  }
652
- return successNoOp(normalized, resolved.taskId, resolved.taskMdPath, currentStep, eventIdentity, row.started, frontmatter, artifactContext);
653
- }
654
- if (eventIdentity.phase === 'completed' && !row?.started && completedRows.length === 0)
644
+ return successNoOp(normalized, resolved.taskId, resolved.taskMdPath, currentStep, eventIdentity, row.startedAt, frontmatter, artifactContext);
645
+ }
646
+ const replayFact = eventIdentity.phase === 'completed' && normalized.artifact && normalized.requestId
647
+ ? parseCompletionFacts(frontmatter.completion_facts).find((fact) => fact.event === normalized.event
648
+ && fact.output === normalized.artifact && fact.requestId === normalized.requestId)
649
+ : undefined;
650
+ const validReplayFact = Boolean(replayFact && normalized.artifact
651
+ && hasValidArtifactCompletion(content, resolved.taskDir, normalized.artifact, normalized.event));
652
+ const completedByHistory = manual || eventIdentity.family === 'validation-run';
653
+ const completedHistoryReplay = completedByHistory && completionRecorded;
654
+ if (eventIdentity.phase === 'completed' && !hasStartedIdentity && !completedHistoryReplay && !validReplayFact)
655
655
  return failed(normalized, { code: 'EVENT_START_MISSING', message: 'completion requires a started event or an earlier completed attempt' }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
656
656
  if (eventIdentity.phase === 'completed') {
657
657
  const validated = validateCompletedArtifact(resolved.taskDir, FAMILY[eventIdentity.family].artifact, normalized.artifact, normalized.round);
@@ -711,10 +711,6 @@ function applyTaskEvent(request, options = {}) {
711
711
  }
712
712
  }
713
713
  }
714
- if (eventIdentity.phase === 'waiting' && section.entries.some((entry) => entry.step === eventIdentity.action && entry.note === eventIdentity.note)) {
715
- const existing = section.entries.find((entry) => entry.step === eventIdentity.action && entry.note === eventIdentity.note);
716
- return successNoOp(normalized, resolved.taskId, resolved.taskMdPath, currentStep, eventIdentity, existing.time, frontmatter, artifactContext);
717
- }
718
714
  if (eventIdentity.phase === 'started') {
719
715
  const trigger = eventTrigger(normalized, eventIdentity.family);
720
716
  const facts = buildLifecycleFacts(resolved.taskDir, content, resolved.state, false, resolved.repoRoot);
@@ -723,7 +719,7 @@ function applyTaskEvent(request, options = {}) {
723
719
  const capability = canStart(lifecycleAction(eventIdentity.family), facts.facts, trigger);
724
720
  const safetyFailure = capability.reasonCode === 'TASK_NOT_ACTIVE'
725
721
  || capability.reasonCode === 'LIFECYCLE_EXECUTION_OPEN';
726
- if (!capability.allowed && (normalized.initiator === 'orchestrator' || safetyFailure)
722
+ if (!capability.allowed && safetyFailure
727
723
  && !(supersededOpenStart && capability.reasonCode === 'LIFECYCLE_EXECUTION_OPEN')) {
728
724
  return failed(normalized, { code: 'EVENT_TRANSITION_INVALID', message: `${capability.reasonCode}: ${capability.evidence.join(', ')}` }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
729
725
  }
@@ -731,29 +727,6 @@ function applyTaskEvent(request, options = {}) {
731
727
  const findingCountError = validateReviewFindingCounts(normalized, content, eventIdentity.family, completedArtifact?.path ?? null);
732
728
  if (findingCountError)
733
729
  return failed(normalized, findingCountError, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
734
- let orchestrationCompletion = null;
735
- if (eventIdentity.phase === 'completed' && normalized.orchestrated
736
- && eventIdentity.family !== 'manual-validation' && eventIdentity.family !== 'validation-run') {
737
- const orchestrationStage = eventIdentity.family === 'analyze' ? 'analysis' : eventIdentity.family;
738
- const execution = validateLifecycleExecution(normalized.taskRef, {
739
- mode: 'orchestrated',
740
- identity: {
741
- stage: orchestrationStage,
742
- round: normalized.round,
743
- artifact: normalized.artifact,
744
- role: eventIdentity.family.startsWith('review-') ? 'reviewer' : 'executor'
745
- },
746
- agent: normalized.agent,
747
- dryRun: normalized.dryRun
748
- }, { repoRoot: options.repoRoot });
749
- if (!execution.ok) {
750
- return failed(normalized, {
751
- code: 'EVENT_TRANSITION_INVALID',
752
- message: `${execution.error?.code ?? 'ORCHESTRATION_PROVENANCE_MISMATCH'}: ${execution.error?.message ?? 'orchestration provenance validation failed'}`
753
- }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase, artifactContext });
754
- }
755
- orchestrationCompletion = execution.completionPlan;
756
- }
757
730
  let metadata;
758
731
  try {
759
732
  metadata = (options.metadataProvider ?? captureTaskWriteMetadata)();
@@ -782,6 +755,9 @@ function applyTaskEvent(request, options = {}) {
782
755
  if (parseCompletionFacts(frontmatter.completion_facts).some((fact) => sameCompletionFact(fact, currentFact))) {
783
756
  return successNoOp(normalized, resolved.taskId, resolved.taskMdPath, currentStep, eventIdentity, completionReceipts[0]?.completedAt ?? metadata.timestamp, frontmatter, artifactContext);
784
757
  }
758
+ if (!hasStartedIdentity && !completedHistoryReplay) {
759
+ return failed(normalized, { code: 'EVENT_START_MISSING', message: 'completion replay does not match the existing completion fact' }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
760
+ }
785
761
  try {
786
762
  const rework = reworkIntentMutationForCompletion(content, resolved.taskDir, eventIdentity.family, completedArtifact, metadata.timestamp);
787
763
  if ('error' in rework)
@@ -794,16 +770,22 @@ function applyTaskEvent(request, options = {}) {
794
770
  }
795
771
  const step = eventIdentity.phase === 'started' || eventIdentity.target === null ? currentStep : eventIdentity.target;
796
772
  const logStep = eventIdentity.phase === 'started' ? `${eventIdentity.action} [started]` : eventIdentity.action;
797
- const supersededBody = supersededOpenStart
798
- ? appendActivityEntry(section, {
799
- time: metadata.timestamp,
800
- step: `${supersededOpenStart.action} [aborted]`,
801
- agent: normalized.agent,
802
- note: `superseded by ${eventIdentity.action}`
803
- })
804
- : section.body;
805
- const body = appendActivityEntry(supersededOpenStart ? { ...section, body: supersededBody } : section, { time: metadata.timestamp, step: logStep, agent: normalized.agent, note: eventIdentity.note });
773
+ let body = null;
774
+ if (section) {
775
+ const supersededBody = supersededOpenStart
776
+ ? appendActivityEntry(section, {
777
+ time: metadata.timestamp, step: `${supersededOpenStart.action} [aborted]`,
778
+ agent: normalized.agent, note: `superseded by ${eventIdentity.action}`
779
+ }) : section.body;
780
+ body = appendActivityEntry({ ...section, body: supersededBody }, { time: metadata.timestamp, step: logStep, agent: normalized.agent, note: eventIdentity.note });
781
+ }
806
782
  const frontmatterSet = { current_step: step, assigned_to: normalized.agent };
783
+ if (eventIdentity.phase === 'started' || eventIdentity.phase === 'completed') {
784
+ const open = rows.filter((item) => !openRows.includes(item) && (!supersededOpenStart || item.family !== supersededOpenStart.family || item.round !== supersededOpenStart.round));
785
+ if (eventIdentity.phase === 'started')
786
+ open.push({ family: eventIdentity.family, agent: normalized.agent, startedAt: metadata.timestamp, round: normalized.round, fixFor: normalized.fixFor, implementationInput: normalized.implementationInput, transactionId: normalized.transactionId });
787
+ frontmatterSet.lifecycle_execution = serializeLifecycleExecution(open, content);
788
+ }
807
789
  if (currentFact)
808
790
  frontmatterSet.completion_facts = JSON.stringify(replaceCompletionFact(parseCompletionFacts(frontmatter.completion_facts), currentFact));
809
791
  if (completedArtifact && ['analyze', 'plan', 'code'].includes(eventIdentity.family)) {
@@ -869,7 +851,7 @@ function applyTaskEvent(request, options = {}) {
869
851
  if (eventIdentity.phase === 'started' && normalized.implementationInput)
870
852
  frontmatterSet.last_reviewed_commit = '';
871
853
  const mutations = [
872
- { kind: 'frontmatter', set: frontmatterSet, remove: frontmatterRemove }
854
+ { kind: 'frontmatter', set: frontmatterSet, remove: frontmatterRemove, ...(frontmatterSet.lifecycle_execution ? { lifecycleExecutionDomain: 'ordinary' } : {}) }
873
855
  ];
874
856
  if (completedArtifact) {
875
857
  const link = buildArtifactLinkSection(content, completedArtifact);
@@ -901,32 +883,11 @@ function applyTaskEvent(request, options = {}) {
901
883
  body: renderImplementationInputs(implementationRows)
902
884
  });
903
885
  }
904
- mutations.push({ kind: 'section', aliases: ['活动日志', 'Activity Log'], heading: section.heading, body });
886
+ if (section && body !== null)
887
+ mutations.push({ kind: 'section', aliases: ['活动日志', 'Activity Log'], heading: section.heading, body });
905
888
  const result = writeTask({ taskRef: normalized.taskRef, expectedState: 'active', dryRun: normalized.dryRun, mutations }, { ...options, metadataProvider: () => metadata });
906
889
  if (result.status === 'failed')
907
890
  return failed(normalized, result.error, { taskId: result.taskId, taskMdPath: result.taskMdPath, fromStep: currentStep, toStep: step, action: eventIdentity.action, phase: eventIdentity.phase, timestamp: result.timestamp, agentInfraVersion: result.agentInfraVersion, operations: result.operations, artifactContext });
908
- if (!normalized.dryRun && orchestrationCompletion) {
909
- try {
910
- (options.commitOrchestrationCompletion ?? commitOrchestrationStageCompletion)(orchestrationCompletion);
911
- }
912
- catch (error) {
913
- return failed(normalized, {
914
- code: 'EVENT_ORCHESTRATION_COMMIT_FAILED',
915
- message: `task.md was written but orchestration completion could not be persisted; manual recovery is required: ${error instanceof Error ? error.message : String(error)}`
916
- }, {
917
- taskId: result.taskId,
918
- taskMdPath: result.taskMdPath,
919
- fromStep: currentStep,
920
- toStep: step,
921
- action: eventIdentity.action,
922
- phase: eventIdentity.phase,
923
- timestamp: result.timestamp,
924
- agentInfraVersion: result.agentInfraVersion,
925
- operations: result.operations,
926
- artifactContext
927
- });
928
- }
929
- }
930
891
  return {
931
892
  status: result.status, changed: result.changed, event: normalized.event,
932
893
  requestRef: normalized.taskRef, taskId: result.taskId, taskMdPath: result.taskMdPath,
@@ -946,5 +907,21 @@ function successNoOp(request, taskId, taskMdPath, currentStep, eventIdentity, ti
946
907
  artifactContext
947
908
  };
948
909
  }
949
- export { eventCatalog, validateTaskEventRequest, applyTaskEvent };
910
+ function applyTaskEventWithWarnings(request, options = {}) {
911
+ const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
912
+ let warnings = [];
913
+ if (resolved.ok) {
914
+ try {
915
+ const inspected = inspectActivityLog(fs.readFileSync(resolved.taskMdPath, 'utf8'));
916
+ if (!inspected.section)
917
+ warnings = [{ code: 'ACTIVITY_LOG_UNAVAILABLE', message: 'Activity Log is missing or ambiguous; no entry was appended' }];
918
+ else if (inspected.invalidEntries.length)
919
+ warnings = [{ code: 'ACTIVITY_LOG_INVALID_ENTRIES', message: 'Activity Log contains malformed entries' }];
920
+ }
921
+ catch { /* The core reports task read errors. */ }
922
+ }
923
+ const result = applyTaskEvent(request, options);
924
+ return result.status === 'failed' || warnings.length === 0 ? result : { ...result, warnings };
925
+ }
926
+ export { eventCatalog, validateTaskEventRequest, applyTaskEventWithWarnings as applyTaskEvent };
950
927
  //# sourceMappingURL=events.js.map
@@ -7,6 +7,7 @@ import { backfillCompletionComments, inspectCompletionBackfillEligibility } from
7
7
  import { taskIssueIdentity } from '../platform/task-identities.js';
8
8
  import { inspectPlatformIssue, syncPlatformIssue } from '../platform/issues.js';
9
9
  import { resourceIdentityEquals } from '../platform/resource-identity.js';
10
+ import { activityWarnings } from './activity-log.js';
10
11
  import { parseTaskFrontmatter } from './frontmatter.js';
11
12
  import { recoverPlatformOperations } from './platform-operation-recovery.js';
12
13
  import { applyTaskLifecycle, inspectTaskLifecycleProgress, previewTaskCompletion } from './lifecycle.js';
@@ -17,6 +18,7 @@ import { projectFinalizationWarning } from './workflow-warning-intents.js';
17
18
  import { mergeOperationWarnings } from './operation-outcome.js';
18
19
  import { readSandboxControlManifest } from '../sandbox/control/lifecycle.js';
19
20
  import { validateSandboxControlIdentity } from '../sandbox/control/identity-sentinel.js';
21
+ import { parseDeliverySummaryContent, renderDeliverySummaryContent } from '../platform/issue-summary-content.js';
20
22
  const RECEIPT_VERSION = 4;
21
23
  const FINALIZATION_STEPS = ['lifecycle', 'task-comment', 'verification', 'summary'];
22
24
  export function resolveTaskFinalizationDirectory(repoRoot, taskId) {
@@ -206,7 +208,8 @@ function lifecycleStep(result) {
206
208
  changed: result.changed,
207
209
  error: result.error ? errorOf(result.error, 'LIFECYCLE_FAILED') : null,
208
210
  completedSteps: result.completedSteps ?? [],
209
- pendingSteps: result.pendingSteps ?? []
211
+ pendingSteps: result.pendingSteps ?? [],
212
+ warnings: (result.warnings ?? []).map((warning) => ({ ...warning, step: 'lifecycle', target: 'activity-log', severity: 'IMPORTANT', retryable: true }))
210
213
  };
211
214
  }
212
215
  function commentStep(result) {
@@ -220,7 +223,18 @@ function verificationStep(result) {
220
223
  return {
221
224
  status: result.status,
222
225
  changed: false,
223
- error: result.status === 'pass' ? null : verificationFailure(result)
226
+ error: result.status === 'pass' ? null : verificationFailure(result),
227
+ warnings: result.invocations.flatMap(({ payload }) => {
228
+ const checks = Array.isArray(payload.checks) ? payload.checks : [payload];
229
+ return checks.flatMap((check) => {
230
+ if (!check || typeof check !== 'object' || !Array.isArray(check.warnings))
231
+ return [];
232
+ return check.warnings.filter((message) => typeof message === 'string').map((message) => ({
233
+ code: 'VERIFICATION_DIAGNOSTIC', message, retryable: true, step: 'verification',
234
+ target: typeof check.checkId === 'string' ? check.checkId : String(check.type ?? 'check'), severity: 'IMPORTANT'
235
+ }));
236
+ });
237
+ })
224
238
  };
225
239
  }
226
240
  function verificationFailure(result) {
@@ -350,7 +364,7 @@ function issueCapability(receipt, scope) {
350
364
  }
351
365
  function capabilityError(code, message) {
352
366
  const error = new Error(message);
353
- error.name = 'OrchestrationStateError';
367
+ error.name = 'TaskFinalizationCapabilityError';
354
368
  Object.assign(error, { code });
355
369
  return error;
356
370
  }
@@ -569,17 +583,25 @@ function readDeliverySummary(taskDir, taskId) {
569
583
  catch {
570
584
  throw Object.assign(new Error('delivery summary staging record is unavailable'), { code: 'SUMMARY_STAGING_INVALID' });
571
585
  }
572
- if (value.taskId !== taskId || typeof value.body !== 'string' || typeof value.sha256 !== 'string') {
586
+ if (value.taskId !== taskId || !value.content || typeof value.contentSha256 !== 'string') {
573
587
  throw Object.assign(new Error('delivery summary staging record is invalid'), { code: 'SUMMARY_STAGING_INVALID' });
574
588
  }
575
- const canonical = canonicalizeSummaryBody(value.body);
576
- if (!canonical.ok || canonical.value !== value.body) {
577
- throw Object.assign(new Error('delivery summary staging body is not canonical'), { code: 'SUMMARY_STAGING_INVALID' });
589
+ let content;
590
+ try {
591
+ content = parseDeliverySummaryContent(value.content);
578
592
  }
593
+ catch {
594
+ throw Object.assign(new Error('delivery summary staging payload is invalid'), { code: 'SUMMARY_STAGING_INVALID' });
595
+ }
596
+ if (content.taskId !== taskId || createHash('sha256').update(JSON.stringify(content)).digest('hex') !== value.contentSha256) {
597
+ throw Object.assign(new Error('delivery summary staging digest does not match payload'), { code: 'SUMMARY_STAGING_INVALID' });
598
+ }
599
+ const body = renderDeliverySummaryContent(content);
600
+ const canonical = canonicalizeSummaryBody(body);
601
+ if (!canonical.ok)
602
+ throw Object.assign(new Error('delivery summary staging body is not canonical'), { code: 'SUMMARY_STAGING_INVALID' });
579
603
  const digest = createHash('sha256').update(canonical.value).digest('hex');
580
- if (digest !== value.sha256)
581
- throw Object.assign(new Error('delivery summary staging digest does not match body'), { code: 'SUMMARY_STAGING_INVALID' });
582
- return { body: canonical.value, sha256: value.sha256 };
604
+ return { body: canonical.value, sha256: digest };
583
605
  }
584
606
  async function syncPendingSummary(input) {
585
607
  let { receipt } = input;
@@ -639,7 +661,7 @@ async function syncPendingSummary(input) {
639
661
  function terminalResult(taskId, receipt, steps, changed, error = null) {
640
662
  const pending = pendingSteps(receipt);
641
663
  const blocked = [steps.backfill, steps.lifecycle, steps.taskComment, steps.verification, steps.summary].some((step) => step?.status === 'blocked');
642
- const warnings = openWarnings(receipt);
664
+ const warnings = mergeOperationWarnings(openWarnings(receipt), steps.lifecycle?.warnings ?? [], steps.verification?.warnings ?? []);
643
665
  const postLifecyclePending = receipt.lifecycle === 'done' && (pending.some((step) => step !== 'lifecycle') || receipt.warningProjection === 'pending');
644
666
  const terminalVerificationPending = receipt.lifecycle === 'done' && receipt.verification === 'pending';
645
667
  const resultError = error ?? (terminalVerificationPending ? steps.verification?.error : null) ?? null;
@@ -678,7 +700,7 @@ function preparedResult(taskId, receipt, steps, changed) {
678
700
  verification: steps.verification ?? null,
679
701
  summary: steps.summary ?? null,
680
702
  completedSteps: completedSteps(receipt), pendingSteps: pendingSteps(receipt),
681
- result: 'prepared', warnings: openWarnings(receipt), error: null
703
+ result: 'prepared', warnings: mergeOperationWarnings(openWarnings(receipt), steps.lifecycle?.warnings ?? []), error: null
682
704
  };
683
705
  }
684
706
  async function prepareTaskFinalizationCore(request, taskId, options) {
@@ -956,7 +978,7 @@ async function prepareTaskFinalizationCore(request, taskId, options) {
956
978
  }
957
979
  return preparedResult(taskId, receipt, { backfill: backfillResult, lifecycle: lifecycleResult, taskComment, verification, summary: summary.step }, changed);
958
980
  }
959
- async function prepareTaskFinalization(request, options) {
981
+ async function prepareTaskFinalizationInner(request, options) {
960
982
  if (request.intent !== 'complete' || !request.taskRef || !request.agent) {
961
983
  return failed(null, { code: 'TASK_FINALIZATION_PAYLOAD_INVALID', message: 'complete finalization requires taskRef and agent', retryable: false });
962
984
  }
@@ -1135,6 +1157,28 @@ async function commitPreparedTaskFinalization(request, options) {
1135
1157
  return failed(resolved.taskId, detail);
1136
1158
  }
1137
1159
  }
1160
+ function withActivityWarnings(result, request, options) {
1161
+ if (result.status === 'failed' || result.status === 'blocked')
1162
+ return result;
1163
+ const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
1164
+ if (!resolved.ok)
1165
+ return result;
1166
+ let diagnostics;
1167
+ try {
1168
+ diagnostics = activityWarnings(fs.readFileSync(resolved.taskMdPath, 'utf8'));
1169
+ }
1170
+ catch {
1171
+ return result;
1172
+ }
1173
+ const warnings = diagnostics.map((warning) => ({ ...warning, step: 'lifecycle', target: 'activity-log', severity: 'IMPORTANT', retryable: true }));
1174
+ return { ...result, warnings: mergeOperationWarnings(result.warnings, warnings) };
1175
+ }
1176
+ async function prepareTaskFinalization(request, options) {
1177
+ return withActivityWarnings(await prepareTaskFinalizationInner(request, options), request, options);
1178
+ }
1179
+ async function commitPreparedTaskFinalizationWithWarnings(request, options) {
1180
+ return withActivityWarnings(await commitPreparedTaskFinalization(request, options), request, options);
1181
+ }
1138
1182
  async function applyTaskFinalization(request, options) {
1139
1183
  const prepared = await prepareTaskFinalization(request, options);
1140
1184
  if (prepared.status !== 'prepared')
@@ -1153,7 +1197,8 @@ async function applyTaskFinalization(request, options) {
1153
1197
  });
1154
1198
  }
1155
1199
  }
1156
- return commitPreparedTaskFinalization(request, options);
1200
+ const committed = await commitPreparedTaskFinalizationWithWarnings(request, options);
1201
+ return { ...committed, warnings: mergeOperationWarnings(prepared.warnings, committed.warnings) };
1157
1202
  }
1158
- export { applyFinalizationReceiptMutation, commitPreparedTaskFinalization, applyTaskFinalization, prepareTaskFinalization, issueCapability as createFinalizationCapability, readTaskFinalizationReceipt, terminalResult };
1203
+ export { applyFinalizationReceiptMutation, commitPreparedTaskFinalizationWithWarnings as commitPreparedTaskFinalization, applyTaskFinalization, prepareTaskFinalization, issueCapability as createFinalizationCapability, readTaskFinalizationReceipt, terminalResult };
1159
1204
  //# sourceMappingURL=finalization.js.map
@@ -7,7 +7,7 @@ import { LEDGER_COLUMNS, LEDGER_HEADINGS, LEDGER_SECTION_MISSING_CODE, LEDGER_SE
7
7
  import { resolveTaskRef } from './resolve-ref.js';
8
8
  import { writeTask } from './write.js';
9
9
  import { parseLegacyReworkIntentDocument, parseReworkIntentDocument, reworkIntentMutation, upsertReworkIntent } from './rework-intent.js';
10
- import { extractSection, extractSubSection } from './sections.js';
10
+ import { extractSection } from './sections.js';
11
11
  import { parseLifecyclePathDecision } from './lifecycle-path.js';
12
12
  import { scanVisibleMarkdown } from './markdown.js';
13
13
  import { inspectArtifactDirectory } from './artifact-lifecycle.js';
@@ -1,37 +1,42 @@
1
- import { inspectOrchestrationStage, pauseOrchestration, planOrchestrationStageCompletion } from './orchestration.js';
2
- import { resolveTaskRef } from './resolve-ref.js';
3
- function failure(mode, code, message) {
4
- return { ok: false, mode, completionPlan: null, error: { code, message } };
5
- }
6
- function inspectLifecycleExecution(taskRef, request, options = {}) {
7
- const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
8
- if (!resolved.ok)
9
- return failure(request.mode, resolved.code, resolved.message);
10
- if (request.mode === 'standalone') {
11
- return { ok: true, mode: request.mode, completionPlan: null, error: null };
12
- }
13
- if (request.agent) {
14
- const planned = planOrchestrationStageCompletion(taskRef, {
15
- ...request.identity,
16
- agent: request.agent
17
- }, options);
18
- if (planned.plan) {
19
- return { ok: true, mode: request.mode, completionPlan: planned.plan, error: null };
20
- }
21
- return failure(request.mode, planned.result.error?.code ?? 'ORCHESTRATION_PROVENANCE_MISMATCH', planned.result.error?.message ?? 'orchestration provenance validation failed');
1
+ import { parseTypedTaskFrontmatter } from './frontmatter.js';
2
+ const labels = {
3
+ 'Analyze Task': 'analyze', 'Review Analysis': 'review-analysis', 'Plan Task': 'plan',
4
+ 'Review Plan': 'review-plan', 'Code Task': 'code', 'Review Code': 'review-code',
5
+ 'Run Manual Validation': 'validation-run'
6
+ };
7
+ export function lifecycleExecutions(content) {
8
+ const value = parseTypedTaskFrontmatter(content).lifecycle_execution;
9
+ if (value !== undefined) {
10
+ if (typeof value !== 'string')
11
+ throw new Error('invalid lifecycle execution state');
12
+ const state = JSON.parse(value);
13
+ if (!state || typeof state !== 'object' || !('version' in state) || state.version !== 1 || !('open' in state) || !Array.isArray(state.open))
14
+ throw new Error('invalid lifecycle execution state');
15
+ return state.open.map((item) => {
16
+ if (!item || typeof item !== 'object' || !('family' in item) || typeof item.family !== 'string' || ![...Object.values(labels), 'manual-validation', 'other'].includes(item.family) || !('agent' in item) || typeof item.agent !== 'string' || !('startedAt' in item) || typeof item.startedAt !== 'string')
17
+ throw new Error('invalid lifecycle execution identity');
18
+ return item;
19
+ });
22
20
  }
23
- const inspected = inspectOrchestrationStage(taskRef, request.identity, options);
24
- if (inspected.status !== 'failed') {
25
- return { ok: true, mode: request.mode, completionPlan: null, error: null };
26
- }
27
- return failure(request.mode, inspected.error?.code ?? 'ORCHESTRATION_PROVENANCE_MISMATCH', inspected.error?.message ?? 'orchestration provenance validation failed');
21
+ return [];
22
+ }
23
+ export function prReviewExecution(content) {
24
+ const value = parseTypedTaskFrontmatter(content).lifecycle_execution;
25
+ if (value === undefined)
26
+ return { open: null, terminals: [] };
27
+ if (typeof value !== 'string')
28
+ throw new Error('invalid lifecycle execution state');
29
+ const state = JSON.parse(value);
30
+ if (state.version !== 1 || !Array.isArray(state.open))
31
+ throw new Error('invalid lifecycle execution state');
32
+ const pr = state.prReview ?? { open: null, terminals: [] };
33
+ const valid = (item) => item && typeof item.artifact === 'string' && typeof item.head === 'string' && typeof item.agent === 'string';
34
+ if (!Array.isArray(pr.terminals) || (pr.open !== null && (!valid(pr.open) || typeof pr.open.startedAt !== 'string')) || !pr.terminals.every((item) => valid(item) && typeof item.note === 'string'))
35
+ throw new Error('invalid PR review execution state');
36
+ return pr;
28
37
  }
29
- function validateLifecycleExecution(taskRef, request, options = {}) {
30
- const inspected = inspectLifecycleExecution(taskRef, request, options);
31
- if (inspected.ok || request.mode === 'standalone' || request.dryRun)
32
- return inspected;
33
- const paused = pauseOrchestration(taskRef, inspected.error?.code ?? 'ORCHESTRATION_PROVENANCE_MISMATCH', inspected.error?.message ?? 'orchestration provenance validation failed', true, options);
34
- return failure(request.mode, paused.run?.pause?.code ?? inspected.error?.code ?? 'ORCHESTRATION_PROVENANCE_MISMATCH', paused.run?.pause?.message ?? inspected.error?.message ?? 'orchestration provenance validation failed');
38
+ export function serializeLifecycleExecution(open, content, prReview) {
39
+ const pr = prReview ?? (content ? prReviewExecution(content) : { open: null, terminals: [] });
40
+ return JSON.stringify({ version: 1, open, prReview: pr });
35
41
  }
36
- export { inspectLifecycleExecution, validateLifecycleExecution };
37
42
  //# sourceMappingURL=lifecycle-execution.js.map