@fitlab-ai/agent-infra 0.12.1 → 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 (303) 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 +18 -10
  21. package/dist/lib/internal/task-create.js +1 -1
  22. package/dist/lib/internal/task-event.js +1 -8
  23. package/dist/lib/internal/task-finalization.js +0 -1
  24. package/dist/lib/internal/task-lifecycle.js +2 -2
  25. package/dist/lib/internal/task-operation-registry.js +4 -20
  26. package/dist/lib/internal/task-review.js +4 -4
  27. package/dist/lib/platform/comment-safety.js +1 -7
  28. package/dist/lib/platform/in-label-sync.js +1 -14
  29. package/dist/lib/platform/issue-comments.js +1 -16
  30. package/dist/lib/platform/issues.js +1 -1
  31. package/dist/lib/platform/operation-coordinator.js +4 -2
  32. package/dist/lib/platform/pr-change-report.js +1 -4
  33. package/dist/lib/platform/pr-checks.js +2 -8
  34. package/dist/lib/platform/provider-validation.js +0 -20
  35. package/dist/lib/platform/pull-requests.js +73 -84
  36. package/dist/lib/platform/releases.js +1 -43
  37. package/dist/lib/platform/verification-required.js +0 -2
  38. package/dist/lib/platform/verification-sync.js +1 -79
  39. package/dist/lib/process-data/normalize.js +1 -185
  40. package/dist/lib/process-data/privacy.js +1 -16
  41. package/dist/lib/process-data/sources.js +2 -279
  42. package/dist/lib/render.js +0 -12
  43. package/dist/lib/run/index.js +15 -10
  44. package/dist/lib/run/skills.js +0 -3
  45. package/dist/lib/sandbox/commands/create.js +40 -53
  46. package/dist/lib/sandbox/commands/list-running.js +0 -18
  47. package/dist/lib/sandbox/commands/start.js +7 -8
  48. package/dist/lib/sandbox/constants.js +0 -6
  49. package/dist/lib/sandbox/control/client.js +0 -1
  50. package/dist/lib/sandbox/control/container-identity.js +1 -16
  51. package/dist/lib/sandbox/control/executor.js +0 -4
  52. package/dist/lib/sandbox/control/identity-sentinel.js +0 -7
  53. package/dist/lib/sandbox/control/lifecycle.js +21 -37
  54. package/dist/lib/sandbox/control/native-file-lock.js +0 -3
  55. package/dist/lib/sandbox/control/server.js +18 -38
  56. package/dist/lib/sandbox/control/state.js +1 -9
  57. package/dist/lib/sandbox/dockerfile.js +0 -6
  58. package/dist/lib/sandbox/engine.js +0 -14
  59. package/dist/lib/sandbox/engines/docker-exact-discovery.js +1 -4
  60. package/dist/lib/sandbox/engines/wsl2-paths.js +0 -3
  61. package/dist/lib/sandbox/recovery.js +24 -26
  62. package/dist/lib/sandbox/removal.js +11 -519
  63. package/dist/lib/sandbox/task-resolver.js +0 -41
  64. package/dist/lib/sandbox/tools.js +1 -4
  65. package/dist/lib/sandbox/workspace-view.js +1 -2
  66. package/dist/lib/server/display.js +0 -6
  67. package/dist/lib/task/activity-intent.js +45 -40
  68. package/dist/lib/task/activity-log.js +9 -16
  69. package/dist/lib/task/artifact-command.js +1 -1
  70. package/dist/lib/task/artifact-lifecycle.js +61 -63
  71. package/dist/lib/task/artifact-name.js +0 -6
  72. package/dist/lib/task/artifact-operations.js +3 -3
  73. package/dist/lib/task/capabilities.js +4 -5
  74. package/dist/lib/task/commands/log.js +0 -6
  75. package/dist/lib/task/commands/status.js +17 -60
  76. package/dist/lib/task/commit-operation.js +28 -39
  77. package/dist/lib/task/completion-facts.js +56 -43
  78. package/dist/lib/task/control-authority.js +23 -256
  79. package/dist/lib/task/control-recovery.js +3 -5
  80. package/dist/lib/task/create.js +2 -4
  81. package/dist/lib/task/decision-intents.js +8 -9
  82. package/dist/lib/task/delivery-target.js +1 -40
  83. package/dist/lib/task/events.js +84 -107
  84. package/dist/lib/task/finalization.js +44 -8
  85. package/dist/lib/task/ledger-intents.js +1 -1
  86. package/dist/lib/task/lifecycle-execution.js +38 -33
  87. package/dist/lib/task/lifecycle.js +49 -41
  88. package/dist/lib/task/local-artifact-finalization.js +1 -4
  89. package/dist/lib/task/manual-validation-evidence.js +1 -37
  90. package/dist/lib/task/platform-operation-recovery.js +67 -24
  91. package/dist/lib/task/pr-delivery-fact.js +2 -5
  92. package/dist/lib/task/qualification-confirmation.js +5 -7
  93. package/dist/lib/task/resolve-ref.js +1 -25
  94. package/dist/lib/task/review-command.js +2 -2
  95. package/dist/lib/task/review-finalization.js +1 -21
  96. package/dist/lib/task/review-fingerprint.js +0 -4
  97. package/dist/lib/task/secure-fs.js +0 -56
  98. package/dist/lib/task/short-id.js +1 -39
  99. package/dist/lib/task/skill-scope.js +0 -1
  100. package/dist/lib/task/verification-engine.js +58 -282
  101. package/dist/lib/task/verification.js +6 -3
  102. package/dist/lib/task/write.js +11 -1
  103. package/lib/agent-clients/adapter.ts +0 -76
  104. package/lib/agent-clients/adapters/antigravity-cli.ts +0 -5
  105. package/lib/agent-clients/adapters/claude-code-credentials.ts +0 -19
  106. package/lib/agent-clients/adapters/claude-code.ts +0 -9
  107. package/lib/agent-clients/adapters/codex.ts +0 -56
  108. package/lib/agent-clients/adapters/opencode.ts +0 -5
  109. package/lib/agent-clients/adapters/traecli.ts +0 -5
  110. package/lib/agent-clients/config.ts +20 -61
  111. package/lib/agent-clients/registry.ts +1 -34
  112. package/lib/agent-clients/schema.ts +0 -18
  113. package/lib/agent-clients/tokens.ts +1 -2
  114. package/lib/agent-clients/types.ts +0 -15
  115. package/lib/decide.ts +1 -0
  116. package/lib/git/worktree-identity.ts +0 -10
  117. package/lib/internal/agent-client.ts +2 -70
  118. package/lib/internal/cli-route-inventory.ts +1 -4
  119. package/lib/internal/manual-validation.ts +16 -9
  120. package/lib/internal/task-create.ts +0 -1
  121. package/lib/internal/task-event.ts +1 -5
  122. package/lib/internal/task-finalization.ts +0 -1
  123. package/lib/internal/task-lifecycle.ts +3 -5
  124. package/lib/internal/task-operation-registry.ts +3 -19
  125. package/lib/internal/task-review.ts +4 -4
  126. package/lib/platform/comment-safety.ts +0 -10
  127. package/lib/platform/github-provider.ts +0 -2
  128. package/lib/platform/in-label-sync.ts +0 -16
  129. package/lib/platform/issue-comments.ts +0 -21
  130. package/lib/platform/issues.ts +0 -2
  131. package/lib/platform/operation-coordinator.ts +4 -2
  132. package/lib/platform/pr-change-report.ts +0 -5
  133. package/lib/platform/pr-checks.ts +1 -10
  134. package/lib/platform/pr-review.ts +1 -1
  135. package/lib/platform/provider-bridge.ts +0 -1
  136. package/lib/platform/provider-loader.ts +1 -5
  137. package/lib/platform/provider-validation.ts +1 -49
  138. package/lib/platform/pull-requests.ts +64 -99
  139. package/lib/platform/releases.ts +1 -40
  140. package/lib/platform/verification-required.ts +0 -2
  141. package/lib/platform/verification-sync.ts +0 -94
  142. package/lib/process-data/normalize.ts +1 -186
  143. package/lib/process-data/privacy.ts +2 -19
  144. package/lib/process-data/sources.ts +3 -283
  145. package/lib/render.ts +0 -15
  146. package/lib/run/index.ts +13 -7
  147. package/lib/run/skills.ts +0 -4
  148. package/lib/sandbox/commands/create.ts +37 -74
  149. package/lib/sandbox/commands/list-running.ts +0 -19
  150. package/lib/sandbox/commands/start.ts +7 -10
  151. package/lib/sandbox/constants.ts +0 -8
  152. package/lib/sandbox/control/client.ts +0 -1
  153. package/lib/sandbox/control/container-identity.ts +1 -16
  154. package/lib/sandbox/control/executor.ts +1 -5
  155. package/lib/sandbox/control/identity-sentinel.ts +0 -8
  156. package/lib/sandbox/control/lifecycle.ts +18 -51
  157. package/lib/sandbox/control/native-file-lock.ts +0 -8
  158. package/lib/sandbox/control/protocol.ts +0 -2
  159. package/lib/sandbox/control/server.ts +13 -39
  160. package/lib/sandbox/control/state.ts +1 -10
  161. package/lib/sandbox/dockerfile.ts +0 -11
  162. package/lib/sandbox/engine.ts +0 -17
  163. package/lib/sandbox/engines/docker-exact-discovery.ts +1 -5
  164. package/lib/sandbox/engines/wsl2-paths.ts +0 -4
  165. package/lib/sandbox/recovery.ts +24 -26
  166. package/lib/sandbox/removal.ts +11 -696
  167. package/lib/sandbox/shell.ts +1 -1
  168. package/lib/sandbox/task-resolver.ts +0 -48
  169. package/lib/sandbox/tools.ts +1 -5
  170. package/lib/sandbox/workspace-view.ts +2 -4
  171. package/lib/server/display.ts +0 -14
  172. package/lib/server/process-control.ts +1 -1
  173. package/lib/task/activity-intent.ts +36 -44
  174. package/lib/task/activity-log.ts +9 -22
  175. package/lib/task/artifact-command.ts +1 -1
  176. package/lib/task/artifact-lifecycle.ts +58 -67
  177. package/lib/task/artifact-name.ts +0 -7
  178. package/lib/task/artifact-operations.ts +3 -3
  179. package/lib/task/capabilities.ts +5 -6
  180. package/lib/task/commands/log.ts +0 -7
  181. package/lib/task/commands/status.ts +14 -79
  182. package/lib/task/commit-operation.ts +29 -51
  183. package/lib/task/completion-facts.ts +45 -42
  184. package/lib/task/control-authority.ts +27 -317
  185. package/lib/task/control-recovery.ts +2 -5
  186. package/lib/task/create.ts +2 -5
  187. package/lib/task/decision-intents.ts +5 -5
  188. package/lib/task/delivery-target.ts +0 -40
  189. package/lib/task/events.ts +89 -123
  190. package/lib/task/finalization.ts +41 -9
  191. package/lib/task/ledger-intents.ts +1 -1
  192. package/lib/task/lifecycle-execution.ts +37 -89
  193. package/lib/task/lifecycle.ts +48 -44
  194. package/lib/task/local-artifact-finalization.ts +0 -7
  195. package/lib/task/manual-validation-evidence.ts +1 -47
  196. package/lib/task/platform-operation-recovery.ts +50 -26
  197. package/lib/task/pr-delivery-fact.ts +2 -11
  198. package/lib/task/qualification-confirmation.ts +6 -6
  199. package/lib/task/resolve-ref.ts +0 -23
  200. package/lib/task/review-command.ts +2 -2
  201. package/lib/task/review-finalization.ts +1 -27
  202. package/lib/task/review-fingerprint.ts +0 -8
  203. package/lib/task/secure-fs.ts +0 -42
  204. package/lib/task/short-id.ts +0 -43
  205. package/lib/task/skill-scope.ts +0 -1
  206. package/lib/task/verification-engine.ts +56 -287
  207. package/lib/task/verification.ts +5 -5
  208. package/lib/task/write.ts +12 -1
  209. package/package.json +2 -2
  210. package/templates/.agents/README.en.md +1 -3
  211. package/templates/.agents/README.zh-CN.md +0 -2
  212. package/templates/.agents/rules/README.en.md +0 -1
  213. package/templates/.agents/rules/README.zh-CN.md +0 -1
  214. package/templates/.agents/rules/commit-and-pr.en.md +1 -1
  215. package/templates/.agents/rules/commit-and-pr.zh-CN.md +1 -1
  216. package/templates/.agents/rules/no-mid-flow-questions.en.md +0 -10
  217. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +0 -10
  218. package/templates/.agents/rules/pr-sync.en.md +1 -1
  219. package/templates/.agents/rules/pr-sync.zh-CN.md +1 -1
  220. package/templates/.agents/rules/task-management.en.md +3 -3
  221. package/templates/.agents/rules/task-management.zh-CN.md +3 -3
  222. package/templates/.agents/skills/analyze-task/SKILL.en.md +3 -3
  223. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +3 -3
  224. package/templates/.agents/skills/cancel-task/SKILL.en.md +2 -2
  225. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +2 -2
  226. package/templates/.agents/skills/code-task/SKILL.en.md +2 -2
  227. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +4 -4
  228. package/templates/.agents/skills/commit/SKILL.en.md +2 -2
  229. package/templates/.agents/skills/commit/SKILL.zh-CN.md +2 -2
  230. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +6 -6
  231. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +6 -6
  232. package/templates/.agents/skills/plan-task/SKILL.en.md +2 -2
  233. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +2 -2
  234. package/templates/.agents/skills/review-analysis/SKILL.en.md +3 -3
  235. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +3 -3
  236. package/templates/.agents/skills/review-code/SKILL.en.md +5 -5
  237. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +5 -5
  238. package/templates/.agents/skills/review-plan/SKILL.en.md +3 -3
  239. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +3 -3
  240. package/templates/.agents/skills/review-pr/SKILL.en.md +4 -4
  241. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +4 -4
  242. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +1 -1
  243. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +1 -1
  244. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +3 -75
  245. package/templates/.agents/templates/task.en.md +1 -0
  246. package/templates/.agents/templates/task.zh-CN.md +1 -0
  247. package/templates/.claude/settings.json +0 -24
  248. package/templates/.codex/hooks.json +0 -50
  249. package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +0 -582
  250. package/dist/lib/agent-clients/adapters/codex-lifecycle/binding.js +0 -114
  251. package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +0 -237
  252. package/dist/lib/agent-clients/adapters/codex-lifecycle/cli.js +0 -443
  253. package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +0 -236
  254. package/dist/lib/agent-clients/adapters/codex-lifecycle/recovery.js +0 -292
  255. package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +0 -267
  256. package/dist/lib/agent-clients/adapters/codex-orchestration.js +0 -466
  257. package/dist/lib/internal/task-orchestration.js +0 -71
  258. package/dist/lib/platform/verification.js +0 -6
  259. package/dist/lib/run/prompt.js +0 -2
  260. package/dist/lib/sandbox/engines/authority.js +0 -289
  261. package/dist/lib/task/delegation-receipts.js +0 -410
  262. package/dist/lib/task/orchestration.js +0 -1233
  263. package/dist/lib/task/verification-checks.js +0 -9
  264. package/dist/lib/task/workspace-snapshot.js +0 -121
  265. package/dist/lifecycle-build-manifest.json +0 -6
  266. package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +0 -688
  267. package/lib/agent-clients/adapters/codex-lifecycle/binding.ts +0 -147
  268. package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +0 -349
  269. package/lib/agent-clients/adapters/codex-lifecycle/cli.ts +0 -506
  270. package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +0 -385
  271. package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +0 -41
  272. package/lib/agent-clients/adapters/codex-lifecycle/recovery.ts +0 -418
  273. package/lib/agent-clients/adapters/codex-lifecycle/store.ts +0 -354
  274. package/lib/agent-clients/adapters/codex-orchestration.ts +0 -630
  275. package/lib/internal/task-orchestration.ts +0 -74
  276. package/lib/platform/verification.ts +0 -11
  277. package/lib/run/prompt.ts +0 -1
  278. package/lib/sandbox/engines/authority.ts +0 -365
  279. package/lib/task/delegation-receipts.ts +0 -547
  280. package/lib/task/orchestration.ts +0 -1651
  281. package/lib/task/verification-checks.ts +0 -10
  282. package/lib/task/workspace-snapshot.ts +0 -144
  283. package/templates/.agents/hooks/lifecycle-delegation.js +0 -140
  284. package/templates/.agents/rules/lifecycle-orchestration.en.md +0 -44
  285. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +0 -44
  286. package/templates/.agents/skills/run-task/SKILL.en.md +0 -29
  287. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +0 -29
  288. package/templates/.agents/skills/run-task/config/verify.en.json +0 -10
  289. package/templates/.agents/skills/run-task/config/verify.zh-CN.json +0 -10
  290. package/templates/.agents/skills/run-task/reference/host-validation.en.md +0 -24
  291. package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +0 -24
  292. package/templates/.claude/agents/agent-infra-lifecycle-executor.en.md +0 -6
  293. package/templates/.claude/agents/agent-infra-lifecycle-executor.zh-CN.md +0 -6
  294. package/templates/.claude/agents/agent-infra-lifecycle-reviewer.en.md +0 -6
  295. package/templates/.claude/agents/agent-infra-lifecycle-reviewer.zh-CN.md +0 -6
  296. package/templates/.claude/commands/run-task.en.md +0 -8
  297. package/templates/.claude/commands/run-task.zh-CN.md +0 -8
  298. package/templates/.codex/agents/agent-infra-lifecycle-executor.en.toml +0 -3
  299. package/templates/.codex/agents/agent-infra-lifecycle-executor.zh-CN.toml +0 -3
  300. package/templates/.codex/agents/agent-infra-lifecycle-reviewer.en.toml +0 -3
  301. package/templates/.codex/agents/agent-infra-lifecycle-reviewer.zh-CN.toml +0 -3
  302. package/templates/.opencode/commands/run-task.en.md +0 -11
  303. package/templates/.opencode/commands/run-task.zh-CN.md +0 -11
@@ -8,6 +8,7 @@ import { readDeliveryDefaults, validateBaseRef, validateRemote } from './deliver
8
8
  import { buildUnboundFact, encodePrDeliveryFact } from './pr-delivery-fact.js';
9
9
  import { CANDIDATE_COLUMNS, CONSTRAINT_COLUMNS, parseTaskQualification } from './qualification-audit.js';
10
10
  import { enumerateAllTaskDirs } from './resolve-ref.js';
11
+ import { serializeLifecycleExecution } from './lifecycle-execution.js';
11
12
  import { parseTaskFrontmatter } from './frontmatter.js';
12
13
  import { AGENT_TOKEN_VALUES } from '../agent-clients/tokens.js';
13
14
  import { resolveProjectTaskWorkspaceRoot } from './workspace-root.js';
@@ -23,7 +24,6 @@ function payloadError(message) {
23
24
  }
24
25
  function exactKeys(value, expected, label, optional = []) {
25
26
  const actual = Object.keys(value).sort();
26
- const wanted = [...expected].sort();
27
27
  const allowed = new Set([...expected, ...optional]);
28
28
  if (actual.some((key) => !allowed.has(key))) {
29
29
  payloadError(`${label} has unknown or missing fields`);
@@ -134,9 +134,6 @@ function taskIdFor(date) {
134
134
  const pad = (value) => String(value).padStart(2, '0');
135
135
  return `TASK-${date.getFullYear()}${pad(date.getMonth() + 1)}${pad(date.getDate())}-${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`;
136
136
  }
137
- function yamlString(value) {
138
- return JSON.stringify(value);
139
- }
140
137
  function markdownBlock(value) {
141
138
  return value.split(/\r?\n/).map((line) => /^(?:#{1,6}\s|```)/.test(line) ? `\\${line}` : line).join('\n');
142
139
  }
@@ -237,6 +234,7 @@ function renderTask(params) {
237
234
  'target_date:',
238
235
  'current_step: requirement-analysis',
239
236
  `assigned_to: ${candidate.agent}`,
237
+ `lifecycle_execution: ${JSON.stringify(serializeLifecycleExecution([]))}`,
240
238
  `pr_delivery_fact: ${JSON.stringify(encodePrDeliveryFact(buildUnboundFact()))}`,
241
239
  `delivery_remote: ${candidate.deliveryRemote ?? params.delivery.remote}`,
242
240
  `delivery_base_ref: ${candidate.deliveryBaseRef ?? params.delivery.baseRef}`,
@@ -1,5 +1,5 @@
1
1
  import fs from 'node:fs';
2
- import { appendActivityEntry, locateActivityLog } from './activity-log.js';
2
+ import { activityWarnings, appendActivityEntry, locateActivityLog } from './activity-log.js';
3
3
  import { isDecisionItem, listDecisionItems, selectDecisionItem } from './decision-items.js';
4
4
  import { createImplementationInput, finalizeImplementationInput, IMPLEMENTATION_INPUT_ALIASES, parseImplementationInputs, renderImplementationInputs, selectDeclaredImplementationInput } from './implementation-inputs.js';
5
5
  import { LEDGER_COLUMNS, LEDGER_HEADINGS, LEDGER_SECTION_MISSING_CODE, LEDGER_SECTION_MISSING_MESSAGE, parseLedgerDocument } from './ledger.js';
@@ -77,7 +77,7 @@ function applyHumanDecision(request, options = {}) {
77
77
  const replay = existingDecision(content, direct[0], request.decision.trim(), request.needsImplementation);
78
78
  if ('conflict' in replay)
79
79
  return failed('DECISION_CONFLICT', replay.conflict, resolved.taskId, direct[0].id);
80
- return { status: 'no-op', changed: false, taskId: resolved.taskId, ledgerId: direct[0].id, recordId: replay.recordId, implementationInputId: replay.implementationInputId, operations: [], error: null };
80
+ return { status: 'no-op', changed: false, taskId: resolved.taskId, ledgerId: direct[0].id, recordId: replay.recordId, implementationInputId: replay.implementationInputId, operations: [], error: null, warnings: activityWarnings(content) };
81
81
  }
82
82
  catch (error) {
83
83
  return failed('DECISION_DOCUMENT_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId, direct[0].id);
@@ -126,8 +126,6 @@ function applyHumanDecision(request, options = {}) {
126
126
  const decision = request.decision.trim();
127
127
  const record = `### ${recordId}\n\n- **原账本 ID**:${row.id}\n- **裁决时间**:${metadata.timestamp}\n- **裁决结果**:${decision}`;
128
128
  const activity = locateActivityLog(content);
129
- if (!activity)
130
- return failed('DECISION_ACTIVITY_MISSING', 'activity log section is missing or ambiguous', resolved.taskId, row.id);
131
129
  const mutations = [
132
130
  {
133
131
  kind: 'table-row', action: 'upsert', sectionAliases: LEDGER_HEADINGS, columns: LEDGER_COLUMNS,
@@ -155,10 +153,11 @@ function applyHumanDecision(request, options = {}) {
155
153
  body: renderImplementationInputs(nextInputs)
156
154
  });
157
155
  }
158
- mutations.push({
159
- kind: 'section', aliases: ACTIVITY_ALIASES, heading: activity.heading,
160
- body: appendActivityEntry(activity, { time: metadata.timestamp, step: 'Human Decision', agent: 'human', note: `${row.id} decided → ${recordId}` })
161
- });
156
+ if (activity)
157
+ mutations.push({
158
+ kind: 'section', aliases: ACTIVITY_ALIASES, heading: activity.heading,
159
+ body: appendActivityEntry(activity, { time: metadata.timestamp, step: 'Human Decision', agent: 'human', note: `${row.id} decided → ${recordId}` })
160
+ });
162
161
  try {
163
162
  const parsedRework = parseReworkIntentDocument(content);
164
163
  if (!parsedRework.ok)
@@ -177,7 +176,7 @@ function applyHumanDecision(request, options = {}) {
177
176
  });
178
177
  if (writeResult.status === 'failed')
179
178
  return failed(writeResult.error.code, writeResult.error.message, writeResult.taskId, row.id);
180
- return { status: writeResult.status, changed: writeResult.changed, taskId: writeResult.taskId, ledgerId: row.id, recordId, implementationInputId, operations: writeResult.operations, error: null };
179
+ return { status: writeResult.status, changed: writeResult.changed, taskId: writeResult.taskId, ledgerId: row.id, recordId, implementationInputId, operations: writeResult.operations, error: null, warnings: activityWarnings(content) };
181
180
  }
182
181
  export { applyHumanDecision };
183
182
  //# sourceMappingURL=decision-intents.js.map
@@ -1,6 +1,5 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { execFileSync } from 'node:child_process';
4
3
  const REMOTE_RE = /^(?!-)(?!.*\.\.)(?!.*[~^:?*\\\s])[A-Za-z0-9._/-]+$/;
5
4
  const REF_RE = /^(?!-)(?!.*\.\.)(?!.*(?:^|\/)\.)(?!.*[~^:?*\\\s])[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)*$/;
6
5
  function validateRemote(value) {
@@ -55,43 +54,5 @@ function resolveDeliveryTarget(repoRoot, existing = {}, explicit = {}) {
55
54
  return defaults;
56
55
  return bindDeliveryTarget({ defaults: defaults.value, existing, explicit });
57
56
  }
58
- function gitText(repoRoot, args) {
59
- return execFileSync('git', [...args], {
60
- cwd: repoRoot,
61
- encoding: 'utf8',
62
- stdio: ['ignore', 'pipe', 'pipe']
63
- }).trim();
64
- }
65
- function resolveTargetHead(repoRoot, target) {
66
- try {
67
- const output = gitText(repoRoot, ['ls-remote', '--refs', target.remote, `refs/heads/${target.baseRef}`]);
68
- const head = output.split(/\s+/)[0] ?? '';
69
- if (!/^[a-f0-9]{40}$/i.test(head)) {
70
- return { ok: false, code: 'DELIVERY_TARGET_UNAVAILABLE', message: `Delivery target ${target.remote}/${target.baseRef} is unavailable` };
71
- }
72
- try {
73
- gitText(repoRoot, ['cat-file', '-e', `${head}^{commit}`]);
74
- }
75
- catch {
76
- return { ok: false, code: 'DELIVERY_TARGET_OBJECT_MISSING', message: `Delivery target commit ${head} is not available locally` };
77
- }
78
- return { ok: true, value: target, head };
79
- }
80
- catch (error) {
81
- return { ok: false, code: 'DELIVERY_TARGET_UNAVAILABLE', message: error instanceof Error ? error.message : String(error) };
82
- }
83
- }
84
- function resolveDiffBase(repoRoot, reviewedHead, targetHead) {
85
- try {
86
- const diffBase = gitText(repoRoot, ['merge-base', reviewedHead, targetHead]);
87
- if (!/^[a-f0-9]{40}$/i.test(diffBase)) {
88
- return { ok: false, code: 'DELIVERY_DIFF_BASE_UNAVAILABLE', message: 'Git returned an invalid diff base' };
89
- }
90
- return { ok: true, diffBase };
91
- }
92
- catch (error) {
93
- return { ok: false, code: 'DELIVERY_DIFF_BASE_UNAVAILABLE', message: error instanceof Error ? error.message : String(error) };
94
- }
95
- }
96
- export { bindDeliveryTarget, readDeliveryDefaults, resolveDeliveryTarget, resolveTargetHead, resolveDiffBase, validateBaseRef, validateRemote };
57
+ export { bindDeliveryTarget, readDeliveryDefaults, resolveDeliveryTarget, validateBaseRef, validateRemote };
97
58
  //# sourceMappingURL=delivery-target.js.map
@@ -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';
@@ -207,7 +208,8 @@ function lifecycleStep(result) {
207
208
  changed: result.changed,
208
209
  error: result.error ? errorOf(result.error, 'LIFECYCLE_FAILED') : null,
209
210
  completedSteps: result.completedSteps ?? [],
210
- pendingSteps: result.pendingSteps ?? []
211
+ pendingSteps: result.pendingSteps ?? [],
212
+ warnings: (result.warnings ?? []).map((warning) => ({ ...warning, step: 'lifecycle', target: 'activity-log', severity: 'IMPORTANT', retryable: true }))
211
213
  };
212
214
  }
213
215
  function commentStep(result) {
@@ -221,7 +223,18 @@ function verificationStep(result) {
221
223
  return {
222
224
  status: result.status,
223
225
  changed: false,
224
- 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
+ })
225
238
  };
226
239
  }
227
240
  function verificationFailure(result) {
@@ -351,7 +364,7 @@ function issueCapability(receipt, scope) {
351
364
  }
352
365
  function capabilityError(code, message) {
353
366
  const error = new Error(message);
354
- error.name = 'OrchestrationStateError';
367
+ error.name = 'TaskFinalizationCapabilityError';
355
368
  Object.assign(error, { code });
356
369
  return error;
357
370
  }
@@ -648,7 +661,7 @@ async function syncPendingSummary(input) {
648
661
  function terminalResult(taskId, receipt, steps, changed, error = null) {
649
662
  const pending = pendingSteps(receipt);
650
663
  const blocked = [steps.backfill, steps.lifecycle, steps.taskComment, steps.verification, steps.summary].some((step) => step?.status === 'blocked');
651
- const warnings = openWarnings(receipt);
664
+ const warnings = mergeOperationWarnings(openWarnings(receipt), steps.lifecycle?.warnings ?? [], steps.verification?.warnings ?? []);
652
665
  const postLifecyclePending = receipt.lifecycle === 'done' && (pending.some((step) => step !== 'lifecycle') || receipt.warningProjection === 'pending');
653
666
  const terminalVerificationPending = receipt.lifecycle === 'done' && receipt.verification === 'pending';
654
667
  const resultError = error ?? (terminalVerificationPending ? steps.verification?.error : null) ?? null;
@@ -687,7 +700,7 @@ function preparedResult(taskId, receipt, steps, changed) {
687
700
  verification: steps.verification ?? null,
688
701
  summary: steps.summary ?? null,
689
702
  completedSteps: completedSteps(receipt), pendingSteps: pendingSteps(receipt),
690
- result: 'prepared', warnings: openWarnings(receipt), error: null
703
+ result: 'prepared', warnings: mergeOperationWarnings(openWarnings(receipt), steps.lifecycle?.warnings ?? []), error: null
691
704
  };
692
705
  }
693
706
  async function prepareTaskFinalizationCore(request, taskId, options) {
@@ -965,7 +978,7 @@ async function prepareTaskFinalizationCore(request, taskId, options) {
965
978
  }
966
979
  return preparedResult(taskId, receipt, { backfill: backfillResult, lifecycle: lifecycleResult, taskComment, verification, summary: summary.step }, changed);
967
980
  }
968
- async function prepareTaskFinalization(request, options) {
981
+ async function prepareTaskFinalizationInner(request, options) {
969
982
  if (request.intent !== 'complete' || !request.taskRef || !request.agent) {
970
983
  return failed(null, { code: 'TASK_FINALIZATION_PAYLOAD_INVALID', message: 'complete finalization requires taskRef and agent', retryable: false });
971
984
  }
@@ -1144,6 +1157,28 @@ async function commitPreparedTaskFinalization(request, options) {
1144
1157
  return failed(resolved.taskId, detail);
1145
1158
  }
1146
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
+ }
1147
1182
  async function applyTaskFinalization(request, options) {
1148
1183
  const prepared = await prepareTaskFinalization(request, options);
1149
1184
  if (prepared.status !== 'prepared')
@@ -1162,7 +1197,8 @@ async function applyTaskFinalization(request, options) {
1162
1197
  });
1163
1198
  }
1164
1199
  }
1165
- return commitPreparedTaskFinalization(request, options);
1200
+ const committed = await commitPreparedTaskFinalizationWithWarnings(request, options);
1201
+ return { ...committed, warnings: mergeOperationWarnings(prepared.warnings, committed.warnings) };
1166
1202
  }
1167
- export { applyFinalizationReceiptMutation, commitPreparedTaskFinalization, applyTaskFinalization, prepareTaskFinalization, issueCapability as createFinalizationCapability, readTaskFinalizationReceipt, terminalResult };
1203
+ export { applyFinalizationReceiptMutation, commitPreparedTaskFinalizationWithWarnings as commitPreparedTaskFinalization, applyTaskFinalization, prepareTaskFinalization, issueCapability as createFinalizationCapability, readTaskFinalizationReceipt, terminalResult };
1168
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';