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
@@ -3,17 +3,53 @@ import {join} from 'node:path';
3
3
  import {run} from './git.js';
4
4
  import {resolveSidecarIdentity} from './sidecar.js';
5
5
  import {resolveItemPathByIdentity} from './item-path.js';
6
+ import {terminalMainPaths} from './item-lock.js';
6
7
  import {workFolderPath, workFolderRel} from './work-layout.js';
7
8
 
9
+ /**
10
+ * Resolve the source item's CURRENT on-disk path INCLUDING its TERMINAL resting
11
+ * records — the orphan-sweep existence predicate.
12
+ *
13
+ * This deliberately WIDENS {@link resolveItemPathByIdentity} (which scans the
14
+ * ACTIVE lifecycle folders + staging, and EXCLUDES terminals on purpose: for the
15
+ * apply rung a terminal-reached item is `vanished`). The orphan sweep asks a
16
+ * DIFFERENT question — "does a source item for this sidecar exist AT ALL?" — and a
17
+ * task/spec that reached its terminal (`tasks/cancelled/`, `specs/dropped/`) is a
18
+ * durable RESTING record that still EXISTS, so its sidecar is NOT an orphan.
19
+ * Treating "reached a terminal" as "gone" would let a routine `gc` delete a live
20
+ * sidecar (and any human answer it carries) — the 2026-07-12 false-positive.
21
+ *
22
+ * Reuses the shared {@link terminalMainPaths} (`item-lock.ts`, the SAME per-type
23
+ * terminal set the lock/branch reapers key off) so the "where do terminals live?"
24
+ * knowledge stays single-sourced. Returns the ACTIVE path when present, else the
25
+ * first existing TERMINAL path, else `undefined` (a genuine orphan).
26
+ */
27
+ function resolveSourceForOrphanSweep(
28
+ cwd: string,
29
+ item: string,
30
+ ): string | undefined {
31
+ const active = resolveItemPathByIdentity(cwd, item);
32
+ if (active !== undefined) {
33
+ return active;
34
+ }
35
+ const {type, slug} = resolveSidecarIdentity(item);
36
+ for (const rel of terminalMainPaths(type, slug)) {
37
+ if (existsSync(join(cwd, rel))) {
38
+ return rel;
39
+ }
40
+ }
41
+ return undefined;
42
+ }
43
+
8
44
  /**
9
45
  * The **orphan-sidecar reaper** — the WORKING-TREE counterpart of the job-worktree
10
46
  * and remote-branch reapers (`gc.ts` / `reap-branches.ts`), folded into `dorfl gc`
11
- * (prd `agentic-question-resolution-retire-disposition-vocabulary`, US #10).
47
+ * (spec `agentic-question-resolution-retire-disposition-vocabulary`, US #10).
12
48
  *
13
49
  * A question sidecar is a tooling-owned file `work/questions/<type>-<slug>.md`
14
50
  * keyed on its source item's `(type, slug)` identity (`sidecarPathFor`). The
15
51
  * contract is that notes/sidecars leave by DELETION (git history is the archive),
16
- * so when a human deletes the source observation (or task/prd) out-of-band, its
52
+ * so when a human deletes the source observation (or task/spec) out-of-band, its
17
53
  * sidecar is ORPHANED.
18
54
  *
19
55
  * WHY THIS IS A SWEEP, NOT AN APPLY STEP. An orphan's source item is GONE, so it
@@ -26,10 +62,14 @@ import {workFolderPath, workFolderRel} from './work-layout.js';
26
62
  *
27
63
  * The existence check REUSES the keystone's extracted `resolveItemPathByIdentity`
28
64
  * (`item-path.ts`, the neutral re-exported seam) — the same working-tree,
29
- * by-identity "does the source item exist?" resolver the apply rung uses — never a
30
- * forked second resolver. A sidecar whose source EXISTS is left untouched; a
31
- * sidecar whose source is ABSENT is `git rm`'d (deletion, not a `git mv`: the
32
- * sidecar leaves by deletion, recoverable from git history).
65
+ * by-identity "does the source item exist?" resolver the apply rung uses — WIDENED
66
+ * to also count a source that has reached a TERMINAL folder (`tasks/cancelled/`,
67
+ * `specs/dropped/`, via the shared `terminalMainPaths`) as EXISTING: a terminal is
68
+ * a durable resting record, not "gone", so its sidecar is NOT an orphan (see
69
+ * `resolveSourceForOrphanSweep`). A sidecar whose source EXISTS anywhere is left
70
+ * untouched; a sidecar whose source is ABSENT from every active AND terminal
71
+ * folder is `git rm`'d (deletion, not a `git mv`: the sidecar leaves by deletion,
72
+ * recoverable from git history).
33
73
  */
34
74
 
35
75
  /** A sidecar the orphan sweep reaped (its source item was absent). */
@@ -111,9 +151,10 @@ export function sweepOrphanSidecars(
111
151
  const {item} = resolveSidecarIdentity(stem.replace('-', ':'));
112
152
  const path = `${workFolderRel('questions')}/${entry}`;
113
153
 
114
- const sourcePath = resolveItemPathByIdentity(input.cwd, item);
154
+ const sourcePath = resolveSourceForOrphanSweep(input.cwd, item);
115
155
  if (sourcePath !== undefined) {
116
- // The source item still exists a LIVE sidecar leave it untouched.
156
+ // The source item still exists (active lifecycle OR a terminal resting
157
+ // record) ⇒ a LIVE sidecar ⇒ leave it untouched.
117
158
  retained.push({path, item, sourcePath});
118
159
  note(`Retained ${path}: source ${item} still exists (${sourcePath}).`);
119
160
  continue;
package/src/pi-harness.ts CHANGED
@@ -65,6 +65,15 @@ import type {HarnessAdapter} from './config.js';
65
65
  /** The default pi CLI binary name (resolved on `PATH`). */
66
66
  export const DEFAULT_PI_BIN = 'pi';
67
67
 
68
+ /**
69
+ * The grace period between a deadline SIGTERM and the follow-up SIGKILL in
70
+ * {@link PiHarness.launchAsync} (spec `graceful-pre-timeout-wip-checkpoint`).
71
+ * Ten seconds gives pi enough time to flush its session `.jsonl` and exit
72
+ * cleanly; a wedged/frozen child that ignores SIGTERM still gets reaped in a
73
+ * bounded time so the promise settles and the caller's checkpoint routing runs.
74
+ */
75
+ export const DEADLINE_SIGKILL_GRACE_MS = 10_000;
76
+
68
77
  export interface PiHarnessOptions {
69
78
  /**
70
79
  * The pi CLI binary (default `pi` on `PATH`). Tests inject a stub script here
@@ -239,11 +248,60 @@ export class PiHarness implements Harness {
239
248
  child.stdout?.on('data', () => {});
240
249
  // Guard so `exit` and a late `error` never double-settle the promise.
241
250
  let settled = false;
251
+ let timedOut = false;
252
+ // DEADLINE RACE (spec `graceful-pre-timeout-wip-checkpoint`): when the
253
+ // caller threads a `deadlineMs` (absolute wall-clock epoch-ms), arm a
254
+ // SOFT SIGTERM at that time, then a HARD SIGKILL after a ~10s grace. The
255
+ // child's own `exit` handler below still resolves the promise (with
256
+ // `timedOut: true`), so we preserve the settle-once + FD-release
257
+ // discipline and never double-settle. A run that finishes BEFORE the
258
+ // deadline clears both timers (see the `exit` handler) — byte-for-byte
259
+ // unchanged from the pre-task behaviour.
260
+ let softTimer: NodeJS.Timeout | undefined;
261
+ let hardTimer: NodeJS.Timeout | undefined;
262
+ const clearDeadlineTimers = (): void => {
263
+ if (softTimer !== undefined) {
264
+ clearTimeout(softTimer);
265
+ softTimer = undefined;
266
+ }
267
+ if (hardTimer !== undefined) {
268
+ clearTimeout(hardTimer);
269
+ hardTimer = undefined;
270
+ }
271
+ };
272
+ if (input.deadlineMs !== undefined) {
273
+ const softMs = Math.max(0, input.deadlineMs - Date.now());
274
+ softTimer = setTimeout(() => {
275
+ if (settled) {
276
+ return;
277
+ }
278
+ timedOut = true;
279
+ try {
280
+ child.kill('SIGTERM');
281
+ } catch {
282
+ // Best-effort: a already-exited child throws ESRCH; the `exit`
283
+ // handler will still settle the promise.
284
+ }
285
+ hardTimer = setTimeout(() => {
286
+ if (settled) {
287
+ return;
288
+ }
289
+ try {
290
+ child.kill('SIGKILL');
291
+ } catch {
292
+ // Best-effort: see above.
293
+ }
294
+ }, DEADLINE_SIGKILL_GRACE_MS);
295
+ hardTimer.unref?.();
296
+ }, softMs);
297
+ softTimer.unref?.();
298
+ }
242
299
  child.on('error', (err) => {
243
300
  if (settled) {
244
301
  return;
245
302
  }
246
303
  settled = true;
304
+ clearDeadlineTimers();
247
305
  reject(new Error(`failed to spawn pi (${this.piBin}): ${err.message}`));
248
306
  });
249
307
  // Resolve on `exit` (pi itself terminated), NOT `close`: `close` waits for
@@ -255,6 +313,7 @@ export class PiHarness implements Harness {
255
313
  return;
256
314
  }
257
315
  settled = true;
316
+ clearDeadlineTimers();
258
317
  // Release our end of the stdio pipes so a leaked grandchild's inherited
259
318
  // FDs stop keeping our streams referenced; `unref` the child handle too.
260
319
  child.stdout?.destroy();
@@ -263,9 +322,11 @@ export class PiHarness implements Harness {
263
322
  child.unref?.();
264
323
  const status = code ?? -1;
265
324
  resolve({
266
- ok: status === 0,
325
+ ok: status === 0 && !timedOut,
267
326
  record,
268
- detail: status === 0 ? undefined : stderr.trim(),
327
+ detail:
328
+ status === 0 && !timedOut ? undefined : stderr.trim() || undefined,
329
+ timedOut: timedOut ? true : undefined,
269
330
  // Read the agent's ANSWER from the `.jsonl` at `exit` — the same
270
331
  // last-assistant-text read `launch` does at return (task
271
332
  // `harness-agent-output`); the process has exited so the log is final.
@@ -354,6 +415,14 @@ export class PiHarness implements Harness {
354
415
  * pointer with an `existsSync` check. This is the pi-native "is there an audit
355
416
  * trail to look at?" signal — distinct from PID liveness, and STILL not mtime
356
417
  * (we check existence, never modification time).
418
+ *
419
+ * Studied (task `pi-harness-polish`, finding
420
+ * `work/notes/findings/pi-harness-channels.md`): the recorded `--session <path>`
421
+ * file remains the right audit pointer even against pi's other output surfaces
422
+ * (`--mode json` stdout stream, `--mode rpc`, in-process SDK) — those are
423
+ * transient stdio channels that do not survive the process, whereas the session
424
+ * file is the versioned, dashboard-visible activity trail pi itself treats as
425
+ * the audit artefact. PID stays the liveness anchor alongside it.
357
426
  */
358
427
  export function piSessionExists(record: HarnessRecord): boolean {
359
428
  return record.session !== undefined && existsSync(record.session);
@@ -368,6 +437,17 @@ export function piSessionExists(record: HarnessRecord): boolean {
368
437
  * It REUSES `watch-session.ts`'s {@link lastAssistantText} (one `.jsonl` parser,
369
438
  * not two). An absent file (pi never wrote it) yields `undefined`, as does a log
370
439
  * with no assistant text — a read error is never thrown back into the launch.
440
+ *
441
+ * Studied (task `pi-harness-polish`, finding
442
+ * `work/notes/findings/pi-harness-channels.md`, pinned against pi 0.73.1 +
443
+ * session format v3): the session `.jsonl` is the right channel for output
444
+ * because it is the only one that is BOTH post-mortem readable AND explicitly
445
+ * versioned + migrated (`docs/session-format.md`). The `--mode json` STDOUT
446
+ * event stream is not versioned and is transient; `--mode rpc` and the
447
+ * in-process SDK cost more without solving anything the file does not. The
448
+ * cross-harness `LaunchResult.output` seam (Option C) is a bare `string | undefined`,
449
+ * so a future stream/HTTP-shaped harness (opencode-style) still fits: the file
450
+ * shape lives BEHIND this reader and is not observable through the seam.
371
451
  */
372
452
  function readLastAssistantText(sessionFile: string): string | undefined {
373
453
  let jsonl: string;
package/src/placement.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * **The shared STAGING/POOL placement resolver** (prd
2
+ * **The shared STAGING/POOL placement resolver** (spec
3
3
  * `staging-pool-position-gate-and-trust-model`, task
4
4
  * `runner-deterministic-slice-placement-policy-and-precedence`, governing ADR
5
5
  * `placement-is-runner-deterministic-humanonly-is-agent-judgement`).
@@ -19,7 +19,7 @@
19
19
  *
20
20
  * LIFECYCLE-GENERIC. The folder names + the configured-default value are
21
21
  * PARAMETERS (`slots`, `configuredDefault`), so the same resolver serves the
22
- * TASK lifecycle (`tasksLandIn`: `pre-backlog`/`ready` — the POOL value was
22
+ * TASK lifecycle (`tasksLandIn`: `backlog`/`ready` — the POOL value was
23
23
  * renamed `'backlog'` → `'todo'` → `'ready'`, ADR
24
24
  * `rename-task-pool-folder-todo-to-ready`) AND the SPEC-
25
25
  * placement lifecycle (`specsLandIn`: `pre-proposed`/`ready`) without forking. A future
@@ -31,19 +31,19 @@
31
31
  * Which side of the staging/pool split the runner chose. The CALLER maps this
32
32
  * onto the lifecycle's concrete folder name via {@link PlacementSlots}.
33
33
  *
34
- * - `'staging'` — land in the staging area (tasks: `pre-backlog/`; prds:
35
- * `prds/proposed/`). Not in the agent pool; a human/runner promotion is needed to make
34
+ * - `'staging'` — land in the staging area (tasks: `tasks/backlog/`; prds:
35
+ * `specs/proposed/`). Not in the agent pool; a human/runner promotion is needed to make
36
36
  * the item eligible. Review-without-PR review surface.
37
37
  * - `'pool'` — land directly in the agent-eligible pool (tasks: `tasks/ready/`;
38
- * prds: `prds/ready/`). The trusted-fast-path landing.
38
+ * prds: `specs/ready/`). The trusted-fast-path landing.
39
39
  */
40
40
  export type PlacementSide = 'staging' | 'pool';
41
41
 
42
42
  /**
43
43
  * The two folder names a lifecycle uses for its staging/pool split. Supplied by
44
44
  * the caller so this resolver stays lifecycle-generic (the TASK caller passes
45
- * `{staging: 'pre-backlog', pool: 'tasks/ready'}`; the PRD-placement caller passes
46
- * `{staging: 'prds/proposed', pool: 'prds/ready'}`).
45
+ * `{staging: 'tasks/backlog', pool: 'tasks/ready'}`; the SPEC-placement caller passes
46
+ * `{staging: 'specs/proposed', pool: 'specs/ready'}`).
47
47
  */
48
48
  export interface PlacementSlots {
49
49
  staging: string;
@@ -100,7 +100,7 @@ const BUILT_IN_FLOOR: PlacementSide = 'staging';
100
100
  * explicit > untrusted-origin ⇒ staging > configured default > built-in
101
101
  *
102
102
  * Pure: no I/O, no env reads — the caller resolves config + reads the
103
- * frontmatter and passes both in. Reused by every lifecycle (task + prd
103
+ * frontmatter and passes both in. Reused by every lifecycle (task + spec
104
104
  * placement + future intake variants) so a precedence change touches ONE place.
105
105
  */
106
106
  export function resolvePlacement(
@@ -8,10 +8,11 @@ import {
8
8
  mkdirSync,
9
9
  rmdirSync,
10
10
  } from 'node:fs';
11
- import {join, relative, dirname} from 'node:path';
11
+ import {join, relative, dirname, basename} from 'node:path';
12
12
  import {run, git, gitMv} from './git.js';
13
13
  import {resolveProtocolDoc} from './prompt.js';
14
14
  import {WORK_ROOT} from './work-layout.js';
15
+ import {repoConfigPath} from './repo-config.js';
15
16
 
16
17
  /**
17
18
  * The **`dorfl prd-to-spec` migration ENGINE** (spec
@@ -675,7 +676,9 @@ export function migrateConfig(
675
676
  migration: VocabularyMigration = MIGRATION,
676
677
  options: {dryRun?: boolean} = {},
677
678
  ): ConfigRewrite[] {
678
- const configAbs = join(repoPath, '.dorfl.json');
679
+ // Resolve the repo's actual config file (prefers `dorfl.json`, falls back to
680
+ // the legacy `.dorfl.json`), so the key rewrite finds it under either name.
681
+ const configAbs = repoConfigPath(repoPath);
679
682
  if (!existsSync(configAbs)) {
680
683
  return [];
681
684
  }
@@ -922,10 +925,15 @@ export function scanForLeaks(
922
925
  scanText(rel, readFileSync(join(repoPath, rel), 'utf8'), []);
923
926
  }
924
927
  }
925
- // The config file (the key layer).
926
- const configAbs = join(repoPath, '.dorfl.json');
928
+ // The config file (the key layer) — under either the preferred `dorfl.json`
929
+ // or the legacy `.dorfl.json`.
930
+ const configAbs = repoConfigPath(repoPath);
927
931
  if (existsSync(configAbs)) {
928
- scanText('.dorfl.json', readFileSync(configAbs, 'utf8'), configKeyPatterns);
932
+ scanText(
933
+ basename(configAbs),
934
+ readFileSync(configAbs, 'utf8'),
935
+ configKeyPatterns,
936
+ );
929
937
  }
930
938
  // The FOLDER TREE itself: a surviving `work/prds/` directory (empty ⇒ no
931
939
  // file, but the folder still leaks). Report it structurally.
package/src/prompt.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Builds the prompt the runner hands to `agentCmd`: a small CONSTANT wrapper
3
- * (only the `<slug>` / source-prd path vary) around the claimed task's own
3
+ * (only the `<slug>` / source-spec path vary) around the claimed task's own
4
4
  * `## Prompt` section. This is dual-use — the SAME assembly the autonomous
5
5
  * runner feeds `agentCmd` and the human `dorfl prompt [<slug>]` command.
6
6
  *
@@ -416,7 +416,7 @@ export function buildContinueBlock(slug: string, ctx: ContinueContext): string {
416
416
  }
417
417
 
418
418
  /**
419
- * Build the full prompt: the canonical wrapper for `slug` (with its source prd
419
+ * Build the full prompt: the canonical wrapper for `slug` (with its source spec
420
420
  * substituted) followed by the task's own `## Prompt` body, appended verbatim.
421
421
  *
422
422
  * In CONTINUE-mode (a {@link ContinueContext} is supplied), a CONTINUE block is
@@ -459,10 +459,7 @@ export interface ResolvedTask {
459
459
  path: string;
460
460
  /** The folder the task was resolved from (in-progress wins over tasks-ready). */
461
461
  folder: TaskFolder;
462
- /**
463
- * The task's source SPEC slug (frontmatter `spec:`, or the legacy `prd:` key
464
- * as read-only back-compat), if any.
465
- */
462
+ /** The task's source SPEC slug (frontmatter `spec:`), if any. */
466
463
  spec: string | undefined;
467
464
  /** The extracted `## Prompt` body. */
468
465
  taskPrompt: string;
@@ -493,7 +490,7 @@ export class PromptError extends Error {}
493
490
  /**
494
491
  * The CONTINUE-only gate that lets {@link resolveTask} reach a task that has
495
492
  * already been done-moved into `work/done/` — story 5 of the `ledger-integrity`
496
- * prd (defect 3). A continue/re-claim can legitimately land on a branch whose
493
+ * spec (defect 3). A continue/re-claim can legitimately land on a branch whose
497
494
  * task was ALREADY moved to `done/` (the green-but-unpushed STRAND state), and
498
495
  * onboard must find it; but a `done/` task is folder-indistinguishable between
499
496
  * two states and re-onboarding a genuinely-finished one would RE-RUN it. So
@@ -533,7 +530,7 @@ export interface ContinueResolutionGate {
533
530
 
534
531
  /**
535
532
  * Extra knobs for {@link resolveTask} beyond the continue gate. Today the only
536
- * member is `allowBacklog` (prd
533
+ * member is `allowBacklog` (spec
537
534
  * `do-allow-backlog-drive-staged-tasks-without-promotion`): the operator's
538
535
  * EXPLICIT `do … --allow-backlog`, which widens resolution to also search
539
536
  * `tasks-backlog` (staging) at LOWEST priority. Default off (omitted) \u21d2 the
@@ -574,7 +571,7 @@ function isStrandedDoneTip(gate: ContinueResolutionGate): boolean {
574
571
 
575
572
  /**
576
573
  * Resolve a task's file: prefer `work/in-progress/<slug>.md`, fall back to
577
- * `work/tasks/ready/<slug>.md` (the pool). Returns the parsed prd + extracted
574
+ * `work/tasks/ready/<slug>.md` (the pool). Returns the parsed spec + extracted
578
575
  * `## Prompt` body. Throws {@link PromptError} when neither file exists or it has
579
576
  * no prompt body.
580
577
  *
@@ -588,11 +585,11 @@ function isStrandedDoneTip(gate: ContinueResolutionGate): boolean {
588
585
  * the only addition, and it is gated. With no gate (a fresh claim) the behaviour
589
586
  * is byte-identical to the original `['in-progress','tasks-ready']`-only resolution.
590
587
  *
591
- * `--allow-backlog` (prd `do-allow-backlog-drive-staged-tasks-without-promotion`):
588
+ * `--allow-backlog` (spec `do-allow-backlog-drive-staged-tasks-without-promotion`):
592
589
  * when {@link ResolveTaskOptions.allowBacklog} is set, `tasks-backlog` (the staging
593
590
  * folder) is appended at the LOWEST priority — after `tasks-ready`, so a slug
594
591
  * present in BOTH the pool and staging resolves to the READY copy (the same-slug
595
- * precedence the prd's decision 5 fixes). Default off ⇒ byte-identical to today
592
+ * precedence the spec's decision 5 fixes). Default off ⇒ byte-identical to today
596
593
  * (no autonomous path sets it; staging stays unreachable to `run`/auto-pick).
597
594
  */
598
595
  export function resolveTask(
@@ -627,9 +624,8 @@ export function resolveTask(
627
624
  );
628
625
  }
629
626
  const fm = parseFrontmatter(content);
630
- // Read the parent-spec pointer off `fm.spec` (populated from EITHER the
631
- // canonical `spec:` key or the legacy `prd:` back-compat alias) into the
632
- // `spec`-only `ResolvedTask` (spec
627
+ // Read the parent-spec pointer off `fm.spec` (populated from the canonical
628
+ // `spec:` key) into the `spec`-only `ResolvedTask` (spec
633
629
  // `prd-to-spec-vocabulary-cutover-and-migration-command`).
634
630
  return {slug, path, folder, spec: fm.spec, taskPrompt};
635
631
  }
@@ -665,13 +661,13 @@ export function inferSlugFromBranch(
665
661
  */
666
662
  /**
667
663
  * Resolve the EFFECTIVE `promptGuidance` for an item by walking the precedence
668
- * chain (highest → lowest): the per-task frontmatter override, the per-prd
669
- * frontmatter override (only when the task carries a `prd:`), then the
664
+ * chain (highest → lowest): the per-task frontmatter override, the per-spec
665
+ * frontmatter override (only when the task carries a `spec:`), then the
670
666
  * already-resolved repo policy. Each nudge member resolves independently — a
671
667
  * task's `promptGuidance.testFirst` override never bleeds into a sibling
672
668
  * member — mirroring the `humanOnly`/`autoBuild` per-item override shape.
673
669
  *
674
- * A task may carry the override even when it has NO `prd:` (a self-contained
670
+ * A task may carry the override even when it has NO `spec:` (a self-contained
675
671
  * chore), by symmetry with `humanOnly` at the item level; `specFrontmatter`
676
672
  * is then simply absent and the chain reads task ⇒ repo.
677
673
  */
@@ -688,11 +684,11 @@ export function resolveItemPromptGuidance(
688
684
  }
689
685
 
690
686
  /**
691
- * Locate a prd's file on disk: prefer `work/prds/ready/<slug>.md` (the
692
- * auto-slice pool), then fall back to `work/prds/tasked/<slug>.md` (tasked,
687
+ * Locate a spec's file on disk: prefer `work/specs/ready/<slug>.md` (the
688
+ * auto-slice pool), then fall back to `work/specs/tasked/<slug>.md` (tasked,
693
689
  * resting). Returns `undefined` when neither exists — the caller treats that
694
- * as "no prd-level override available" and the precedence chain falls
695
- * through to the repo policy (a missing prd is NOT an error at this seam;
690
+ * as "no spec-level override available" and the precedence chain falls
691
+ * through to the repo policy (a missing spec is NOT an error at this seam;
696
692
  * the per-item override is OPTIONAL by design).
697
693
  */
698
694
  export function findSpecPath(
@@ -714,7 +710,7 @@ export function findSpecPath(
714
710
  /**
715
711
  * The convenience seam every caller of {@link buildAgentPrompt} reuses to
716
712
  * resolve the per-item override: load the task frontmatter from its file +
717
- * (when the task carries `prd:`) the prd frontmatter, then walk
713
+ * (when the task carries `spec:`) the spec frontmatter, then walk
718
714
  * {@link resolveItemPromptGuidance}. Pure-ish (reads at most two files);
719
715
  * returns the repo policy verbatim when neither item layer overrides anything.
720
716
  */
@@ -725,8 +721,7 @@ export function resolvePromptGuidanceForItem(options: {
725
721
  }): PromptGuidance {
726
722
  const taskFm = parseFrontmatter(options.taskContent);
727
723
  let specFm: Frontmatter | undefined;
728
- // Read the parent-spec pointer off `fm.spec` (populated from the `spec:` key or
729
- // the legacy `prd:` back-compat alias).
724
+ // Read the parent-spec pointer off `fm.spec` (populated from the `spec:` key).
730
725
  if (taskFm.spec !== undefined) {
731
726
  const specPath = findSpecPath(options.cwd, taskFm.spec);
732
727
  if (specPath !== undefined) {
@@ -745,7 +740,7 @@ export function renderPrompt(options: PromptOptions): string {
745
740
  );
746
741
  }
747
742
  const task = resolveTask(options.cwd, slug);
748
- // Per-item override layer: a task or prd may pin `promptGuidance.testFirst`
743
+ // Per-item override layer: a task or spec may pin `promptGuidance.testFirst`
749
744
  // in its frontmatter, superseding the resolved repo policy for THIS item.
750
745
  // We ALWAYS walk the resolver (even when no repo policy was threaded), so a
751
746
  // task can opt IN to the strengthened nudge even on a repo whose default is
package/src/readiness.ts CHANGED
@@ -16,7 +16,7 @@ import {ledgerRead} from './ledger-read.js';
16
16
  * the shared {@link resolveBlockedBy} (no reimplemented dep resolution).
17
17
  *
18
18
  * The two axes are deliberately treated differently (see WORK-CONTRACT and the
19
- * task prd):
19
+ * task spec):
20
20
  *
21
21
  * - `blockedBy` unmet is a FACTUAL prerequisite (the dep work does not exist
22
22
  * yet) → REFUSE by default. An override flag is the human escape hatch.
@@ -1,6 +1,7 @@
1
1
  import {run} from './git.js';
2
- import {isAncestor} from './gc.js';
2
+ import {isProvablyMergedForReap} from './gc.js';
3
3
  import {parseWorkBranchRef} from './slug-namespace.js';
4
+ import type {SidecarType} from './sidecar.js';
4
5
 
5
6
  /**
6
7
  * The **remote merged-work-branch reaper** — the cross-machine COUNTERPART of the
@@ -9,13 +10,15 @@ import {parseWorkBranchRef} from './slug-namespace.js';
9
10
  * the arbiter after their propose-mode PR has MERGED.
10
11
  *
11
12
  * The safety lynchpin is the SAME provably-merged predicate the worktree reaper
12
- * uses (`gc.ts` `isAncestor`, REUSED here, never a second one): a remote
13
- * `work/<slug>` branch is reapable **iff** its tip is
14
- * `git merge-base --is-ancestor <tip> <arbiter>/main` — provably on `main`. A
15
- * merely-pushed-but-unmerged branch (an in-flight, kept-for-continue recovery
16
- * point) is NOT an ancestor of `main`, so the predicate AUTOMATICALLY excludes it
17
- * the never-delete-the-in-flight-branch invariant (ADR §4 deletion-safety)
18
- * stays absolute. Deletion of a fully-merged ref needs NO force, so this NEVER
13
+ * uses (`gc.ts` `isProvablyMergedForReap`, REUSED here, never a second one): a
14
+ * remote `work/<slug>` branch is reapable **iff** it is provably on
15
+ * `<arbiter>/main` — EITHER `git merge-base --is-ancestor <tip> <arbiter>/main`
16
+ * (fast path) OR the squash-aware fallback (durable done/dropped record on main
17
+ * AND branch carries nothing main lacks). A merely-pushed-but-unmerged branch
18
+ * (an in-flight, kept-for-continue recovery point) has no terminal record on
19
+ * main AND is not an ancestor, so the predicate AUTOMATICALLY excludes it — the
20
+ * never-delete-the-in-flight-branch invariant (ADR §4 deletion-safety) stays
21
+ * absolute. Deletion of a fully-merged ref needs NO force, so this NEVER
19
22
  * `--force`s.
20
23
  *
21
24
  * It is provider-AGNOSTIC plain git (`git ls-remote` to enumerate, `git push
@@ -101,8 +104,9 @@ export interface SweepRemoteBranchesResult {
101
104
  * 2. Fetch `<arbiter>/main` into a local tracking ref so the ancestor check
102
105
  * resolves the descendant LOCALLY; fetch each candidate tip object too (so
103
106
  * `merge-base` can read it) — best-effort, into a scratch ref.
104
- * 3. For each branch whose tip `--is-ancestor` of the fetched main delete via
105
- * `git push <arbiter> --delete <branch>`; else retain with a reason.
107
+ * 3. For each branch that is provably merged for reap (fast-path ancestor
108
+ * OR squash-aware fallback {@link isProvablyMergedForReap}) delete
109
+ * via `git push <arbiter> --delete <branch>`; else retain with a reason.
106
110
  */
107
111
  export function sweepRemoteMergedBranches(
108
112
  input: SweepRemoteBranchesInput,
@@ -126,12 +130,32 @@ export function sweepRemoteMergedBranches(
126
130
  retain(retained, note, branch, tip, 'main-unresolved');
127
131
  continue;
128
132
  }
129
- // Make the candidate tip OBJECT readable locally so `merge-base` can use it
130
- // (ls-remote gave us the sha, but the object may not be in the local repo).
133
+ // Make the candidate tip OBJECT readable locally so `merge-base` /
134
+ // `diff` / `cherry` can read it (ls-remote gave us the sha, but the
135
+ // object may not be in the local repo).
131
136
  fetchScratch(input.cwd, input.arbiter, branch, env);
132
137
 
133
- if (!isAncestor(input.cwd, tip, mainRef, env)) {
134
- // NOT an ancestor of main ⇒ still in-flight ⇒ NEVER delete (the invariant).
138
+ const parsed = parseWorkBranchRef(branch);
139
+ if (parsed === undefined) {
140
+ // Guarded above by `listRemoteWorkBranches` (which only enumerates
141
+ // parseable heads), but keep a defensive belt: without a slug the
142
+ // squash-aware fallback has no anchor ⇒ retain.
143
+ retain(retained, note, branch, tip, 'not-merged');
144
+ continue;
145
+ }
146
+
147
+ if (
148
+ !isProvablyMergedForReap({
149
+ cwd: input.cwd,
150
+ tip,
151
+ arbiterMain: mainRef,
152
+ namespace: parsed.namespace as SidecarType,
153
+ slug: parsed.slug,
154
+ env,
155
+ })
156
+ ) {
157
+ // NOT provably merged (neither ancestor nor squash-aware equivalent)
158
+ // ⇒ still in-flight ⇒ NEVER delete (the invariant).
135
159
  retain(retained, note, branch, tip, 'not-merged');
136
160
  continue;
137
161
  }
@@ -11,7 +11,7 @@ import type {ReviewProvider} from './integrator.js';
11
11
 
12
12
  /**
13
13
  * **`complete --isolated <slug>` — FINISH an already-committed, already-done-moved
14
- * STRANDED isolated worktree** (prd `ledger-integrity` story 6, the
14
+ * STRANDED isolated worktree** (spec `ledger-integrity` story 6, the
15
15
  * `finish-already-committed-branch` task). The LOCATE-EXISTING inverse of
16
16
  * `do --isolated` (which CREATES a worktree): it resolves the slug's RETAINED job
17
17
  * worktree via the existing arbiter-URL-keyed naming
@@ -57,6 +57,18 @@ export interface RecoverIsolatedOptions {
57
57
  integration?: IntegrationMode;
58
58
  /** Suppress the PR on the propose path (push the branch, open no review request). */
59
59
  noPR?: boolean;
60
+ /**
61
+ * **The cross-job merge-serialiser CAS-retry cap** (config `mergeRetries`, spec
62
+ * `land-time-reverify-and-parallel-merge-ceiling` Story 5 / Applied Answer q1
63
+ * (a)). Threaded VERBATIM into {@link performIntegration} so a wide-matrix CI's
64
+ * raised cap actually reaches the cross-job land queue on the isolated-recovery
65
+ * path too (task `thread-merge-retries-cross-task-and-ratify-default`). Resolved
66
+ * ONCE at the CLI (the `complete --isolated` command) through the SAME
67
+ * gate-family precedence chain the plain `complete` path uses (flag > env >
68
+ * per-repo > global > default). Unset ⇒ the engine's `DEFAULT_MERGE_RETRIES =
69
+ * 1000` (byte-for-byte unchanged).
70
+ */
71
+ mergeRetries?: number;
60
72
  /** Optional fully-formed provider used verbatim (test/embedding seam). */
61
73
  providerInstance?: ReviewProvider;
62
74
  /** Optional injectable PR opener (legacy bridge); used in `propose` mode. */
@@ -177,6 +189,11 @@ export async function performRecoverIsolated(
177
189
  recovering: false,
178
190
  committedRecovery: true,
179
191
  mode: options.integration ?? 'propose',
192
+ // The cross-job merge-serialiser CAS-retry cap (config `mergeRetries`) — the
193
+ // git-alone floor of the cross-job land queue, resolved through the gate-
194
+ // family precedence chain in the CLI and threaded here so the isolated-
195
+ // recovery land tail respects the per-repo cap.
196
+ mergeRetries: options.mergeRetries,
180
197
  noPR: options.noPR,
181
198
  providerInstance: options.providerInstance,
182
199
  openPr: options.openPr,