@fitlab-ai/agent-infra 0.9.13 → 0.9.15

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 (428) hide show
  1. package/README.md +10 -0
  2. package/README.zh-CN.md +10 -0
  3. package/bin/cli.ts +26 -9
  4. package/bin/internal-cli.sh +45 -0
  5. package/dist/bin/cli.js +173 -157
  6. package/dist/bin/internal-cli.js +126 -42
  7. package/dist/lib/agent-client.js +5 -0
  8. package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +165 -27
  9. package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +3 -2
  10. package/dist/lib/defaults.json +103 -103
  11. package/dist/lib/fs/durable-write.js +37 -0
  12. package/dist/lib/fs/file-lock.js +111 -0
  13. package/dist/lib/host-control/audit.js +19 -0
  14. package/dist/lib/host-control/client.js +142 -0
  15. package/dist/lib/host-control/command.js +49 -0
  16. package/dist/lib/host-control/path.js +160 -0
  17. package/dist/lib/host-control/secure-fs.js +140 -0
  18. package/dist/lib/host-control/server.js +159 -0
  19. package/dist/lib/host-control/service.js +112 -0
  20. package/dist/lib/init.js +11 -2
  21. package/dist/lib/internal/agent-client.js +5 -2
  22. package/dist/lib/internal/cli-route-inventory.js +154 -0
  23. package/dist/lib/internal/codex-lifecycle.js +15 -12
  24. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  25. package/dist/lib/internal/demo-promotion.js +322 -0
  26. package/dist/lib/internal/demo-transcript.js +454 -0
  27. package/dist/lib/internal/git-workflow.js +10 -6
  28. package/dist/lib/internal/host-control.js +28 -0
  29. package/dist/lib/internal/manual-validation.js +322 -0
  30. package/dist/lib/internal/platform-checks.js +16 -4
  31. package/dist/lib/internal/platform-comment.js +16 -4
  32. package/dist/lib/internal/platform-context.js +4 -1
  33. package/dist/lib/internal/platform-issue.js +12 -4
  34. package/dist/lib/internal/platform-metadata.js +88 -0
  35. package/dist/lib/internal/platform-pr-review.js +16 -3
  36. package/dist/lib/internal/platform-pr.js +42 -14
  37. package/dist/lib/internal/platform-release-notes.js +6 -3
  38. package/dist/lib/internal/platform-security.js +93 -0
  39. package/dist/lib/internal/pr-review-grade.js +14 -3
  40. package/dist/lib/internal/release-workflow.js +82 -89
  41. package/dist/lib/internal/sandbox-control.js +171 -7
  42. package/dist/lib/internal/task-activity.js +13 -4
  43. package/dist/lib/internal/task-artifact.js +19 -107
  44. package/dist/lib/internal/task-context.js +4 -1
  45. package/dist/lib/internal/task-create.js +48 -14
  46. package/dist/lib/internal/task-delivery.js +4 -1
  47. package/dist/lib/internal/task-event.js +38 -35
  48. package/dist/lib/internal/task-finalization.js +4 -1
  49. package/dist/lib/internal/task-invalidation.js +4 -1
  50. package/dist/lib/internal/task-ledger.js +12 -1
  51. package/dist/lib/internal/task-lifecycle.js +4 -1
  52. package/dist/lib/internal/task-operation-registry.js +519 -0
  53. package/dist/lib/internal/task-orchestration.js +12 -0
  54. package/dist/lib/internal/task-override.js +10 -3
  55. package/dist/lib/internal/task-qualification.js +90 -0
  56. package/dist/lib/internal/task-review.js +10 -52
  57. package/dist/lib/internal/task-short-id.js +11 -1
  58. package/dist/lib/internal/task-snapshot.js +4 -1
  59. package/dist/lib/internal/task-validate.js +37 -12
  60. package/dist/lib/internal/task-verify.js +5 -1
  61. package/dist/lib/internal/task-warning.js +8 -1
  62. package/dist/lib/owned-path.js +33 -0
  63. package/dist/lib/platform/check-status.js +11 -0
  64. package/dist/lib/platform/comment-safety.js +229 -0
  65. package/dist/lib/platform/completion-backfill.js +1 -1
  66. package/dist/lib/platform/github-data.js +241 -0
  67. package/dist/lib/platform/github-provider.js +248 -26
  68. package/dist/lib/platform/issue-comments.js +146 -34
  69. package/dist/lib/platform/issues.js +1 -179
  70. package/dist/lib/platform/pr-change-report.js +6 -12
  71. package/dist/lib/platform/pr-checks.js +12 -65
  72. package/dist/lib/platform/pr-summary.js +83 -10
  73. package/dist/lib/platform/provider-contract.d.ts +67 -1
  74. package/dist/lib/platform/provider-contract.js +6 -2
  75. package/dist/lib/platform/provider-validation.js +76 -3
  76. package/dist/lib/platform/pull-requests.js +117 -275
  77. package/dist/lib/platform/repository-metadata.js +377 -0
  78. package/dist/lib/platform/security-alerts.js +155 -0
  79. package/dist/lib/platform/snapshots.js +2 -0
  80. package/dist/lib/platform/verification-sync.js +154 -162
  81. package/dist/lib/process-data/index.js +7 -0
  82. package/dist/lib/release/workflow.js +1 -1
  83. package/dist/lib/run/index.js +5 -0
  84. package/dist/lib/sandbox/commands/control-status.js +22 -0
  85. package/dist/lib/sandbox/commands/create.js +39 -8
  86. package/dist/lib/sandbox/commands/ls.js +5 -0
  87. package/dist/lib/sandbox/commands/rm.js +3 -807
  88. package/dist/lib/sandbox/commands/show.js +16 -0
  89. package/dist/lib/sandbox/control/audit.js +203 -0
  90. package/dist/lib/sandbox/control/client.js +125 -12
  91. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  92. package/dist/lib/sandbox/control/container-identity.js +28 -31
  93. package/dist/lib/sandbox/control/executor.js +233 -34
  94. package/dist/lib/sandbox/control/finalization-response.js +27 -0
  95. package/dist/lib/sandbox/control/identity-sentinel.js +107 -0
  96. package/dist/lib/sandbox/control/lifecycle.js +656 -128
  97. package/dist/lib/sandbox/control/native-file-lock.js +85 -0
  98. package/dist/lib/sandbox/control/protocol.js +55 -4
  99. package/dist/lib/sandbox/control/server.js +720 -79
  100. package/dist/lib/sandbox/control/state.js +63 -3
  101. package/dist/lib/sandbox/control/task-view.js +183 -0
  102. package/dist/lib/sandbox/control/task-workflow.js +74 -0
  103. package/dist/lib/sandbox/control/workflow-executor.js +99 -0
  104. package/dist/lib/sandbox/engines/authority.js +289 -0
  105. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  106. package/dist/lib/sandbox/index.js +7 -2
  107. package/dist/lib/sandbox/recovery.js +49 -5
  108. package/dist/lib/sandbox/removal.js +1717 -0
  109. package/dist/lib/sandbox/task-cleanup.js +217 -0
  110. package/dist/lib/sandbox/workspace-view.js +15 -15
  111. package/dist/lib/sandbox/worktree-safety.js +4 -1
  112. package/dist/lib/server/index.js +8 -0
  113. package/dist/lib/task/activity-intent.js +2 -1
  114. package/dist/lib/task/activity-log.js +30 -24
  115. package/dist/lib/task/artifact-command.js +101 -0
  116. package/dist/lib/task/artifact-lifecycle.js +71 -40
  117. package/dist/lib/task/artifact-name.js +36 -0
  118. package/dist/lib/task/artifact-operations.js +474 -0
  119. package/dist/lib/task/artifact-receipts.js +3 -15
  120. package/dist/lib/task/artifact-repair-intent.js +130 -0
  121. package/dist/lib/task/artifact-schema.js +127 -0
  122. package/dist/lib/task/capabilities.js +83 -19
  123. package/dist/lib/task/codex-orchestration.js +71 -25
  124. package/dist/lib/task/commit-identity.js +28 -0
  125. package/dist/lib/task/commit-operation.js +2 -16
  126. package/dist/lib/task/control-authority.js +375 -5
  127. package/dist/lib/task/control-recovery.js +128 -0
  128. package/dist/lib/task/create-service.js +103 -4
  129. package/dist/lib/task/create.js +80 -2
  130. package/dist/lib/task/decision-details.js +2 -46
  131. package/dist/lib/task/events.js +306 -76
  132. package/dist/lib/task/finalization-state.js +9 -0
  133. package/dist/lib/task/human-override.js +3 -6
  134. package/dist/lib/task/implementation-inputs.js +3 -3
  135. package/dist/lib/task/index.js +11 -3
  136. package/dist/lib/task/intermediate-cleanup.js +383 -0
  137. package/dist/lib/task/invalidation.js +18 -65
  138. package/dist/lib/task/ledger-intents.js +7 -22
  139. package/dist/lib/task/ledger.js +1 -3
  140. package/dist/lib/task/lifecycle.js +19 -1
  141. package/dist/lib/task/local-artifact-finalization.js +190 -290
  142. package/dist/lib/task/manual-validation-completion.js +26 -0
  143. package/dist/lib/task/manual-validation-evidence.js +130 -0
  144. package/dist/lib/task/manual-validation-receipt.js +101 -0
  145. package/dist/lib/task/manual-validation-shared.js +40 -0
  146. package/dist/lib/task/manual-validation-transaction.js +243 -0
  147. package/dist/lib/task/markdown.js +47 -0
  148. package/dist/lib/task/orchestration.js +206 -69
  149. package/dist/lib/task/qualification-audit.js +476 -0
  150. package/dist/lib/task/qualification-confirmation.js +109 -0
  151. package/dist/lib/task/qualification-intents.js +148 -0
  152. package/dist/lib/task/review-artifacts.js +23 -40
  153. package/dist/lib/task/review-command.js +25 -0
  154. package/dist/lib/task/review-finalization.js +146 -97
  155. package/dist/lib/task/review-fingerprint.js +2 -2
  156. package/dist/lib/task/sections.js +34 -54
  157. package/dist/lib/task/verification-config.js +11 -0
  158. package/dist/lib/task/verification-engine.js +170 -327
  159. package/dist/lib/task/verification.js +1 -1
  160. package/dist/lib/task/workflow-command.js +17 -0
  161. package/dist/lib/task/workflow-warning-intents.js +0 -16
  162. package/dist/lib/task/workflow-warnings.js +28 -2
  163. package/dist/lib/update.js +2 -0
  164. package/dist/lifecycle-build-manifest.json +3 -3
  165. package/lib/agent-client.ts +9 -0
  166. package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +223 -33
  167. package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +3 -2
  168. package/lib/fs/durable-write.ts +29 -0
  169. package/lib/fs/file-lock.ts +113 -0
  170. package/lib/host-control/audit.ts +22 -0
  171. package/lib/host-control/client.ts +172 -0
  172. package/lib/host-control/command.ts +60 -0
  173. package/lib/host-control/path.ts +167 -0
  174. package/lib/host-control/secure-fs.ts +135 -0
  175. package/lib/host-control/server.ts +180 -0
  176. package/lib/host-control/service.ts +133 -0
  177. package/lib/init.ts +15 -2
  178. package/lib/internal/agent-client.ts +4 -2
  179. package/lib/internal/cli-route-inventory.ts +142 -0
  180. package/lib/internal/codex-lifecycle.ts +14 -12
  181. package/lib/internal/codex-sandbox-controller.ts +7 -2
  182. package/lib/internal/demo-promotion.ts +354 -0
  183. package/lib/internal/demo-transcript.ts +419 -0
  184. package/lib/internal/git-workflow.ts +9 -6
  185. package/lib/internal/host-control.ts +28 -0
  186. package/lib/internal/manual-validation.ts +306 -0
  187. package/lib/internal/platform-checks.ts +12 -4
  188. package/lib/internal/platform-comment.ts +12 -4
  189. package/lib/internal/platform-context.ts +3 -1
  190. package/lib/internal/platform-issue.ts +11 -4
  191. package/lib/internal/platform-metadata.ts +70 -0
  192. package/lib/internal/platform-pr-review.ts +14 -3
  193. package/lib/internal/platform-pr.ts +38 -14
  194. package/lib/internal/platform-release-notes.ts +5 -3
  195. package/lib/internal/platform-security.ts +83 -0
  196. package/lib/internal/pr-review-grade.ts +10 -3
  197. package/lib/internal/release-workflow.ts +91 -87
  198. package/lib/internal/sandbox-control.ts +181 -6
  199. package/lib/internal/task-activity.ts +12 -4
  200. package/lib/internal/task-artifact.ts +15 -79
  201. package/lib/internal/task-context.ts +3 -1
  202. package/lib/internal/task-create.ts +76 -15
  203. package/lib/internal/task-delivery.ts +3 -1
  204. package/lib/internal/task-event.ts +21 -10
  205. package/lib/internal/task-finalization.ts +3 -1
  206. package/lib/internal/task-invalidation.ts +3 -1
  207. package/lib/internal/task-ledger.ts +11 -1
  208. package/lib/internal/task-lifecycle.ts +3 -1
  209. package/lib/internal/task-operation-registry.ts +590 -0
  210. package/lib/internal/task-orchestration.ts +12 -0
  211. package/lib/internal/task-override.ts +9 -3
  212. package/lib/internal/task-qualification.ts +61 -0
  213. package/lib/internal/task-review.ts +7 -50
  214. package/lib/internal/task-short-id.ts +10 -1
  215. package/lib/internal/task-snapshot.ts +3 -1
  216. package/lib/internal/task-validate.ts +32 -12
  217. package/lib/internal/task-verify.ts +4 -1
  218. package/lib/internal/task-warning.ts +7 -1
  219. package/lib/owned-path.ts +26 -0
  220. package/lib/platform/check-status.ts +9 -0
  221. package/lib/platform/comment-safety.ts +255 -0
  222. package/lib/platform/completion-backfill.ts +1 -1
  223. package/lib/platform/github-data.ts +322 -0
  224. package/lib/platform/github-provider.ts +244 -27
  225. package/lib/platform/issue-comments.ts +159 -35
  226. package/lib/platform/issues.ts +4 -245
  227. package/lib/platform/pr-change-report.ts +6 -12
  228. package/lib/platform/pr-checks.ts +13 -77
  229. package/lib/platform/pr-summary.ts +88 -11
  230. package/lib/platform/provider-contract.ts +78 -3
  231. package/lib/platform/provider-validation.ts +85 -3
  232. package/lib/platform/pull-requests.ts +129 -348
  233. package/lib/platform/repository-metadata.ts +453 -0
  234. package/lib/platform/security-alerts.ts +191 -0
  235. package/lib/platform/snapshots.ts +53 -0
  236. package/lib/platform/verification-sync.ts +171 -177
  237. package/lib/process-data/index.ts +7 -0
  238. package/lib/release/workflow.ts +3 -3
  239. package/lib/run/index.ts +5 -0
  240. package/lib/sandbox/commands/control-status.ts +26 -0
  241. package/lib/sandbox/commands/create.ts +53 -12
  242. package/lib/sandbox/commands/ls.ts +7 -0
  243. package/lib/sandbox/commands/rm.ts +3 -996
  244. package/lib/sandbox/commands/show.ts +16 -0
  245. package/lib/sandbox/control/audit.ts +253 -0
  246. package/lib/sandbox/control/client.ts +150 -13
  247. package/lib/sandbox/control/completed-reentry.ts +98 -0
  248. package/lib/sandbox/control/container-identity.ts +27 -43
  249. package/lib/sandbox/control/executor.ts +262 -37
  250. package/lib/sandbox/control/finalization-response.ts +29 -0
  251. package/lib/sandbox/control/identity-sentinel.ts +137 -0
  252. package/lib/sandbox/control/lifecycle.ts +672 -18
  253. package/lib/sandbox/control/native-file-lock.ts +108 -0
  254. package/lib/sandbox/control/protocol.ts +80 -8
  255. package/lib/sandbox/control/server.ts +779 -82
  256. package/lib/sandbox/control/state.ts +84 -3
  257. package/lib/sandbox/control/task-view.ts +240 -0
  258. package/lib/sandbox/control/task-workflow.ts +95 -0
  259. package/lib/sandbox/control/workflow-executor.ts +102 -0
  260. package/lib/sandbox/engines/authority.ts +365 -0
  261. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  262. package/lib/sandbox/index.ts +9 -2
  263. package/lib/sandbox/recovery.ts +49 -6
  264. package/lib/sandbox/removal.ts +2144 -0
  265. package/lib/sandbox/task-cleanup.ts +209 -0
  266. package/lib/sandbox/workspace-view.ts +26 -18
  267. package/lib/sandbox/worktree-safety.ts +4 -1
  268. package/lib/server/index.ts +10 -0
  269. package/lib/task/activity-intent.ts +2 -2
  270. package/lib/task/activity-log.ts +27 -19
  271. package/lib/task/artifact-command.ts +104 -0
  272. package/lib/task/artifact-lifecycle.ts +66 -39
  273. package/lib/task/artifact-name.ts +55 -0
  274. package/lib/task/artifact-operations.ts +580 -0
  275. package/lib/task/artifact-receipts.ts +3 -14
  276. package/lib/task/artifact-repair-intent.ts +152 -0
  277. package/lib/task/artifact-schema.ts +163 -0
  278. package/lib/task/capabilities.ts +82 -22
  279. package/lib/task/codex-orchestration.ts +85 -24
  280. package/lib/task/commit-identity.ts +31 -0
  281. package/lib/task/commit-operation.ts +2 -16
  282. package/lib/task/control-authority.ts +513 -6
  283. package/lib/task/control-recovery.ts +174 -0
  284. package/lib/task/create-service.ts +131 -6
  285. package/lib/task/create.ts +83 -1
  286. package/lib/task/decision-details.ts +3 -71
  287. package/lib/task/events.ts +292 -75
  288. package/lib/task/finalization-state.ts +11 -0
  289. package/lib/task/human-override.ts +3 -8
  290. package/lib/task/implementation-inputs.ts +3 -3
  291. package/lib/task/index.ts +16 -3
  292. package/lib/task/intermediate-cleanup.ts +455 -0
  293. package/lib/task/invalidation.ts +18 -62
  294. package/lib/task/ledger-intents.ts +7 -24
  295. package/lib/task/ledger.ts +1 -3
  296. package/lib/task/lifecycle.ts +17 -1
  297. package/lib/task/local-artifact-finalization.ts +223 -388
  298. package/lib/task/manual-validation-completion.ts +40 -0
  299. package/lib/task/manual-validation-evidence.ts +209 -0
  300. package/lib/task/manual-validation-receipt.ts +152 -0
  301. package/lib/task/manual-validation-shared.ts +50 -0
  302. package/lib/task/manual-validation-transaction.ts +304 -0
  303. package/lib/task/markdown.ts +70 -0
  304. package/lib/task/orchestration.ts +191 -68
  305. package/lib/task/qualification-audit.ts +588 -0
  306. package/lib/task/qualification-confirmation.ts +117 -0
  307. package/lib/task/qualification-intents.ts +150 -0
  308. package/lib/task/review-artifacts.ts +21 -41
  309. package/lib/task/review-command.ts +23 -0
  310. package/lib/task/review-finalization.ts +154 -153
  311. package/lib/task/review-fingerprint.ts +2 -2
  312. package/lib/task/sections.ts +33 -52
  313. package/lib/task/verification-config.ts +12 -0
  314. package/lib/task/verification-engine.ts +165 -370
  315. package/lib/task/verification-types.ts +17 -0
  316. package/lib/task/verification.ts +1 -1
  317. package/lib/task/workflow-command.ts +18 -0
  318. package/lib/task/workflow-warning-intents.ts +0 -13
  319. package/lib/task/workflow-warnings.ts +21 -2
  320. package/lib/update.ts +6 -0
  321. package/package.json +7 -2
  322. package/templates/.agents/hooks/lifecycle-delegation.js +6 -6
  323. package/templates/.agents/rules/README.en.md +2 -0
  324. package/templates/.agents/rules/README.zh-CN.md +2 -0
  325. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  326. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  327. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  328. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  329. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  330. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  331. package/templates/.agents/rules/local-artifact-repair.en.md +5 -1
  332. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +5 -1
  333. package/templates/.agents/rules/security-alerts.en.md +8 -8
  334. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  335. package/templates/.agents/rules/testing-discipline.en.md +2 -0
  336. package/templates/.agents/rules/testing-discipline.zh-CN.md +2 -0
  337. package/templates/.agents/scripts/package.json +3 -0
  338. package/templates/.agents/skills/analyze-task/SKILL.en.md +15 -2
  339. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +19 -2
  340. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  341. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  342. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  343. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  344. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  345. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  346. package/templates/.agents/skills/code-task/SKILL.en.md +14 -1
  347. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +14 -1
  348. package/templates/.agents/skills/code-task/config/verify.en.json +5 -14
  349. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +5 -14
  350. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  351. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  352. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  353. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  354. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  355. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  356. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  357. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  358. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +37 -21
  359. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +37 -21
  360. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
  361. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
  362. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +4 -0
  363. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +4 -0
  364. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +16 -7
  365. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +16 -7
  366. package/templates/.agents/skills/complete-task/SKILL.en.md +10 -23
  367. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +10 -23
  368. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  369. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  370. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  371. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  372. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  373. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  374. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  375. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  376. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  377. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  378. package/templates/.agents/skills/plan-task/SKILL.en.md +14 -1
  379. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +16 -1
  380. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  381. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  382. package/templates/.agents/skills/release/SKILL.en.md +7 -3
  383. package/templates/.agents/skills/release/SKILL.zh-CN.md +7 -3
  384. package/templates/.agents/skills/review-analysis/SKILL.en.md +14 -1
  385. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -1
  386. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  387. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  388. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  389. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  390. package/templates/.agents/skills/review-code/SKILL.en.md +14 -1
  391. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +14 -1
  392. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  393. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  394. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  395. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  396. package/templates/.agents/skills/review-plan/SKILL.en.md +14 -1
  397. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -1
  398. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  399. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  400. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  401. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  402. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  403. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  404. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  405. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  406. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +25 -4
  407. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +25 -4
  408. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.en.md +4 -1
  409. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +4 -1
  410. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +5 -1
  411. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +5 -1
  412. package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
  413. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
  414. package/templates/.agents/skills/test/SKILL.en.md +29 -7
  415. package/templates/.agents/skills/test/SKILL.zh-CN.md +29 -7
  416. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  417. package/templates/.agents/templates/task.en.md +6 -0
  418. package/templates/.agents/templates/task.zh-CN.md +6 -0
  419. package/templates/.claude/commands/run-manual-validation.en.md +1 -1
  420. package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
  421. package/dist/lib/platform/adapters.js +0 -56
  422. package/lib/platform/adapters.ts +0 -197
  423. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  424. package/templates/.agents/scripts/security-alerts.sh +0 -31
  425. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  426. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  427. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  428. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -12,16 +12,27 @@ import { resolveMaterializedReviewedHeadRelation } from "../platform/change-requ
12
12
  import { resolveReviewedHeadRelation } from "../platform/merged-pr-equivalence.js";
13
13
  import { resolveLocalReviewedCommitRelation } from "../git/reviewed-commit-equivalence.js";
14
14
  import { parseTypedTaskFrontmatter } from "./frontmatter.js";
15
- import { LEDGER_SECTION_MISSING_CODE, LEDGER_SECTION_MISSING_MESSAGE, parseLedgerDocument, summarizeLedgerStage, validateLedgerRows } from "./ledger.js";
15
+ import { LEDGER_TERMINAL, LEDGER_SECTION_MISSING_CODE, LEDGER_SECTION_MISSING_MESSAGE, parseLedgerDocument, summarizeLedgerStage, validateLedgerRows } from "./ledger.js";
16
16
  import { isValidAgentInfraVersion } from "../version.js";
17
17
  import { equalCounts, parseReviewSummary } from "./review-artifacts.js";
18
18
  import { inspectDecisionDetailDuplicates } from "./decision-details.js";
19
+ import { parseImplementationInputs } from "./implementation-inputs.js";
20
+ import { scanVisibleMarkdown } from "./markdown.js";
19
21
  import { loadVerificationConfig } from "./verification-config.js";
20
22
  import { snapshotReview } from "../git/review-snapshot.js";
23
+ import { inspectActivityLog } from "./activity-log.js";
24
+ import { parseWorkflowWarnings } from "./workflow-warnings.js";
21
25
  import { OrchestrationStateError, readRun } from "./orchestration.js";
22
26
  import { resolveDeliveryTarget } from "./delivery-target.js";
23
27
  import { readPrDeliveryFact } from "./pr-delivery-fact.js";
24
28
  import { validateLocalArtifact } from "./local-artifact-finalization.js";
29
+ import { validateQualificationAudit } from "./qualification-audit.js";
30
+ import { getArtifactSchema } from "./artifact-schema.js";
31
+ import { inspectArtifactContract } from "./artifact-operations.js";
32
+ import { manualValidationFinalSummaryProjectionMatches } from "./manual-validation-receipt.js";
33
+ import { readManualValidationCompletion } from "./manual-validation-completion.js";
34
+ import { sha256File } from "./artifact-receipts.js";
35
+ import { summaryCommentState } from "../platform/pr-summary.js";
25
36
  const TASK_ENUMS = {
26
37
  type: ["feature", "bugfix", "refactor", "docs", "chore"],
27
38
  workflow: ["feature-development", "bug-fix", "refactoring"],
@@ -39,7 +50,6 @@ const DEFAULT_REQUIRED_FIELDS = [
39
50
  "assigned_to"
40
51
  ];
41
52
  const DATE_TIME_PATTERN = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:[+-]\d{2}:\d{2})?$/;
42
- const ACTIVITY_LOG_PATTERN = /^- (\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:[+-]\d{2}:\d{2})?) — \*\*(.+?)\*\* by (.+?) — (.+)$/;
43
53
  // Start markers (action suffixed with ` [started]`) are excluded from the
44
54
  // "latest action" / freshness computation so a step's in-flight marker never
45
55
  // satisfies a skill's expected_action_pattern; the matching done entry does.
@@ -47,27 +57,11 @@ const ACTIVITY_LOG_STARTED_RE = /\s*\[started\]\s*$/;
47
57
  const BRANCH_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
48
58
  // Review disagreement ledger (see .agents/rules/review-handshake.md).
49
59
  const LEDGER_SECTION_NAMES = ["审查分歧账本", "Review Disagreement Ledger"];
50
- const LEDGER_STATUSES = new Set([
51
- "open",
52
- "accepted",
53
- "adjusted",
54
- "refuted",
55
- "cannot-judge",
56
- "confirmed",
57
- "needs-human-decision",
58
- "closed",
59
- "human-decided"
60
- ]);
61
- const LEDGER_TERMINAL_OK = new Set(["confirmed", "closed", "human-decided"]);
62
60
  const DEFAULT_MAX_HANDSHAKE_ROUNDS = 3;
63
61
  const POST_REVIEW_COMMIT_STAGE = "post-review-commit";
64
62
  const SHA_PATTERN = /^[0-9a-f]{7,40}$/i;
65
- const WORKFLOW_WARNING_SECTION_NAMES = ["工作流告警", "Workflow Warnings"];
66
- const WORKFLOW_WARNING_STATUSES = new Set(["open", "resolved", "ignored"]);
67
- const WORKFLOW_WARNING_SEVERITIES = new Set(["IMPORTANT", "ACTION_REQUIRED"]);
68
- const WORKFLOW_WARNING_ID_PATTERN = /^WW-\d+$/;
69
63
  const scriptPath = fileURLToPath(import.meta.url);
70
- let repoRoot = path.resolve(path.dirname(scriptPath), "..", "..");
64
+ const defaultRepoRoot = path.resolve(path.dirname(scriptPath), "..", "..");
71
65
  const PLATFORM_ADAPTERS = {
72
66
  "platform-sync": checkPlatformSync,
73
67
  "platform-sync-preflight": async (context, shared) => ({ ...await checkPlatformSync(context, shared), type: "platform-sync-preflight" }),
@@ -172,14 +166,12 @@ function exactText(value) {
172
166
  function validateCleanCompletionEvidence(run) {
173
167
  const evidence = run.completionEvidence;
174
168
  const shaPattern = /^[0-9a-f]{40}$/i;
175
- if (evidence?.kind !== 'reviewed-head-clean'
176
- || !exactText(evidence.observedAt)
169
+ if (!evidence
177
170
  || Number.isNaN(Date.parse(evidence.observedAt))
178
171
  || !shaPattern.test(evidence.head)
179
172
  || !shaPattern.test(evidence.headTree)
180
173
  || !shaPattern.test(evidence.worktreeTree)
181
174
  || !shaPattern.test(evidence.lastReviewedCommit)
182
- || !(evidence.prNumber === null || (Number.isInteger(evidence.prNumber) && evidence.prNumber > 0))
183
175
  || !(evidence.prHead === null || shaPattern.test(evidence.prHead))) {
184
176
  return 'Clean completion evidence has an invalid structure';
185
177
  }
@@ -192,7 +184,6 @@ function validateCleanCompletionEvidence(run) {
192
184
  || run.pendingDelegation !== null
193
185
  || run.commitAuthorization?.issuedAt !== null
194
186
  || run.commitAuthorization?.consumedAt !== null
195
- || !Array.isArray(run.receipts)
196
187
  || run.receipts.some((receipt) => receipt.stage === 'commit')) {
197
188
  return 'Clean completion evidence conflicts with commit delegation state';
198
189
  }
@@ -211,43 +202,10 @@ function checkOrchestrationEvidence({ taskDir }) {
211
202
  const message = error instanceof OrchestrationStateError ? error.message : String(error);
212
203
  return failResult('orchestration-evidence', `Invalid orchestration.json: ${message}`);
213
204
  }
205
+ if (!run)
206
+ return failResult('orchestration-evidence', 'orchestration.json is missing');
207
+ // readRun validates the persisted schema, receipt identities and client provenance.
214
208
  const policy = run.modelPolicy;
215
- if (!policy
216
- || !exactText(policy.executor?.model)
217
- || !exactText(policy.executor?.reasoningEffort)
218
- || !exactText(policy.reviewer?.model)
219
- || !exactText(policy.reviewer?.reasoningEffort)) {
220
- return failResult('orchestration-evidence', 'Run model policy requires exact executor and reviewer model and effort');
221
- }
222
- if (!run.modelPolicySource
223
- || !['explicit', 'project-config'].includes(run.modelPolicySource.kind)
224
- || !exactText(run.modelPolicySource.client)
225
- || !exactText(run.modelPolicySource.resolvedAt)
226
- || !Array.isArray(run.recoveryHistory)) {
227
- return failResult('orchestration-evidence', 'Run model policy source or recovery history is invalid');
228
- }
229
- for (const recovery of run.recoveryHistory) {
230
- const guards = recovery.guards;
231
- const validClaudeCodeRecovery = recovery.code === 'CLIENT_CAPABILITY_ENABLED'
232
- && recovery.previousStatus === 'paused'
233
- && recovery.previousPause?.code === 'ORCHESTRATION_CLIENT_UNSUPPORTED'
234
- && recovery.client === 'claude-code'
235
- && recovery.resultingStatus === 'running'
236
- && exactText(recovery.recoveredAt)
237
- && guards?.stepCount === 0
238
- && guards?.nextStage === null
239
- && guards?.baselineEmpty === true
240
- && guards?.receiptCount === 0
241
- && guards?.pendingDelegation === false
242
- && guards?.commitAuthorizationUnused === true
243
- && guards?.completionEvidenceAbsent === true;
244
- if (!validClaudeCodeRecovery) {
245
- return failResult('orchestration-evidence', 'Run recovery history contains invalid provenance');
246
- }
247
- }
248
- if (!Array.isArray(run.receipts)) {
249
- return failResult('orchestration-evidence', 'Run receipts must be an array');
250
- }
251
209
  if (run.completionEvidence != null) {
252
210
  const evidenceError = validateCleanCompletionEvidence(run);
253
211
  if (evidenceError)
@@ -279,10 +237,6 @@ function checkOrchestrationEvidence({ taskDir }) {
279
237
  return failResult('orchestration-evidence', `Receipt '${receipt.id ?? '(unknown)'}' has no host-observed actual reasoning effort`);
280
238
  }
281
239
  }
282
- // parentId/childId 校验对所有 client 保持统一(不新增分支);spawnMode 检查按 client 判断
283
- if (!exactText(receipt.parentId) || !exactText(receipt.childId) || receipt.parentId === receipt.childId) {
284
- return failResult('orchestration-evidence', `Receipt '${receipt.id ?? '(unknown)'}' has invalid delegation identity`);
285
- }
286
240
  if (!isClaudeCode && receipt.spawnMode !== 'fresh') {
287
241
  return failResult('orchestration-evidence', `Receipt '${receipt.id ?? '(unknown)'}' has invalid fresh delegation identity`);
288
242
  }
@@ -304,41 +258,6 @@ function checkOrchestrationEvidence({ taskDir }) {
304
258
  && receipt.reasoningEffortFallbackReason !== null) {
305
259
  return failResult('orchestration-evidence', `Receipt '${receipt.id ?? '(unknown)'}' has an unrelated reasoning-effort fallback reason`);
306
260
  }
307
- if (receipt.client === 'codex') {
308
- const activatedCodex = ['activated', 'stage-completed', 'sealed', 'consumed'].includes(receipt.status);
309
- const host = receipt.hostEvidence;
310
- const provenance = receipt.lifecycleProvenance;
311
- if (!provenance
312
- || (activatedCodex && (host?.kind !== 'codex-lifecycle-v2'
313
- || host.protocolVersion !== provenance.protocolVersion
314
- || host.hookDefinitionHash !== provenance.hookDefinitionHash
315
- || host.hookSource !== provenance.hookSource
316
- || host.hookSourcePathDigest !== provenance.hookSourcePathDigest
317
- || host.hookSourceHash !== provenance.hookSourceHash
318
- || host.capabilitySessionId !== provenance.capabilitySessionId
319
- || receipt.parentId !== provenance.capabilitySessionId
320
- || host.capabilityTurnId !== provenance.capabilityTurnId
321
- || host.controllerInstanceDigest !== provenance.controllerInstanceDigest
322
- || host.controlGeneration !== provenance.controlGeneration
323
- || host.spawnToolUseId === provenance.capabilityToolUseId
324
- || !exactText(host.spawnToolUseId)
325
- || !Number.isFinite(Date.parse(host.spawnObservedAt ?? ''))
326
- || !Number.isFinite(Date.parse(receipt.spawnDispatchedAt ?? ''))
327
- || !Number.isFinite(Date.parse(receipt.activationDeadlineAt ?? ''))
328
- || Date.parse(host.spawnObservedAt ?? '') < Date.parse(receipt.spawnDispatchedAt ?? '')
329
- || Date.parse(host.spawnObservedAt ?? '') > Date.parse(receipt.activationDeadlineAt ?? '')
330
- || !exactText(host.hookDefinitionHash)
331
- || !Number.isSafeInteger(host.startRevision)
332
- || host.startRevision < 1))) {
333
- return failResult('orchestration-evidence', `Receipt '${receipt.id ?? '(unknown)'}' has invalid Codex start evidence`);
334
- }
335
- if (['sealed', 'consumed'].includes(receipt.status) && (!Number.isSafeInteger(host.stopRevision)
336
- || host.stopRevision <= host.startRevision
337
- || host.consumer !== receipt.id
338
- || !exactText(host.consumedAt))) {
339
- return failResult('orchestration-evidence', `Receipt '${receipt.id ?? '(unknown)'}' has invalid Codex consumed stop evidence`);
340
- }
341
- }
342
261
  }
343
262
  }
344
263
  if (run.receipts.some((receipt) => receipt.status !== 'consumed')) {
@@ -347,7 +266,7 @@ function checkOrchestrationEvidence({ taskDir }) {
347
266
  return passResult('orchestration-evidence', 'Persisted orchestration model and delegation evidence is internally consistent');
348
267
  }
349
268
  // === Check Functions ===
350
- function checkTaskMeta({ taskDir, config }) {
269
+ function checkTaskMeta({ taskDir, config, repositoryRoot }) {
351
270
  const task = loadTask(taskDir);
352
271
  if (!task.ok) {
353
272
  return failResult("task-meta", task.message);
@@ -377,13 +296,15 @@ function checkTaskMeta({ taskDir, config }) {
377
296
  return failResult("task-meta", `Invalid ${field}: ${metadata[field]}`);
378
297
  }
379
298
  }
380
- const branchValidationError = validateTaskBranch(metadata);
299
+ const branchValidationError = validateTaskBranch(metadata, repositoryRoot);
381
300
  if (branchValidationError) {
382
301
  return failResult("task-meta", branchValidationError);
383
302
  }
384
- const warningValidationErrors = validateWorkflowWarnings(task.content);
385
- if (warningValidationErrors.length > 0) {
386
- return failResult("task-meta", `Invalid Workflow Warnings: ${warningValidationErrors.join("; ")}`);
303
+ try {
304
+ parseWorkflowWarnings(task.content);
305
+ }
306
+ catch (error) {
307
+ return failResult("task-meta", `Invalid Workflow Warnings: ${error instanceof Error ? error.message : String(error)}`);
387
308
  }
388
309
  const expectedStep = config.expected_step;
389
310
  if (expectedStep && metadata.current_step !== expectedStep) {
@@ -478,11 +399,11 @@ async function checkRequiredPrDelivery({ taskDir, repositoryRoot, mode }) {
478
399
  }
479
400
  return passResult('required-pr-delivery', `Pull request delivery policy satisfied (${status})`);
480
401
  }
481
- function validateTaskBranch(metadata) {
402
+ function validateTaskBranch(metadata, repoRoot) {
482
403
  if (isBlank(metadata.branch)) {
483
404
  return null;
484
405
  }
485
- const projectName = loadProjectName();
406
+ const projectName = loadProjectName(repoRoot);
486
407
  const expectedPrefix = projectName ? `${projectName}-${metadata.type}-` : "";
487
408
  if (expectedPrefix && !String(metadata.branch).startsWith(expectedPrefix)) {
488
409
  return `Invalid branch: expected prefix '${expectedPrefix}', got '${metadata.branch}'`;
@@ -493,7 +414,7 @@ function validateTaskBranch(metadata) {
493
414
  }
494
415
  return null;
495
416
  }
496
- function loadProjectName() {
417
+ function loadProjectName(repoRoot) {
497
418
  const configPath = path.join(repoRoot, ".agents", ".airc.json");
498
419
  if (!fs.existsSync(configPath)) {
499
420
  return "";
@@ -520,21 +441,57 @@ function checkArtifact({ taskDir, config, artifactFile, skillName }) {
520
441
  return failResult("artifact", `Artifact is empty: ${path.basename(artifactPath)}`);
521
442
  }
522
443
  const content = fs.readFileSync(artifactPath, "utf8");
523
- const requiredSections = config.required_sections || [];
444
+ let taskContent = "";
445
+ const taskPath = path.join(taskDir, "task.md");
446
+ if (fs.existsSync(taskPath)) {
447
+ try {
448
+ taskContent = fs.readFileSync(taskPath, "utf8");
449
+ }
450
+ catch (error) {
451
+ return failResult("artifact", `Cannot read task qualification contract: ${error instanceof Error ? error.message : String(error)}`);
452
+ }
453
+ }
454
+ if (taskContent && /^review-(?:analysis|plan|code)$/.test(skillName)) {
455
+ const qualification = validateQualificationAudit(taskContent, content, { artifact: path.basename(artifactPath) });
456
+ if (!qualification.ok)
457
+ return failResult("artifact", `${path.basename(artifactPath)} has qualification audit errors: ${qualification.code}: ${qualification.message}`);
458
+ }
459
+ const schemaFamily = skillName === "analyze-task"
460
+ ? "analysis"
461
+ : skillName === "review-analysis"
462
+ ? "review-analysis"
463
+ : skillName === "plan-task"
464
+ ? "plan"
465
+ : skillName === "review-plan"
466
+ ? "review-plan"
467
+ : skillName === "code-task"
468
+ ? "code"
469
+ : skillName === "review-code" ? "review-code" : null;
470
+ const schema = schemaFamily ? getArtifactSchema(schemaFamily) : null;
524
471
  const localFamily = skillName === "analyze-task"
525
472
  ? "analysis"
526
473
  : skillName === "plan-task" ? "plan" : skillName === "code-task" ? "code" : null;
474
+ if (schema) {
475
+ const structure = inspectArtifactContract(content, schema);
476
+ if (!structure.ok && !localFamily) {
477
+ return failResult("artifact", `${path.basename(artifactPath)} has shared structural errors: ${structure.diagnostics.map((item) => `${item.code}: ${item.message}`).join('; ')}`);
478
+ }
479
+ }
527
480
  if (localFamily) {
528
481
  const local = validateLocalArtifact(content, {
529
482
  family: localFamily,
530
- requiredSections: requiredSections.filter((section) => typeof section === "string"),
531
- requiredPatterns: (config.required_patterns || []).filter((pattern) => typeof pattern === "string")
483
+ ...(taskContent ? { taskContent } : {}),
484
+ artifact: path.basename(artifactPath)
532
485
  });
533
486
  if (!local.ok) {
534
487
  return failResult("artifact", `${path.basename(artifactPath)} has local structural errors: ${local.diagnostics.map((item) => `${item.code}: ${item.message}`).join('; ')}`);
535
488
  }
536
- return passResult("artifact", `${path.basename(artifactPath)} passed (${requiredSections.length} sections)`);
489
+ return passResult("artifact", `${path.basename(artifactPath)} passed (${schema?.sections.length ?? 0} sections)`);
490
+ }
491
+ if (schema) {
492
+ return passResult("artifact", `${path.basename(artifactPath)} passed (${schema.sections.length} sections)`);
537
493
  }
494
+ const requiredSections = config.required_sections || [];
538
495
  const missingSections = requiredSections.filter((section) => !new RegExp(`^##\\s+${escapeRegExp(section)}\\s*$`, "m").test(content));
539
496
  if (missingSections.length > 0) {
540
497
  return failResult("artifact", `${path.basename(artifactPath)} is missing sections: ${missingSections.join(", ")}`);
@@ -608,30 +565,17 @@ function checkImplementationInput({ taskDir, artifactFile }) {
608
565
  const artifactPath = path.join(taskDir, artifactFile);
609
566
  if (!safeStat(artifactPath)?.isFile())
610
567
  return failResult("implementation-input", `Artifact not found: ${artifactFile}`);
611
- const inputSection = getSectionContent(task.content, ["实现输入", "Implementation Inputs"]);
612
- const rows = [];
613
- if (inputSection) {
614
- const table = inputSection.split(/\r?\n/).filter((line) => line.trim().startsWith("|"));
615
- const cells = (line) => line.split("|").slice(1, -1).map((cell) => cell.trim());
616
- const expected = ["id", "ledger_id", "decision_evidence", "stage", "needs_implementation", "decided_at", "status", "consumed_by"];
617
- if (table.length < 2 || JSON.stringify(cells(table[0])) !== JSON.stringify(expected)) {
618
- return failResult("implementation-input", "Implementation Inputs table schema is invalid");
619
- }
620
- const seen = new Set();
621
- for (const line of table.slice(2)) {
622
- const row = cells(line);
623
- if (row.length !== 8 || !/^II-[1-9]\d*$/.test(row[0]) || seen.has(row[0])) {
624
- return failResult("implementation-input", "Implementation Inputs table contains an invalid or duplicate id");
625
- }
626
- seen.add(row[0]);
627
- rows.push({ id: row[0], ledgerId: row[1], evidence: row[2], stage: row[3], needs: row[4], status: row[6], consumedBy: row[7] });
628
- }
568
+ let rows;
569
+ try {
570
+ rows = parseImplementationInputs(task.content).rows;
629
571
  }
630
- const logSection = getSectionContent(task.content, ["活动日志", "Activity Log"]);
631
- const doneActions = logSection.split(/\r?\n/).flatMap((line) => {
632
- const match = line.trim().match(ACTIVITY_LOG_PATTERN);
633
- return match && !ACTIVITY_LOG_STARTED_RE.test(match[2]) ? [match[2]] : [];
634
- });
572
+ catch (error) {
573
+ return failResult("implementation-input", `Invalid Implementation Inputs: ${error instanceof Error ? error.message : String(error)}`);
574
+ }
575
+ const doneActions = (inspectActivityLog(task.content).section?.entries ?? [])
576
+ .filter((entry) => !ACTIVITY_LOG_STARTED_RE.test(entry.step))
577
+ .map((entry) => entry.step)
578
+ .filter((step) => /^(?:Code Task|Code) \(Round \d+/.test(step));
635
579
  const latestAction = doneActions.at(-1) || "";
636
580
  const actionDecision = /(?:Code Task|Code) \(Round \d+, decision (II-[1-9]\d*)\)/.exec(latestAction)?.[1] || null;
637
581
  const report = fs.readFileSync(artifactPath, "utf8");
@@ -659,10 +603,10 @@ function checkImplementationInput({ taskDir, artifactFile }) {
659
603
  if (matches.length !== 1)
660
604
  return failResult("implementation-input", `${actionDecision} is missing or duplicated in task table`);
661
605
  const row = matches[0];
662
- if (row.stage !== "code" || row.needs !== "true" || row.status !== "consumed" || row.consumedBy !== artifactFile || !row.evidence) {
606
+ if (row.stage !== "code" || !row.needsImplementation || row.status !== "consumed" || row.consumedBy !== artifactFile || !row.decisionEvidence) {
663
607
  return failResult("implementation-input", `${actionDecision} is not a consumed input for ${artifactFile}`);
664
608
  }
665
- if (reportLedger !== row.ledgerId || reportEvidence !== row.evidence) {
609
+ if (reportLedger !== row.ledgerId || reportEvidence !== row.decisionEvidence) {
666
610
  return failResult("implementation-input", `${actionDecision} report identity does not match task table evidence`);
667
611
  }
668
612
  return passResult("implementation-input", `${actionDecision} matches Activity Log, report, and task table`);
@@ -672,26 +616,22 @@ function checkActivityLog({ taskDir, config }) {
672
616
  if (!task.ok) {
673
617
  return failResult("activity-log", task.message);
674
618
  }
675
- const logSection = getSectionContent(task.content, ["活动日志", "Activity Log"]);
676
- if (!logSection) {
677
- return failResult("activity-log", "Activity Log section not found");
678
- }
679
- const entries = logSection
680
- .split(/\r?\n/)
681
- .map((line) => line.trim())
682
- .filter((line) => line.startsWith("- "));
683
- if (entries.length === 0) {
619
+ const { section, invalidEntries } = inspectActivityLog(task.content);
620
+ if (!section)
621
+ return failResult("activity-log", "Activity Log section not found or ambiguous");
622
+ if (invalidEntries.length)
623
+ return failResult("activity-log", `Invalid Activity Log entry format: ${invalidEntries[0]}`);
624
+ const entries = section.entries;
625
+ if (entries.length === 0)
684
626
  return failResult("activity-log", "Activity Log has no entries");
685
- }
686
627
  let previousTimestamp = "";
687
628
  let latestAction = "";
688
629
  let latestTimestamp = "";
630
+ const doneActions = [];
689
631
  for (const entry of entries) {
690
- const match = entry.match(ACTIVITY_LOG_PATTERN);
691
- if (!match) {
692
- return failResult("activity-log", `Invalid Activity Log entry format: ${entry}`);
693
- }
694
- const [, timestamp, action] = match;
632
+ if (!entry.note.trim())
633
+ return failResult("activity-log", "Activity Log entry note is required");
634
+ const { time: timestamp, step: action } = entry;
695
635
  if (previousTimestamp && timestamp < previousTimestamp) {
696
636
  return failResult("activity-log", "Activity Log timestamps are not in ascending order");
697
637
  }
@@ -702,6 +642,16 @@ function checkActivityLog({ taskDir, config }) {
702
642
  if (!ACTIVITY_LOG_STARTED_RE.test(action)) {
703
643
  latestTimestamp = timestamp;
704
644
  latestAction = action;
645
+ doneActions.push(action);
646
+ }
647
+ }
648
+ if (config.expected_action_pattern && !new RegExp(config.expected_action_pattern).test(latestAction)) {
649
+ const expected = new RegExp(config.expected_action_pattern);
650
+ let index = doneActions.length - 1;
651
+ while (index >= 0 && doneActions[index] === 'Commit' && !expected.test(doneActions[index]))
652
+ index -= 1;
653
+ if (index >= 0 && expected.test(doneActions[index])) {
654
+ latestAction = doneActions[index];
705
655
  }
706
656
  }
707
657
  if (config.expected_action_pattern && !new RegExp(config.expected_action_pattern).test(latestAction)) {
@@ -736,111 +686,7 @@ function checkCompletionChecklist({ taskDir, config }) {
736
686
  }
737
687
  return passResult("completion-checklist", `Completion Checklist valid (${items.length} items checked)`);
738
688
  }
739
- function splitMarkdownTableRow(line) {
740
- let value = String(line || "").trim();
741
- if (!value.startsWith("|")) {
742
- return [];
743
- }
744
- value = value.replace(/^\|/, "").replace(/\|$/, "");
745
- const cells = [];
746
- let cell = "";
747
- for (let index = 0; index < value.length; index += 1) {
748
- const char = value[index];
749
- if (char === "|" && !isEscapedAt(value, index)) {
750
- cells.push(unescapeMarkdownTableCell(cell.trim()));
751
- cell = "";
752
- continue;
753
- }
754
- cell += char;
755
- }
756
- cells.push(unescapeMarkdownTableCell(cell.trim()));
757
- return cells;
758
- }
759
- function unescapeMarkdownTableCell(value) {
760
- let output = "";
761
- for (let index = 0; index < value.length; index += 1) {
762
- const char = value[index];
763
- const next = value[index + 1];
764
- if (char === "\\" && (next === "\\" || next === "|")) {
765
- output += next;
766
- index += 1;
767
- continue;
768
- }
769
- output += char;
770
- }
771
- return output;
772
- }
773
- function isEscapedAt(value, index) {
774
- let backslashes = 0;
775
- for (let cursor = index - 1; cursor >= 0 && value[cursor] === "\\"; cursor -= 1) {
776
- backslashes += 1;
777
- }
778
- return backslashes % 2 === 1;
779
- }
780
- function parseWorkflowWarningRows(section) {
781
- const rows = [];
782
- for (const rawLine of String(section || "").split(/\r?\n/)) {
783
- const cells = splitMarkdownTableRow(rawLine);
784
- if (cells.length === 0) {
785
- continue;
786
- }
787
- if ((cells[0] || "").toLowerCase() === "id") {
788
- continue;
789
- }
790
- if (cells.every((cell) => /^:?-{3,}:?$/.test(cell))) {
791
- continue;
792
- }
793
- rows.push(cells);
794
- }
795
- return rows;
796
- }
797
- function validateWorkflowWarnings(content) {
798
- const section = getSectionContent(content, WORKFLOW_WARNING_SECTION_NAMES);
799
- if (!section.trim()) {
800
- return [];
801
- }
802
- const rows = parseWorkflowWarningRows(section);
803
- const errors = [];
804
- for (const cells of rows) {
805
- if (cells.length < 11) {
806
- errors.push(`malformed row (expected 11 columns): ${cells.join(" | ")}`);
807
- continue;
808
- }
809
- const [id, time, step, severity, code, status, target, message, action, resolvedAt, resolution] = cells;
810
- if (!WORKFLOW_WARNING_ID_PATTERN.test(id)) {
811
- errors.push(`${id || "(empty id)"}: invalid id`);
812
- }
813
- if (!DATE_TIME_PATTERN.test(time)) {
814
- errors.push(`${id}: invalid time '${time}'`);
815
- }
816
- if (isBlank(step)) {
817
- errors.push(`${id}: step is required`);
818
- }
819
- if (!WORKFLOW_WARNING_SEVERITIES.has(severity)) {
820
- errors.push(`${id}: illegal severity '${severity}'`);
821
- }
822
- if (isBlank(code)) {
823
- errors.push(`${id}: code is required`);
824
- }
825
- if (!WORKFLOW_WARNING_STATUSES.has(status)) {
826
- errors.push(`${id}: illegal status '${status}'`);
827
- }
828
- if (isBlank(target)) {
829
- errors.push(`${id}: target is required`);
830
- }
831
- if (isBlank(message)) {
832
- errors.push(`${id}: message is required`);
833
- }
834
- if (status === "open" && isBlank(action)) {
835
- errors.push(`${id}: open warning requires action`);
836
- }
837
- if ((status === "resolved" || status === "ignored") && (isBlank(resolvedAt) || isBlank(resolution))) {
838
- errors.push(`${id}: ${status} warning requires resolved_at and resolution`);
839
- }
840
- }
841
- return errors;
842
- }
843
- function resolveReviewSetting(config, key, fallback) {
689
+ function resolveReviewSetting(config, key, fallback, repoRoot) {
844
690
  if (config && config[key] !== undefined && config[key] !== null) {
845
691
  return config[key];
846
692
  }
@@ -850,7 +696,7 @@ function resolveReviewSetting(config, key, fallback) {
850
696
  }
851
697
  return fallback;
852
698
  }
853
- function checkReviewLedger({ taskDir, config }) {
699
+ function checkReviewLedger({ taskDir, config, repositoryRoot }) {
854
700
  const task = loadTask(taskDir);
855
701
  if (!task.ok) {
856
702
  return failResult("review-ledger", task.message);
@@ -860,9 +706,7 @@ function checkReviewLedger({ taskDir, config }) {
860
706
  const ledger = parseLedgerDocument(task.content);
861
707
  if (!ledger.present)
862
708
  return failResult("review-ledger", `${LEDGER_SECTION_MISSING_CODE}: ${LEDGER_SECTION_MISSING_MESSAGE}`);
863
- rows = ledger.rows.map((row) => [
864
- row.id, row.stage, row.round, row.severity, row.status, row.evidence
865
- ]);
709
+ rows = ledger.rows;
866
710
  }
867
711
  catch (error) {
868
712
  return failResult("review-ledger", `Invalid disagreement ledger: ${error instanceof Error ? error.message : String(error)}`);
@@ -871,15 +715,11 @@ function checkReviewLedger({ taskDir, config }) {
871
715
  return passResult("review-ledger", "Disagreement ledger has no entries");
872
716
  }
873
717
  const stageScope = Array.isArray(config.stage_scope) ? config.stage_scope : null;
874
- const maxRounds = Number(resolveReviewSetting(config, "maxHandshakeRounds", DEFAULT_MAX_HANDSHAKE_ROUNDS));
718
+ const maxRounds = Number(resolveReviewSetting(config, "maxHandshakeRounds", DEFAULT_MAX_HANDSHAKE_ROUNDS, repositoryRoot));
875
719
  const problems = [];
876
720
  let inScopeCount = 0;
877
- for (const cells of rows) {
878
- if (cells.length < 6) {
879
- problems.push(`malformed row (expected 6 columns): ${cells.join(" | ")}`);
880
- continue;
881
- }
882
- const [id, stage, roundRaw, , status, evidence] = cells;
721
+ for (const row of rows) {
722
+ const { id, stage, round: roundRaw, status, evidence } = row;
883
723
  const stageScoped = stageScope ? stageScope.includes(stage) : true;
884
724
  // post-review-commit exemption rows are consumed by the post-review-commit
885
725
  // check, not enforced here.
@@ -890,8 +730,9 @@ function checkReviewLedger({ taskDir, config }) {
890
730
  continue;
891
731
  }
892
732
  inScopeCount += 1;
893
- if (!LEDGER_STATUSES.has(status)) {
894
- problems.push(`${id}: illegal status '${status}'`);
733
+ const invalid = validateLedgerRows([row]);
734
+ if (invalid) {
735
+ problems.push(`${invalid.code}: ${invalid.message}`);
895
736
  continue;
896
737
  }
897
738
  if (status !== "open" && evidence === "") {
@@ -900,11 +741,11 @@ function checkReviewLedger({ taskDir, config }) {
900
741
  const round = Number.parseInt(roundRaw, 10);
901
742
  if (Number.isFinite(round) &&
902
743
  round >= maxRounds &&
903
- !LEDGER_TERMINAL_OK.has(status) &&
744
+ !LEDGER_TERMINAL.has(status) &&
904
745
  status !== "needs-human-decision") {
905
746
  problems.push(`${id}: round ${round} reached limit ${maxRounds} without convergence; escalate to needs-human-decision`);
906
747
  }
907
- if (!LEDGER_TERMINAL_OK.has(status)) {
748
+ if (!LEDGER_TERMINAL.has(status)) {
908
749
  problems.push(`${id}: unresolved (status '${status}')`);
909
750
  }
910
751
  }
@@ -914,7 +755,7 @@ function checkReviewLedger({ taskDir, config }) {
914
755
  const scopeLabel = stageScope ? ` for stages [${stageScope.join(", ")}]` : "";
915
756
  return passResult("review-ledger", `Disagreement ledger clean (${inScopeCount} in-scope entries terminal${scopeLabel})`);
916
757
  }
917
- function checkManualValidation({ taskDir }) {
758
+ async function checkManualValidation({ taskDir, repositoryRoot }) {
918
759
  // 1. Latest review-code artifact; none -> pass (no review, check not applicable).
919
760
  const review = findAuthoritativeReviewCodeArtifact(taskDir);
920
761
  if (!review.ok) {
@@ -945,10 +786,23 @@ function checkManualValidation({ taskDir }) {
945
786
  const task = loadTask(taskDir);
946
787
  if (!task.ok)
947
788
  return failResult("manual-validation", task.message);
948
- const log = getSectionContent(task.content, ["活动日志", "Activity Log"]);
949
- const completed = new RegExp(`\\*\\*Complete Manual Validation\\*\\*[\\s\\S]*?Manual validation passed → ${escapeRegExp(artifactName)};`);
950
- if (!completed.test(log)) {
951
- return failResult("manual-validation", `Manual validation artifact exists but completion is not recorded for ${artifactName}: re-run /complete-manual-validation`);
789
+ const completion = readManualValidationCompletion(taskDir, {
790
+ taskId: task.metadata.id,
791
+ artifact: artifactName
792
+ });
793
+ if (!completion.ok) {
794
+ const source = completion.error.code.startsWith('MANUAL_VALIDATION_RECEIPT_') ? 'receipt' : 'transaction';
795
+ return failResult("manual-validation", `Manual validation ${source} is unavailable: ${completion.error.message}`);
796
+ }
797
+ const { receipt, transaction } = completion.value;
798
+ if (transaction.phase !== "committed" || !transaction.eventAppended || !transaction.postWriteVerified) {
799
+ return failResult("manual-validation", "Manual validation transaction has not reached the committed post-write-verified state");
800
+ }
801
+ if (transaction.pendingSummaryDigest !== receipt.pendingSummaryDigest || transaction.finalSummaryDigest !== receipt.finalSummaryDigest) {
802
+ return failResult("manual-validation", "Manual validation summary digests do not match the committed receipt");
803
+ }
804
+ if (sha256File(resolved.path) !== receipt.artifactSha256) {
805
+ return failResult("manual-validation", `Manual validation artifact digest does not match the receipt for ${artifactName}`);
952
806
  }
953
807
  // 6. Timing correlation (PL-3 fix, PL-4 corrected): the completion entry must
954
808
  // sit AFTER the latest review-code round's completion entry in the
@@ -957,21 +811,39 @@ function checkManualValidation({ taskDir }) {
957
811
  // which indexOf never matches). Not reusing completed.exec().index: exec
958
812
  // anchors to the first '**Complete Manual Validation**' heading, which can
959
813
  // belong to an earlier round's entry and misorder the standard path.
960
- const reviewDoneIndex = log.indexOf(`**Review Code (Round ${review.round})** by `);
961
- const completedIndex = log.indexOf(`Manual validation passed → ${artifactName};`);
962
- if (reviewDoneIndex === -1) {
963
- // The latest review-code round's completion entry is missing entirely (abnormal
964
- // state, e.g. a restored/historical task without a review-code.completed record).
965
- // Re-running complete-manual-validation cannot restore it, so the remediation
966
- // targets the review record itself. Fail closed either way.
967
- return failResult("manual-validation", `Latest review-code (round ${review.round}) completion entry is missing from the Activity Log (abnormal state): re-run review-code or restore the completion record`);
968
- }
969
- if (completedIndex < reviewDoneIndex) {
970
- return failResult("manual-validation", `Latest review-code (round ${review.round}) came after the manual validation completion recorded for ${artifactName}: re-run /complete-manual-validation to cover new pending items`);
971
- }
972
- return passResult("manual-validation", `Manual validation completed → ${artifactName}`);
814
+ const inspectedLog = inspectActivityLog(task.content);
815
+ if (!inspectedLog.section)
816
+ return failResult("manual-validation", "Activity Log is missing or invalid");
817
+ const reviewDoneIndex = inspectedLog.section.entries.findIndex((entry) => entry.step === `Review Code (Round ${review.round})`);
818
+ const completedIndex = inspectedLog.section.entries.findIndex((entry) => entry.step === "Complete Manual Validation"
819
+ && entry.note.includes(`Manual validation passed → ${artifactName};`)
820
+ && entry.note.includes(`transaction=${receipt.transactionId};`)
821
+ && entry.note.includes(`receipt=${receipt.receiptDigest};`)
822
+ && entry.note.includes(`head=${receipt.prHeadSha}`));
823
+ if (reviewDoneIndex === -1)
824
+ return failResult("manual-validation", `Latest review-code (round ${review.round}) completion entry is missing from the Activity Log`);
825
+ if (completedIndex === -1)
826
+ return failResult("manual-validation", `Committed manual validation completion is not recorded for ${artifactName}`);
827
+ if (completedIndex < reviewDoneIndex)
828
+ return failResult("manual-validation", `Latest review-code (round ${review.round}) came after the manual validation completion recorded for ${artifactName}`);
829
+ const fact = readPrDeliveryFact(task.metadata);
830
+ if (fact.status === "invalid")
831
+ return failResult("manual-validation", fact.error.message);
832
+ if (fact.status === "valid" && fact.fact.state === "bound") {
833
+ const inspected = await inspectPlatformPullRequest(task.metadata.id, { cwd: repositoryRoot });
834
+ if (!inspected.pullRequest)
835
+ return failResult("manual-validation", inspected.error?.message ?? "canonical pull-request head is unavailable");
836
+ if (inspected.pullRequest.head.sha !== receipt.prHeadSha)
837
+ return failResult("manual-validation", "manual validation receipt is stale for the current pull-request head");
838
+ const summary = await summaryCommentState(task.metadata.id, { cwd: repositoryRoot });
839
+ if (!summary.comment)
840
+ return failResult("manual-validation", "canonical pull-request summary comment is unavailable");
841
+ if (!manualValidationFinalSummaryProjectionMatches(summary.comment.body, receipt))
842
+ return failResult("manual-validation", "canonical pull-request summary does not match the committed manual validation projection");
843
+ }
844
+ return passResult("manual-validation", `Manual validation completed → ${artifactName} (committed receipt and post-write verification)`);
973
845
  }
974
- async function checkPostReviewCommit({ taskDir, config }) {
846
+ async function checkPostReviewCommit({ taskDir, config, repositoryRoot }) {
975
847
  const reviewArtifact = findAuthoritativeReviewCodeArtifact(taskDir);
976
848
  if (!reviewArtifact.ok) {
977
849
  if (reviewArtifact.error)
@@ -993,7 +865,7 @@ async function checkPostReviewCommit({ taskDir, config }) {
993
865
  return failResult("post-review-commit", factRead.error.message);
994
866
  const fact = factRead.status === 'valid' ? factRead.fact : null;
995
867
  const lastReviewedCommit = task.ok ? (task.metadata.last_reviewed_commit || "").trim() : "";
996
- const globs = resolvePostReviewGlobs(config, loadPostReviewConfig(repoRoot));
868
+ const globs = resolvePostReviewGlobs(config, loadPostReviewConfig(repositoryRoot));
997
869
  const hasPullRequest = fact?.state === 'bound';
998
870
  let inspected = null;
999
871
  if (hasPullRequest) {
@@ -1139,7 +1011,7 @@ function resolvePostReviewExemption(content) {
1139
1011
  };
1140
1012
  }
1141
1013
  }
1142
- function checkReviewFact({ taskDir, artifactFile }) {
1014
+ function checkReviewFact({ taskDir, artifactFile, repositoryRoot }) {
1143
1015
  const resolvedArtifact = resolveArtifactPath(taskDir, "review-code.md|review-code-r{N}.md", artifactFile);
1144
1016
  if (!resolvedArtifact.ok) {
1145
1017
  return failResult("review-fact", resolvedArtifact.message);
@@ -1205,7 +1077,7 @@ function checkReviewFact({ taskDir, artifactFile }) {
1205
1077
  mode: "worktree",
1206
1078
  baseline,
1207
1079
  diffBase,
1208
- globs: resolvePostReviewGlobs({}, loadPostReviewConfig(repoRoot))
1080
+ globs: resolvePostReviewGlobs({}, loadPostReviewConfig(repositoryRoot))
1209
1081
  });
1210
1082
  }
1211
1083
  catch {
@@ -1292,40 +1164,12 @@ function resolveArtifactPath(taskDir, filePattern, artifactFile) {
1292
1164
  return { ok: true, path: path.join(taskDir, matches[0].fileName) };
1293
1165
  }
1294
1166
  function getSectionContent(content, names) {
1295
- const lines = content.split(/\r?\n/);
1296
- function visibleHeadings() {
1297
- const headings = [];
1298
- let fence = null;
1299
- for (let index = 0; index < lines.length; index += 1) {
1300
- const line = lines[index];
1301
- if (fence) {
1302
- const closer = line.match(/^ {0,3}(`+|~+)\s*$/);
1303
- if (closer && closer[1][0] === fence.character && closer[1].length >= fence.length) {
1304
- fence = null;
1305
- }
1306
- continue;
1307
- }
1308
- const opener = line.match(/^ {0,3}(`{3,}|~{3,})(?:[^`~].*)?$/);
1309
- if (opener) {
1310
- fence = { character: opener[1][0], length: opener[1].length };
1311
- continue;
1312
- }
1313
- if (line.startsWith("## ")) {
1314
- headings.push({ index, text: line.trim() });
1315
- }
1316
- }
1317
- return headings;
1318
- }
1319
- const headings = visibleHeadings();
1167
+ const headings = scanVisibleMarkdown(content).headings.filter((heading) => heading.level === 2);
1320
1168
  for (const name of names) {
1321
- const heading = `## ${name}`;
1322
- const position = headings.findIndex((item) => item.text === heading);
1323
- if (position === -1) {
1169
+ const position = headings.findIndex((heading) => heading.text === name);
1170
+ if (position === -1)
1324
1171
  continue;
1325
- }
1326
- const startIndex = headings[position].index;
1327
- const endIndex = headings[position + 1]?.index ?? lines.length;
1328
- return lines.slice(startIndex + 1, endIndex).join("\n").trim();
1172
+ return content.slice(headings[position].end + 1, headings[position + 1]?.start ?? content.length).replace(/\r\n/g, "\n").trim();
1329
1173
  }
1330
1174
  return "";
1331
1175
  }
@@ -1429,9 +1273,8 @@ function isBlank(value) {
1429
1273
  return value === undefined || value === null || String(value).trim() === "";
1430
1274
  }
1431
1275
  async function verifyInProcess({ mode, skillName, taskDir, artifactFile, checks: requestedChecks, repositoryRoot }) {
1432
- if (repositoryRoot)
1433
- repoRoot = path.resolve(repositoryRoot);
1434
- else {
1276
+ let repoRoot = repositoryRoot ? path.resolve(repositoryRoot) : defaultRepoRoot;
1277
+ if (!repositoryRoot) {
1435
1278
  let cursor = path.resolve(taskDir);
1436
1279
  while (path.dirname(cursor) !== cursor && !fs.existsSync(path.join(cursor, ".agents")))
1437
1280
  cursor = path.dirname(cursor);