dorfl 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (492) hide show
  1. package/dist/advance-ci-template.d.ts +3 -3
  2. package/dist/advance-ci-template.js +1 -1
  3. package/dist/advance-ci-template.js.map +1 -1
  4. package/dist/advance-classify.d.ts +5 -5
  5. package/dist/advance-classify.d.ts.map +1 -1
  6. package/dist/advance-classify.js +4 -4
  7. package/dist/advance-drivers.d.ts +8 -8
  8. package/dist/advance-drivers.d.ts.map +1 -1
  9. package/dist/advance-drivers.js +20 -8
  10. package/dist/advance-drivers.js.map +1 -1
  11. package/dist/advance-isolated.d.ts +3 -3
  12. package/dist/advance-isolated.d.ts.map +1 -1
  13. package/dist/advance-isolated.js +1 -1
  14. package/dist/advance-lifecycle-template.d.ts +2 -2
  15. package/dist/advance-lifecycle-template.d.ts.map +1 -1
  16. package/dist/advance-lifecycle-template.js +85 -13
  17. package/dist/advance-lifecycle-template.js.map +1 -1
  18. package/dist/advance-loop-driver.d.ts +3 -3
  19. package/dist/advance-loop-driver.d.ts.map +1 -1
  20. package/dist/advance-loop-driver.js +1 -1
  21. package/dist/advance-treeless-publish.d.ts +24 -1
  22. package/dist/advance-treeless-publish.d.ts.map +1 -1
  23. package/dist/advance-treeless-publish.js +41 -0
  24. package/dist/advance-treeless-publish.js.map +1 -1
  25. package/dist/advance.d.ts +69 -17
  26. package/dist/advance.d.ts.map +1 -1
  27. package/dist/advance.js +409 -102
  28. package/dist/advance.js.map +1 -1
  29. package/dist/advancing-lock.d.ts +31 -3
  30. package/dist/advancing-lock.d.ts.map +1 -1
  31. package/dist/advancing-lock.js +55 -5
  32. package/dist/advancing-lock.js.map +1 -1
  33. package/dist/agent-launch.d.ts +12 -0
  34. package/dist/agent-launch.d.ts.map +1 -1
  35. package/dist/agent-launch.js +22 -12
  36. package/dist/agent-launch.js.map +1 -1
  37. package/dist/agent-stop.d.ts +40 -2
  38. package/dist/agent-stop.d.ts.map +1 -1
  39. package/dist/agent-stop.js +30 -2
  40. package/dist/agent-stop.js.map +1 -1
  41. package/dist/apply-decide.d.ts +19 -5
  42. package/dist/apply-decide.d.ts.map +1 -1
  43. package/dist/apply-decide.js +38 -9
  44. package/dist/apply-decide.js.map +1 -1
  45. package/dist/apply-merge-action.d.ts +20 -8
  46. package/dist/apply-merge-action.d.ts.map +1 -1
  47. package/dist/apply-merge-action.js +44 -9
  48. package/dist/apply-merge-action.js.map +1 -1
  49. package/dist/apply-persist.d.ts +62 -31
  50. package/dist/apply-persist.d.ts.map +1 -1
  51. package/dist/apply-persist.js +173 -44
  52. package/dist/apply-persist.js.map +1 -1
  53. package/dist/apply-stuck-action.d.ts +151 -0
  54. package/dist/apply-stuck-action.d.ts.map +1 -0
  55. package/dist/apply-stuck-action.js +125 -0
  56. package/dist/apply-stuck-action.js.map +1 -0
  57. package/dist/brand.d.ts +12 -1
  58. package/dist/brand.d.ts.map +1 -1
  59. package/dist/brand.js +2 -1
  60. package/dist/brand.js.map +1 -1
  61. package/dist/buildable-body.d.ts +14 -14
  62. package/dist/buildable-body.js +9 -9
  63. package/dist/claim-cas.d.ts +3 -3
  64. package/dist/claim-cas.js +1 -1
  65. package/dist/claim-cas.js.map +1 -1
  66. package/dist/cli-spinner.d.ts +1 -1
  67. package/dist/cli-spinner.js +1 -1
  68. package/dist/cli.d.ts +10 -0
  69. package/dist/cli.d.ts.map +1 -1
  70. package/dist/cli.js +385 -128
  71. package/dist/cli.js.map +1 -1
  72. package/dist/close-job-template.d.ts +3 -3
  73. package/dist/close-job-template.js +9 -9
  74. package/dist/close-job.d.ts +8 -8
  75. package/dist/close-job.js +25 -25
  76. package/dist/close-job.js.map +1 -1
  77. package/dist/complete.d.ts +9 -6
  78. package/dist/complete.d.ts.map +1 -1
  79. package/dist/complete.js +99 -45
  80. package/dist/complete.js.map +1 -1
  81. package/dist/concurrency.d.ts +1 -1
  82. package/dist/concurrency.js +1 -1
  83. package/dist/config.d.ts +86 -40
  84. package/dist/config.d.ts.map +1 -1
  85. package/dist/config.js +61 -9
  86. package/dist/config.js.map +1 -1
  87. package/dist/continue-branch.d.ts +1 -1
  88. package/dist/continue-branch.d.ts.map +1 -1
  89. package/dist/continue-branch.js +23 -1
  90. package/dist/continue-branch.js.map +1 -1
  91. package/dist/cwd-section.js +1 -1
  92. package/dist/cwd-section.js.map +1 -1
  93. package/dist/decision-engine.d.ts +39 -11
  94. package/dist/decision-engine.d.ts.map +1 -1
  95. package/dist/decision-engine.js +10 -6
  96. package/dist/decision-engine.js.map +1 -1
  97. package/dist/do-autopick.d.ts +6 -6
  98. package/dist/do-autopick.d.ts.map +1 -1
  99. package/dist/do-autopick.js +16 -6
  100. package/dist/do-autopick.js.map +1 -1
  101. package/dist/do-config.d.ts +4 -4
  102. package/dist/do-config.js +3 -3
  103. package/dist/do-config.js.map +1 -1
  104. package/dist/do-remote-auto.d.ts +2 -2
  105. package/dist/do-remote-auto.js +1 -1
  106. package/dist/do.d.ts +74 -81
  107. package/dist/do.d.ts.map +1 -1
  108. package/dist/do.js +439 -50
  109. package/dist/do.js.map +1 -1
  110. package/dist/drop-source.d.ts +2 -2
  111. package/dist/env-config.d.ts.map +1 -1
  112. package/dist/env-config.js +19 -11
  113. package/dist/env-config.js.map +1 -1
  114. package/dist/failure-cause.d.ts +3 -2
  115. package/dist/failure-cause.d.ts.map +1 -1
  116. package/dist/failure-cause.js +28 -1
  117. package/dist/failure-cause.js.map +1 -1
  118. package/dist/format.d.ts +6 -6
  119. package/dist/format.d.ts.map +1 -1
  120. package/dist/format.js +13 -30
  121. package/dist/format.js.map +1 -1
  122. package/dist/frontmatter.d.ts +28 -15
  123. package/dist/frontmatter.d.ts.map +1 -1
  124. package/dist/frontmatter.js +38 -24
  125. package/dist/frontmatter.js.map +1 -1
  126. package/dist/gc.d.ts +65 -6
  127. package/dist/gc.d.ts.map +1 -1
  128. package/dist/gc.js +126 -9
  129. package/dist/gc.js.map +1 -1
  130. package/dist/github.d.ts +14 -0
  131. package/dist/github.d.ts.map +1 -1
  132. package/dist/github.js +73 -0
  133. package/dist/github.js.map +1 -1
  134. package/dist/harness.d.ts +25 -0
  135. package/dist/harness.d.ts.map +1 -1
  136. package/dist/harness.js.map +1 -1
  137. package/dist/index.d.ts +4 -1
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/index.js +2 -1
  140. package/dist/index.js.map +1 -1
  141. package/dist/install-ci-branch-protection.d.ts +133 -39
  142. package/dist/install-ci-branch-protection.d.ts.map +1 -1
  143. package/dist/install-ci-branch-protection.js +191 -49
  144. package/dist/install-ci-branch-protection.js.map +1 -1
  145. package/dist/install-ci-capabilities/advance-lifecycle.d.ts +1 -1
  146. package/dist/install-ci-capabilities/advance-lifecycle.js +1 -1
  147. package/dist/install-ci-capabilities/close-job.d.ts +1 -1
  148. package/dist/install-ci-capabilities/close-job.js +1 -1
  149. package/dist/install-ci-capabilities/example-noop.d.ts +1 -1
  150. package/dist/install-ci-capabilities/example-noop.js +1 -1
  151. package/dist/install-ci-capabilities/intake.d.ts +2 -2
  152. package/dist/install-ci-capabilities/intake.js +2 -2
  153. package/dist/install-ci-capabilities/verify.d.ts +1 -1
  154. package/dist/install-ci-capabilities/verify.js +1 -1
  155. package/dist/install-ci-core.d.ts +24 -4
  156. package/dist/install-ci-core.d.ts.map +1 -1
  157. package/dist/install-ci-core.js +12 -5
  158. package/dist/install-ci-core.js.map +1 -1
  159. package/dist/install-ci-github.d.ts +33 -1
  160. package/dist/install-ci-github.d.ts.map +1 -1
  161. package/dist/install-ci-github.js +74 -1
  162. package/dist/install-ci-github.js.map +1 -1
  163. package/dist/install-ci.d.ts +1 -1
  164. package/dist/install-ci.js +4 -4
  165. package/dist/install-ci.js.map +1 -1
  166. package/dist/install-skills.d.ts +123 -0
  167. package/dist/install-skills.d.ts.map +1 -0
  168. package/dist/install-skills.js +100 -0
  169. package/dist/install-skills.js.map +1 -0
  170. package/dist/intake-event.d.ts +6 -6
  171. package/dist/intake-event.js +6 -6
  172. package/dist/intake-marker.d.ts +3 -3
  173. package/dist/intake-marker.d.ts.map +1 -1
  174. package/dist/intake-triage.d.ts +1 -1
  175. package/dist/intake-triage.js +2 -2
  176. package/dist/intake-trigger-template.d.ts +8 -8
  177. package/dist/intake-trigger-template.d.ts.map +1 -1
  178. package/dist/intake-trigger-template.js +17 -17
  179. package/dist/intake-trigger-template.js.map +1 -1
  180. package/dist/intake.d.ts +65 -52
  181. package/dist/intake.d.ts.map +1 -1
  182. package/dist/intake.js +92 -76
  183. package/dist/intake.js.map +1 -1
  184. package/dist/integration-core.d.ts +27 -24
  185. package/dist/integration-core.d.ts.map +1 -1
  186. package/dist/integration-core.js +191 -77
  187. package/dist/integration-core.js.map +1 -1
  188. package/dist/integrator.d.ts +1 -1
  189. package/dist/integrator.d.ts.map +1 -1
  190. package/dist/integrator.js +19 -3
  191. package/dist/integrator.js.map +1 -1
  192. package/dist/isolation.d.ts +4 -4
  193. package/dist/isolation.d.ts.map +1 -1
  194. package/dist/isolation.js +9 -0
  195. package/dist/isolation.js.map +1 -1
  196. package/dist/issue-provider.d.ts +4 -4
  197. package/dist/issue-provider.js +1 -1
  198. package/dist/item-lock.d.ts +216 -149
  199. package/dist/item-lock.d.ts.map +1 -1
  200. package/dist/item-lock.js +345 -270
  201. package/dist/item-lock.js.map +1 -1
  202. package/dist/item-path.d.ts +2 -2
  203. package/dist/item-path.js +2 -2
  204. package/dist/ledger-lint.d.ts +9 -9
  205. package/dist/ledger-lint.js +9 -9
  206. package/dist/ledger-read.d.ts +57 -57
  207. package/dist/ledger-read.d.ts.map +1 -1
  208. package/dist/ledger-read.js +24 -24
  209. package/dist/ledger-read.js.map +1 -1
  210. package/dist/ledger-write.d.ts +33 -28
  211. package/dist/ledger-write.d.ts.map +1 -1
  212. package/dist/ledger-write.js +100 -122
  213. package/dist/ledger-write.js.map +1 -1
  214. package/dist/lifecycle-gather.d.ts +18 -1
  215. package/dist/lifecycle-gather.d.ts.map +1 -1
  216. package/dist/lifecycle-gather.js +23 -17
  217. package/dist/lifecycle-gather.js.map +1 -1
  218. package/dist/lifecycle-pools.d.ts +44 -7
  219. package/dist/lifecycle-pools.d.ts.map +1 -1
  220. package/dist/lifecycle-pools.js +27 -7
  221. package/dist/lifecycle-pools.js.map +1 -1
  222. package/dist/merge-question-surfacer.d.ts +18 -4
  223. package/dist/merge-question-surfacer.d.ts.map +1 -1
  224. package/dist/merge-question-surfacer.js +20 -5
  225. package/dist/merge-question-surfacer.js.map +1 -1
  226. package/dist/migrate-stuck-locks.d.ts +129 -0
  227. package/dist/migrate-stuck-locks.d.ts.map +1 -0
  228. package/dist/migrate-stuck-locks.js +355 -0
  229. package/dist/migrate-stuck-locks.js.map +1 -0
  230. package/dist/mint-adr.js +4 -4
  231. package/dist/mirror-pool-scan.d.ts +2 -2
  232. package/dist/mirror-pool-scan.js +3 -3
  233. package/dist/mirror-pool-scan.js.map +1 -1
  234. package/dist/needs-attention.d.ts +304 -27
  235. package/dist/needs-attention.d.ts.map +1 -1
  236. package/dist/needs-attention.js +542 -67
  237. package/dist/needs-attention.js.map +1 -1
  238. package/dist/orphan-sidecar.d.ts +10 -6
  239. package/dist/orphan-sidecar.d.ts.map +1 -1
  240. package/dist/orphan-sidecar.js +35 -2
  241. package/dist/orphan-sidecar.js.map +1 -1
  242. package/dist/pi-harness.d.ts +16 -0
  243. package/dist/pi-harness.d.ts.map +1 -1
  244. package/dist/pi-harness.js +82 -2
  245. package/dist/pi-harness.js.map +1 -1
  246. package/dist/placement.d.ts +8 -8
  247. package/dist/placement.js +3 -3
  248. package/dist/prd-to-spec.d.ts.map +1 -1
  249. package/dist/prd-to-spec.js +9 -5
  250. package/dist/prd-to-spec.js.map +1 -1
  251. package/dist/prompt.d.ts +16 -19
  252. package/dist/prompt.d.ts.map +1 -1
  253. package/dist/prompt.js +17 -19
  254. package/dist/prompt.js.map +1 -1
  255. package/dist/protocol/CLAIM-PROTOCOL.md +17 -10
  256. package/dist/protocol/REVIEW-PROTOCOL.md +4 -1
  257. package/dist/protocol/SURFACE-PROTOCOL.md +16 -2
  258. package/dist/protocol/TASKING-PROTOCOL.md +3 -1
  259. package/dist/protocol/WORK-CONTRACT.md +22 -18
  260. package/dist/protocol/task-template.md +1 -1
  261. package/dist/readiness.d.ts +1 -1
  262. package/dist/reap-branches.d.ts +12 -9
  263. package/dist/reap-branches.d.ts.map +1 -1
  264. package/dist/reap-branches.js +25 -7
  265. package/dist/reap-branches.js.map +1 -1
  266. package/dist/recover-isolated.d.ts +12 -0
  267. package/dist/recover-isolated.d.ts.map +1 -1
  268. package/dist/recover-isolated.js +6 -1
  269. package/dist/recover-isolated.js.map +1 -1
  270. package/dist/repo-config.d.ts +23 -2
  271. package/dist/repo-config.d.ts.map +1 -1
  272. package/dist/repo-config.js +64 -18
  273. package/dist/repo-config.js.map +1 -1
  274. package/dist/repo-mirror.d.ts.map +1 -1
  275. package/dist/repo-mirror.js +18 -2
  276. package/dist/repo-mirror.js.map +1 -1
  277. package/dist/review-gate.d.ts +3 -3
  278. package/dist/review-gate.d.ts.map +1 -1
  279. package/dist/review-gate.js +11 -10
  280. package/dist/review-gate.js.map +1 -1
  281. package/dist/review-verdict.d.ts +2 -2
  282. package/dist/review-verdict.d.ts.map +1 -1
  283. package/dist/review-verdict.js +2 -2
  284. package/dist/review-verdict.js.map +1 -1
  285. package/dist/run.d.ts +2 -2
  286. package/dist/run.d.ts.map +1 -1
  287. package/dist/run.js +58 -23
  288. package/dist/run.js.map +1 -1
  289. package/dist/scan.d.ts +26 -17
  290. package/dist/scan.d.ts.map +1 -1
  291. package/dist/scan.js +29 -15
  292. package/dist/scan.js.map +1 -1
  293. package/dist/select-order.d.ts +1 -1
  294. package/dist/select-priority.d.ts +14 -14
  295. package/dist/select-priority.d.ts.map +1 -1
  296. package/dist/select-priority.js +5 -5
  297. package/dist/select-priority.js.map +1 -1
  298. package/dist/sidecar-apply.js +1 -1
  299. package/dist/sidecar-apply.js.map +1 -1
  300. package/dist/sidecar.d.ts +47 -12
  301. package/dist/sidecar.d.ts.map +1 -1
  302. package/dist/sidecar.js +84 -4
  303. package/dist/sidecar.js.map +1 -1
  304. package/dist/skills/answer-questions/SKILL.md +89 -0
  305. package/dist/skills/capture-signal/SKILL.md +52 -0
  306. package/dist/skills/convert-from-prd-to-spec/SKILL.md +90 -0
  307. package/dist/skills/drive-tasks/SKILL.md +218 -0
  308. package/dist/skills/from-idea/SKILL.md +83 -0
  309. package/dist/skills/merge-prs/SKILL.md +70 -0
  310. package/dist/skills/orchestrate/SKILL.md +101 -0
  311. package/dist/skills/promote/SKILL.md +35 -0
  312. package/dist/skills/review/SKILL.md +16 -0
  313. package/dist/skills/setup/SKILL.md +258 -0
  314. package/dist/skills/setup/protocol/ADR-FORMAT.md +47 -0
  315. package/dist/skills/setup/protocol/CLAIM-PROTOCOL.md +224 -0
  316. package/dist/skills/setup/protocol/REVIEW-PROTOCOL.md +122 -0
  317. package/dist/skills/setup/protocol/SURFACE-PROTOCOL.md +135 -0
  318. package/dist/skills/setup/protocol/TASKING-PROTOCOL.md +124 -0
  319. package/dist/skills/setup/protocol/WORK-CONTRACT.md +280 -0
  320. package/dist/skills/setup/protocol/spec-template.md +71 -0
  321. package/dist/skills/setup/protocol/task-template.md +65 -0
  322. package/dist/skills/surface-questions/SKILL.md +16 -0
  323. package/dist/skills/to-spec/SKILL.md +34 -0
  324. package/dist/skills/to-task/SKILL.md +19 -0
  325. package/dist/skills/triage-observations/SKILL.md +78 -0
  326. package/dist/skills/work/SKILL.md +51 -0
  327. package/dist/slug-namespace.d.ts +6 -6
  328. package/dist/slug-namespace.js +8 -8
  329. package/dist/slug-namespace.js.map +1 -1
  330. package/dist/spec-complete.d.ts.map +1 -1
  331. package/dist/spec-complete.js +4 -5
  332. package/dist/spec-complete.js.map +1 -1
  333. package/dist/start.d.ts +1 -1
  334. package/dist/start.d.ts.map +1 -1
  335. package/dist/start.js +54 -60
  336. package/dist/start.js.map +1 -1
  337. package/dist/status.d.ts +3 -3
  338. package/dist/status.js +4 -4
  339. package/dist/status.js.map +1 -1
  340. package/dist/surface-gate.d.ts +2 -2
  341. package/dist/surface-gate.d.ts.map +1 -1
  342. package/dist/surface-gate.js +10 -3
  343. package/dist/surface-gate.js.map +1 -1
  344. package/dist/surface-persist.d.ts +2 -2
  345. package/dist/surface-persist.d.ts.map +1 -1
  346. package/dist/surface-persist.js +1 -1
  347. package/dist/surface-persist.js.map +1 -1
  348. package/dist/tasker-review-loop.d.ts +11 -10
  349. package/dist/tasker-review-loop.d.ts.map +1 -1
  350. package/dist/tasker-review-loop.js +8 -8
  351. package/dist/tasker-review-loop.js.map +1 -1
  352. package/dist/tasking-eligibility.d.ts +21 -21
  353. package/dist/tasking-eligibility.d.ts.map +1 -1
  354. package/dist/tasking-eligibility.js +10 -10
  355. package/dist/tasking-lock.d.ts +10 -10
  356. package/dist/tasking-lock.d.ts.map +1 -1
  357. package/dist/tasking-lock.js +69 -49
  358. package/dist/tasking-lock.js.map +1 -1
  359. package/dist/tasking.d.ts +73 -39
  360. package/dist/tasking.d.ts.map +1 -1
  361. package/dist/tasking.js +309 -95
  362. package/dist/tasking.js.map +1 -1
  363. package/dist/triage-gate.d.ts +1 -1
  364. package/dist/triage-persist.d.ts +15 -11
  365. package/dist/triage-persist.d.ts.map +1 -1
  366. package/dist/triage-persist.js +48 -18
  367. package/dist/triage-persist.js.map +1 -1
  368. package/dist/vendor/incur/agents.d.ts +58 -0
  369. package/dist/vendor/incur/agents.d.ts.map +1 -0
  370. package/dist/vendor/incur/agents.js +343 -0
  371. package/dist/vendor/incur/agents.js.map +1 -0
  372. package/dist/verify-workflow-template.d.ts +1 -1
  373. package/dist/verify-workflow-template.js +3 -3
  374. package/dist/watch-session.d.ts +11 -3
  375. package/dist/watch-session.d.ts.map +1 -1
  376. package/dist/watch-session.js +94 -7
  377. package/dist/watch-session.js.map +1 -1
  378. package/dist/work-layout.d.ts +15 -9
  379. package/dist/work-layout.d.ts.map +1 -1
  380. package/dist/work-layout.js +14 -9
  381. package/dist/work-layout.js.map +1 -1
  382. package/dist/workspace.d.ts +2 -2
  383. package/package.json +2 -2
  384. package/src/advance-ci-template.ts +4 -4
  385. package/src/advance-classify.ts +5 -5
  386. package/src/advance-drivers.ts +26 -13
  387. package/src/advance-isolated.ts +3 -3
  388. package/src/advance-lifecycle-template.ts +98 -13
  389. package/src/advance-loop-driver.ts +3 -3
  390. package/src/advance-treeless-publish.ts +46 -1
  391. package/src/advance.ts +495 -115
  392. package/src/advancing-lock.ts +102 -7
  393. package/src/agent-launch.ts +37 -12
  394. package/src/agent-stop.ts +60 -2
  395. package/src/apply-decide.ts +38 -9
  396. package/src/apply-merge-action.ts +49 -11
  397. package/src/apply-persist.ts +236 -62
  398. package/src/apply-stuck-action.ts +260 -0
  399. package/src/brand.ts +14 -2
  400. package/src/buildable-body.ts +14 -14
  401. package/src/claim-cas.ts +4 -4
  402. package/src/cli-spinner.ts +1 -1
  403. package/src/cli.ts +472 -141
  404. package/src/close-job-template.ts +9 -9
  405. package/src/close-job.ts +26 -26
  406. package/src/complete.ts +121 -63
  407. package/src/concurrency.ts +1 -1
  408. package/src/config.ts +143 -49
  409. package/src/continue-branch.ts +23 -1
  410. package/src/cwd-section.ts +1 -1
  411. package/src/decision-engine.ts +57 -19
  412. package/src/do-autopick.ts +21 -10
  413. package/src/do-config.ts +7 -7
  414. package/src/do-remote-auto.ts +2 -2
  415. package/src/do.ts +558 -85
  416. package/src/drop-source.ts +2 -2
  417. package/src/env-config.ts +19 -11
  418. package/src/failure-cause.ts +30 -1
  419. package/src/format.ts +13 -33
  420. package/src/frontmatter.ts +55 -35
  421. package/src/gc.ts +172 -9
  422. package/src/github.ts +78 -0
  423. package/src/harness.ts +25 -0
  424. package/src/index.ts +10 -0
  425. package/src/install-ci-branch-protection.ts +283 -58
  426. package/src/install-ci-capabilities/advance-lifecycle.ts +1 -1
  427. package/src/install-ci-capabilities/close-job.ts +1 -1
  428. package/src/install-ci-capabilities/example-noop.ts +1 -1
  429. package/src/install-ci-capabilities/intake.ts +2 -2
  430. package/src/install-ci-capabilities/verify.ts +1 -1
  431. package/src/install-ci-core.ts +34 -7
  432. package/src/install-ci-github.ts +87 -1
  433. package/src/install-ci.ts +4 -4
  434. package/src/install-skills.ts +166 -0
  435. package/src/intake-event.ts +6 -6
  436. package/src/intake-marker.ts +3 -3
  437. package/src/intake-triage.ts +2 -2
  438. package/src/intake-trigger-template.ts +18 -18
  439. package/src/intake.ts +138 -103
  440. package/src/integration-core.ts +234 -100
  441. package/src/integrator.ts +22 -9
  442. package/src/isolation.ts +13 -4
  443. package/src/issue-provider.ts +4 -4
  444. package/src/item-lock.ts +505 -361
  445. package/src/item-path.ts +2 -2
  446. package/src/ledger-lint.ts +9 -9
  447. package/src/ledger-read.ts +81 -81
  448. package/src/ledger-write.ts +137 -152
  449. package/src/lifecycle-gather.ts +45 -22
  450. package/src/lifecycle-pools.ts +71 -13
  451. package/src/merge-question-surfacer.ts +32 -8
  452. package/src/migrate-stuck-locks.ts +451 -0
  453. package/src/mint-adr.ts +4 -4
  454. package/src/mirror-pool-scan.ts +5 -5
  455. package/src/needs-attention.ts +877 -104
  456. package/src/orphan-sidecar.ts +49 -8
  457. package/src/pi-harness.ts +82 -2
  458. package/src/placement.ts +8 -8
  459. package/src/prd-to-spec.ts +13 -5
  460. package/src/prompt.ts +20 -25
  461. package/src/readiness.ts +1 -1
  462. package/src/reap-branches.ts +38 -14
  463. package/src/recover-isolated.ts +18 -1
  464. package/src/repo-config.ts +66 -17
  465. package/src/repo-mirror.ts +23 -1
  466. package/src/review-gate.ts +12 -11
  467. package/src/review-verdict.ts +3 -3
  468. package/src/run.ts +69 -23
  469. package/src/scan.ts +36 -22
  470. package/src/select-order.ts +1 -1
  471. package/src/select-priority.ts +15 -15
  472. package/src/sidecar-apply.ts +1 -1
  473. package/src/sidecar.ts +141 -14
  474. package/src/slug-namespace.ts +10 -10
  475. package/src/spec-complete.ts +4 -5
  476. package/src/start.ts +57 -63
  477. package/src/status.ts +7 -7
  478. package/src/surface-gate.ts +12 -5
  479. package/src/surface-persist.ts +3 -3
  480. package/src/tasker-review-loop.ts +18 -17
  481. package/src/tasking-eligibility.ts +21 -21
  482. package/src/tasking-lock.ts +75 -60
  483. package/src/tasking.ts +381 -135
  484. package/src/triage-gate.ts +1 -1
  485. package/src/triage-persist.ts +71 -27
  486. package/src/vendor/incur/LICENSE +21 -0
  487. package/src/vendor/incur/README.md +19 -0
  488. package/src/vendor/incur/agents.ts +392 -0
  489. package/src/verify-workflow-template.ts +3 -3
  490. package/src/watch-session.ts +102 -7
  491. package/src/work-layout.ts +14 -9
  492. package/src/workspace.ts +2 -2
package/dist/do.js CHANGED
@@ -21,11 +21,162 @@ import { shouldFailProposePrIntent, PROPOSE_PR_INTENT_GH_UNAVAILABLE_MESSAGE, }
21
21
  import { checkGatePreconditions, detectLockfileOnDisk, detectLockfileOnMirrorMain, } from './gate-readiness.js';
22
22
  import { git, run, runAsync, localMainAheadCount } from './git.js';
23
23
  import { identityEnv, assertTransportAllowed, } from './identity.js';
24
- import { parseStopSentinel, isWorkBranchDiffEmpty, emptyDiffStopReason, } from './agent-stop.js';
24
+ import { parseStopSentinel, isWorkBranchDiffEmpty, emptyDiffStopReason, emptyDiffDisposeEnvelope, } from './agent-stop.js';
25
+ import { surfaceStuckToNeedsAttention, routeToNeedsAttention, } from './needs-attention.js';
26
+ import { resolveItemPathByIdentity } from './item-path.js';
25
27
  import { classifyFailureCause, failureCauseLabel, } from './failure-cause.js';
28
+ /**
29
+ * `dorfl do <slug>` (in-place form) — the per-repo, in-place WORKER that
30
+ * claims + builds + gates + integrates in ONE checkout, then EXITS (ADR §3).
31
+ * **This is the CI command** (CI has a checkout, is one repo, is one triggered
32
+ * invocation, exits) and it ABSORBS the manual `ar-run.sh` test-driver.
33
+ *
34
+ * In-place `do` is on the ISOLATION SEAM (`do-run-share-isolation-seam`): it is
35
+ * the FIRST production consumer of `selectIsolationStrategy`/`inPlaceStrategy`,
36
+ * so all THREE `do`/`run` forms (in-place `do`, `do --remote`, `run`) share the
37
+ * ONE `IsolatedTree`-handle post-claim shape. The composition mirrors
38
+ * `do --remote`/`run` exactly: keep the two in-place GUARDS (dirty-tree refusal
39
+ * + pre-flight diverged-main guard) in this driver BEFORE onboarding, CLAIM
40
+ * explicitly via the CAS (`performClaim`), then let
41
+ * `selectIsolationStrategy({checkout}).prepare()` do the ONBOARDING half (fetch +
42
+ * continue-detection + fresh-main `work/<slug>` switch, incl. the §14
43
+ * continue/rebase + §10 conflict path) WITHOUT re-claiming. The agent run is the
44
+ * ONLY new middle step (the one `ar-run.sh` shelled out for, `prompt | pi`). The
45
+ * runner owns EVERY git-state transition (claim, done-move, completion commit,
46
+ * integration); the agent only edits code.
47
+ *
48
+ * The in-place ISOLATION (ADR §3): the current checkout / CI container IS the
49
+ * isolation — no hub mirror, no external worktree. `inPlaceStrategy.prepare()`
50
+ * puts the checkout on `work/<slug>` cut from the freshly-fetched
51
+ * `<arbiter>/main`; its handle's `teardown` is a NO-OP (the checkout is left in a
52
+ * defined state on `work/<slug>`, NEVER reaped). `do --remote` (the job-worktree
53
+ * strategy) is the SEPARATE `do-remote` task; auto-pick / multi-arg / `-n` is
54
+ * `do-autopick`.
55
+ *
56
+ * CLAIM SEMANTICS (autonomous, same as `do --remote`/`run`): the claim is
57
+ * explicit and claim-or-lose. An item that is NOT in the pool (`tasks-ready`) on
58
+ * the arbiter (already in-progress / done / absent) is not claimable, so the CAS
59
+ * returns
60
+ * `lost` (exit 2) and the run skips cleanly — `do`, the unattended CI worker,
61
+ * never re-claims an item someone else holds and never silently picks up a
62
+ * needs-attention item (a human does that through the human face).
63
+ *
64
+ * **CRITICAL — `do` is AUTONOMOUS, so its failure path is `run`'s, NOT
65
+ * `complete`'s.** On a red gate / rebase conflict, `performComplete` routes the
66
+ * item to needs-attention via the SAME seam call as `run`'s `runOneItem`, but
67
+ * `complete` calls it WITHOUT an arbiter (the human path: a human is right
68
+ * there). `do` runs UNATTENDED, so it MUST get the autonomous, arbiter-passed
69
+ * surfacing like `run` (the on-`main` cherry-pick that makes a stuck CI run
70
+ * visible to `scan`/`status`/another machine). We achieve this by passing
71
+ * `surfaceArbiter` into `performComplete` (resolution (a) from the task): the
72
+ * success path reuses `complete`'s machinery; only the NEEDS-ATTENTION routing
73
+ * becomes the autonomous variant.
74
+ *
75
+ * `--propose` (default) / `--merge` is resolved at integrate-time exactly like
76
+ * `complete` (the caller threads the resolved mode in as `integration`).
77
+ */
78
+ /**
79
+ * The commit-message subject the deadline-checkpoint save writes, and the
80
+ * pattern used to COUNT consecutive checkpoints on the branch (spec
81
+ * `graceful-pre-timeout-wip-checkpoint` — the anti-loop ceiling). Living
82
+ * on-branch means the counter naturally RESETS when the item completes (the
83
+ * branch is discarded on integration) and when a `--reset` requeue discards
84
+ * the branch: a genuinely-progressing task cannot silently accumulate a
85
+ * ceiling breach across generations.
86
+ */
87
+ const DEADLINE_CHECKPOINT_COMMIT_SUBJECT_PREFIX = 'chore(deadline-checkpoint)';
88
+ /**
89
+ * Distinct reason strings for the two deadline-checkpoint branches (spec
90
+ * `graceful-pre-timeout-wip-checkpoint` — the CI/human report must NEVER
91
+ * collapse to a generic "agent-failed"). Auto-continue and surface carry
92
+ * different phrasing so the counter + ceiling are legible.
93
+ */
94
+ function deadlineAutoContinueReason(params) {
95
+ return (`deadline checkpoint (auto-continued ${params.count}/${params.max}): ` +
96
+ `'${params.slug}' hit the dorfl-internal deadline with new work-branch ` +
97
+ `progress this session; saved the WIP and released the lock so the next ` +
98
+ `tick continues from the branch tip.`);
99
+ }
100
+ function deadlineSurfaceReason(params) {
101
+ if (params.kind === 'no-progress') {
102
+ return (`deadline checkpoint (no progress / ceiling): '${params.slug}' hit ` +
103
+ `the dorfl-internal deadline WITHOUT any work-branch progress this ` +
104
+ `session — indistinguishable from a wedge; surfaced for a human to ` +
105
+ `decide (continue / split / cancel).`);
106
+ }
107
+ return (`deadline checkpoint (no progress / ceiling): '${params.slug}' has hit ` +
108
+ `the dorfl-internal deadline ${params.count}/${params.max} times ` +
109
+ `consecutively — it may be too big for one CI leg. Split it or run ` +
110
+ `it locally; surfaced for a human to decide.`);
111
+ }
112
+ /**
113
+ * Count how many DEADLINE-CHECKPOINT commits (subject prefix
114
+ * `chore(deadline-checkpoint)`) currently sit on the work branch ahead of
115
+ * `<arbiter>/main` — the branch-based anti-loop counter (spec
116
+ * `graceful-pre-timeout-wip-checkpoint`). A best-effort count: an unreachable
117
+ * arbiter / a bare mirror reads as 0 (the SAFE direction — never falsely block
118
+ * an auto-continue) so a genuine plumbing fault degrades to "under the ceiling"
119
+ * rather than surfacing a spurious ceiling breach. Resets naturally when the
120
+ * item completes (the branch is discarded on integration).
121
+ */
122
+ async function countDeadlineCheckpointsOnBranch(params) {
123
+ const { cwd, arbiter, branch, env } = params;
124
+ const range = `${arbiter}/main..HEAD`;
125
+ void branch;
126
+ const r = await runAsync('git', ['log', '--format=%s', range], cwd, { env });
127
+ if (r.status !== 0) {
128
+ return 0;
129
+ }
130
+ const lines = r.stdout.split('\n').filter((s) => s.length > 0);
131
+ return lines.filter((s) => s.startsWith(DEADLINE_CHECKPOINT_COMMIT_SUBJECT_PREFIX)).length;
132
+ }
133
+ /**
134
+ * SAVE the WIP on a deadline stop (spec `graceful-pre-timeout-wip-checkpoint`,
135
+ * build step 3): commit the tree as-is + push `work/<slug>`. Reuses the SAVE
136
+ * HALF of the needs-attention mechanism ({@link routeToNeedsAttention}) but
137
+ * ADDS a distinguishing checkpoint-marker commit on top so
138
+ * {@link countDeadlineCheckpointsOnBranch} can count auto-continues. Distinct
139
+ * from `applyNeedsAttentionTransition` (the whole thing) which ALSO marks the
140
+ * lock stuck — auto-continue must NOT mark stuck; only the surface branch does.
141
+ */
142
+ async function saveDeadlineCheckpoint(params) {
143
+ const { slug, branch, cwd, arbiter, reason, env, note } = params;
144
+ void reason;
145
+ // Save any uncommitted work first (the routeToNeedsAttention save half also
146
+ // commits + pushes; but we ALSO want a distinct checkpoint-marker commit so
147
+ // countDeadlineCheckpointsOnBranch can enumerate them). Stage everything and
148
+ // commit a MARKER commit if there's anything to record OR if there is not
149
+ // already a marker on the tip — the marker's job is to make the checkpoint
150
+ // COUNTABLE, not to represent new work.
151
+ const addResult = await runAsync('git', ['add', '-A'], cwd, { env });
152
+ void addResult;
153
+ const diffCached = await runAsync('git', ['diff', '--cached', '--quiet'], cwd, { env });
154
+ const hasStaged = diffCached.status !== 0;
155
+ if (hasStaged) {
156
+ await runAsync('git', [
157
+ 'commit',
158
+ '-q',
159
+ '-m',
160
+ `${DEADLINE_CHECKPOINT_COMMIT_SUBJECT_PREFIX}: save wip for '${slug}'`,
161
+ ], cwd, { env });
162
+ }
163
+ // Push the branch to the arbiter (best-effort). Reuse routeToNeedsAttention's
164
+ // save-half exact contract: it commits any residue + pushes the branch with
165
+ // bounded backoff. We already committed above; the wip commit inside
166
+ // routeToNeedsAttention will be a no-op (clean tree) and the push runs.
167
+ return routeToNeedsAttention({
168
+ cwd,
169
+ slug,
170
+ reason: `deadline-checkpoint save for '${slug}' (see branch)`,
171
+ arbiter,
172
+ branch,
173
+ note,
174
+ env,
175
+ });
176
+ }
26
177
  const DEFAULT_ARBITER = 'origin';
27
178
  /**
28
- * Map a `do prd:<slug>` {@link TaskResult} onto the `do` {@link DoResult}
179
+ * Map a `do spec:<slug>` {@link TaskResult} onto the `do` {@link DoResult}
29
180
  * contract: outcomes pass through (tasked / gate-refused / stale / agent-failed /
30
181
  * usage-error), the lock-lost outcome splits into `lost` (exit 2) vs `contended`
31
182
  * (exit 3) by its exit code, and the tasking-only exit 4 (stale) is reported on
@@ -60,7 +211,7 @@ function taskResultToDoResult(tasked) {
60
211
  break;
61
212
  case 'needs-attention':
62
213
  // The tasker review→edit loop found the decomposition unclear and routed the
63
- // prd to needs-attention (no guessed tasks). Same exit class as a stuck
214
+ // spec to needs-attention (no guessed tasks). Same exit class as a stuck
64
215
  // build (1).
65
216
  outcome = 'needs-attention';
66
217
  exitCode = 1;
@@ -119,8 +270,8 @@ export async function performDo(options) {
119
270
  };
120
271
  }
121
272
  // 1. Resolve the slug across BOTH namespaces — `do` is the ONE command that
122
- // spans them (ADR §3a): bare → task (after a no-prd-collision check;
123
- // ERROR on collision), `task:`/`prd:` explicit. A collision / resolution
273
+ // spans them (ADR §3a): bare → task (after a no-spec-collision check;
274
+ // ERROR on collision), `task:`/`spec:` explicit. A collision / resolution
124
275
  // failure is a loud usage error (exit 1).
125
276
  let resolved;
126
277
  try {
@@ -152,10 +303,10 @@ export async function performDo(options) {
152
303
  arbiter,
153
304
  doer: 'agent',
154
305
  autoTask: options.autoTask,
155
- // EXPLICIT dispatch: a `do prd:<slug>` target was NAMED (the operator typed
306
+ // EXPLICIT dispatch: a `do spec:<slug>` target was NAMED (the operator typed
156
307
  // it, or the auto-pick POOL already filtered it on `autoTask` before
157
308
  // dispatching here — the single policy-enforcement point). So the tasking gate
158
- // drops the `autoTask` policy term and binds only the prd's own readiness
309
+ // drops the `autoTask` policy term and binds only the spec's own readiness
159
310
  // (`humanOnly`/`needsAnswers`) + `taskedAfter`, EXACTLY as `do <task>` builds a
160
311
  // named task regardless of `autoBuild` (the pool gates the policy, not the
161
312
  // explicit claim).
@@ -176,19 +327,24 @@ export async function performDo(options) {
176
327
  // `integration:'propose'` + `taskingIntegration:'merge'` lands the task FILES
177
328
  // on main here while the BUILD path below still threads plain `integration`.
178
329
  integration: options.taskingIntegration ?? options.integration,
330
+ // The cross-job merge-serialiser CAS-retry cap (config `mergeRetries`) —
331
+ // threaded so the `do spec:` tasking-transition's land tail respects the
332
+ // same per-repo cap the build path uses (task
333
+ // `thread-merge-retries-cross-task-and-ratify-default`).
334
+ mergeRetries: options.mergeRetries,
179
335
  // The per-repo TASK-PLACEMENT default + the operator's explicit
180
336
  // override (task `runner-deterministic-slice-placement-policy-and-
181
337
  // precedence`). The tasker reads them as the configured-default + the
182
338
  // top rung of the runner-deterministic placement resolver; the
183
339
  // `originTrust: untrusted` force is read inside the tasker from the
184
- // prd's stamped frontmatter.
340
+ // spec's stamped frontmatter.
185
341
  tasksLandIn: options.tasksLandIn,
186
342
  explicitTasksLandIn: options.explicitTasksLandIn,
187
343
  noPR: options.noPR,
188
344
  providerInstance: options.providerInstance,
189
345
  // The tasker review→edit→converge loop (slicer-review-edit-loop): improves the
190
346
  // candidate tasks in place + routes the verdict through the needsAnswers /
191
- // needs-attention sink. Threaded only on the `do prd:` path; omitted ⇒ no loop.
347
+ // needs-attention sink. Threaded only on the `do spec:` path; omitted ⇒ no loop.
192
348
  reviewLoop: options.reviewLoop,
193
349
  taskerLoopMax: options.taskerLoopMax,
194
350
  reviewExecutions: options.reviewExecutions,
@@ -362,14 +518,17 @@ export async function performDo(options) {
362
518
  // auto-resolved). Surface to needs-attention TREE-LESSLY via the SAME `#89`
363
519
  // mechanism `requeue` uses for the reverse direction — the rebase was
364
520
  // ABORTED, so the kept `work/<slug>` tip == the arbiter tip (already on the
365
- // arbiter, after-commit, recoverable). The surface is purely the one-file
366
- // `in-progress/ needs-attention/` ledger move + reason (no branch push, no
367
- // worktree mutation) instead of running the agent — the §10 path. The work
521
+ // arbiter, after-commit, recoverable). The surface is purely the lock amend
522
+ // to `state: stuck` with the reason (post lock-cutover no folder move, no
523
+ // branch push, no worktree mutation) instead of running the agent — the §10
524
+ // path. The work
368
525
  // did NOT onboard; the runner owns the bounce.
369
526
  if (tree.continueRebaseConflict) {
370
527
  const reason = `continuing the kept ${tree.branch}: rebase onto the latest main ` +
371
- 'conflicted (aborted, never auto-resolved) — resolve against the latest ' +
372
- 'main, or `requeue --reset` to discard and start fresh';
528
+ 'conflicted (aborted, never auto-resolved) — run `requeue --reconcile` ' +
529
+ 'to non-destructively re-sync the mirror and retry the rebase (keeps ' +
530
+ 'the work). Last resort: `requeue --reset` DESTRUCTIVELY discards the ' +
531
+ 'branch and starts fresh.';
373
532
  const surfaced = await ledgerWrite.applyTreelessNeedsAttentionTransition({
374
533
  cwd: tree.dir,
375
534
  slug,
@@ -401,8 +560,10 @@ export async function performDo(options) {
401
560
  if (tree.continuePushFailure !== undefined) {
402
561
  const reason = `continuing the kept ${tree.branch}: publishing the rebased work branch ` +
403
562
  `to the arbiter failed terminally (${tree.continuePushFailure}) — the kept ` +
404
- 'branch is left intact on the arbiter (recoverable); `requeue` to retry ' +
405
- 'once the churn settles, or `requeue --reset` to discard and start fresh';
563
+ 'branch is left intact on the arbiter (recoverable); `requeue --reconcile` ' +
564
+ 'to non-destructively re-sync the mirror and retry once the churn ' +
565
+ 'settles (keeps the work). Last resort: `requeue --reset` DESTRUCTIVELY ' +
566
+ 'discards the branch and starts fresh.';
406
567
  const surfaced = await ledgerWrite.applyTreelessNeedsAttentionTransition({
407
568
  cwd: tree.dir,
408
569
  slug,
@@ -424,7 +585,7 @@ export async function performDo(options) {
424
585
  }
425
586
  // 5. Run the agent autonomously in the checkout, ON the work branch — the
426
587
  // SAME prompt assembly `dorfl prompt` emits (canonical wrapper +
427
- // source prd + the task's ## Prompt). The agent only edits code (it does
588
+ // source spec + the task's ## Prompt). The agent only edits code (it does
428
589
  // no git). This is the one NEW middle step `ar-run.sh` shelled out for
429
590
  // (`prompt | pi`).
430
591
  // The post-claim pipeline reads the uniform `IsolatedTree` handle (`tree.dir`)
@@ -459,7 +620,7 @@ export async function performDo(options) {
459
620
  content: readFileSync(task.path, 'utf8'),
460
621
  env,
461
622
  });
462
- // Per-item override layer: a task or prd may pin `promptGuidance.testFirst`
623
+ // Per-item override layer: a task or spec may pin `promptGuidance.testFirst`
463
624
  // in its frontmatter, superseding the resolved repo policy for THIS item.
464
625
  const itemGuidance = resolvePromptGuidanceForItem({
465
626
  cwd: tree.dir,
@@ -502,6 +663,23 @@ export async function performDo(options) {
502
663
  note,
503
664
  });
504
665
  }
666
+ // DEADLINE CHECKPOINT (spec `graceful-pre-timeout-wip-checkpoint`): the
667
+ // dorfl-internal deadline fired — stop is graceful, NOT a failure. Route
668
+ // through the shared checkpoint path (save WIP + auto-continue on progress
669
+ // under the ceiling, else surface). Distinct from `saveAgentFailure` on
670
+ // purpose — the deadline path must NOT mark the item stuck when it
671
+ // auto-continues.
672
+ if (agent.timedOut) {
673
+ return await routeDeadlineCheckpoint({
674
+ slug,
675
+ branch,
676
+ cwd: tree.dir,
677
+ arbiter: tree.arbiterRemote,
678
+ maxAutoCheckpoints: options.maxAutoCheckpoints ?? 5,
679
+ env,
680
+ note,
681
+ });
682
+ }
505
683
  if (!agent.ok) {
506
684
  const detail = agent.detail ?? `the agent failed to build '${slug}'.`;
507
685
  return await saveAgentFailure({
@@ -535,7 +713,8 @@ export async function performDo(options) {
535
713
  branch,
536
714
  cwd: tree.dir,
537
715
  arbiter: tree.arbiterRemote,
538
- reason: stopReason,
716
+ reason: stopReason.reason,
717
+ kind: stopReason.kind,
539
718
  env,
540
719
  note,
541
720
  });
@@ -587,7 +766,7 @@ export async function performDo(options) {
587
766
  verify: options.verify,
588
767
  freshWorktreeGate: options.freshWorktreeGate,
589
768
  // The cross-job merge-serialiser CAS-retry cap (config `mergeRetries`) — the
590
- // git-alone FLOOR of the cross-job land queue (prd `land-time-reverify-and-
769
+ // git-alone FLOOR of the cross-job land queue (spec `land-time-reverify-and-
591
770
  // parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)). Threaded so a
592
771
  // wide-matrix CI's raised cap actually reaches the merge loop.
593
772
  mergeRetries: options.mergeRetries,
@@ -682,8 +861,10 @@ export async function performDo(options) {
682
861
  // (`runRemotePipeline`) uses, so `advance task:<slug>` (via the default
683
862
  // `doDriver = performDo`) agrees with the remote path on the caller-visible
684
863
  // label.
864
+ //
865
+ // PR-2b D3: a clean surface (routedToNeedsAttention:true) is GREEN.
685
866
  return {
686
- exitCode: 1,
867
+ exitCode: completed.routedToNeedsAttention ? 0 : 1,
687
868
  outcome: 'needs-attention',
688
869
  slug,
689
870
  branch,
@@ -770,7 +951,9 @@ function routeReport(routed, branch) {
770
951
  // so loudly, the work is saved LOCALLY only, and how to recover.
771
952
  return {
772
953
  fragment: `push of ${branch} FAILED — the work is saved LOCALLY only; push it ` +
773
- 'when online, then `requeue` (continue), or `requeue --reset` to discard',
954
+ 'when online, then `requeue` (continue) or `requeue --reconcile` ' +
955
+ '(non-destructive retry). Last resort: `requeue --reset` ' +
956
+ 'DESTRUCTIVELY discards.',
774
957
  pushFailed: true,
775
958
  };
776
959
  }
@@ -787,7 +970,9 @@ function routeReport(routed, branch) {
787
970
  landed = 'saved locally';
788
971
  }
789
972
  return {
790
- fragment: `${landed}. Recover via \`requeue\` (continue) or \`requeue --reset\` to discard`,
973
+ fragment: `${landed}. Recover via \`requeue\` (continue) or \`requeue --reconcile\` ` +
974
+ '(non-destructive retry). Last resort: `requeue --reset` ' +
975
+ 'DESTRUCTIVELY discards.',
791
976
  pushFailed: false,
792
977
  };
793
978
  }
@@ -800,10 +985,12 @@ function routeReport(routed, branch) {
800
985
  *
801
986
  * This routes it through the SAME work-preserving machinery a RED GATE uses: the
802
987
  * ledger write seam's needs-attention transition (`git add -A` + a wip commit
803
- * capturing the agent's work + the `git mv needs-attention/` move-only commit
804
- * with the failure detail recorded as the reason in the body), surfaced on the
805
- * arbiter's `main` (the autonomous, cross-machine-visible mode-M surfacing `do`
806
- * already uses for the gate-fail path) so `scan`/`status`/another machine see it.
988
+ * capturing the agent's work, then post lock-cutover a LOCK AMEND to
989
+ * `state: stuck` with the failure detail as the reason on the lock entry, in
990
+ * place of the retired `git mv → needs-attention/` move-only commit), surfaced on
991
+ * the arbiter's `main` (the autonomous, cross-machine-visible mode-M surfacing
992
+ * `do` already uses for the gate-fail path) so `scan`/`status`/another machine
993
+ * see it.
807
994
  *
808
995
  * It ALSO pushes the `work/<slug>` branch to the arbiter so the saved partial
809
996
  * commits travel cross-machine and the item is RECOVERABLE via `requeue`
@@ -826,7 +1013,8 @@ function routeReport(routed, branch) {
826
1013
  * contract stays coherent). Only the WORK-PRESERVING side-effect (unchanged here)
827
1014
  * matches the gate-failure path. We do NOT validate or "fix" the partial work — a broken
828
1015
  * tree committed + surfaced (with the reason) is recoverable; the human chooses
829
- * `requeue` (continue) vs `requeue --reset` (discard).
1016
+ * `requeue` (continue) / `requeue --reconcile` (non-destructive retry) vs
1017
+ * `requeue --reset` (destructive last resort).
830
1018
  */
831
1019
  async function saveAgentFailure(params) {
832
1020
  const { slug, cwd, arbiter, detail, env, note } = params;
@@ -864,8 +1052,10 @@ async function saveAgentFailure(params) {
864
1052
  : `Agent run failed building '${slug}' [${cause}] (${detail}); could not ` +
865
1053
  `mark '${slug}' stuck (${routed.reasonNotMoved ?? 'unknown'}).`;
866
1054
  note(message);
1055
+ // PR-2b D3: a cleanly-surfaced bounce is GREEN (exitCode 0); a FAILED surface
1056
+ // stays non-zero.
867
1057
  return {
868
- exitCode: 1,
1058
+ exitCode: routed.moved ? 0 : 1,
869
1059
  outcome: failureCauseToDoOutcome(cause),
870
1060
  slug,
871
1061
  branch,
@@ -884,7 +1074,9 @@ function failureCauseToDoOutcome(cause) {
884
1074
  }
885
1075
  /**
886
1076
  * Build the HONEST result for a CONTINUE-site surface that did NOT land on the
887
- * arbiter (`{moved: false}`). The tree-less `in-progress/ needs-attention/` move
1077
+ * arbiter (`{moved: false}`). The tree-less stuck-lock amend (post lock-cutover
1078
+ * `state: stuck` with the reason, in place of the retired `in-progress/ →
1079
+ * needs-attention/` move)
888
1080
  * lost the CAS race against a busy arbiter (its contention-retry cap exhausted) or
889
1081
  * had no arbiter to publish to, so the item is STILL in-progress on the arbiter —
890
1082
  * a clean `needs-attention` would mislead (it claims the surface landed). Distinct
@@ -920,10 +1112,10 @@ async function resolveStopReason(params) {
920
1112
  const { output, slug, cwd, arbiter, env } = params;
921
1113
  const sentinel = parseStopSentinel(output);
922
1114
  if (sentinel !== undefined) {
923
- return sentinel.reason;
1115
+ return { kind: 'sentinel', reason: sentinel.reason };
924
1116
  }
925
1117
  if (await isWorkBranchDiffEmpty({ cwd, arbiter, env })) {
926
- return emptyDiffStopReason(slug);
1118
+ return { kind: 'empty-diff', reason: emptyDiffStopReason(slug) };
927
1119
  }
928
1120
  return undefined;
929
1121
  }
@@ -936,8 +1128,59 @@ async function resolveStopReason(params) {
936
1128
  * needs-attention reason. The acceptance gate AND Gate-2 are NEVER reached.
937
1129
  */
938
1130
  async function saveAgentStop(params) {
939
- const { slug, cwd, arbiter, reason, env, note } = params;
1131
+ const { slug, cwd, arbiter, reason, kind, env, note } = params;
940
1132
  const branch = params.branch ?? workBranchRef('task', slug);
1133
+ // EMPTY-DIFF branch (spec resolved decision #2, task
1134
+ // `empty-diff-bounce-surfaces-dispose-defaulted-question`): surface a sidecar
1135
+ // on `<arbiter>/main` carrying an engine-authored DISPOSE-DEFAULTED envelope
1136
+ // question, THEN release the lock. "Nothing to do" is a non-deterministic LLM
1137
+ // judgement, so this seam MUST NOT blindly requeue (that would infinite-loop);
1138
+ // the surfaced sidecar + `needsAnswers:true` on `main` parks the item as a
1139
+ // human-visible question a `dispose` answer settles to `tasks/cancelled/`.
1140
+ if (kind === 'empty-diff') {
1141
+ const item = `task:${slug}`;
1142
+ const itemPath = resolveItemPathByIdentity(cwd, item);
1143
+ if (itemPath === undefined) {
1144
+ const message = `The agent STOPPED building '${slug}' (empty diff) but its body could ` +
1145
+ `not be located on the arbiter to surface a sidecar. Reason: ${reason}`;
1146
+ note(message);
1147
+ return {
1148
+ exitCode: 1,
1149
+ outcome: 'agent-stopped',
1150
+ slug,
1151
+ branch,
1152
+ routedToNeedsAttention: false,
1153
+ message,
1154
+ };
1155
+ }
1156
+ const surfaced = await surfaceStuckToNeedsAttention({
1157
+ cwd,
1158
+ slug,
1159
+ item,
1160
+ itemPath,
1161
+ reason,
1162
+ envelope: emptyDiffDisposeEnvelope({ item, reason }),
1163
+ arbiter,
1164
+ env,
1165
+ note,
1166
+ });
1167
+ const message = surfaced.surfaced
1168
+ ? `The agent STOPPED building '${slug}' (empty diff); surfaced a ` +
1169
+ `dispose-defaulted question on ${arbiter}/main and released the lock. ` +
1170
+ `Reason: ${reason}`
1171
+ : `The agent STOPPED building '${slug}' (empty diff) but the surface ` +
1172
+ `did not land (${surfaced.reasonNotSurfaced ?? 'unknown'}). ` +
1173
+ `Reason: ${reason}`;
1174
+ note(message);
1175
+ return {
1176
+ exitCode: 1,
1177
+ outcome: 'agent-stopped',
1178
+ slug,
1179
+ branch,
1180
+ routedToNeedsAttention: surfaced.surfaced,
1181
+ message,
1182
+ };
1183
+ }
941
1184
  const routed = await ledgerWrite.applyNeedsAttentionTransition({
942
1185
  cwd,
943
1186
  slug,
@@ -954,8 +1197,11 @@ async function saveAgentStop(params) {
954
1197
  : `The agent STOPPED building '${slug}' but it could not be marked stuck ` +
955
1198
  `(${routed.reasonNotMoved ?? 'unknown'}). Reason: ${reason}`;
956
1199
  note(message);
1200
+ // PR-2b D3: agent-stopped (sentinel) on a clean surface is GREEN (exitCode 0);
1201
+ // a FAILED surface stays non-zero. The empty-diff branch above is UNCHANGED
1202
+ // (owned by `empty-diff-bounce-surfaces-dispose-defaulted-question`).
957
1203
  return {
958
- exitCode: 1,
1204
+ exitCode: routed.moved ? 0 : 1,
959
1205
  outcome: 'agent-stopped',
960
1206
  slug,
961
1207
  branch,
@@ -986,6 +1232,15 @@ async function runDoAgent(options, cwd, prompt, slug) {
986
1232
  return options.dorfl({ cwd, prompt, slug, env: options.env });
987
1233
  }
988
1234
  const harness = options.harness ?? new NullHarness();
1235
+ // Convert the dorfl-internal deadline (minutes) into a wall-clock epoch-ms so
1236
+ // the harness (`launchAsync`) can race the child against it (spec
1237
+ // `graceful-pre-timeout-wip-checkpoint`). Absent ⇒ no deadline; a run that
1238
+ // finishes before it is byte-for-byte unchanged (the harness clears the
1239
+ // timer on normal exit). Forcing the async path when a deadline is set is
1240
+ // {@link launchWithOptionalWatch}'s job.
1241
+ const deadlineMs = options.agentDeadlineMinutes !== undefined
1242
+ ? Date.now() + options.agentDeadlineMinutes * 60_000
1243
+ : undefined;
989
1244
  const launched = await launchWithOptionalWatch({
990
1245
  harness,
991
1246
  dir: cwd,
@@ -997,6 +1252,7 @@ async function runDoAgent(options, cwd, prompt, slug) {
997
1252
  sessionId: slug,
998
1253
  sessionsDir: options.sessionsDir,
999
1254
  watch: options.watch,
1255
+ deadlineMs,
1000
1256
  watchSink: options.watchSink,
1001
1257
  color: options.color,
1002
1258
  env: options.env,
@@ -1004,7 +1260,115 @@ async function runDoAgent(options, cwd, prompt, slug) {
1004
1260
  // Surface the agent's FINAL SUMMARY (`LaunchResult.output`) — the source channel
1005
1261
  // for the propose-mode PR body — instead of dropping it. Absent (no parseable
1006
1262
  // assistant text) ⇒ undefined ⇒ the body degrades to `--fill` (no regression).
1007
- return { ok: launched.ok, detail: launched.detail, output: launched.output };
1263
+ return {
1264
+ ok: launched.ok,
1265
+ detail: launched.detail,
1266
+ output: launched.output,
1267
+ timedOut: launched.timedOut,
1268
+ };
1269
+ }
1270
+ /**
1271
+ * Route a DEADLINE STOP (spec `graceful-pre-timeout-wip-checkpoint`) through
1272
+ * the checkpoint machinery: ALWAYS save the WIP (commit + push), then
1273
+ * decide — progress AND under ceiling ⇒ AUTO-CONTINUE (release lock, keep
1274
+ * branch, NO sidecar, exit 0); else ⇒ SURFACE a `needsAnswers:true` question.
1275
+ * Shared by {@link performDo} and {@link runRemotePipeline} so the in-place
1276
+ * and remote forms route a deadline stop identically.
1277
+ */
1278
+ async function routeDeadlineCheckpoint(params) {
1279
+ const { slug, branch, cwd, arbiter, maxAutoCheckpoints, env, note } = params;
1280
+ // 1. ALWAYS save the WIP first: commit any residue + push the work branch.
1281
+ const savedReason = `deadline checkpoint save for '${slug}'`;
1282
+ const saved = await saveDeadlineCheckpoint({
1283
+ slug,
1284
+ branch,
1285
+ cwd,
1286
+ arbiter,
1287
+ reason: savedReason,
1288
+ env,
1289
+ note,
1290
+ });
1291
+ void saved;
1292
+ // 2. Progress this session? Reuse the SAME primitive the STOP backstop uses.
1293
+ const emptyDiff = await isWorkBranchDiffEmpty({ cwd, arbiter, env });
1294
+ const madeProgressThisSession = !emptyDiff;
1295
+ // 3. Count consecutive deadline checkpoints on the branch (ceiling gate). The
1296
+ // marker commit we just saved is included — so the count is the number
1297
+ // of checkpoints INCLUDING this one.
1298
+ const checkpointCount = await countDeadlineCheckpointsOnBranch({
1299
+ cwd,
1300
+ arbiter,
1301
+ branch,
1302
+ env,
1303
+ });
1304
+ if (madeProgressThisSession && checkpointCount <= maxAutoCheckpoints) {
1305
+ // AUTO-CONTINUE: release the lock via the SAME default keep+continue path
1306
+ // `requeue` uses (no --reset, no --reconcile, no sidecar). The branch is
1307
+ // KEPT on the arbiter so the next claim continues from its tip.
1308
+ const reason = deadlineAutoContinueReason({
1309
+ slug,
1310
+ count: checkpointCount,
1311
+ max: maxAutoCheckpoints,
1312
+ });
1313
+ const returned = await ledgerWrite.applyReturnToBacklogTransition({
1314
+ cwd,
1315
+ slug,
1316
+ arbiter,
1317
+ env,
1318
+ note,
1319
+ });
1320
+ if (returned.moved) {
1321
+ const message = `Auto-continued '${slug}' at the dorfl-internal deadline (checkpoint ` +
1322
+ `${checkpointCount}/${maxAutoCheckpoints}): WIP saved + branch pushed, ` +
1323
+ `lock released so the next tick continues from ${branch}. ${reason}`;
1324
+ note(message);
1325
+ return {
1326
+ exitCode: 0,
1327
+ outcome: 'deadline-auto-continued',
1328
+ slug,
1329
+ branch,
1330
+ message,
1331
+ };
1332
+ }
1333
+ // The auto-continue lock release did not land — fall through to SURFACE.
1334
+ note(`Auto-continue lock release for '${slug}' did not land ` +
1335
+ `(${returned.reasonNotMoved ?? 'unknown'}); surfacing instead.`);
1336
+ }
1337
+ // SURFACE: mark the lock stuck via the whole applyNeedsAttentionTransition
1338
+ // (save + push + stuck). The WIP was already saved above; a second save is
1339
+ // idempotent (empty commit is skipped inside routeToNeedsAttention).
1340
+ const surfaceReason = madeProgressThisSession
1341
+ ? deadlineSurfaceReason({
1342
+ slug,
1343
+ kind: 'ceiling',
1344
+ count: checkpointCount,
1345
+ max: maxAutoCheckpoints,
1346
+ })
1347
+ : deadlineSurfaceReason({ slug, kind: 'no-progress' });
1348
+ const routed = await ledgerWrite.applyNeedsAttentionTransition({
1349
+ cwd,
1350
+ slug,
1351
+ reason: surfaceReason,
1352
+ arbiter,
1353
+ env,
1354
+ note,
1355
+ });
1356
+ const report = routed.moved ? routeReport(routed, branch) : undefined;
1357
+ const message = routed.moved
1358
+ ? `Surfaced '${slug}' at the deadline checkpoint (${madeProgressThisSession
1359
+ ? `ceiling ${checkpointCount}/${maxAutoCheckpoints}`
1360
+ : 'no progress this session'}); ${report.fragment}. ${surfaceReason}`
1361
+ : `Could not surface '${slug}' at the deadline checkpoint ` +
1362
+ `(${routed.reasonNotMoved ?? 'unknown'}). ${surfaceReason}`;
1363
+ note(message);
1364
+ return {
1365
+ exitCode: 1,
1366
+ outcome: 'deadline-surfaced',
1367
+ slug,
1368
+ branch,
1369
+ routedToNeedsAttention: routed.moved,
1370
+ message,
1371
+ };
1008
1372
  }
1009
1373
  /**
1010
1374
  * True when the working tree has uncommitted (unstaged OR staged) changes — the
@@ -1200,7 +1564,7 @@ export async function performDoRemote(options) {
1200
1564
  try {
1201
1565
  // 2a. Resolve the slug across BOTH namespaces against the claim clone (it
1202
1566
  // carries `work/` from the mirror's main). A collision / resolution
1203
- // failure is a loud usage error; a `prd:` arg reaches the not-yet-wired
1567
+ // failure is a loud usage error; a `spec:` arg reaches the not-yet-wired
1204
1568
  // stub — identical behaviour to in-place `do`.
1205
1569
  let resolved;
1206
1570
  try {
@@ -1230,9 +1594,9 @@ export async function performDoRemote(options) {
1230
1594
  arbiter: 'origin',
1231
1595
  doer: 'agent',
1232
1596
  autoTask: options.autoTask,
1233
- // EXPLICIT dispatch (same as the in-place path above): the `prd:<slug>` was
1597
+ // EXPLICIT dispatch (same as the in-place path above): the `spec:<slug>` was
1234
1598
  // NAMED (typed, or pool-filtered on `autoTask` before reaching here), so the
1235
- // tasking gate drops the policy term — only the prd's own readiness +
1599
+ // tasking gate drops the policy term — only the spec's own readiness +
1236
1600
  // `taskedAfter` bind, mirroring the build path vs `autoBuild`.
1237
1601
  explicit: true,
1238
1602
  dorfl: options.dorfl,
@@ -1244,22 +1608,26 @@ export async function performDoRemote(options) {
1244
1608
  // `provider` is the SAME the task-build path threads (arg parity), but the
1245
1609
  // MODE is the per-TRANSITION TASKING resolution
1246
1610
  // (`per-transition-integration-mode-slicing-vs-build`):
1247
- // `taskingIntegration ?? integration`, so the `--remote prd:` output ALSO
1611
+ // `taskingIntegration ?? integration`, so the `--remote spec:` output ALSO
1248
1612
  // routes through the shared core with the tasking-resolved mode.
1249
1613
  integration: options.taskingIntegration ?? options.integration,
1614
+ // The cross-job merge-serialiser CAS-retry cap (config `mergeRetries`) —
1615
+ // threaded on the no-checkout `do --remote spec:` tasking path too,
1616
+ // mirroring the in-place site above.
1617
+ mergeRetries: options.mergeRetries,
1250
1618
  // The per-repo TASK-PLACEMENT default + the operator's explicit
1251
1619
  // override (task `runner-deterministic-slice-placement-policy-and-
1252
- // precedence`). Same threading as the in-place `do prd:` path.
1620
+ // precedence`). Same threading as the in-place `do spec:` path.
1253
1621
  tasksLandIn: options.tasksLandIn,
1254
1622
  explicitTasksLandIn: options.explicitTasksLandIn,
1255
1623
  noPR: options.noPR,
1256
1624
  providerInstance: options.providerInstance,
1257
- // The tasker review→edit→converge loop on the `do --remote prd:` path too.
1625
+ // The tasker review→edit→converge loop on the `do --remote spec:` path too.
1258
1626
  reviewLoop: options.reviewLoop,
1259
1627
  taskerLoopMax: options.taskerLoopMax,
1260
1628
  reviewExecutions: options.reviewExecutions,
1261
1629
  taskerLoopModel: options.taskerLoopModel,
1262
- // The task-SET ACCEPTANCE GATE on the `do --remote prd:` path too.
1630
+ // The task-SET ACCEPTANCE GATE on the `do --remote spec:` path too.
1263
1631
  review: options.review,
1264
1632
  reviewGate: options.taskReviewGate,
1265
1633
  acceptanceReviewModel: options.reviewModel,
@@ -1402,8 +1770,10 @@ async function runRemotePipeline(options, tree, slug, note, env) {
1402
1770
  // agent — the §10 path `run` uses.
1403
1771
  if (tree.continueRebaseConflict) {
1404
1772
  const reason = `continuing the kept ${tree.branch}: rebase onto the latest main ` +
1405
- 'conflicted (aborted, never auto-resolved) — resolve against the latest ' +
1406
- 'main, or `requeue --reset` to discard and start fresh';
1773
+ 'conflicted (aborted, never auto-resolved) — run `requeue --reconcile` ' +
1774
+ 'to non-destructively re-sync the mirror and retry the rebase (keeps ' +
1775
+ 'the work). Last resort: `requeue --reset` DESTRUCTIVELY discards the ' +
1776
+ 'branch and starts fresh.';
1407
1777
  await ledgerWrite.applyNeedsAttentionTransition({
1408
1778
  cwd,
1409
1779
  slug,
@@ -1433,8 +1803,10 @@ async function runRemotePipeline(options, tree, slug, note, env) {
1433
1803
  if (tree.continuePushFailure !== undefined) {
1434
1804
  const reason = `continuing the kept ${tree.branch}: publishing the rebased work branch ` +
1435
1805
  `to the arbiter failed terminally (${tree.continuePushFailure}) — the kept ` +
1436
- 'branch is left intact on the arbiter (recoverable); `requeue` to retry ' +
1437
- 'once the churn settles, or `requeue --reset` to discard and start fresh';
1806
+ 'branch is left intact on the arbiter (recoverable); `requeue --reconcile` ' +
1807
+ 'to non-destructively re-sync the mirror and retry once the churn ' +
1808
+ 'settles (keeps the work). Last resort: `requeue --reset` DESTRUCTIVELY ' +
1809
+ 'discards the branch and starts fresh.';
1438
1810
  await ledgerWrite.applyNeedsAttentionTransition({
1439
1811
  cwd,
1440
1812
  slug,
@@ -1531,7 +1903,7 @@ async function runRemotePipeline(options, tree, slug, note, env) {
1531
1903
  content: readFileSync(task.path, 'utf8'),
1532
1904
  env,
1533
1905
  });
1534
- // Per-item override layer (mirrors in-place `do`): the task/prd frontmatter
1906
+ // Per-item override layer (mirrors in-place `do`): the task/spec frontmatter
1535
1907
  // may override the resolved repo `promptGuidance.testFirst` for THIS item.
1536
1908
  const itemGuidance = resolvePromptGuidanceForItem({
1537
1909
  cwd,
@@ -1574,6 +1946,19 @@ async function runRemotePipeline(options, tree, slug, note, env) {
1574
1946
  note,
1575
1947
  });
1576
1948
  }
1949
+ // Deadline checkpoint on the no-checkout `do --remote` path — same routing
1950
+ // as the in-place path (see performDo).
1951
+ if (agent.timedOut) {
1952
+ return await routeDeadlineCheckpoint({
1953
+ slug,
1954
+ branch: branch ?? workBranchRef('task', slug),
1955
+ cwd,
1956
+ arbiter: arbiterRemote,
1957
+ maxAutoCheckpoints: options.maxAutoCheckpoints ?? 5,
1958
+ env,
1959
+ note,
1960
+ });
1961
+ }
1577
1962
  if (!agent.ok) {
1578
1963
  const detail = agent.detail ?? `the agent failed to build '${slug}'.`;
1579
1964
  return await saveRemoteAgentFailure({
@@ -1604,7 +1989,8 @@ async function runRemotePipeline(options, tree, slug, note, env) {
1604
1989
  branch,
1605
1990
  cwd,
1606
1991
  arbiter: arbiterRemote,
1607
- reason: stopReason,
1992
+ reason: stopReason.reason,
1993
+ kind: stopReason.kind,
1608
1994
  env,
1609
1995
  note,
1610
1996
  });
@@ -1775,8 +2161,9 @@ async function saveRemoteAgentFailure(params) {
1775
2161
  : `Agent run failed building '${slug}' [${cause}] (${detail}); could not ` +
1776
2162
  `mark '${slug}' stuck (${routed.reasonNotMoved ?? 'unknown'}).`;
1777
2163
  note(message);
2164
+ // PR-2b D3: cleanly-surfaced remote agent failure is GREEN.
1778
2165
  return {
1779
- exitCode: 1,
2166
+ exitCode: routed.moved ? 0 : 1,
1780
2167
  outcome: failureCauseToDoOutcome(cause),
1781
2168
  slug,
1782
2169
  branch,
@@ -1831,7 +2218,7 @@ async function primeWorktreeTrackingRef(cwd, arbiter, head, env) {
1831
2218
  * identity) ride VERBATIM from the threaded `DoOptions` onto the structurally-
1832
2219
  * matching {@link DoRemoteOptions} fields; `cwd` is DROPPED (the worktree replaces
1833
2220
  * it) and `remote` + `workspacesDir` are supplied from this driver's closure (the
1834
- * mirror's arbiter URL + the agents' execution area). A `prd:` arg flows through
2221
+ * mirror's arbiter URL + the agents' execution area). A `spec:` arg flows through
1835
2222
  * unchanged — `performDoRemote` tasks it against the claim clone with NO build
1836
2223
  * worktree (the tasking/surface/triage/apply rungs are tree-less ledger moves, the
1837
2224
  * substrate the task's criterion 4 preserves).
@@ -1871,6 +2258,8 @@ export function jobWorktreeDoDriver(closure) {
1871
2258
  watch: options.watch,
1872
2259
  watchSink: options.watchSink,
1873
2260
  color: options.color,
2261
+ agentDeadlineMinutes: options.agentDeadlineMinutes,
2262
+ maxAutoCheckpoints: options.maxAutoCheckpoints,
1874
2263
  read: options.read,
1875
2264
  env: options.env,
1876
2265
  note: options.note,