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
@@ -2,6 +2,7 @@ import {readFileSync, existsSync} from 'node:fs';
2
2
  import {join} from 'node:path';
3
3
  import {
4
4
  mergeConfig,
5
+ validateDeadlineConfig,
5
6
  warnDeprecatedConfigKeys,
6
7
  type Config,
7
8
  type PartialConfig,
@@ -61,23 +62,23 @@ export const REPO_CONFIG_FILENAME = brand.repoConfigFilename;
61
62
  */
62
63
  export const REPO_ALLOWED_KEYS = [
63
64
  'integration',
64
- // `taskingIntegration` (the per-TRANSITION override for the prd→tasks TASKING
65
+ // `taskingIntegration` (the per-TRANSITION override for the spec→tasks TASKING
65
66
  // transition ONLY) is a genuine repo property exactly like `integration`: whether
66
- // THIS repo tasks a prd straight onto `main` (task FILES land, no PR) while it
67
+ // THIS repo tasks a spec straight onto `main` (task FILES land, no PR) while it
67
68
  // still BUILDS each task as a reviewable PR is agreed by all collaborators +
68
69
  // travels with the repo. Resolved per-repo through the SAME chain as
69
70
  // `integration`, then falls back to `integration` when unset. DISTINCT from
70
- // intake's per-EMITTED-TYPE `{task, prd}` resolver (front door, author-trust):
71
+ // intake's per-EMITTED-TYPE `{task, spec}` resolver (front door, author-trust):
71
72
  // this is a per-lifecycle-transition knob, inside the boundary, config-resolved.
72
73
  'taskingIntegration',
73
- // `tasksLandIn` (the per-repo TASK-PLACEMENT default — staging vs pool, prd
74
+ // `tasksLandIn` (the per-repo TASK-PLACEMENT default — staging vs pool, spec
74
75
  // `staging-pool-position-gate-and-trust-model` US #5) is a genuine repo property
75
76
  // exactly like `taskingIntegration`/`integration`: whether THIS repo's tasker
76
- // output lands STAGED (`pre-backlog/`, review-without-PR human-promote path) or
77
+ // output lands STAGED (`tasks/backlog/`, review-without-PR human-promote path) or
77
78
  // straight in the agent-eligible POOL (`ready/`, trusted fast-path) is agreed
78
79
  // by all collaborators + travels with the repo. Resolved per-repo through the
79
80
  // SAME chain as `taskingIntegration` (flag > env > per-repo > global > built-in
80
- // `pre-backlog`). DISTINCT from intake's per-emitted-type stamps (front door):
81
+ // `backlog`). DISTINCT from intake's per-emitted-type stamps (front door):
81
82
  // this is a per-lifecycle PLACEMENT knob, inside the trust boundary,
82
83
  // config-resolved. Fed into the shared placement resolver as the
83
84
  // configured-default rung (`src/placement.ts`).
@@ -91,7 +92,7 @@ export const REPO_ALLOWED_KEYS = [
91
92
  // through the SAME chain as `tasksLandIn` (flag `--specs-land-in` > env
92
93
  // `DORFL_SPECS_LAND_IN` > per-repo > global > built-in). Fed into the shared
93
94
  // placement resolver as the configured-default rung for the spec lifecycle
94
- // (`src/placement.ts`). The sole spec-placement key after the prd → spec HARD
95
+ // (`src/placement.ts`). The sole spec-placement key after the ''prd''`spec` HARD
95
96
  // CUTOVER (the legacy `prdsLandIn` key is GONE — clean break, no accepted alias).
96
97
  'specsLandIn',
97
98
  // `noPR` (the PR-INTENT axis — push the branch but deliberately skip the PR) is
@@ -116,7 +117,7 @@ export const REPO_ALLOWED_KEYS = [
116
117
  'autoBuild',
117
118
  // `autoTask` (may an agent auto-task undeclared prds in this repo?) is a
118
119
  // genuine repo property — the tasking-autonomy mirror of `autoBuild`
119
- // (`work/prds/auto-task.md`), resolved per-repo through the same chain.
120
+ // (`work/specs/auto-task.md`), resolved per-repo through the same chain.
120
121
  'autoTask',
121
122
  // `observationTriage` (the 3-state `off|ask|auto` gate over the observation
122
123
  // INBOX) is a genuine repo property — the observation-side question-surfacing
@@ -125,7 +126,7 @@ export const REPO_ALLOWED_KEYS = [
125
126
  // boolean (no alias; no external users owed a migration window, 2026-06-12).
126
127
  'observationTriage',
127
128
  // `mergeQuestions` (the 3-state `off|ask|auto` gate over the MERGE-QUESTION
128
- // SURFACER — prd `land-time-reverify-and-parallel-merge-ceiling` Story 17 /
129
+ // SURFACER — spec `land-time-reverify-and-parallel-merge-ceiling` Story 17 /
129
130
  // task `merge-questions-gate-axis`) is a genuine repo property exactly like
130
131
  // `observationTriage`: whether THIS repo's unmerged `work/*` branches surface
131
132
  // as merge-questions (and whether they auto-land) is agreed by all
@@ -136,13 +137,13 @@ export const REPO_ALLOWED_KEYS = [
136
137
  // (flag > env > per-repo > global > default `ask`).
137
138
  'mergeQuestions',
138
139
  // `surfaceBlockers` (the BOOLEAN gate over DECLARED blocked work — whether a
139
- // task/prd carrying `needsAnswers:true` is rendered into a question sidecar) is a
140
+ // task/spec carrying `needsAnswers:true` is rendered into a question sidecar) is a
140
141
  // genuine repo property — the blocked-work side of the question-surfacing gate
141
142
  // family (ADR `ci-config-policy-and-gate-family`), the orthogonal peer of
142
143
  // `observationTriage`, resolved per-repo through the same chain as `autoBuild`.
143
144
  'surfaceBlockers',
144
145
  // `surfaceStaging` (the BOOLEAN gate-family member that widens SURFACE into
145
- // STAGING — prd `staging-surface-and-apply-promote-safety` F2) is a genuine
146
+ // STAGING — spec `staging-surface-and-apply-promote-safety` F2) is a genuine
146
147
  // repo property exactly like its siblings (`surfaceBlockers`/`autoBuild`):
147
148
  // whether THIS repo inspects staging for questions is agreed by all
148
149
  // collaborators + travels with the repo. Default `true`; resolved per-repo
@@ -161,8 +162,8 @@ export const REPO_ALLOWED_KEYS = [
161
162
  // (machine paths/commands), so they are rejected below.
162
163
  'model',
163
164
  'harness',
164
- // Gate 2 (PR/code review) policy is a genuine repo property (GATES prd
165
- // `work/prds/tasked/review.md`), resolved per-repo like `integration`/`autoBuild`:
165
+ // Gate 2 (PR/code review) policy is a genuine repo property (GATES spec
166
+ // `work/specs/tasked/review.md`), resolved per-repo like `integration`/`autoBuild`:
166
167
  // whether this repo runs Gate 2 (`review`), which model the review agent runs
167
168
  // on (`reviewModel`), and the revise↔review loop bound (`reviewMaxRounds`).
168
169
  // `reviewModel` is routing intent (not auth), so — like `model` — it is
@@ -185,7 +186,7 @@ export const REPO_ALLOWED_KEYS = [
185
186
  // artifact (and pays the per-gate install cost) is agreed by all collaborators
186
187
  // + travels with the repo. Resolved per-repo through the SAME chain.
187
188
  'freshWorktreeGate',
188
- // `mergeRetries` (the cross-job merge serialiser's CAS-retry cap — prd
189
+ // `mergeRetries` (the cross-job merge serialiser's CAS-retry cap — spec
189
190
  // `land-time-reverify-and-parallel-merge-ceiling` Story 5 / Applied Answer q1 (a))
190
191
  // is a genuine repo property exactly like `freshWorktreeGate`: "how many
191
192
  // re-rebase-and-retry attempts before a contender bounces to needs-attention"
@@ -195,7 +196,7 @@ export const REPO_ALLOWED_KEYS = [
195
196
  // CAS still costs only a re-rebase + re-gate retry, never a `--force`.
196
197
  'mergeRetries',
197
198
  // `strictMergeApproval` (the OPT-IN strictness layered on the OQ6
198
- // stale-approval default — prd `land-time-reverify-and-parallel-merge-ceiling`
199
+ // stale-approval default — spec `land-time-reverify-and-parallel-merge-ceiling`
199
200
  // sidecar OQ6 / task `strict-merge-approval-gate`) is a genuine repo property
200
201
  // exactly like `mergeQuestions`/`mergeRetries`: whether THIS repo re-surfaces
201
202
  // the merge-question on a merge-base change (the host-agnostic analogue of
@@ -207,6 +208,16 @@ export const REPO_ALLOWED_KEYS = [
207
208
  // default or shape. The re-surface vs. land branch is
208
209
  // `apply-rung-merge-disposition`'s consumer, never here.
209
210
  'strictMergeApproval',
211
+ // `agentDeadlineMinutes` / `checkpointHeadroomMinutes` / `maxAutoCheckpoints`
212
+ // (spec `graceful-pre-timeout-wip-checkpoint`) are genuine repo properties:
213
+ // how long an agent session runs before checkpointing, and how much head-room
214
+ // the GitHub backstop leaves above it, are agreed by all collaborators + travel
215
+ // with the repo. The dynamic GitHub `timeout-minutes` cap is rendered by the
216
+ // `enumerate` job at run time FROM this committed config, so an edit reflects
217
+ // EVERYWHERE (internal deadline AND GitHub cap) with no install-ci re-run.
218
+ 'agentDeadlineMinutes',
219
+ 'checkpointHeadroomMinutes',
220
+ 'maxAutoCheckpoints',
210
221
  // `promptGuidance` (the NUDGE namespace — prompt-text knobs that strengthen
211
222
  // the worker's in-band wrapper line, e.g. `testFirst`) is a genuine repo
212
223
  // property: "is this repo nudged toward test-first?" travels with the repo
@@ -257,9 +268,42 @@ export type RepoRejectedKey = (typeof REPO_REJECTED_KEYS)[number];
257
268
 
258
269
  const ALLOWED_SET = new Set<string>(REPO_ALLOWED_KEYS);
259
270
 
260
- /** The path to a repo's `.dorfl.json` (repo root + filename). */
271
+ /**
272
+ * The LEGACY per-repo config filename (`.dorfl.json`, the original dotfile form)
273
+ * still honoured on READ for backward compatibility. Reads prefer
274
+ * {@link REPO_CONFIG_FILENAME} (`dorfl.json`) and fall back to this; writes /
275
+ * `setup` use the preferred name. Derived from the single brand identity so a
276
+ * rename flips it in lockstep (see `brand.ts`).
277
+ */
278
+ export const REPO_CONFIG_FILENAME_LEGACY = brand.repoConfigFilenameLegacy;
279
+
280
+ /**
281
+ * Resolve which per-repo config file a repo USES: the PREFERRED
282
+ * `dorfl.json` if present, else the LEGACY `.dorfl.json` if present, else the
283
+ * preferred path (the location a missing file WOULD live / be created at). So a
284
+ * repo that already committed the legacy dotfile keeps working, while a fresh
285
+ * repo (and every write) uses the plain name. If BOTH exist, the preferred
286
+ * `dorfl.json` wins (a deliberate, documented precedence, not a merge).
287
+ */
288
+ export function resolveRepoConfigPath(repoPath: string): string {
289
+ const preferred = join(repoPath, REPO_CONFIG_FILENAME);
290
+ if (existsSync(preferred)) {
291
+ return preferred;
292
+ }
293
+ const legacy = join(repoPath, REPO_CONFIG_FILENAME_LEGACY);
294
+ if (existsSync(legacy)) {
295
+ return legacy;
296
+ }
297
+ return preferred;
298
+ }
299
+
300
+ /**
301
+ * The path to a repo's config file. Prefers the plain `dorfl.json`, falls back
302
+ * to the legacy `.dorfl.json` when only that exists (see
303
+ * {@link resolveRepoConfigPath}).
304
+ */
261
305
  export function repoConfigPath(repoPath: string): string {
262
- return join(repoPath, REPO_CONFIG_FILENAME);
306
+ return resolveRepoConfigPath(repoPath);
263
307
  }
264
308
 
265
309
  /** The result of reading (and filtering) a repo's `.dorfl.json`. */
@@ -542,6 +586,11 @@ export function resolveRepoConfigFromLoaded(
542
586
  ...envOverrides(env),
543
587
  ...(flags ?? {}),
544
588
  });
589
+ // Fail-loud range validation for the deadline / backstop / ceiling triple
590
+ // (spec `graceful-pre-timeout-wip-checkpoint`): a bad value from ANY layer
591
+ // (flag / env / per-repo / global) throws with a clear message naming the
592
+ // field + range — NEVER silently clamped.
593
+ validateDeadlineConfig(config);
545
594
  return {
546
595
  config,
547
596
  rejected: repo.rejected,
@@ -5,6 +5,7 @@ import type {Config, PartialConfig} from './config.js';
5
5
  import type {ConfigOverrideMap} from './config-override.js';
6
6
  import {
7
7
  REPO_CONFIG_FILENAME,
8
+ REPO_CONFIG_FILENAME_LEGACY,
8
9
  loadRepoConfigFromContent,
9
10
  resolveRepoConfigFromLoaded,
10
11
  type LoadedRepoConfig,
@@ -247,7 +248,28 @@ export function readRepoConfigFromMirrorMain(
247
248
  mirrorDir: string,
248
249
  env?: NodeJS.ProcessEnv,
249
250
  ): string | undefined {
250
- const spec = `main:${REPO_CONFIG_FILENAME}`;
251
+ // Prefer the plain `dorfl.json`; fall back to the legacy `.dorfl.json` when the
252
+ // preferred name is absent on `main` (a repo that committed the dotfile before
253
+ // dual-support). A genuine read fault on the FIRST attempt propagates; a
254
+ // path-missing on the first falls through to the legacy attempt.
255
+ const preferred = showConfigOnMain(mirrorDir, REPO_CONFIG_FILENAME, env);
256
+ if (preferred !== undefined) {
257
+ return preferred;
258
+ }
259
+ return showConfigOnMain(mirrorDir, REPO_CONFIG_FILENAME_LEGACY, env);
260
+ }
261
+
262
+ /**
263
+ * `git show main:<filename>` in a mirror, returning the bytes, or `undefined`
264
+ * when the PATH is absent on `main` (the expected config-less / wrong-name case).
265
+ * A genuine fault (unresolvable `main` / bad object) throws.
266
+ */
267
+ function showConfigOnMain(
268
+ mirrorDir: string,
269
+ filename: string,
270
+ env?: NodeJS.ProcessEnv,
271
+ ): string | undefined {
272
+ const spec = `main:${filename}`;
251
273
  const res = run('git', ['show', spec], mirrorDir, {env});
252
274
  if (res.status === 0) {
253
275
  return res.stdout;
@@ -1,6 +1,7 @@
1
1
  import {NullHarness, substituteModel, type Harness} from './harness.js';
2
2
  import {launchWithOptionalWatch} from './agent-launch.js';
3
3
  import {boundaryLine} from './watch-session.js';
4
+ import {workItemRel} from './work-layout.js';
4
5
  import {
5
6
  parseReviewVerdict,
6
7
  ReviewParseError,
@@ -18,7 +19,7 @@ export {
18
19
  } from './review-verdict.js';
19
20
 
20
21
  /**
21
- * **Gate 2 — the PR/code review gate** (GATES prd `work/prds/tasked/review.md`), the
22
+ * **Gate 2 — the PR/code review gate** (GATES spec `work/specs/tasked/review.md`), the
22
23
  * JUDGEMENT layer that rides ON TOP of the deterministic `verify` floor (ADR §8).
23
24
  *
24
25
  * After the green `verify` and BEFORE the done-move, `complete`/`do` invoke the
@@ -110,7 +111,7 @@ export function buildReviewPrompt(slug: string): string {
110
111
  return [
111
112
  `You are a FRESH-CONTEXT reviewer (Gate 2 — PR/code review). Review the`,
112
113
  `code changes on this work branch AGAINST the task that specified them`,
113
- `(work/in-progress/${slug}.md or work/done/${slug}.md) and its source prd.`,
114
+ `(work/in-progress/${slug}.md or work/done/${slug}.md) and its source spec.`,
114
115
  ``,
115
116
  reviewDisciplinePrompt(),
116
117
  ``,
@@ -150,7 +151,7 @@ export function buildReviewPrompt(slug: string): string {
150
151
  `comment on the PR — write it FOR a human landing there, NOT as scratch`,
151
152
  `thinking. LEAD with the verdict ("Approved" or "Blocked") and then give the`,
152
153
  `lenses' reasoning and the destination check ("merged as written, do we reach`,
153
- `the task/prd goal?"). Write it deliberately; do NOT narrate your process`,
154
+ `the task/spec goal?"). Write it deliberately; do NOT narrate your process`,
154
155
  `("Let me check…"). Keep it TIGHT: aim for a few short sentences and DO NOT`,
155
156
  `exceed ~1500 characters — a long, multi-paragraph field is exactly what`,
156
157
  `corrupts the JSON on large diffs; say less, not more. It is plain text inside`,
@@ -247,10 +248,10 @@ export function harnessReviewGate(
247
248
  * Render the TASK-SET acceptance-gate PROMPT — the task-path mirror of
248
249
  * {@link buildReviewPrompt} (task `slice-acceptance-gate`). Instead of
249
250
  * reviewing a code diff against ONE task, this instructs a FRESH-CONTEXT
250
- * agent to review the WHOLE candidate SET of tasks produced for prd `slug`,
251
+ * agent to review the WHOLE candidate SET of tasks produced for spec `slug`,
251
252
  * using the **review discipline**'s SET-OF-TASKS lens (coherence / dependency
252
253
  * graph / gaps + overlap / "if every task is built exactly as written, do we
253
- * reach the system the prd describes, and is each task
254
+ * reach the system the spec describes, and is each task
254
255
  * correct-if-implemented?"). It emits the SAME unified `ReviewVerdict` shape
255
256
  * so {@link parseReviewVerdict} reads it identically.
256
257
  *
@@ -265,24 +266,24 @@ export function harnessReviewGate(
265
266
  export function buildTaskAcceptancePrompt(slug: string): string {
266
267
  return [
267
268
  `You are a FRESH-CONTEXT reviewer (the task-SET ACCEPTANCE GATE). Review`,
268
- `the candidate tasks this tasking run produced for the prd "${slug}" — the`,
269
+ `the candidate tasks this tasking run produced for the spec "${slug}" — the`,
269
270
  `new/changed candidate task files on this work branch — AGAINST their source`,
270
- `prd (work/prds/ready/${slug}.md — the held prd stays in prds/ready/ while it is being`,
271
+ `spec (${workItemRel('specs-ready', `${slug}.md`)} — the held spec stays in specs/ready/ while it is being`,
271
272
  `tasked).`,
272
273
  ``,
273
274
  reviewDisciplinePrompt(),
274
275
  ``,
275
276
  `Review the WHOLE SET as a SET, not each task in isolation. The set-level`,
276
277
  `framings the review discipline names:`,
277
- ` - COHERENCE — do the tasks speak the prd's (and the system's) language`,
278
- ` consistently; no task re-means or forks a concept another task/the prd`,
278
+ ` - COHERENCE — do the tasks speak the spec's (and the system's) language`,
279
+ ` consistently; no task re-means or forks a concept another task/the spec`,
279
280
  ` already owns?`,
280
281
  ` - DEPENDENCY GRAPH — is the \`blockedBy\`/ordering graph sound (acyclic, the`,
281
282
  ` keystone first, each task's stated blockers really land its premise)?`,
282
- ` - GAPS + OVERLAP — does the set COVER the prd with no missing piece, and`,
283
+ ` - GAPS + OVERLAP — does the set COVER the spec with no missing piece, and`,
283
284
  ` without two tasks doing the same work or fighting over the same seam?`,
284
285
  ` - CORRECT-IF-IMPLEMENTED — if EVERY task is built EXACTLY as written, do we`,
285
- ` reach the system the prd describes, and is each task individually`,
286
+ ` reach the system the spec describes, and is each task individually`,
286
287
  ` correct-if-implemented (no task that compiles but builds the wrong thing)?`,
287
288
  ``,
288
289
  `This is a TERMINAL one-shot accept/reject gate: do NOT edit any task, do NOT`,
@@ -4,7 +4,7 @@
4
4
  * (`work/protocol/REVIEW-PROTOCOL.md`, source-of-truth
5
5
  * `skills/setup/protocol/REVIEW-PROTOCOL.md`).
6
6
  *
7
- * This is the keystone of the `runner-invoked-disciplines-into-protocol` prd
7
+ * This is the keystone of the `runner-invoked-disciplines-into-protocol` spec
8
8
  * (task 1, D4): every runner-invoked review prompt builder
9
9
  * ({@link buildReviewPrompt}, {@link buildTaskAcceptancePrompt} in
10
10
  * `review-gate.ts`; {@link buildLoneTaskReviewPrompt} in `intake.ts`;
@@ -84,7 +84,7 @@ export interface ReviewVerdict {
84
84
  questions?: string[];
85
85
  /** For the tasker improver loop: specific tasks to emit `needsAnswers: true`. */
86
86
  uncertainTasks?: UncertainTask[];
87
- /** For the tasker improver loop: route the WHOLE prd to needs-attention. */
87
+ /** For the tasker improver loop: route the WHOLE spec to needs-attention. */
88
88
  decompositionUnclear?: {questions: string[]};
89
89
  }
90
90
 
@@ -397,7 +397,7 @@ export function reviewDisciplinePrompt(): string {
397
397
  '(the in-band, protocol-native review protocol every set-up repo carries;',
398
398
  'the human-facing pointer is `skills/review/SKILL.md`). Apply its lenses',
399
399
  'IN ORDER, ENDING in the destination check ("if this is built/merged',
400
- 'exactly as written, do we end up with the system the prd/task',
400
+ 'exactly as written, do we end up with the system the spec/task',
401
401
  'goal describes?"). Be ADVERSARIAL; verify against what ACTUALLY LANDED',
402
402
  '(the bytes on disk), not intent. Weight findings by REAL impact \u2014 the',
403
403
  'lenses find candidates, impact decides severity (a technically-true nit',
package/src/run.ts CHANGED
@@ -31,7 +31,11 @@ import {
31
31
  parseStopSentinel,
32
32
  isWorkBranchDiffEmpty,
33
33
  emptyDiffStopReason,
34
+ emptyDiffDisposeEnvelope,
35
+ type AgentStopKind,
34
36
  } from './agent-stop.js';
37
+ import {surfaceStuckToNeedsAttention} from './needs-attention.js';
38
+ import {resolveItemPathByIdentity} from './item-path.js';
35
39
  import {
36
40
  classifyFailureCause,
37
41
  failureCauseLabel,
@@ -190,6 +194,7 @@ export type ItemStatus =
190
194
  | 'surface-unmoved' // the tree-less surface to needs-attention did NOT land on the arbiter (lost the CAS race / no arbiter) — the item is STILL in-progress on the arbiter; retry/resolve
191
195
  | 'agent-failed' // the agent ran but produced bad/empty output (the conservative generic), OR the cause is unknown
192
196
  | 'transient-infra' // a harness-surfaced model/connection outage (post-retry) or a git/provider outage — RETRY the same work (FAILURE-CAUSE axis)
197
+ | 'needs-reauth' // a credential expired / was revoked (OAuth refresh) — retry cannot help; a human must RE-AUTH (FAILURE-CAUSE axis)
193
198
  | 'config-error' // a thrown CORE wiring/config error (e.g. review on, no reviewGate) — fix the WIRING, not the task (FAILURE-CAUSE axis)
194
199
  | 'agent-stopped'; // the agent DELIBERATELY stopped (task drifted) OR produced no change — gate + Gate-2 skipped
195
200
 
@@ -457,6 +462,7 @@ export async function runOnce(options: RunOnceOptions): Promise<RunOnceResult> {
457
462
  // are the same agent/run-failure routed to needs-attention, just labelled
458
463
  // by cause).
459
464
  i.status === 'transient-infra' ||
465
+ i.status === 'needs-reauth' ||
460
466
  i.status === 'config-error' ||
461
467
  // The surface to needs-attention did NOT land (lost the CAS race); the item
462
468
  // is still in-progress on the arbiter — a genuine FAILURE (not a clean
@@ -709,16 +715,19 @@ async function runOneItem(
709
715
  // `work/<slug>` tip == the arbiter tip (the kept branch, unchanged,
710
716
  // after-commit). The DURABLE artifact is that branch on the arbiter + the
711
717
  // main surface (ADR §14: the job worktree is a disposable cache; recovery
712
- // flows through the branch + folder-native surfaces, NOT by editing the
713
- // worktree). So the surface is purely the one-file `in-progress/
714
- // needs-attention/` ledger move + reason — no branch push, no worktree
715
- // mutation. Because the branch is provably on the arbiter, the §4 reap
718
+ // flows through the branch + lock surfaces, NOT by editing the
719
+ // worktree). So the surface is purely the lock amend to `state: stuck` +
720
+ // reason (post lock-cutover — no `in-progress/ needs-attention/` folder
721
+ // move, no branch push, no worktree
722
+ // mutation). Because the branch is provably on the arbiter, the §4 reap
716
723
  // predicate still HOLDS and this worktree is reaped — more §14-aligned.
717
724
  if (tree.continueRebaseConflict) {
718
725
  const reason =
719
726
  `continuing the kept ${tree.branch}: rebase onto the latest main ` +
720
- 'conflicted (aborted, never auto-resolved) — resolve against the latest ' +
721
- 'main, or `requeue --reset` to discard and start fresh';
727
+ 'conflicted (aborted, never auto-resolved) — run `requeue --reconcile` ' +
728
+ 'to non-destructively re-sync the mirror and retry the rebase (keeps ' +
729
+ 'the work). Last resort: `requeue --reset` DESTRUCTIVELY discards the ' +
730
+ 'branch and starts fresh.';
722
731
  updateJobRecord(tree.dir, {state: 'needs-attention', reason});
723
732
  const surfaced = await ledgerWrite.applyTreelessNeedsAttentionTransition({
724
733
  cwd: tree.dir,
@@ -747,9 +756,10 @@ async function runOneItem(
747
756
  const reason =
748
757
  `continuing the kept ${tree.branch}: publishing the rebased work branch ` +
749
758
  `to the arbiter failed terminally (${tree.continuePushFailure}) — the ` +
750
- 'kept branch is left intact on the arbiter (recoverable); `requeue` to ' +
751
- 'retry once the churn settles, or `requeue --reset` to discard and start ' +
752
- 'fresh';
759
+ 'kept branch is left intact on the arbiter (recoverable); ' +
760
+ '`requeue --reconcile` to non-destructively re-sync the mirror and ' +
761
+ 'retry once the churn settles (keeps the work). Last resort: ' +
762
+ '`requeue --reset` DESTRUCTIVELY discards the branch and starts fresh.';
753
763
  updateJobRecord(tree.dir, {state: 'needs-attention', reason});
754
764
  const surfaced = await ledgerWrite.applyTreelessNeedsAttentionTransition({
755
765
  cwd: tree.dir,
@@ -765,7 +775,7 @@ async function runOneItem(
765
775
  }
766
776
 
767
777
  // 3. Build the prompt — the SAME dual-use assembly `dorfl prompt`
768
- // emits: the canonical wrapper (+ source prd) + the task's ## Prompt.
778
+ // emits: the canonical wrapper (+ source spec) + the task's ## Prompt.
769
779
  let prompt: string;
770
780
  try {
771
781
  // CONTINUE-aware resolution: only on a continue (the job continued a kept
@@ -801,7 +811,7 @@ async function runOneItem(
801
811
  })
802
812
  : undefined;
803
813
  // Thread the resolved per-repo nudge through the per-item override layer
804
- // (a task or prd may pin `promptGuidance.testFirst` in its frontmatter,
814
+ // (a task or spec may pin `promptGuidance.testFirst` in its frontmatter,
805
815
  // superseding the repo policy for THIS item) before the wrapper is built.
806
816
  const itemGuidance = resolvePromptGuidanceForItem({
807
817
  cwd: tree.dir,
@@ -862,24 +872,31 @@ async function runOneItem(
862
872
  // the arbiter) and SKIPS the gate + Gate-2 (the whole `performIntegration`
863
873
  // band) — a clean STOP is NOT "a build that changed nothing".
864
874
  const sentinel = parseStopSentinel(agent.output);
865
- const stopReason =
875
+ const stopReason: {kind: AgentStopKind; reason: string} | undefined =
866
876
  sentinel !== undefined
867
- ? sentinel.reason
877
+ ? {kind: 'sentinel', reason: sentinel.reason}
868
878
  : (await isWorkBranchDiffEmpty({
869
879
  cwd: tree.dir,
870
880
  arbiter: tree.arbiterRemote,
871
881
  env: gitEnv,
872
882
  }))
873
- ? emptyDiffStopReason(slug)
883
+ ? {kind: 'empty-diff', reason: emptyDiffStopReason(slug)}
874
884
  : undefined;
875
885
  if (stopReason !== undefined) {
876
- return await saveAgentStop(base, tree, slug, stopReason, ctx);
886
+ return await saveAgentStop(
887
+ base,
888
+ tree,
889
+ slug,
890
+ stopReason.reason,
891
+ stopReason.kind,
892
+ ctx,
893
+ );
877
894
  }
878
895
 
879
896
  // 5–7 (CONVERGED). The whole gate → review → done-move → commit → rebase →
880
897
  // integrate band — plus the needs-attention routing on any failure — now runs
881
898
  // through the SHARED `performIntegration` core (`integration-core.ts`, the
882
- // run/do convergence prd). `run` no longer forks its own gate / done-move /
899
+ // run/do convergence spec). `run` no longer forks its own gate / done-move /
883
900
  // completion commit / `Integrator`+`integrateWithRebase`: that closed all
884
901
  // three drift instances at once (the fleet now gets the review gate, the PR
885
902
  // title/body, AND the per-repo language-agnostic `verify` gate instead of the
@@ -954,7 +971,7 @@ async function runOneItem(
954
971
  // (`do`/`--isolated`/`--remote`/`complete`) already pass it unconditionally.
955
972
  freshWorktreeGate: config.freshWorktreeGate,
956
973
  // The cross-job merge-serialiser CAS-retry cap (config `mergeRetries`) —
957
- // the git-alone FLOOR of the cross-job land queue (prd `land-time-reverify-
974
+ // the git-alone FLOOR of the cross-job land queue (spec `land-time-reverify-
958
975
  // and-parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)). Threaded
959
976
  // from the per-repo resolved config so a wide-matrix CI's raised cap actually
960
977
  // reaches the merge loop — across separate `run` fleet jobs the CAS loop IS
@@ -1138,9 +1155,10 @@ function runAgent(
1138
1155
  * This mirrors `do.ts`'s `saveAgentFailure`: route the failure through the SAME
1139
1156
  * ledger write seam's needs-attention transition the gate-fail / integrate-
1140
1157
  * conflict bounces use — which (with the arbiter) saves the agent's work as a wip
1141
- * commit, `git mv`s the item to needs-attention/ with the failure detail recorded
1142
- * as the reason, surfaces the move-only commit on the arbiter's `main`
1143
- * (OBSERVABLE), AND pushes the `work/<slug>` branch (RECOVERABLE the durable
1158
+ * commit, then post lock-cutover amends the item's per-item lock to
1159
+ * `state: stuck` with the failure detail as the reason on the lock entry
1160
+ * (OBSERVABLE; the `needs-attention/` folder move is retired), AND pushes the
1161
+ * `work/<slug>` branch (RECOVERABLE — the durable
1144
1162
  * artifact a requeue-continue lands the next agent on; continue-detection reads
1145
1163
  * <arbiter>/work/<slug> ahead of main). The push is best-effort — an unreachable
1146
1164
  * arbiter leaves the retained worktree + the local commits standing (the genuinely
@@ -1194,8 +1212,9 @@ function failureCauseToItemStatus(cause: FailureCause): ItemStatus {
1194
1212
 
1195
1213
  /**
1196
1214
  * Build the HONEST {@link ItemResult} for a CONTINUE-site surface that did NOT
1197
- * land on the arbiter (`{moved: false}`). The tree-less `in-progress/
1198
- * needs-attention/` move lost the CAS race against a busy arbiter (its
1215
+ * land on the arbiter (`{moved: false}`). The tree-less stuck-lock amend (post
1216
+ * lock-cutover `state: stuck` + reason, in place of the retired `in-progress/ →
1217
+ * needs-attention/` move) lost the CAS race against a busy arbiter (its
1199
1218
  * contention-retry cap exhausted) or had no arbiter to publish to, so the item is
1200
1219
  * STILL in-progress on the arbiter — reporting a clean `needs-attention` would
1201
1220
  * mislead (it claims the surface landed, when it did not). The DISTINCT
@@ -1236,9 +1255,36 @@ async function saveAgentStop(
1236
1255
  tree: IsolatedTree,
1237
1256
  slug: string,
1238
1257
  reason: string,
1258
+ kind: AgentStopKind,
1239
1259
  ctx: OneItemContext,
1240
1260
  ): Promise<ItemResult> {
1241
1261
  updateJobRecord(tree.dir, {state: 'needs-attention', reason});
1262
+ // EMPTY-DIFF branch (spec resolved decision #2, task
1263
+ // `empty-diff-bounce-surfaces-dispose-defaulted-question`): surface a sidecar
1264
+ // carrying an engine-authored DISPOSE-DEFAULTED envelope question on
1265
+ // `<arbiter>/main` (via the PR-1 tree-less surface primitive) and release the
1266
+ // lock — NOT the general lock-stuck bounce path. "Nothing to do" is a
1267
+ // non-deterministic LLM judgement, so a blind requeue would infinite-loop;
1268
+ // the surfaced sidecar + `needsAnswers:true` on `main` parks the item as a
1269
+ // human-visible question a `dispose` answer settles to `tasks/cancelled/`.
1270
+ if (kind === 'empty-diff') {
1271
+ const item = `task:${slug}`;
1272
+ const itemPath = resolveItemPathByIdentity(tree.dir, item);
1273
+ if (itemPath !== undefined) {
1274
+ await surfaceStuckToNeedsAttention({
1275
+ cwd: tree.dir,
1276
+ slug,
1277
+ item,
1278
+ itemPath,
1279
+ reason,
1280
+ envelope: emptyDiffDisposeEnvelope({item, reason}),
1281
+ arbiter: tree.arbiterRemote,
1282
+ env: ctx.gitEnv ?? ctx.env,
1283
+ });
1284
+ return {...base, status: 'agent-stopped', detail: reason};
1285
+ }
1286
+ // Fallthrough (body missing) — fall through to the lock-stuck bounce below.
1287
+ }
1242
1288
  await ledgerWrite.applyNeedsAttentionTransition({
1243
1289
  cwd: tree.dir,
1244
1290
  slug,
@@ -1262,7 +1308,7 @@ export function defaultRunWorkspace(): string {
1262
1308
  * One supervised TICK over the registry, as a swappable unit. Today the tick IS
1263
1309
  * `runOnce` (claim+build+integrate a concurrent batch of eligible TASKS). The
1264
1310
  * loop ({@link runLoop}) is deliberately written against this signature — NOT
1265
- * against `runOnce` directly — so the advance-loop prd can later swap the tick
1311
+ * against `runOnce` directly — so the advance-loop spec can later swap the tick
1266
1312
  * (build / task / triage / surface / apply) WITHOUT re-architecting the loop
1267
1313
  * (the forward-pointer: the loop owns concurrency/scheduling, the tick owns one
1268
1314
  * item's work). The loop never reaches inside a tick.