dorfl 0.0.0 → 0.1.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 (619) hide show
  1. package/dist/advance-ci-template.d.ts +73 -0
  2. package/dist/advance-ci-template.d.ts.map +1 -0
  3. package/dist/advance-ci-template.js +104 -0
  4. package/dist/advance-ci-template.js.map +1 -0
  5. package/dist/advance-classify.d.ts +132 -0
  6. package/dist/advance-classify.d.ts.map +1 -0
  7. package/dist/advance-classify.js +120 -0
  8. package/dist/advance-classify.js.map +1 -0
  9. package/dist/advance-drivers.d.ts +182 -0
  10. package/dist/advance-drivers.d.ts.map +1 -0
  11. package/dist/advance-drivers.js +231 -0
  12. package/dist/advance-drivers.js.map +1 -0
  13. package/dist/advance-isolated.d.ts +156 -0
  14. package/dist/advance-isolated.d.ts.map +1 -0
  15. package/dist/advance-isolated.js +256 -0
  16. package/dist/advance-isolated.js.map +1 -0
  17. package/dist/advance-lifecycle-template.d.ts +107 -0
  18. package/dist/advance-lifecycle-template.d.ts.map +1 -0
  19. package/dist/advance-lifecycle-template.js +668 -0
  20. package/dist/advance-lifecycle-template.js.map +1 -0
  21. package/dist/advance-loop-driver.d.ts +325 -0
  22. package/dist/advance-loop-driver.d.ts.map +1 -0
  23. package/dist/advance-loop-driver.js +437 -0
  24. package/dist/advance-loop-driver.js.map +1 -0
  25. package/dist/advance-treeless-publish.d.ts +108 -0
  26. package/dist/advance-treeless-publish.d.ts.map +1 -0
  27. package/dist/advance-treeless-publish.js +71 -0
  28. package/dist/advance-treeless-publish.js.map +1 -0
  29. package/dist/advance.d.ts +340 -0
  30. package/dist/advance.d.ts.map +1 -0
  31. package/dist/advance.js +1122 -0
  32. package/dist/advance.js.map +1 -0
  33. package/dist/advancing-lock.d.ts +294 -0
  34. package/dist/advancing-lock.d.ts.map +1 -0
  35. package/dist/advancing-lock.js +594 -0
  36. package/dist/advancing-lock.js.map +1 -0
  37. package/dist/agent-launch.d.ts +79 -0
  38. package/dist/agent-launch.d.ts.map +1 -0
  39. package/dist/agent-launch.js +61 -0
  40. package/dist/agent-launch.js.map +1 -0
  41. package/dist/agent-stop.d.ts +149 -0
  42. package/dist/agent-stop.d.ts.map +1 -0
  43. package/dist/agent-stop.js +307 -0
  44. package/dist/agent-stop.js.map +1 -0
  45. package/dist/apply-decide.d.ts +127 -0
  46. package/dist/apply-decide.d.ts.map +1 -0
  47. package/dist/apply-decide.js +176 -0
  48. package/dist/apply-decide.js.map +1 -0
  49. package/dist/apply-merge-action.d.ts +206 -0
  50. package/dist/apply-merge-action.d.ts.map +1 -0
  51. package/dist/apply-merge-action.js +307 -0
  52. package/dist/apply-merge-action.js.map +1 -0
  53. package/dist/apply-persist.d.ts +174 -0
  54. package/dist/apply-persist.d.ts.map +1 -0
  55. package/dist/apply-persist.js +359 -0
  56. package/dist/apply-persist.js.map +1 -0
  57. package/dist/arbiter.d.ts +120 -0
  58. package/dist/arbiter.d.ts.map +1 -0
  59. package/dist/arbiter.js +255 -0
  60. package/dist/arbiter.js.map +1 -0
  61. package/dist/brand.d.ts +70 -0
  62. package/dist/brand.d.ts.map +1 -0
  63. package/dist/brand.js +84 -0
  64. package/dist/brand.js.map +1 -0
  65. package/dist/buildable-body.d.ts +132 -0
  66. package/dist/buildable-body.d.ts.map +1 -0
  67. package/dist/buildable-body.js +131 -0
  68. package/dist/buildable-body.js.map +1 -0
  69. package/dist/categorise.d.ts +66 -0
  70. package/dist/categorise.d.ts.map +1 -0
  71. package/dist/categorise.js +106 -0
  72. package/dist/categorise.js.map +1 -0
  73. package/dist/claim-cas.d.ts +117 -0
  74. package/dist/claim-cas.d.ts.map +1 -0
  75. package/dist/claim-cas.js +312 -0
  76. package/dist/claim-cas.js.map +1 -0
  77. package/dist/cli-spinner.d.ts +112 -0
  78. package/dist/cli-spinner.d.ts.map +1 -0
  79. package/dist/cli-spinner.js +157 -0
  80. package/dist/cli-spinner.js.map +1 -0
  81. package/dist/cli.d.ts +11 -0
  82. package/dist/cli.d.ts.map +1 -0
  83. package/dist/cli.js +3094 -0
  84. package/dist/cli.js.map +1 -0
  85. package/dist/close-job-template.d.ts +70 -0
  86. package/dist/close-job-template.d.ts.map +1 -0
  87. package/dist/close-job-template.js +180 -0
  88. package/dist/close-job-template.js.map +1 -0
  89. package/dist/close-job.d.ts +95 -0
  90. package/dist/close-job.d.ts.map +1 -0
  91. package/dist/close-job.js +226 -0
  92. package/dist/close-job.js.map +1 -0
  93. package/dist/complete.d.ts +361 -0
  94. package/dist/complete.d.ts.map +1 -0
  95. package/dist/complete.js +885 -0
  96. package/dist/complete.js.map +1 -0
  97. package/dist/concurrency.d.ts +68 -0
  98. package/dist/concurrency.d.ts.map +1 -0
  99. package/dist/concurrency.js +112 -0
  100. package/dist/concurrency.js.map +1 -0
  101. package/dist/config-override.d.ts +76 -0
  102. package/dist/config-override.d.ts.map +1 -0
  103. package/dist/config-override.js +50 -0
  104. package/dist/config-override.js.map +1 -0
  105. package/dist/config.d.ts +668 -0
  106. package/dist/config.d.ts.map +1 -0
  107. package/dist/config.js +241 -0
  108. package/dist/config.js.map +1 -0
  109. package/dist/continue-branch.d.ts +249 -0
  110. package/dist/continue-branch.d.ts.map +1 -0
  111. package/dist/continue-branch.js +389 -0
  112. package/dist/continue-branch.js.map +1 -0
  113. package/dist/cwd-section.d.ts +186 -0
  114. package/dist/cwd-section.d.ts.map +1 -0
  115. package/dist/cwd-section.js +209 -0
  116. package/dist/cwd-section.js.map +1 -0
  117. package/dist/decision-engine.d.ts +170 -0
  118. package/dist/decision-engine.d.ts.map +1 -0
  119. package/dist/decision-engine.js +136 -0
  120. package/dist/decision-engine.js.map +1 -0
  121. package/dist/detect.d.ts +17 -0
  122. package/dist/detect.d.ts.map +1 -0
  123. package/dist/detect.js +118 -0
  124. package/dist/detect.js.map +1 -0
  125. package/dist/do-autopick.d.ts +85 -0
  126. package/dist/do-autopick.d.ts.map +1 -0
  127. package/dist/do-autopick.js +112 -0
  128. package/dist/do-autopick.js.map +1 -0
  129. package/dist/do-config.d.ts +312 -0
  130. package/dist/do-config.d.ts.map +1 -0
  131. package/dist/do-config.js +358 -0
  132. package/dist/do-config.js.map +1 -0
  133. package/dist/do-remote-auto.d.ts +75 -0
  134. package/dist/do-remote-auto.d.ts.map +1 -0
  135. package/dist/do-remote-auto.js +111 -0
  136. package/dist/do-remote-auto.js.map +1 -0
  137. package/dist/do.d.ts +621 -0
  138. package/dist/do.d.ts.map +1 -0
  139. package/dist/do.js +1882 -0
  140. package/dist/do.js.map +1 -0
  141. package/dist/drop-source.d.ts +96 -0
  142. package/dist/drop-source.d.ts.map +1 -0
  143. package/dist/drop-source.js +91 -0
  144. package/dist/drop-source.js.map +1 -0
  145. package/dist/eligibility.d.ts +46 -0
  146. package/dist/eligibility.d.ts.map +1 -0
  147. package/dist/eligibility.js +34 -0
  148. package/dist/eligibility.js.map +1 -0
  149. package/dist/env-config.d.ts +51 -0
  150. package/dist/env-config.d.ts.map +1 -0
  151. package/dist/env-config.js +272 -0
  152. package/dist/env-config.js.map +1 -0
  153. package/dist/failure-cause.d.ts +70 -0
  154. package/dist/failure-cause.d.ts.map +1 -0
  155. package/dist/failure-cause.js +126 -0
  156. package/dist/failure-cause.js.map +1 -0
  157. package/dist/format.d.ts +43 -0
  158. package/dist/format.d.ts.map +1 -0
  159. package/dist/format.js +256 -0
  160. package/dist/format.js.map +1 -0
  161. package/dist/frontmatter.d.ts +215 -0
  162. package/dist/frontmatter.d.ts.map +1 -0
  163. package/dist/frontmatter.js +345 -0
  164. package/dist/frontmatter.js.map +1 -0
  165. package/dist/gate-readiness.d.ts +84 -0
  166. package/dist/gate-readiness.d.ts.map +1 -0
  167. package/dist/gate-readiness.js +103 -0
  168. package/dist/gate-readiness.js.map +1 -0
  169. package/dist/gc.d.ts +165 -0
  170. package/dist/gc.d.ts.map +1 -0
  171. package/dist/gc.js +313 -0
  172. package/dist/gc.js.map +1 -0
  173. package/dist/gh-failure.d.ts +42 -0
  174. package/dist/gh-failure.d.ts.map +1 -0
  175. package/dist/gh-failure.js +49 -0
  176. package/dist/gh-failure.js.map +1 -0
  177. package/dist/git.d.ts +75 -0
  178. package/dist/git.d.ts.map +1 -0
  179. package/dist/git.js +130 -0
  180. package/dist/git.js.map +1 -0
  181. package/dist/github.d.ts +187 -0
  182. package/dist/github.d.ts.map +1 -0
  183. package/dist/github.js +343 -0
  184. package/dist/github.js.map +1 -0
  185. package/dist/harness.d.ts +242 -0
  186. package/dist/harness.d.ts.map +1 -0
  187. package/dist/harness.js +157 -0
  188. package/dist/harness.js.map +1 -0
  189. package/dist/identity.d.ts +167 -0
  190. package/dist/identity.d.ts.map +1 -0
  191. package/dist/identity.js +231 -0
  192. package/dist/identity.js.map +1 -0
  193. package/dist/index.d.ts +147 -0
  194. package/dist/index.d.ts.map +1 -0
  195. package/dist/index.js +76 -0
  196. package/dist/index.js.map +1 -0
  197. package/dist/install-ci-branch-protection.d.ts +147 -0
  198. package/dist/install-ci-branch-protection.d.ts.map +1 -0
  199. package/dist/install-ci-branch-protection.js +166 -0
  200. package/dist/install-ci-branch-protection.js.map +1 -0
  201. package/dist/install-ci-capabilities/advance-lifecycle.d.ts +15 -0
  202. package/dist/install-ci-capabilities/advance-lifecycle.d.ts.map +1 -0
  203. package/dist/install-ci-capabilities/advance-lifecycle.js +28 -0
  204. package/dist/install-ci-capabilities/advance-lifecycle.js.map +1 -0
  205. package/dist/install-ci-capabilities/close-job.d.ts +13 -0
  206. package/dist/install-ci-capabilities/close-job.d.ts.map +1 -0
  207. package/dist/install-ci-capabilities/close-job.js +26 -0
  208. package/dist/install-ci-capabilities/close-job.js.map +1 -0
  209. package/dist/install-ci-capabilities/example-noop.d.ts +16 -0
  210. package/dist/install-ci-capabilities/example-noop.d.ts.map +1 -0
  211. package/dist/install-ci-capabilities/example-noop.js +23 -0
  212. package/dist/install-ci-capabilities/example-noop.js.map +1 -0
  213. package/dist/install-ci-capabilities/intake.d.ts +15 -0
  214. package/dist/install-ci-capabilities/intake.d.ts.map +1 -0
  215. package/dist/install-ci-capabilities/intake.js +28 -0
  216. package/dist/install-ci-capabilities/intake.js.map +1 -0
  217. package/dist/install-ci-capabilities/verify.d.ts +14 -0
  218. package/dist/install-ci-capabilities/verify.d.ts.map +1 -0
  219. package/dist/install-ci-capabilities/verify.js +27 -0
  220. package/dist/install-ci-capabilities/verify.js.map +1 -0
  221. package/dist/install-ci-core.d.ts +446 -0
  222. package/dist/install-ci-core.d.ts.map +1 -0
  223. package/dist/install-ci-core.js +760 -0
  224. package/dist/install-ci-core.js.map +1 -0
  225. package/dist/install-ci-github.d.ts +167 -0
  226. package/dist/install-ci-github.d.ts.map +1 -0
  227. package/dist/install-ci-github.js +315 -0
  228. package/dist/install-ci-github.js.map +1 -0
  229. package/dist/install-ci.d.ts +105 -0
  230. package/dist/install-ci.d.ts.map +1 -0
  231. package/dist/install-ci.js +363 -0
  232. package/dist/install-ci.js.map +1 -0
  233. package/dist/intake-event.d.ts +88 -0
  234. package/dist/intake-event.d.ts.map +1 -0
  235. package/dist/intake-event.js +66 -0
  236. package/dist/intake-event.js.map +1 -0
  237. package/dist/intake-marker.d.ts +95 -0
  238. package/dist/intake-marker.d.ts.map +1 -0
  239. package/dist/intake-marker.js +127 -0
  240. package/dist/intake-marker.js.map +1 -0
  241. package/dist/intake-triage.d.ts +48 -0
  242. package/dist/intake-triage.d.ts.map +1 -0
  243. package/dist/intake-triage.js +95 -0
  244. package/dist/intake-triage.js.map +1 -0
  245. package/dist/intake-trigger-template.d.ts +185 -0
  246. package/dist/intake-trigger-template.d.ts.map +1 -0
  247. package/dist/intake-trigger-template.js +449 -0
  248. package/dist/intake-trigger-template.js.map +1 -0
  249. package/dist/intake.d.ts +569 -0
  250. package/dist/intake.d.ts.map +1 -0
  251. package/dist/intake.js +1628 -0
  252. package/dist/intake.js.map +1 -0
  253. package/dist/integration-core.d.ts +539 -0
  254. package/dist/integration-core.d.ts.map +1 -0
  255. package/dist/integration-core.js +2195 -0
  256. package/dist/integration-core.js.map +1 -0
  257. package/dist/integrator.d.ts +343 -0
  258. package/dist/integrator.d.ts.map +1 -0
  259. package/dist/integrator.js +400 -0
  260. package/dist/integrator.js.map +1 -0
  261. package/dist/isolation.d.ts +219 -0
  262. package/dist/isolation.d.ts.map +1 -0
  263. package/dist/isolation.js +261 -0
  264. package/dist/isolation.js.map +1 -0
  265. package/dist/issue-provider.d.ts +349 -0
  266. package/dist/issue-provider.d.ts.map +1 -0
  267. package/dist/issue-provider.js +360 -0
  268. package/dist/issue-provider.js.map +1 -0
  269. package/dist/item-lock.d.ts +626 -0
  270. package/dist/item-lock.d.ts.map +1 -0
  271. package/dist/item-lock.js +1381 -0
  272. package/dist/item-lock.js.map +1 -0
  273. package/dist/item-path.d.ts +49 -0
  274. package/dist/item-path.d.ts.map +1 -0
  275. package/dist/item-path.js +66 -0
  276. package/dist/item-path.js.map +1 -0
  277. package/dist/ledger-lint.d.ts +129 -0
  278. package/dist/ledger-lint.d.ts.map +1 -0
  279. package/dist/ledger-lint.js +249 -0
  280. package/dist/ledger-lint.js.map +1 -0
  281. package/dist/ledger-read.d.ts +357 -0
  282. package/dist/ledger-read.d.ts.map +1 -0
  283. package/dist/ledger-read.js +442 -0
  284. package/dist/ledger-read.js.map +1 -0
  285. package/dist/ledger-write.d.ts +330 -0
  286. package/dist/ledger-write.d.ts.map +1 -0
  287. package/dist/ledger-write.js +411 -0
  288. package/dist/ledger-write.js.map +1 -0
  289. package/dist/lifecycle-gather.d.ts +30 -0
  290. package/dist/lifecycle-gather.d.ts.map +1 -0
  291. package/dist/lifecycle-gather.js +205 -0
  292. package/dist/lifecycle-gather.js.map +1 -0
  293. package/dist/lifecycle-pools.d.ts +180 -0
  294. package/dist/lifecycle-pools.d.ts.map +1 -0
  295. package/dist/lifecycle-pools.js +78 -0
  296. package/dist/lifecycle-pools.js.map +1 -0
  297. package/dist/merge-question-surfacer.d.ts +166 -0
  298. package/dist/merge-question-surfacer.d.ts.map +1 -0
  299. package/dist/merge-question-surfacer.js +297 -0
  300. package/dist/merge-question-surfacer.js.map +1 -0
  301. package/dist/mint-adr.d.ts +126 -0
  302. package/dist/mint-adr.d.ts.map +1 -0
  303. package/dist/mint-adr.js +257 -0
  304. package/dist/mint-adr.js.map +1 -0
  305. package/dist/mirror-pool-scan.d.ts +125 -0
  306. package/dist/mirror-pool-scan.d.ts.map +1 -0
  307. package/dist/mirror-pool-scan.js +104 -0
  308. package/dist/mirror-pool-scan.js.map +1 -0
  309. package/dist/needs-attention.d.ts +341 -0
  310. package/dist/needs-attention.d.ts.map +1 -0
  311. package/dist/needs-attention.js +900 -0
  312. package/dist/needs-attention.js.map +1 -0
  313. package/dist/orphan-sidecar.d.ts +79 -0
  314. package/dist/orphan-sidecar.d.ts.map +1 -0
  315. package/dist/orphan-sidecar.js +71 -0
  316. package/dist/orphan-sidecar.js.map +1 -0
  317. package/dist/output.d.ts +48 -0
  318. package/dist/output.d.ts.map +1 -0
  319. package/dist/output.js +66 -0
  320. package/dist/output.js.map +1 -0
  321. package/dist/pi-harness.d.ts +179 -0
  322. package/dist/pi-harness.d.ts.map +1 -0
  323. package/dist/pi-harness.js +342 -0
  324. package/dist/pi-harness.js.map +1 -0
  325. package/dist/placement.d.ts +99 -0
  326. package/dist/placement.d.ts.map +1 -0
  327. package/dist/placement.js +67 -0
  328. package/dist/placement.js.map +1 -0
  329. package/dist/prd-to-spec.d.ts +315 -0
  330. package/dist/prd-to-spec.d.ts.map +1 -0
  331. package/dist/prd-to-spec.js +684 -0
  332. package/dist/prd-to-spec.js.map +1 -0
  333. package/dist/prepare.d.ts +121 -0
  334. package/dist/prepare.d.ts.map +1 -0
  335. package/dist/prepare.js +140 -0
  336. package/dist/prepare.js.map +1 -0
  337. package/dist/prompt.d.ts +360 -0
  338. package/dist/prompt.d.ts.map +1 -0
  339. package/dist/prompt.js +499 -0
  340. package/dist/prompt.js.map +1 -0
  341. package/dist/protocol/ADR-FORMAT.md +47 -0
  342. package/dist/protocol/CLAIM-PROTOCOL.md +217 -0
  343. package/dist/protocol/REVIEW-PROTOCOL.md +119 -0
  344. package/dist/protocol/SURFACE-PROTOCOL.md +121 -0
  345. package/dist/protocol/TASKING-PROTOCOL.md +122 -0
  346. package/dist/protocol/WORK-CONTRACT.md +276 -0
  347. package/dist/protocol/spec-template.md +71 -0
  348. package/dist/protocol/task-template.md +65 -0
  349. package/dist/readiness.d.ts +66 -0
  350. package/dist/readiness.d.ts.map +1 -0
  351. package/dist/readiness.js +36 -0
  352. package/dist/readiness.js.map +1 -0
  353. package/dist/reap-branches.d.ts +102 -0
  354. package/dist/reap-branches.d.ts.map +1 -0
  355. package/dist/reap-branches.js +149 -0
  356. package/dist/reap-branches.js.map +1 -0
  357. package/dist/recover-isolated.d.ts +72 -0
  358. package/dist/recover-isolated.d.ts.map +1 -0
  359. package/dist/recover-isolated.js +188 -0
  360. package/dist/recover-isolated.js.map +1 -0
  361. package/dist/registry.d.ts +172 -0
  362. package/dist/registry.d.ts.map +1 -0
  363. package/dist/registry.js +296 -0
  364. package/dist/registry.js.map +1 -0
  365. package/dist/repo-config.d.ts +201 -0
  366. package/dist/repo-config.d.ts.map +1 -0
  367. package/dist/repo-config.js +414 -0
  368. package/dist/repo-config.js.map +1 -0
  369. package/dist/repo-key.d.ts +20 -0
  370. package/dist/repo-key.d.ts.map +1 -0
  371. package/dist/repo-key.js +68 -0
  372. package/dist/repo-key.js.map +1 -0
  373. package/dist/repo-mirror.d.ts +177 -0
  374. package/dist/repo-mirror.d.ts.map +1 -0
  375. package/dist/repo-mirror.js +271 -0
  376. package/dist/repo-mirror.js.map +1 -0
  377. package/dist/retry-backoff.d.ts +90 -0
  378. package/dist/retry-backoff.d.ts.map +1 -0
  379. package/dist/retry-backoff.js +98 -0
  380. package/dist/retry-backoff.js.map +1 -0
  381. package/dist/review-gate.d.ts +173 -0
  382. package/dist/review-gate.d.ts.map +1 -0
  383. package/dist/review-gate.js +261 -0
  384. package/dist/review-gate.js.map +1 -0
  385. package/dist/review-verdict.d.ts +149 -0
  386. package/dist/review-verdict.d.ts.map +1 -0
  387. package/dist/review-verdict.js +332 -0
  388. package/dist/review-verdict.js.map +1 -0
  389. package/dist/run.d.ts +221 -0
  390. package/dist/run.d.ts.map +1 -0
  391. package/dist/run.js +963 -0
  392. package/dist/run.js.map +1 -0
  393. package/dist/scan.d.ts +308 -0
  394. package/dist/scan.d.ts.map +1 -0
  395. package/dist/scan.js +374 -0
  396. package/dist/scan.js.map +1 -0
  397. package/dist/select-order.d.ts +75 -0
  398. package/dist/select-order.d.ts.map +1 -0
  399. package/dist/select-order.js +108 -0
  400. package/dist/select-order.js.map +1 -0
  401. package/dist/select-priority.d.ts +188 -0
  402. package/dist/select-priority.d.ts.map +1 -0
  403. package/dist/select-priority.js +80 -0
  404. package/dist/select-priority.js.map +1 -0
  405. package/dist/select.d.ts +25 -0
  406. package/dist/select.d.ts.map +1 -0
  407. package/dist/select.js +43 -0
  408. package/dist/select.js.map +1 -0
  409. package/dist/session-path.d.ts +36 -0
  410. package/dist/session-path.d.ts.map +1 -0
  411. package/dist/session-path.js +129 -0
  412. package/dist/session-path.js.map +1 -0
  413. package/dist/sidecar-apply.d.ts +83 -0
  414. package/dist/sidecar-apply.d.ts.map +1 -0
  415. package/dist/sidecar-apply.js +111 -0
  416. package/dist/sidecar-apply.js.map +1 -0
  417. package/dist/sidecar.d.ts +245 -0
  418. package/dist/sidecar.d.ts.map +1 -0
  419. package/dist/sidecar.js +481 -0
  420. package/dist/sidecar.js.map +1 -0
  421. package/dist/slug-namespace.d.ts +204 -0
  422. package/dist/slug-namespace.d.ts.map +1 -0
  423. package/dist/slug-namespace.js +229 -0
  424. package/dist/slug-namespace.js.map +1 -0
  425. package/dist/spec-complete.d.ts +44 -0
  426. package/dist/spec-complete.d.ts.map +1 -0
  427. package/dist/spec-complete.js +69 -0
  428. package/dist/spec-complete.js.map +1 -0
  429. package/dist/start.d.ts +97 -0
  430. package/dist/start.d.ts.map +1 -0
  431. package/dist/start.js +633 -0
  432. package/dist/start.js.map +1 -0
  433. package/dist/status.d.ts +199 -0
  434. package/dist/status.d.ts.map +1 -0
  435. package/dist/status.js +228 -0
  436. package/dist/status.js.map +1 -0
  437. package/dist/surface-gate.d.ts +162 -0
  438. package/dist/surface-gate.d.ts.map +1 -0
  439. package/dist/surface-gate.js +206 -0
  440. package/dist/surface-gate.js.map +1 -0
  441. package/dist/surface-persist.d.ts +86 -0
  442. package/dist/surface-persist.d.ts.map +1 -0
  443. package/dist/surface-persist.js +129 -0
  444. package/dist/surface-persist.js.map +1 -0
  445. package/dist/tasker-review-loop.d.ts +249 -0
  446. package/dist/tasker-review-loop.d.ts.map +1 -0
  447. package/dist/tasker-review-loop.js +369 -0
  448. package/dist/tasker-review-loop.js.map +1 -0
  449. package/dist/tasking-eligibility.d.ts +74 -0
  450. package/dist/tasking-eligibility.d.ts.map +1 -0
  451. package/dist/tasking-eligibility.js +52 -0
  452. package/dist/tasking-eligibility.js.map +1 -0
  453. package/dist/tasking-lock.d.ts +111 -0
  454. package/dist/tasking-lock.d.ts.map +1 -0
  455. package/dist/tasking-lock.js +256 -0
  456. package/dist/tasking-lock.js.map +1 -0
  457. package/dist/tasking.d.ts +275 -0
  458. package/dist/tasking.d.ts.map +1 -0
  459. package/dist/tasking.js +952 -0
  460. package/dist/tasking.js.map +1 -0
  461. package/dist/triage-gate.d.ts +127 -0
  462. package/dist/triage-gate.d.ts.map +1 -0
  463. package/dist/triage-gate.js +139 -0
  464. package/dist/triage-gate.js.map +1 -0
  465. package/dist/triage-persist.d.ts +163 -0
  466. package/dist/triage-persist.d.ts.map +1 -0
  467. package/dist/triage-persist.js +387 -0
  468. package/dist/triage-persist.js.map +1 -0
  469. package/dist/verdict-json.d.ts +32 -0
  470. package/dist/verdict-json.d.ts.map +1 -0
  471. package/dist/verdict-json.js +74 -0
  472. package/dist/verdict-json.js.map +1 -0
  473. package/dist/verify-workflow-template.d.ts +60 -0
  474. package/dist/verify-workflow-template.d.ts.map +1 -0
  475. package/dist/verify-workflow-template.js +126 -0
  476. package/dist/verify-workflow-template.js.map +1 -0
  477. package/dist/verify.d.ts +60 -0
  478. package/dist/verify.d.ts.map +1 -0
  479. package/dist/verify.js +62 -0
  480. package/dist/verify.js.map +1 -0
  481. package/dist/watch-session.d.ts +112 -0
  482. package/dist/watch-session.d.ts.map +1 -0
  483. package/dist/watch-session.js +347 -0
  484. package/dist/watch-session.js.map +1 -0
  485. package/dist/work-layout.d.ts +198 -0
  486. package/dist/work-layout.d.ts.map +1 -0
  487. package/dist/work-layout.js +217 -0
  488. package/dist/work-layout.js.map +1 -0
  489. package/dist/work-on.d.ts +154 -0
  490. package/dist/work-on.d.ts.map +1 -0
  491. package/dist/work-on.js +387 -0
  492. package/dist/work-on.js.map +1 -0
  493. package/dist/workspace.d.ts +224 -0
  494. package/dist/workspace.d.ts.map +1 -0
  495. package/dist/workspace.js +325 -0
  496. package/dist/workspace.js.map +1 -0
  497. package/package.json +46 -2
  498. package/src/advance-ci-template.ts +203 -0
  499. package/src/advance-classify.ts +197 -0
  500. package/src/advance-drivers.ts +414 -0
  501. package/src/advance-isolated.ts +432 -0
  502. package/src/advance-lifecycle-template.ts +791 -0
  503. package/src/advance-loop-driver.ts +745 -0
  504. package/src/advance-treeless-publish.ts +177 -0
  505. package/src/advance.ts +1564 -0
  506. package/src/advancing-lock.ts +988 -0
  507. package/src/agent-launch.ts +137 -0
  508. package/src/agent-stop.ts +361 -0
  509. package/src/apply-decide.ts +242 -0
  510. package/src/apply-merge-action.ts +502 -0
  511. package/src/apply-persist.ts +518 -0
  512. package/src/arbiter.ts +372 -0
  513. package/src/brand.ts +111 -0
  514. package/src/buildable-body.ts +196 -0
  515. package/src/categorise.ts +158 -0
  516. package/src/claim-cas.ts +513 -0
  517. package/src/cli-spinner.ts +225 -0
  518. package/src/cli.ts +4369 -0
  519. package/src/close-job-template.ts +236 -0
  520. package/src/close-job.ts +319 -0
  521. package/src/complete.ts +1379 -0
  522. package/src/concurrency.ts +151 -0
  523. package/src/config-override.ts +116 -0
  524. package/src/config.ts +883 -0
  525. package/src/continue-branch.ts +542 -0
  526. package/src/cwd-section.ts +392 -0
  527. package/src/decision-engine.ts +272 -0
  528. package/src/detect.ts +124 -0
  529. package/src/do-autopick.ts +223 -0
  530. package/src/do-config.ts +589 -0
  531. package/src/do-remote-auto.ts +197 -0
  532. package/src/do.ts +2623 -0
  533. package/src/drop-source.ts +194 -0
  534. package/src/eligibility.ts +79 -0
  535. package/src/env-config.ts +305 -0
  536. package/src/failure-cause.ts +142 -0
  537. package/src/format.ts +313 -0
  538. package/src/frontmatter.ts +485 -0
  539. package/src/gate-readiness.ts +147 -0
  540. package/src/gc.ts +510 -0
  541. package/src/gh-failure.ts +53 -0
  542. package/src/git.ts +186 -0
  543. package/src/github.ts +468 -0
  544. package/src/harness.ts +355 -0
  545. package/src/identity.ts +322 -0
  546. package/src/index.ts +785 -0
  547. package/src/install-ci-branch-protection.ts +255 -0
  548. package/src/install-ci-capabilities/advance-lifecycle.ts +34 -0
  549. package/src/install-ci-capabilities/close-job.ts +32 -0
  550. package/src/install-ci-capabilities/example-noop.ts +24 -0
  551. package/src/install-ci-capabilities/intake.ts +34 -0
  552. package/src/install-ci-capabilities/verify.ts +33 -0
  553. package/src/install-ci-core.ts +1088 -0
  554. package/src/install-ci-github.ts +376 -0
  555. package/src/install-ci.ts +552 -0
  556. package/src/intake-event.ts +102 -0
  557. package/src/intake-marker.ts +195 -0
  558. package/src/intake-triage.ts +138 -0
  559. package/src/intake-trigger-template.ts +591 -0
  560. package/src/intake.ts +2445 -0
  561. package/src/integration-core.ts +3065 -0
  562. package/src/integrator.ts +771 -0
  563. package/src/isolation.ts +484 -0
  564. package/src/issue-provider.ts +733 -0
  565. package/src/item-lock.ts +1858 -0
  566. package/src/item-path.ts +75 -0
  567. package/src/ledger-lint.ts +332 -0
  568. package/src/ledger-read.ts +924 -0
  569. package/src/ledger-write.ts +865 -0
  570. package/src/lifecycle-gather.ts +298 -0
  571. package/src/lifecycle-pools.ts +250 -0
  572. package/src/merge-question-surfacer.ts +496 -0
  573. package/src/mint-adr.ts +362 -0
  574. package/src/mirror-pool-scan.ts +240 -0
  575. package/src/needs-attention.ts +1506 -0
  576. package/src/orphan-sidecar.ts +150 -0
  577. package/src/output.ts +89 -0
  578. package/src/pi-harness.ts +403 -0
  579. package/src/placement.ts +131 -0
  580. package/src/prd-to-spec.ts +1023 -0
  581. package/src/prepare.ts +230 -0
  582. package/src/prompt.ts +760 -0
  583. package/src/readiness.ts +98 -0
  584. package/src/reap-branches.ts +278 -0
  585. package/src/recover-isolated.ts +276 -0
  586. package/src/registry.ts +475 -0
  587. package/src/repo-config.ts +550 -0
  588. package/src/repo-key.ts +74 -0
  589. package/src/repo-mirror.ts +367 -0
  590. package/src/retry-backoff.ts +130 -0
  591. package/src/review-gate.ts +389 -0
  592. package/src/review-verdict.ts +422 -0
  593. package/src/run.ts +1430 -0
  594. package/src/scan.ts +611 -0
  595. package/src/select-order.ts +143 -0
  596. package/src/select-priority.ts +266 -0
  597. package/src/select.ts +62 -0
  598. package/src/session-path.ts +153 -0
  599. package/src/sidecar-apply.ts +216 -0
  600. package/src/sidecar.ts +700 -0
  601. package/src/slug-namespace.ts +367 -0
  602. package/src/spec-complete.ts +118 -0
  603. package/src/start.ts +974 -0
  604. package/src/status.ts +441 -0
  605. package/src/surface-gate.ts +337 -0
  606. package/src/surface-persist.ts +241 -0
  607. package/src/tasker-review-loop.ts +671 -0
  608. package/src/tasking-eligibility.ts +114 -0
  609. package/src/tasking-lock.ts +416 -0
  610. package/src/tasking.ts +1438 -0
  611. package/src/triage-gate.ts +248 -0
  612. package/src/triage-persist.ts +570 -0
  613. package/src/verdict-json.ts +73 -0
  614. package/src/verify-workflow-template.ts +159 -0
  615. package/src/verify.ts +123 -0
  616. package/src/watch-session.ts +397 -0
  617. package/src/work-layout.ts +262 -0
  618. package/src/work-on.ts +660 -0
  619. package/src/workspace.ts +502 -0
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Pure categorisation of backlog items into the "who can take it" groups used by
3
+ * the human decision dashboard. Grouping is deliberately INDEPENDENT of the
4
+ * repo's `autoBuild` policy: a human always sees the full picture, and the
5
+ * policy only changes the eligibility *verdict* / summary counts elsewhere —
6
+ * never which group an item lands in.
7
+ */
8
+
9
+ import type {ScannedItem} from './scan.js';
10
+
11
+ /**
12
+ * Which group an item belongs to, derived from its two autonomy axes
13
+ * (`humanOnly`, `needsAnswers`) and its dependency readiness (NOT the runner's
14
+ * `autoBuild` policy):
15
+ * - `agent-claimable` — neither axis gated AND deps satisfied: an agent can
16
+ * claim it now (provided this repo's `autoBuild` policy is on).
17
+ * - `human-only` — `humanOnly: true`: a human decides/builds it; an agent never
18
+ * claims it, regardless of policy or deps.
19
+ * - `needs-answers` — not `humanOnly` but `needsAnswers: true`: open questions
20
+ * block autonomous work until they are answered (the questions live in the
21
+ * body); an agent never claims it.
22
+ * - `blocked` — neither axis gated but deps unsatisfied: would be
23
+ * agent-claimable once its blockers reach `work/done/`.
24
+ *
25
+ * `humanOnly` takes precedence over `needsAnswers` for display grouping (a single
26
+ * group per item), but BOTH gate the agent identically in `eligibility`.
27
+ */
28
+ export type Category =
29
+ | 'agent-claimable'
30
+ | 'human-only'
31
+ | 'needs-answers'
32
+ | 'blocked';
33
+
34
+ /** Stable display order for the four groups. */
35
+ export const CATEGORY_ORDER: Category[] = [
36
+ 'agent-claimable',
37
+ 'human-only',
38
+ 'needs-answers',
39
+ 'blocked',
40
+ ];
41
+
42
+ /** Human-facing section headings for each group. */
43
+ export const CATEGORY_LABELS: Record<Category, string> = {
44
+ 'agent-claimable':
45
+ 'Agent-claimable now (not human-only, no open questions, deps satisfied; needs --auto-build)',
46
+ 'human-only': 'Human-only (humanOnly: true — a human decides/builds)',
47
+ 'needs-answers':
48
+ 'Needs answers (needsAnswers: true — open questions block autonomous work)',
49
+ blocked: 'Blocked (not gated, waiting on deps)',
50
+ };
51
+
52
+ /** A scanned item, classified for the dashboard. */
53
+ export interface CategorisedItem {
54
+ item: ScannedItem;
55
+ category: Category;
56
+ /** Whether its `blockedBy` deps are all satisfied (ready to be picked up). */
57
+ ready: boolean;
58
+ }
59
+
60
+ /**
61
+ * Map an item's autonomy axes (`humanOnly`, `needsAnswers`) + dependency
62
+ * readiness to its dashboard category. Policy-independent by design: the
63
+ * category reflects what the author declared and whether its deps are met, not
64
+ * the runner's `autoBuild` policy. `humanOnly` is shown before `needsAnswers`
65
+ * when both are set, so the REASON is always visible.
66
+ */
67
+ export function categoriseItem(item: ScannedItem): CategorisedItem {
68
+ const ready = item.eligibility.blockedBy.satisfied;
69
+ let category: Category;
70
+ if (item.humanOnly === true) {
71
+ category = 'human-only';
72
+ } else if (item.needsAnswers === true) {
73
+ category = 'needs-answers';
74
+ } else if (ready) {
75
+ category = 'agent-claimable';
76
+ } else {
77
+ category = 'blocked';
78
+ }
79
+ return {item, category, ready};
80
+ }
81
+
82
+ /** The items of one repo, bucketed by category and sorted ready-first. */
83
+ export type CategorisedGroups = Record<Category, CategorisedItem[]>;
84
+
85
+ function emptyGroups(): CategorisedGroups {
86
+ return {
87
+ 'agent-claimable': [],
88
+ 'human-only': [],
89
+ 'needs-answers': [],
90
+ blocked: [],
91
+ };
92
+ }
93
+
94
+ /**
95
+ * Bucket a repo's scanned items into the three groups. Within each group, ready
96
+ * (deps-satisfied) items sort above blocked ones; ties keep the incoming order
97
+ * (the scan core already sorts items by slug), so the result is deterministic.
98
+ */
99
+ export function categoriseItems(items: ScannedItem[]): CategorisedGroups {
100
+ const groups = emptyGroups();
101
+ for (const item of items) {
102
+ const categorised = categoriseItem(item);
103
+ groups[categorised.category].push(categorised);
104
+ }
105
+ for (const category of CATEGORY_ORDER) {
106
+ groups[category] = sortReadyFirst(groups[category]);
107
+ }
108
+ return groups;
109
+ }
110
+
111
+ /** Stable sort placing ready items before blocked ones, preserving order otherwise. */
112
+ export function sortReadyFirst(items: CategorisedItem[]): CategorisedItem[] {
113
+ return items
114
+ .map((value, index) => ({value, index}))
115
+ .sort((a, b) => {
116
+ if (a.value.ready !== b.value.ready) {
117
+ return a.value.ready ? -1 : 1;
118
+ }
119
+ return a.index - b.index;
120
+ })
121
+ .map((entry) => entry.value);
122
+ }
123
+
124
+ /** Per-category and readiness tallies for the dashboard summary. */
125
+ export interface CategorySummary {
126
+ agentClaimable: number;
127
+ humanOnly: number;
128
+ needsAnswers: number;
129
+ blocked: number;
130
+ ready: number;
131
+ }
132
+
133
+ /** Aggregate counts across every repo's groups for the summary line. */
134
+ export function summariseGroups(
135
+ allGroups: CategorisedGroups[],
136
+ ): CategorySummary {
137
+ const summary: CategorySummary = {
138
+ agentClaimable: 0,
139
+ humanOnly: 0,
140
+ needsAnswers: 0,
141
+ blocked: 0,
142
+ ready: 0,
143
+ };
144
+ for (const groups of allGroups) {
145
+ summary.agentClaimable += groups['agent-claimable'].length;
146
+ summary.humanOnly += groups['human-only'].length;
147
+ summary.needsAnswers += groups['needs-answers'].length;
148
+ summary.blocked += groups['blocked'].length;
149
+ for (const category of CATEGORY_ORDER) {
150
+ for (const entry of groups[category]) {
151
+ if (entry.ready) {
152
+ summary.ready++;
153
+ }
154
+ }
155
+ }
156
+ }
157
+ return summary;
158
+ }
@@ -0,0 +1,513 @@
1
+ import {runAsync, type RunResult} from './git.js';
2
+ import {acquireItemLock, releaseItemLock, heldTaskSlugs} from './item-lock.js';
3
+ import {extractPromptSection} from './prompt.js';
4
+ import {resolveReadiness} from './readiness.js';
5
+ import {workBranchRef} from './slug-namespace.js';
6
+ import {workItemRel} from './work-layout.js';
7
+
8
+ /**
9
+ * In-process TypeScript implementation of the atomic compare-and-swap claim from
10
+ * `scripts/CLAIM-PROTOCOL.md`. This is the first-class `dorfl claim`
11
+ * command (ADR §9: dorfl is the PRIMARY implementation of the claim
12
+ * protocol; `scripts/claim.sh` is retained as the portable, zero-dependency
13
+ * bootstrap / reference). The lock-substrate cut-over (prd
14
+ * `ledger-status-per-item-lock-refs`) has since diverged it from `claim.sh`'s
15
+ * body-move semantics — see the lock note below — but the exit codes are the same.
16
+ *
17
+ * It is async (each git call is a non-blocking `runAsync`) so two awaited claims
18
+ * over the same slug genuinely race — the arbiter's per-item-ref CAS (not test
19
+ * ordering) picks the single winner.
20
+ *
21
+ * Exit codes:
22
+ * 0 claim landed (the per-item lock is held; the body stays where it rested:
23
+ * `tasks/ready/` normally, or `tasks/backlog/` under --allow-backlog)
24
+ * 1 usage / environment error, or a readiness REFUSAL (unmet blockedBy)
25
+ * 2 item not claimable (not in backlog, or lost the lock race to someone else)
26
+ * 3 (legacy) push contention — no longer reachable: the per-item lock never
27
+ * falsely contends, so there is no retry budget to exhaust
28
+ *
29
+ * UNIFIED PER-ITEM LOCK (prd `ledger-status-per-item-lock-refs` US #1/#15/#16,
30
+ * ADR `ledger-status-on-per-item-lock-refs`): a claim ACQUIRES the item's
31
+ * per-item lock (`action: implement`) via the lock module and writes NOTHING to
32
+ * `main` — the body STAYS at `work/backlog/<slug>.md`. The claimable predicate is
33
+ * "in `backlog/` on `main` AND no lock held"; the held lock IS the claim. The lock
34
+ * is acquired FIRST, so a lock `lost` (the SAME item is already locked) makes the
35
+ * claim lose definitively (exit 2, NO retry budget). A subsequent claimability
36
+ * re-check (the body left `backlog/`) RELEASES the lock (never orphaned). Because
37
+ * claim touches no `main` (and no protected ref), a protected-`main` repo CAN be
38
+ * claimed. The interim dual-write (`git mv backlog→in-progress` + a `main` claim
39
+ * commit) is GONE.
40
+ *
41
+ * Before the claim runs, the HUMAN path's readiness guard (resolveReadiness) is
42
+ * applied: a task with an unmet `blockedBy` is REFUSED (exit 1, outcome
43
+ * 'not-ready') unless overridden; a `needsAnswers: true` task is WARNED about
44
+ * but still claimed. The autonomous runner does NOT pass `humanPath`, so its
45
+ * behaviour is unchanged (eligibility already filters those items upstream).
46
+ */
47
+
48
+ /** Maps onto the four claim.sh exit codes. */
49
+ export type ClaimExitCode = 0 | 1 | 2 | 3;
50
+
51
+ /** A semantic label for each exit code (for callers/tests, never the verdict). */
52
+ export type ClaimCasOutcome =
53
+ | 'claimed'
54
+ | 'usage-error'
55
+ | 'lost'
56
+ | 'contended'
57
+ | 'not-ready';
58
+
59
+ export interface ClaimCasOptions {
60
+ /** The slug to claim (`work/backlog/<slug>.md`). */
61
+ slug: string;
62
+ /** Working clone/worktree the claim runs in. */
63
+ cwd: string;
64
+ /** Name of the arbiter remote (`--arbiter`). Defaults to `origin`. */
65
+ arbiter?: string;
66
+ /**
67
+ * (LEGACY, accepted-but-ignored) Cap on push retries when main merely advanced.
68
+ * The per-item lock never falsely contends (a per-item ref CAS is self-arbitrating),
69
+ * so there is no retry loop and nothing to bound. Kept on the option shape so
70
+ * existing callers/tests that pass `--retries` keep type-checking; it has NO effect.
71
+ */
72
+ retries?: number;
73
+ /** Show the intended push without mutating the arbiter (`--dry-run`). */
74
+ dryRun?: boolean;
75
+ /**
76
+ * Apply the human-path readiness guard before the CAS: refuse an unmet
77
+ * `blockedBy`, warn on `needsAnswers`. The HUMAN `claim`/`start` path sets
78
+ * this; the autonomous runner leaves it off (it filters upstream via
79
+ * eligibility and must NOT change behaviour here).
80
+ */
81
+ humanPath?: boolean;
82
+ /**
83
+ * Override flag (`--force` / `--ignore-not-ready`): bypass the readiness
84
+ * refusal and silence the `needsAnswers` warning, printing a loud notice that
85
+ * the guard was overridden. Only meaningful with `humanPath`.
86
+ */
87
+ override?: boolean;
88
+ /**
89
+ * `--allow-backlog` (prd
90
+ * `do-allow-backlog-drive-staged-tasks-without-promotion`): WIDEN the claimable
91
+ * predicate to ALSO accept a `tasks/backlog/`-resident body (staging), so a
92
+ * human can drive a staged task in place WITHOUT promoting it to the pool. The
93
+ * claim STAYS a pure per-item-lock acquire \u2014 it writes NOTHING to `main` and
94
+ * does NOT `git mv` the body (the body stays in `tasks/backlog/`). Competitor
95
+ * exclusion is the HELD LOCK (the pool scan subtracts held slugs folder-
96
+ * agnostically), not the folder, so no move is needed. Default off \u21d2 the
97
+ * predicate is "in `tasks/ready/` on `main` AND no lock held" exactly as today;
98
+ * reachable ONLY via the explicit flag, never `run`/auto-pick/advance.
99
+ */
100
+ allowBacklog?: boolean;
101
+ /** Environment for child git processes (identity etc.). */
102
+ env?: NodeJS.ProcessEnv;
103
+ /** Sink for human-readable progress notes (claim.sh writes these to stderr). */
104
+ note?: (message: string) => void;
105
+ }
106
+
107
+ export interface ClaimCasResult {
108
+ exitCode: ClaimExitCode;
109
+ outcome: ClaimCasOutcome;
110
+ /** Human-readable summary of the terminal condition. */
111
+ message: string;
112
+ /**
113
+ * (RETAINED for the option shape; now ALWAYS absent.) Historically the sha of
114
+ * the CLAIM COMMIT that landed on `main`, used by in-place onboarding to branch
115
+ * the work branch off the exact claim commit. The lock-substrate claim writes
116
+ * NOTHING to `main` (the body stays where it rested — `tasks/ready/` normally,
117
+ * or `tasks/backlog/` under --allow-backlog), so there is no claim
118
+ * commit — onboarding cuts the work branch straight off `<arbiter>/main` (which
119
+ * carries the backlog body). Kept on the result shape so existing readers
120
+ * (`do.ts` threads `claim.claimCommit` into onboarding) keep type-checking; an
121
+ * `undefined` value drives onboarding's fresh-off-`<arbiter>/main` branch path.
122
+ */
123
+ claimCommit?: string;
124
+ }
125
+
126
+ /**
127
+ * The "lost" diagnostic for a held-lock loss, reused so its message carries the
128
+ * recovery hints a human re-running their OWN item needs. The body now STAYS in
129
+ * `work/backlog/` (claim never moves it), so a held item is identified by its LOCK
130
+ * (`action: implement` held on the per-item ref), not an `in-progress/` folder: a
131
+ * held lock + the body still in `backlog/` is the normal claimed state. We fetch
132
+ * the lock refs and, when the slug's lock is held, surface the resume/requeue
133
+ * recovery hints; otherwise (the body left `backlog/` entirely — done/removed) we
134
+ * fall back to the generic message.
135
+ */
136
+ async function lostMessage(
137
+ slug: string,
138
+ arbiter: string,
139
+ cwd: string,
140
+ env: NodeJS.ProcessEnv | undefined,
141
+ fallback: string,
142
+ ): Promise<string> {
143
+ const held = await heldTaskSlugs(cwd, arbiter, env);
144
+ if (held.has(slug)) {
145
+ return `'${slug}' is already claimed on ${arbiter}/main (its per-item lock is held). If someone else claimed it, pick another item; if it's your own (e.g. an interrupted run), continue it with \`dorfl resume ${slug}\` (or \`work-on\`), or recover via \`requeue\`.`;
146
+ }
147
+ return fallback;
148
+ }
149
+
150
+ /** Raised for usage/environment errors (exit 1). */
151
+ class ClaimUsageError extends Error {}
152
+
153
+ /**
154
+ * Raised for a deliberate readiness REFUSAL (exit 1, outcome 'not-ready') —
155
+ * distinct from a usage/environment error. The task has an unmet `blockedBy`
156
+ * and the override was not supplied, so nothing is claimed.
157
+ */
158
+ class ClaimNotReady extends Error {}
159
+
160
+ const DEFAULT_ARBITER = 'origin';
161
+
162
+ /**
163
+ * Perform the claim CAS. Never throws for the expected "lost the race" or
164
+ * "contended" cases — those are returned as exit 2 / 3. Usage/environment
165
+ * problems surface as exit 1. A successful claim is exit 0. This mirrors
166
+ * claim.sh's control flow exactly (refuse dirty tree → loop attempts → on
167
+ * rejection refetch & decide lost-vs-advanced → cap retries → back off).
168
+ */
169
+ export async function performClaim(
170
+ options: ClaimCasOptions,
171
+ ): Promise<ClaimCasResult> {
172
+ const note = options.note ?? (() => {});
173
+ try {
174
+ return await runClaim(options, note);
175
+ } catch (err) {
176
+ if (err instanceof ClaimNotReady) {
177
+ return {exitCode: 1, outcome: 'not-ready', message: err.message};
178
+ }
179
+ if (err instanceof ClaimUsageError) {
180
+ return {exitCode: 1, outcome: 'usage-error', message: err.message};
181
+ }
182
+ // Any other unexpected failure is an environment error (exit 1), never a
183
+ // false "claimed". claim.sh treats unexpected rc the same way (die → 1).
184
+ const message = err instanceof Error ? err.message : String(err);
185
+ return {exitCode: 1, outcome: 'usage-error', message};
186
+ }
187
+ }
188
+
189
+ async function runClaim(
190
+ options: ClaimCasOptions,
191
+ note: (m: string) => void,
192
+ ): Promise<ClaimCasResult> {
193
+ const slug = options.slug;
194
+ const arbiter = options.arbiter ?? DEFAULT_ARBITER;
195
+ const dryRun = options.dryRun ?? false;
196
+ const cwd = options.cwd;
197
+ const env = options.env;
198
+
199
+ if (!slug) {
200
+ throw new ClaimUsageError(
201
+ 'missing <slug>. usage: dorfl claim <slug> [--arbiter remote]',
202
+ );
203
+ }
204
+ if ((await gitSoft(['rev-parse', '--git-dir'], cwd, env)).status !== 0) {
205
+ throw new ClaimUsageError('not inside a git repository');
206
+ }
207
+ if ((await gitSoft(['remote', 'get-url', arbiter], cwd, env)).status !== 0) {
208
+ throw new ClaimUsageError(
209
+ `no git remote named '${arbiter}' (set one, or pass --arbiter)`,
210
+ );
211
+ }
212
+
213
+ // Refuse to run with a dirty tree — the claim must be a clean, isolated commit.
214
+ const dirtyWorktree =
215
+ (await gitSoft(['diff', '--quiet'], cwd, env)).status !== 0;
216
+ const dirtyIndex =
217
+ (await gitSoft(['diff', '--cached', '--quiet'], cwd, env)).status !== 0;
218
+ if (dirtyWorktree || dirtyIndex) {
219
+ throw new ClaimUsageError(
220
+ 'working tree has uncommitted changes; commit/stash them before claiming',
221
+ );
222
+ }
223
+
224
+ // HUMAN-path readiness guard (run BEFORE the CAS so a not-ready task is never
225
+ // claimed). Reads the task frontmatter + `work/done/` from `<arbiter>/main`
226
+ // (the same source of truth the folder check uses) and resolves `blockedBy`
227
+ // via the shared resolveBlockedBy. Skipped entirely for the autonomous runner
228
+ // (no `humanPath`), whose eligibility filter already handles these upstream.
229
+ if (options.humanPath) {
230
+ await gitHard(['fetch', '--quiet', arbiter], cwd, env);
231
+ const readiness = await resolveReadiness({
232
+ slug,
233
+ cwd,
234
+ arbiter,
235
+ override: options.override === true,
236
+ env,
237
+ });
238
+ if (readiness.refuse) {
239
+ const missing = readiness.missing.join(', ');
240
+ const message =
241
+ `'${slug}' is not ready: blocked by unmet dependencies not yet in ` +
242
+ `work/done/ on ${arbiter}/main: ${missing}. ` +
243
+ 'Re-run with --force (or --ignore-not-ready) to claim it anyway.';
244
+ note(message);
245
+ throw new ClaimNotReady(message);
246
+ }
247
+ if (readiness.overridden && readiness.missing.length > 0) {
248
+ note(
249
+ `!! readiness guard OVERRIDDEN: claiming '${slug}' despite unmet ` +
250
+ `blockedBy: ${readiness.missing.join(', ')} (not yet in work/done/).`,
251
+ );
252
+ }
253
+ if (readiness.needsAnswers && !readiness.overridden) {
254
+ note(
255
+ `!! WARNING: '${slug}' is flagged needsAnswers: true — it has open ` +
256
+ 'questions (see the task body). Claiming it anyway (human path); ' +
257
+ 'resolve the questions before/while building.',
258
+ );
259
+ } else if (readiness.needsAnswers && readiness.overridden) {
260
+ note(
261
+ `!! readiness guard OVERRIDDEN: silencing the needsAnswers warning for '${slug}'.`,
262
+ );
263
+ }
264
+ }
265
+
266
+ const backlog = workItemRel('tasks-ready', `${slug}.md`);
267
+ const staged = workItemRel('tasks-backlog', `${slug}.md`);
268
+ const branch = workBranchRef('task', slug);
269
+
270
+ /**
271
+ * The CLAIMABLE-RESIDENCE half of the predicate: the body rests in the pool
272
+ * (`tasks/ready/`) on `<arbiter>/main`, OR \u2014 under `--allow-backlog` \u2014 in
273
+ * `tasks/backlog/` (staging). The held-lock half is the create-only acquire.
274
+ * Folder-agnostic exclusion is the lock, never the folder, so a staged body is
275
+ * a legitimate claimable residence under the flag; otherwise staging is invisible.
276
+ */
277
+ async function claimableBodyRel(): Promise<string | undefined> {
278
+ if (await catFileExists(`${arbiter}/main:${backlog}`, cwd, env)) {
279
+ return backlog;
280
+ }
281
+ if (
282
+ options.allowBacklog === true &&
283
+ (await catFileExists(`${arbiter}/main:${staged}`, cwd, env))
284
+ ) {
285
+ return staged;
286
+ }
287
+ return undefined;
288
+ }
289
+ async function bodyRestsClaimable(): Promise<boolean> {
290
+ return (await claimableBodyRel()) !== undefined;
291
+ }
292
+
293
+ /**
294
+ * The human-facing folder label for a resolved claimable body path (`work/<dir>`,
295
+ * e.g. `work/tasks/ready` or `work/tasks/backlog`). Derived from the ACTUAL
296
+ * resolved residence so the claim message never hard-codes the wrong folder.
297
+ */
298
+ function residenceFolder(bodyRel: string): string {
299
+ const dir = bodyRel.slice(0, bodyRel.lastIndexOf('/'));
300
+ return dir === '' ? bodyRel : dir;
301
+ }
302
+
303
+ /**
304
+ * PRE-CLAIM WELL-FORMEDNESS GUARD (this task's interim guard against the
305
+ * promptless-promoted-task strand). The validator `resolveTask` /
306
+ * `extractPromptSection` (`prompt.ts`) requires a task body to carry a
307
+ * `## Prompt` section; it runs at DISPATCH (`do.ts` step 5), AFTER the claim,
308
+ * so a body missing `## Prompt` was caught only post-claim — the failure routed
309
+ * to `saveAgentFailure`, which left the lock `state: stuck`. We run the SAME
310
+ * validator (`extractPromptSection`, the single source of truth for "what makes
311
+ * a task dispatchable") HERE, BEFORE the lock is acquired, so a malformed body
312
+ * from ANY source (promotion, hand-authored, externally edited) is refused with a
313
+ * clean usage error and NO lock is taken. `bodyRel` is the resolved claimable
314
+ * residence (`tasks/ready/` or, under the flag, `tasks/backlog/`). A genuinely
315
+ * absent body is NOT this guard's concern (the claimability check returns `lost`
316
+ * separately) — this only fires when a body that DOES rest claimable lacks a
317
+ * `## Prompt`.
318
+ */
319
+ async function assertBodyWellFormed(bodyRel: string): Promise<void> {
320
+ const show = await gitSoft(
321
+ ['show', `${arbiter}/main:${bodyRel}`],
322
+ cwd,
323
+ env,
324
+ );
325
+ if (show.status !== 0) {
326
+ // The body vanished between the residence check and this read — leave it to
327
+ // the claimability path to report `lost`; do not synthesise a guard error.
328
+ return;
329
+ }
330
+ if (extractPromptSection(show.stdout) === undefined) {
331
+ throw new ClaimUsageError(
332
+ `'${slug}' (${bodyRel}) has no '## Prompt' section, so it is not ` +
333
+ 'dispatchable — add a `## Prompt` section to the task body before ' +
334
+ 'claiming it. NO lock was acquired.',
335
+ );
336
+ }
337
+ }
338
+
339
+ // UNIFIED PER-ITEM LOCK — the WHOLE of the claim now (prd
340
+ // `ledger-status-per-item-lock-refs` US #1/#15/#16; ADR
341
+ // `ledger-status-on-per-item-lock-refs`). The interim dual-write is GONE: claim
342
+ // acquires the item's per-item lock (`action: implement`) and writes NOTHING to
343
+ // `main` — the body STAYS at `work/backlog/<slug>.md`, the claimable predicate is
344
+ // "in `backlog/` on `main` AND no lock held", and the held lock IS the claim. So
345
+ // a protected-`main` repo can be claimed (claim touches no protected ref).
346
+ //
347
+ // A dry-run takes no lock (it mutates nothing) and just reports it WOULD claim.
348
+ /** The not-found diagnostic, naming the pool (and staging under the flag). */
349
+ const notFoundFallback =
350
+ options.allowBacklog === true
351
+ ? `neither '${backlog}' nor '${staged}' found on ${arbiter}/main (already done/removed, or wrong slug).`
352
+ : `'${backlog}' not found on ${arbiter}/main (already done/removed, or wrong slug).`;
353
+
354
+ if (dryRun) {
355
+ await gitHard(['fetch', '--quiet', arbiter], cwd, env);
356
+ const bodyRel = await claimableBodyRel();
357
+ if (bodyRel === undefined) {
358
+ const message = await lostMessage(
359
+ slug,
360
+ arbiter,
361
+ cwd,
362
+ env,
363
+ notFoundFallback,
364
+ );
365
+ note(message);
366
+ return {exitCode: 2, outcome: 'lost', message};
367
+ }
368
+ // A dry-run still runs the pre-claim well-formedness guard so it reports a
369
+ // promptless body as a usage error rather than "would claim" it.
370
+ await assertBodyWellFormed(bodyRel);
371
+ const message = `DRY-RUN: would acquire the per-item lock for '${slug}' (body stays in ${residenceFolder(bodyRel)}/).`;
372
+ note(message);
373
+ return {exitCode: 0, outcome: 'claimed', message};
374
+ }
375
+
376
+ // PRE-CLAIM WELL-FORMEDNESS GUARD: fetch + read the claimable body and refuse a
377
+ // task missing its `## Prompt` BEFORE the lock is acquired (so a malformed body
378
+ // never strands a `state: stuck` lock at dispatch). A genuinely absent body is
379
+ // left to the post-lock claimability re-check to report as `lost`; this guard
380
+ // only fires for a body that DOES rest claimable but is not dispatchable.
381
+ await gitHard(['fetch', '--quiet', arbiter], cwd, env);
382
+ {
383
+ const bodyRel = await claimableBodyRel();
384
+ if (bodyRel !== undefined) {
385
+ await assertBodyWellFormed(bodyRel);
386
+ }
387
+ }
388
+
389
+ // Acquire the lock FIRST. A lock `lost` (someone already holds this SAME item's
390
+ // lock) makes claim lose DEFINITIVELY — exit 2, NO retry budget (a per-item ref
391
+ // never falsely contends, so a rejection is a GENUINE same-item conflict the
392
+ // loser should lose). We do NOT try to tell "our own orphaned lock" apart by
393
+ // holder identity and auto-reclaim it: holder ids are NOT unique (a CI bot claims
394
+ // many items under one `user.name`), so a release+re-acquire "reclaim" could let a
395
+ // concurrent LOSER release the WINNER's still-valid lock — and an automatic sweep
396
+ // contradicts the ADR's recovery model (`ledger-status-on-per-item-lock-refs`:
397
+ // "no liveness heartbeat, no auto-sweep; a human asserts a lock is dead"). A
398
+ // genuinely orphaned lock is cleared by the human-mediated `release-lock` verb +
399
+ // `gc --ledger` report, never an auto-steal at claim time.
400
+ const lock = await acquireItemLock({
401
+ item: `task:${slug}`,
402
+ action: 'implement',
403
+ cwd,
404
+ arbiter,
405
+ env,
406
+ });
407
+ if (lock.outcome === 'error') {
408
+ // Environment/usage problem acquiring the lock — surface as exit 1, never a
409
+ // false claim. Nothing was acquired.
410
+ throw new ClaimUsageError(
411
+ `failed to acquire the item lock for '${slug}': ${lock.message}`,
412
+ );
413
+ }
414
+ if (lock.outcome === 'lost') {
415
+ const message = await lostMessage(slug, arbiter, cwd, env, lock.message);
416
+ note(message);
417
+ return {exitCode: 2, outcome: 'lost', message};
418
+ }
419
+
420
+ /** Release the lock we just acquired (best-effort) — used when the claimability
421
+ * re-check finds the item is no longer in the pool, so the lock is never
422
+ * orphaned (the body never moved, so the item is cleanly returned to the pool). */
423
+ async function releaseHeldLock(): Promise<void> {
424
+ await releaseItemLock({item: `task:${slug}`, cwd, arbiter, env});
425
+ }
426
+
427
+ // The RESOLVED claimable residence (`tasks/ready/` or, under `--allow-backlog`,
428
+ // `tasks/backlog/`), captured by the post-lock claimability re-check below so the
429
+ // success message reports the real folder rather than a hard-coded guess.
430
+ let claimedBodyRel: string | undefined;
431
+
432
+ try {
433
+ // CLAIMABLE PREDICATE (US #15): "in `tasks/ready/` (the pool) on `main` AND no
434
+ // lock held" \u2014 widened under `--allow-backlog` to ALSO accept a
435
+ // `tasks/backlog/`-resident body (staging), so a human can drive a staged task
436
+ // in place. The HELD-LOCK half is the create-only acquire above (a held slug
437
+ // already lost the race). Confirm the residence here \u2014 the body STAYS where it
438
+ // rested (claim moves nothing, even under the flag), so a `done`/absent item is
439
+ // not claimable: release the lock we just took (it never protected any in-flight
440
+ // work) and lose (exit 2).
441
+ await gitHard(['fetch', '--quiet', arbiter], cwd, env);
442
+ claimedBodyRel = await claimableBodyRel();
443
+ if (claimedBodyRel === undefined) {
444
+ await releaseHeldLock();
445
+ const message = await lostMessage(
446
+ slug,
447
+ arbiter,
448
+ cwd,
449
+ env,
450
+ notFoundFallback,
451
+ );
452
+ note(message);
453
+ return {exitCode: 2, outcome: 'lost', message};
454
+ }
455
+ } catch (err) {
456
+ // A plumbing failure after we took the lock: release it so the held lock does
457
+ // not orphan an item that never started, then re-throw for the top-level
458
+ // handler to classify (exit 1).
459
+ await releaseHeldLock();
460
+ throw err;
461
+ }
462
+
463
+ // CLAIMED. The body rests where it was claimed from (`tasks/ready/` normally, or
464
+ // `tasks/backlog/` under `--allow-backlog`) on `<arbiter>/main` and the lock is
465
+ // held. There is NO claim commit and nothing on `main` to branch from —
466
+ // onboarding cuts the work branch straight off `<arbiter>/main` (which carries the
467
+ // body). The folder is the RESOLVED residence, not a hard-coded guess: a `ready/`
468
+ // claim must not falsely report `backlog/` (it misled a whole CI-incident triage).
469
+ // `claimedBodyRel` is always set here (the claimability re-check above returns
470
+ // `lost` otherwise); fall back to the pool residence (`backlog` IS the
471
+ // `tasks-ready` path constant) for type-safety — derived via the layout helper,
472
+ // never a raw `work/<folder>` literal (the work-layout guard).
473
+ const residence = residenceFolder(claimedBodyRel ?? backlog);
474
+ const message = `CLAIMED '${slug}' (lock held; body stays in ${residence}/ on ${arbiter}/main).`;
475
+ note(message);
476
+ note(
477
+ `Start work: git fetch ${arbiter} && git switch -C ${branch} ${arbiter}/main`,
478
+ );
479
+ return {exitCode: 0, outcome: 'claimed', message};
480
+ }
481
+
482
+ /** `git cat-file -e <object>` — true iff the object exists. */
483
+ async function catFileExists(
484
+ object: string,
485
+ cwd: string,
486
+ env: NodeJS.ProcessEnv | undefined,
487
+ ): Promise<boolean> {
488
+ return (await gitSoft(['cat-file', '-e', object], cwd, env)).status === 0;
489
+ }
490
+
491
+ /** Run git, returning the raw result (no throw) — for soft checks. */
492
+ function gitSoft(
493
+ args: string[],
494
+ cwd: string,
495
+ env: NodeJS.ProcessEnv | undefined,
496
+ ): Promise<RunResult> {
497
+ return runAsync('git', args, cwd, {env});
498
+ }
499
+
500
+ /** Run git; throw on non-zero (genuinely unexpected plumbing failures). */
501
+ async function gitHard(
502
+ args: string[],
503
+ cwd: string,
504
+ env: NodeJS.ProcessEnv | undefined,
505
+ ): Promise<RunResult> {
506
+ const result = await runAsync('git', args, cwd, {env});
507
+ if (result.status !== 0) {
508
+ throw new Error(
509
+ `git ${args.join(' ')} failed (exit ${result.status}): ${result.stderr.trim()}`,
510
+ );
511
+ }
512
+ return result;
513
+ }