dorfl 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (492) hide show
  1. package/dist/advance-ci-template.d.ts +3 -3
  2. package/dist/advance-ci-template.js +1 -1
  3. package/dist/advance-ci-template.js.map +1 -1
  4. package/dist/advance-classify.d.ts +5 -5
  5. package/dist/advance-classify.d.ts.map +1 -1
  6. package/dist/advance-classify.js +4 -4
  7. package/dist/advance-drivers.d.ts +8 -8
  8. package/dist/advance-drivers.d.ts.map +1 -1
  9. package/dist/advance-drivers.js +20 -8
  10. package/dist/advance-drivers.js.map +1 -1
  11. package/dist/advance-isolated.d.ts +3 -3
  12. package/dist/advance-isolated.d.ts.map +1 -1
  13. package/dist/advance-isolated.js +1 -1
  14. package/dist/advance-lifecycle-template.d.ts +2 -2
  15. package/dist/advance-lifecycle-template.d.ts.map +1 -1
  16. package/dist/advance-lifecycle-template.js +85 -13
  17. package/dist/advance-lifecycle-template.js.map +1 -1
  18. package/dist/advance-loop-driver.d.ts +3 -3
  19. package/dist/advance-loop-driver.d.ts.map +1 -1
  20. package/dist/advance-loop-driver.js +1 -1
  21. package/dist/advance-treeless-publish.d.ts +24 -1
  22. package/dist/advance-treeless-publish.d.ts.map +1 -1
  23. package/dist/advance-treeless-publish.js +41 -0
  24. package/dist/advance-treeless-publish.js.map +1 -1
  25. package/dist/advance.d.ts +69 -17
  26. package/dist/advance.d.ts.map +1 -1
  27. package/dist/advance.js +409 -102
  28. package/dist/advance.js.map +1 -1
  29. package/dist/advancing-lock.d.ts +31 -3
  30. package/dist/advancing-lock.d.ts.map +1 -1
  31. package/dist/advancing-lock.js +55 -5
  32. package/dist/advancing-lock.js.map +1 -1
  33. package/dist/agent-launch.d.ts +12 -0
  34. package/dist/agent-launch.d.ts.map +1 -1
  35. package/dist/agent-launch.js +22 -12
  36. package/dist/agent-launch.js.map +1 -1
  37. package/dist/agent-stop.d.ts +40 -2
  38. package/dist/agent-stop.d.ts.map +1 -1
  39. package/dist/agent-stop.js +30 -2
  40. package/dist/agent-stop.js.map +1 -1
  41. package/dist/apply-decide.d.ts +19 -5
  42. package/dist/apply-decide.d.ts.map +1 -1
  43. package/dist/apply-decide.js +38 -9
  44. package/dist/apply-decide.js.map +1 -1
  45. package/dist/apply-merge-action.d.ts +20 -8
  46. package/dist/apply-merge-action.d.ts.map +1 -1
  47. package/dist/apply-merge-action.js +44 -9
  48. package/dist/apply-merge-action.js.map +1 -1
  49. package/dist/apply-persist.d.ts +62 -31
  50. package/dist/apply-persist.d.ts.map +1 -1
  51. package/dist/apply-persist.js +173 -44
  52. package/dist/apply-persist.js.map +1 -1
  53. package/dist/apply-stuck-action.d.ts +151 -0
  54. package/dist/apply-stuck-action.d.ts.map +1 -0
  55. package/dist/apply-stuck-action.js +125 -0
  56. package/dist/apply-stuck-action.js.map +1 -0
  57. package/dist/brand.d.ts +12 -1
  58. package/dist/brand.d.ts.map +1 -1
  59. package/dist/brand.js +2 -1
  60. package/dist/brand.js.map +1 -1
  61. package/dist/buildable-body.d.ts +14 -14
  62. package/dist/buildable-body.js +9 -9
  63. package/dist/claim-cas.d.ts +3 -3
  64. package/dist/claim-cas.js +1 -1
  65. package/dist/claim-cas.js.map +1 -1
  66. package/dist/cli-spinner.d.ts +1 -1
  67. package/dist/cli-spinner.js +1 -1
  68. package/dist/cli.d.ts +10 -0
  69. package/dist/cli.d.ts.map +1 -1
  70. package/dist/cli.js +385 -128
  71. package/dist/cli.js.map +1 -1
  72. package/dist/close-job-template.d.ts +3 -3
  73. package/dist/close-job-template.js +9 -9
  74. package/dist/close-job.d.ts +8 -8
  75. package/dist/close-job.js +25 -25
  76. package/dist/close-job.js.map +1 -1
  77. package/dist/complete.d.ts +9 -6
  78. package/dist/complete.d.ts.map +1 -1
  79. package/dist/complete.js +99 -45
  80. package/dist/complete.js.map +1 -1
  81. package/dist/concurrency.d.ts +1 -1
  82. package/dist/concurrency.js +1 -1
  83. package/dist/config.d.ts +86 -40
  84. package/dist/config.d.ts.map +1 -1
  85. package/dist/config.js +61 -9
  86. package/dist/config.js.map +1 -1
  87. package/dist/continue-branch.d.ts +1 -1
  88. package/dist/continue-branch.d.ts.map +1 -1
  89. package/dist/continue-branch.js +23 -1
  90. package/dist/continue-branch.js.map +1 -1
  91. package/dist/cwd-section.js +1 -1
  92. package/dist/cwd-section.js.map +1 -1
  93. package/dist/decision-engine.d.ts +39 -11
  94. package/dist/decision-engine.d.ts.map +1 -1
  95. package/dist/decision-engine.js +10 -6
  96. package/dist/decision-engine.js.map +1 -1
  97. package/dist/do-autopick.d.ts +6 -6
  98. package/dist/do-autopick.d.ts.map +1 -1
  99. package/dist/do-autopick.js +16 -6
  100. package/dist/do-autopick.js.map +1 -1
  101. package/dist/do-config.d.ts +4 -4
  102. package/dist/do-config.js +3 -3
  103. package/dist/do-config.js.map +1 -1
  104. package/dist/do-remote-auto.d.ts +2 -2
  105. package/dist/do-remote-auto.js +1 -1
  106. package/dist/do.d.ts +74 -81
  107. package/dist/do.d.ts.map +1 -1
  108. package/dist/do.js +439 -50
  109. package/dist/do.js.map +1 -1
  110. package/dist/drop-source.d.ts +2 -2
  111. package/dist/env-config.d.ts.map +1 -1
  112. package/dist/env-config.js +19 -11
  113. package/dist/env-config.js.map +1 -1
  114. package/dist/failure-cause.d.ts +3 -2
  115. package/dist/failure-cause.d.ts.map +1 -1
  116. package/dist/failure-cause.js +28 -1
  117. package/dist/failure-cause.js.map +1 -1
  118. package/dist/format.d.ts +6 -6
  119. package/dist/format.d.ts.map +1 -1
  120. package/dist/format.js +13 -30
  121. package/dist/format.js.map +1 -1
  122. package/dist/frontmatter.d.ts +28 -15
  123. package/dist/frontmatter.d.ts.map +1 -1
  124. package/dist/frontmatter.js +38 -24
  125. package/dist/frontmatter.js.map +1 -1
  126. package/dist/gc.d.ts +65 -6
  127. package/dist/gc.d.ts.map +1 -1
  128. package/dist/gc.js +126 -9
  129. package/dist/gc.js.map +1 -1
  130. package/dist/github.d.ts +14 -0
  131. package/dist/github.d.ts.map +1 -1
  132. package/dist/github.js +73 -0
  133. package/dist/github.js.map +1 -1
  134. package/dist/harness.d.ts +25 -0
  135. package/dist/harness.d.ts.map +1 -1
  136. package/dist/harness.js.map +1 -1
  137. package/dist/index.d.ts +4 -1
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/index.js +2 -1
  140. package/dist/index.js.map +1 -1
  141. package/dist/install-ci-branch-protection.d.ts +133 -39
  142. package/dist/install-ci-branch-protection.d.ts.map +1 -1
  143. package/dist/install-ci-branch-protection.js +191 -49
  144. package/dist/install-ci-branch-protection.js.map +1 -1
  145. package/dist/install-ci-capabilities/advance-lifecycle.d.ts +1 -1
  146. package/dist/install-ci-capabilities/advance-lifecycle.js +1 -1
  147. package/dist/install-ci-capabilities/close-job.d.ts +1 -1
  148. package/dist/install-ci-capabilities/close-job.js +1 -1
  149. package/dist/install-ci-capabilities/example-noop.d.ts +1 -1
  150. package/dist/install-ci-capabilities/example-noop.js +1 -1
  151. package/dist/install-ci-capabilities/intake.d.ts +2 -2
  152. package/dist/install-ci-capabilities/intake.js +2 -2
  153. package/dist/install-ci-capabilities/verify.d.ts +1 -1
  154. package/dist/install-ci-capabilities/verify.js +1 -1
  155. package/dist/install-ci-core.d.ts +24 -4
  156. package/dist/install-ci-core.d.ts.map +1 -1
  157. package/dist/install-ci-core.js +12 -5
  158. package/dist/install-ci-core.js.map +1 -1
  159. package/dist/install-ci-github.d.ts +33 -1
  160. package/dist/install-ci-github.d.ts.map +1 -1
  161. package/dist/install-ci-github.js +74 -1
  162. package/dist/install-ci-github.js.map +1 -1
  163. package/dist/install-ci.d.ts +1 -1
  164. package/dist/install-ci.js +4 -4
  165. package/dist/install-ci.js.map +1 -1
  166. package/dist/install-skills.d.ts +123 -0
  167. package/dist/install-skills.d.ts.map +1 -0
  168. package/dist/install-skills.js +100 -0
  169. package/dist/install-skills.js.map +1 -0
  170. package/dist/intake-event.d.ts +6 -6
  171. package/dist/intake-event.js +6 -6
  172. package/dist/intake-marker.d.ts +3 -3
  173. package/dist/intake-marker.d.ts.map +1 -1
  174. package/dist/intake-triage.d.ts +1 -1
  175. package/dist/intake-triage.js +2 -2
  176. package/dist/intake-trigger-template.d.ts +8 -8
  177. package/dist/intake-trigger-template.d.ts.map +1 -1
  178. package/dist/intake-trigger-template.js +17 -17
  179. package/dist/intake-trigger-template.js.map +1 -1
  180. package/dist/intake.d.ts +65 -52
  181. package/dist/intake.d.ts.map +1 -1
  182. package/dist/intake.js +92 -76
  183. package/dist/intake.js.map +1 -1
  184. package/dist/integration-core.d.ts +27 -24
  185. package/dist/integration-core.d.ts.map +1 -1
  186. package/dist/integration-core.js +191 -77
  187. package/dist/integration-core.js.map +1 -1
  188. package/dist/integrator.d.ts +1 -1
  189. package/dist/integrator.d.ts.map +1 -1
  190. package/dist/integrator.js +19 -3
  191. package/dist/integrator.js.map +1 -1
  192. package/dist/isolation.d.ts +4 -4
  193. package/dist/isolation.d.ts.map +1 -1
  194. package/dist/isolation.js +9 -0
  195. package/dist/isolation.js.map +1 -1
  196. package/dist/issue-provider.d.ts +4 -4
  197. package/dist/issue-provider.js +1 -1
  198. package/dist/item-lock.d.ts +216 -149
  199. package/dist/item-lock.d.ts.map +1 -1
  200. package/dist/item-lock.js +345 -270
  201. package/dist/item-lock.js.map +1 -1
  202. package/dist/item-path.d.ts +2 -2
  203. package/dist/item-path.js +2 -2
  204. package/dist/ledger-lint.d.ts +9 -9
  205. package/dist/ledger-lint.js +9 -9
  206. package/dist/ledger-read.d.ts +57 -57
  207. package/dist/ledger-read.d.ts.map +1 -1
  208. package/dist/ledger-read.js +24 -24
  209. package/dist/ledger-read.js.map +1 -1
  210. package/dist/ledger-write.d.ts +33 -28
  211. package/dist/ledger-write.d.ts.map +1 -1
  212. package/dist/ledger-write.js +100 -122
  213. package/dist/ledger-write.js.map +1 -1
  214. package/dist/lifecycle-gather.d.ts +18 -1
  215. package/dist/lifecycle-gather.d.ts.map +1 -1
  216. package/dist/lifecycle-gather.js +23 -17
  217. package/dist/lifecycle-gather.js.map +1 -1
  218. package/dist/lifecycle-pools.d.ts +44 -7
  219. package/dist/lifecycle-pools.d.ts.map +1 -1
  220. package/dist/lifecycle-pools.js +27 -7
  221. package/dist/lifecycle-pools.js.map +1 -1
  222. package/dist/merge-question-surfacer.d.ts +18 -4
  223. package/dist/merge-question-surfacer.d.ts.map +1 -1
  224. package/dist/merge-question-surfacer.js +20 -5
  225. package/dist/merge-question-surfacer.js.map +1 -1
  226. package/dist/migrate-stuck-locks.d.ts +129 -0
  227. package/dist/migrate-stuck-locks.d.ts.map +1 -0
  228. package/dist/migrate-stuck-locks.js +355 -0
  229. package/dist/migrate-stuck-locks.js.map +1 -0
  230. package/dist/mint-adr.js +4 -4
  231. package/dist/mirror-pool-scan.d.ts +2 -2
  232. package/dist/mirror-pool-scan.js +3 -3
  233. package/dist/mirror-pool-scan.js.map +1 -1
  234. package/dist/needs-attention.d.ts +304 -27
  235. package/dist/needs-attention.d.ts.map +1 -1
  236. package/dist/needs-attention.js +542 -67
  237. package/dist/needs-attention.js.map +1 -1
  238. package/dist/orphan-sidecar.d.ts +10 -6
  239. package/dist/orphan-sidecar.d.ts.map +1 -1
  240. package/dist/orphan-sidecar.js +35 -2
  241. package/dist/orphan-sidecar.js.map +1 -1
  242. package/dist/pi-harness.d.ts +16 -0
  243. package/dist/pi-harness.d.ts.map +1 -1
  244. package/dist/pi-harness.js +82 -2
  245. package/dist/pi-harness.js.map +1 -1
  246. package/dist/placement.d.ts +8 -8
  247. package/dist/placement.js +3 -3
  248. package/dist/prd-to-spec.d.ts.map +1 -1
  249. package/dist/prd-to-spec.js +9 -5
  250. package/dist/prd-to-spec.js.map +1 -1
  251. package/dist/prompt.d.ts +16 -19
  252. package/dist/prompt.d.ts.map +1 -1
  253. package/dist/prompt.js +17 -19
  254. package/dist/prompt.js.map +1 -1
  255. package/dist/protocol/CLAIM-PROTOCOL.md +17 -10
  256. package/dist/protocol/REVIEW-PROTOCOL.md +4 -1
  257. package/dist/protocol/SURFACE-PROTOCOL.md +16 -2
  258. package/dist/protocol/TASKING-PROTOCOL.md +3 -1
  259. package/dist/protocol/WORK-CONTRACT.md +22 -18
  260. package/dist/protocol/task-template.md +1 -1
  261. package/dist/readiness.d.ts +1 -1
  262. package/dist/reap-branches.d.ts +12 -9
  263. package/dist/reap-branches.d.ts.map +1 -1
  264. package/dist/reap-branches.js +25 -7
  265. package/dist/reap-branches.js.map +1 -1
  266. package/dist/recover-isolated.d.ts +12 -0
  267. package/dist/recover-isolated.d.ts.map +1 -1
  268. package/dist/recover-isolated.js +6 -1
  269. package/dist/recover-isolated.js.map +1 -1
  270. package/dist/repo-config.d.ts +23 -2
  271. package/dist/repo-config.d.ts.map +1 -1
  272. package/dist/repo-config.js +64 -18
  273. package/dist/repo-config.js.map +1 -1
  274. package/dist/repo-mirror.d.ts.map +1 -1
  275. package/dist/repo-mirror.js +18 -2
  276. package/dist/repo-mirror.js.map +1 -1
  277. package/dist/review-gate.d.ts +3 -3
  278. package/dist/review-gate.d.ts.map +1 -1
  279. package/dist/review-gate.js +11 -10
  280. package/dist/review-gate.js.map +1 -1
  281. package/dist/review-verdict.d.ts +2 -2
  282. package/dist/review-verdict.d.ts.map +1 -1
  283. package/dist/review-verdict.js +2 -2
  284. package/dist/review-verdict.js.map +1 -1
  285. package/dist/run.d.ts +2 -2
  286. package/dist/run.d.ts.map +1 -1
  287. package/dist/run.js +58 -23
  288. package/dist/run.js.map +1 -1
  289. package/dist/scan.d.ts +26 -17
  290. package/dist/scan.d.ts.map +1 -1
  291. package/dist/scan.js +29 -15
  292. package/dist/scan.js.map +1 -1
  293. package/dist/select-order.d.ts +1 -1
  294. package/dist/select-priority.d.ts +14 -14
  295. package/dist/select-priority.d.ts.map +1 -1
  296. package/dist/select-priority.js +5 -5
  297. package/dist/select-priority.js.map +1 -1
  298. package/dist/sidecar-apply.js +1 -1
  299. package/dist/sidecar-apply.js.map +1 -1
  300. package/dist/sidecar.d.ts +47 -12
  301. package/dist/sidecar.d.ts.map +1 -1
  302. package/dist/sidecar.js +84 -4
  303. package/dist/sidecar.js.map +1 -1
  304. package/dist/skills/answer-questions/SKILL.md +89 -0
  305. package/dist/skills/capture-signal/SKILL.md +52 -0
  306. package/dist/skills/convert-from-prd-to-spec/SKILL.md +90 -0
  307. package/dist/skills/drive-tasks/SKILL.md +218 -0
  308. package/dist/skills/from-idea/SKILL.md +83 -0
  309. package/dist/skills/merge-prs/SKILL.md +70 -0
  310. package/dist/skills/orchestrate/SKILL.md +101 -0
  311. package/dist/skills/promote/SKILL.md +35 -0
  312. package/dist/skills/review/SKILL.md +16 -0
  313. package/dist/skills/setup/SKILL.md +258 -0
  314. package/dist/skills/setup/protocol/ADR-FORMAT.md +47 -0
  315. package/dist/skills/setup/protocol/CLAIM-PROTOCOL.md +224 -0
  316. package/dist/skills/setup/protocol/REVIEW-PROTOCOL.md +122 -0
  317. package/dist/skills/setup/protocol/SURFACE-PROTOCOL.md +135 -0
  318. package/dist/skills/setup/protocol/TASKING-PROTOCOL.md +124 -0
  319. package/dist/skills/setup/protocol/WORK-CONTRACT.md +280 -0
  320. package/dist/skills/setup/protocol/spec-template.md +71 -0
  321. package/dist/skills/setup/protocol/task-template.md +65 -0
  322. package/dist/skills/surface-questions/SKILL.md +16 -0
  323. package/dist/skills/to-spec/SKILL.md +34 -0
  324. package/dist/skills/to-task/SKILL.md +19 -0
  325. package/dist/skills/triage-observations/SKILL.md +78 -0
  326. package/dist/skills/work/SKILL.md +51 -0
  327. package/dist/slug-namespace.d.ts +6 -6
  328. package/dist/slug-namespace.js +8 -8
  329. package/dist/slug-namespace.js.map +1 -1
  330. package/dist/spec-complete.d.ts.map +1 -1
  331. package/dist/spec-complete.js +4 -5
  332. package/dist/spec-complete.js.map +1 -1
  333. package/dist/start.d.ts +1 -1
  334. package/dist/start.d.ts.map +1 -1
  335. package/dist/start.js +54 -60
  336. package/dist/start.js.map +1 -1
  337. package/dist/status.d.ts +3 -3
  338. package/dist/status.js +4 -4
  339. package/dist/status.js.map +1 -1
  340. package/dist/surface-gate.d.ts +2 -2
  341. package/dist/surface-gate.d.ts.map +1 -1
  342. package/dist/surface-gate.js +10 -3
  343. package/dist/surface-gate.js.map +1 -1
  344. package/dist/surface-persist.d.ts +2 -2
  345. package/dist/surface-persist.d.ts.map +1 -1
  346. package/dist/surface-persist.js +1 -1
  347. package/dist/surface-persist.js.map +1 -1
  348. package/dist/tasker-review-loop.d.ts +11 -10
  349. package/dist/tasker-review-loop.d.ts.map +1 -1
  350. package/dist/tasker-review-loop.js +8 -8
  351. package/dist/tasker-review-loop.js.map +1 -1
  352. package/dist/tasking-eligibility.d.ts +21 -21
  353. package/dist/tasking-eligibility.d.ts.map +1 -1
  354. package/dist/tasking-eligibility.js +10 -10
  355. package/dist/tasking-lock.d.ts +10 -10
  356. package/dist/tasking-lock.d.ts.map +1 -1
  357. package/dist/tasking-lock.js +69 -49
  358. package/dist/tasking-lock.js.map +1 -1
  359. package/dist/tasking.d.ts +73 -39
  360. package/dist/tasking.d.ts.map +1 -1
  361. package/dist/tasking.js +309 -95
  362. package/dist/tasking.js.map +1 -1
  363. package/dist/triage-gate.d.ts +1 -1
  364. package/dist/triage-persist.d.ts +15 -11
  365. package/dist/triage-persist.d.ts.map +1 -1
  366. package/dist/triage-persist.js +48 -18
  367. package/dist/triage-persist.js.map +1 -1
  368. package/dist/vendor/incur/agents.d.ts +58 -0
  369. package/dist/vendor/incur/agents.d.ts.map +1 -0
  370. package/dist/vendor/incur/agents.js +343 -0
  371. package/dist/vendor/incur/agents.js.map +1 -0
  372. package/dist/verify-workflow-template.d.ts +1 -1
  373. package/dist/verify-workflow-template.js +3 -3
  374. package/dist/watch-session.d.ts +11 -3
  375. package/dist/watch-session.d.ts.map +1 -1
  376. package/dist/watch-session.js +94 -7
  377. package/dist/watch-session.js.map +1 -1
  378. package/dist/work-layout.d.ts +15 -9
  379. package/dist/work-layout.d.ts.map +1 -1
  380. package/dist/work-layout.js +14 -9
  381. package/dist/work-layout.js.map +1 -1
  382. package/dist/workspace.d.ts +2 -2
  383. package/package.json +2 -2
  384. package/src/advance-ci-template.ts +4 -4
  385. package/src/advance-classify.ts +5 -5
  386. package/src/advance-drivers.ts +26 -13
  387. package/src/advance-isolated.ts +3 -3
  388. package/src/advance-lifecycle-template.ts +98 -13
  389. package/src/advance-loop-driver.ts +3 -3
  390. package/src/advance-treeless-publish.ts +46 -1
  391. package/src/advance.ts +495 -115
  392. package/src/advancing-lock.ts +102 -7
  393. package/src/agent-launch.ts +37 -12
  394. package/src/agent-stop.ts +60 -2
  395. package/src/apply-decide.ts +38 -9
  396. package/src/apply-merge-action.ts +49 -11
  397. package/src/apply-persist.ts +236 -62
  398. package/src/apply-stuck-action.ts +260 -0
  399. package/src/brand.ts +14 -2
  400. package/src/buildable-body.ts +14 -14
  401. package/src/claim-cas.ts +4 -4
  402. package/src/cli-spinner.ts +1 -1
  403. package/src/cli.ts +472 -141
  404. package/src/close-job-template.ts +9 -9
  405. package/src/close-job.ts +26 -26
  406. package/src/complete.ts +121 -63
  407. package/src/concurrency.ts +1 -1
  408. package/src/config.ts +143 -49
  409. package/src/continue-branch.ts +23 -1
  410. package/src/cwd-section.ts +1 -1
  411. package/src/decision-engine.ts +57 -19
  412. package/src/do-autopick.ts +21 -10
  413. package/src/do-config.ts +7 -7
  414. package/src/do-remote-auto.ts +2 -2
  415. package/src/do.ts +558 -85
  416. package/src/drop-source.ts +2 -2
  417. package/src/env-config.ts +19 -11
  418. package/src/failure-cause.ts +30 -1
  419. package/src/format.ts +13 -33
  420. package/src/frontmatter.ts +55 -35
  421. package/src/gc.ts +172 -9
  422. package/src/github.ts +78 -0
  423. package/src/harness.ts +25 -0
  424. package/src/index.ts +10 -0
  425. package/src/install-ci-branch-protection.ts +283 -58
  426. package/src/install-ci-capabilities/advance-lifecycle.ts +1 -1
  427. package/src/install-ci-capabilities/close-job.ts +1 -1
  428. package/src/install-ci-capabilities/example-noop.ts +1 -1
  429. package/src/install-ci-capabilities/intake.ts +2 -2
  430. package/src/install-ci-capabilities/verify.ts +1 -1
  431. package/src/install-ci-core.ts +34 -7
  432. package/src/install-ci-github.ts +87 -1
  433. package/src/install-ci.ts +4 -4
  434. package/src/install-skills.ts +166 -0
  435. package/src/intake-event.ts +6 -6
  436. package/src/intake-marker.ts +3 -3
  437. package/src/intake-triage.ts +2 -2
  438. package/src/intake-trigger-template.ts +18 -18
  439. package/src/intake.ts +138 -103
  440. package/src/integration-core.ts +234 -100
  441. package/src/integrator.ts +22 -9
  442. package/src/isolation.ts +13 -4
  443. package/src/issue-provider.ts +4 -4
  444. package/src/item-lock.ts +505 -361
  445. package/src/item-path.ts +2 -2
  446. package/src/ledger-lint.ts +9 -9
  447. package/src/ledger-read.ts +81 -81
  448. package/src/ledger-write.ts +137 -152
  449. package/src/lifecycle-gather.ts +45 -22
  450. package/src/lifecycle-pools.ts +71 -13
  451. package/src/merge-question-surfacer.ts +32 -8
  452. package/src/migrate-stuck-locks.ts +451 -0
  453. package/src/mint-adr.ts +4 -4
  454. package/src/mirror-pool-scan.ts +5 -5
  455. package/src/needs-attention.ts +877 -104
  456. package/src/orphan-sidecar.ts +49 -8
  457. package/src/pi-harness.ts +82 -2
  458. package/src/placement.ts +8 -8
  459. package/src/prd-to-spec.ts +13 -5
  460. package/src/prompt.ts +20 -25
  461. package/src/readiness.ts +1 -1
  462. package/src/reap-branches.ts +38 -14
  463. package/src/recover-isolated.ts +18 -1
  464. package/src/repo-config.ts +66 -17
  465. package/src/repo-mirror.ts +23 -1
  466. package/src/review-gate.ts +12 -11
  467. package/src/review-verdict.ts +3 -3
  468. package/src/run.ts +69 -23
  469. package/src/scan.ts +36 -22
  470. package/src/select-order.ts +1 -1
  471. package/src/select-priority.ts +15 -15
  472. package/src/sidecar-apply.ts +1 -1
  473. package/src/sidecar.ts +141 -14
  474. package/src/slug-namespace.ts +10 -10
  475. package/src/spec-complete.ts +4 -5
  476. package/src/start.ts +57 -63
  477. package/src/status.ts +7 -7
  478. package/src/surface-gate.ts +12 -5
  479. package/src/surface-persist.ts +3 -3
  480. package/src/tasker-review-loop.ts +18 -17
  481. package/src/tasking-eligibility.ts +21 -21
  482. package/src/tasking-lock.ts +75 -60
  483. package/src/tasking.ts +381 -135
  484. package/src/triage-gate.ts +1 -1
  485. package/src/triage-persist.ts +71 -27
  486. package/src/vendor/incur/LICENSE +21 -0
  487. package/src/vendor/incur/README.md +19 -0
  488. package/src/vendor/incur/agents.ts +392 -0
  489. package/src/verify-workflow-template.ts +3 -3
  490. package/src/watch-session.ts +102 -7
  491. package/src/work-layout.ts +14 -9
  492. package/src/workspace.ts +2 -2
package/src/intake.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import {existsSync, mkdirSync, readFileSync, writeFileSync} from 'node:fs';
2
2
  import {dirname, join} from 'node:path';
3
3
  import {runAsync, type RunResult} from './git.js';
4
- import {workFolderRel, workItemRel} from './work-layout.js';
4
+ import {workFolderRel, workFolderPrefix, workItemRel} from './work-layout.js';
5
5
  import {paramCase} from './brand.js';
6
6
  import {
7
7
  performIntegration,
@@ -48,7 +48,7 @@ import {triageIntake, type IntakeTriageDecision} from './intake-triage.js';
48
48
  import {renderTaskBody, renderSpecBody} from './buildable-body.js';
49
49
 
50
50
  /**
51
- * **`intake <N>`** (prd `issue-intake`, task `intake-tracer-slice-outcome`): the
51
+ * **`intake <N>`** (spec `issue-intake`, task `intake-tracer-slice-outcome`): the
52
52
  * KEYSTONE of the issue front-door. A new, GATE-FREE command — explicit invocation
53
53
  * IS the authorization (precedent: `explicit-do-prd-not-gated-by-autoslice`), so
54
54
  * `autoTask`/`autoBuild` config does NOT apply — that reads a GitHub issue + its
@@ -62,24 +62,24 @@ import {renderTaskBody, renderSpecBody} from './buildable-body.js';
62
62
  * prompt's JUDGEMENT is NOT unit-tested (like the review prompt's is not); only the
63
63
  * dispatch is.
64
64
  *
65
- * The dispatcher implements the FULL four-outcome decision table (prd
65
+ * The dispatcher implements the FULL four-outcome decision table (spec
66
66
  * `issue-intake` — the source of truth):
67
67
  * - **ASK** (not clear enough to act on): `postIssueComment` the next clarifying
68
68
  * question; emit NOTHING; STOP.
69
69
  * - **TASK** (clear AND fits ONE tracer-bullet task): write
70
- * `work/backlog/<slug>.md` (`covers: []`, NO `prd:`) carrying `issue: N` (the
70
+ * `work/backlog/<slug>.md` (`covers: []`, NO `spec:`) carrying `issue: N` (the
71
71
  * lone-task closure link, NOT `Fixes #N`), integrate via {@link
72
72
  * performIntegration} (default `propose`).
73
- * - **PRD** (clear AND coherent but >1 task — INCLUDING a coupled-but-SMALL pair,
74
- * which is NEVER bounced): write the prd file (`work/prds/ready/<slug>.md`) with `issue: N` (+ the gate
75
- * axes the verdict carried), integrate, STOP (tasking is the separate `do prd:`
73
+ * - **SPEC** (clear AND coherent but >1 task — INCLUDING a coupled-but-SMALL pair,
74
+ * which is NEVER bounced): write the spec file (`work/specs/ready/<slug>.md`) with `issue: N` (+ the gate
75
+ * axes the verdict carried), integrate, STOP (tasking is the separate `do spec:`
76
76
  * step).
77
77
  * - **BOUNCE** (genuinely UNRELATED concerns — no shared vision): the bounce is
78
78
  * TERMINAL (the asks are unrelated and must be re-filed), so intake CLOSES the
79
79
  * issue ATOMICALLY — the "file separate issues" text as the closing comment +
80
80
  * `reason: not planned` (the honest GitHub-native signal) in ONE `closeIssue`
81
81
  * call; emit NOTHING. Intake closes on BOUNCE (as not planned); NEVER on
82
- * task/prd (CI's close-job closes those via the `issue:` field) / ask.
82
+ * task/spec (CI's close-job closes those via the `issue:` field) / ask.
83
83
  *
84
84
  * The per-outcome integration KNOBS, the processing LOCK, and event-classification
85
85
  * are LATER tasks and are NOT built here (default `propose` is fine here).
@@ -92,10 +92,10 @@ import {renderTaskBody, renderSpecBody} from './buildable-body.js';
92
92
 
93
93
  /**
94
94
  * The four outcomes the decision prompt classifies an issue into (the decision
95
- * table). EXPAND step (prd
95
+ * table). EXPAND step (spec
96
96
  * `prd-to-spec-vocabulary-cutover-and-migration-command`): the `spec` outcome
97
97
  * names the "clear + coherent but >1 task" classification (a parent SPEC). HARD
98
- * CUTOVER (contract step): the legacy `prd` outcome token is GONE — the prompt
98
+ * CUTOVER (contract step): the legacy ''prd'' outcome token is GONE — the prompt
99
99
  * emits `spec` and the parser rejects any other token.
100
100
  */
101
101
  export type IntakeOutcome = 'ask' | 'task' | 'spec' | 'bounce';
@@ -122,7 +122,7 @@ export interface IntakeVerdict {
122
122
  /**
123
123
  * The drafted task BODY (`task` outcome) — the markdown AFTER the frontmatter
124
124
  * (the `## What to build` / `## Acceptance criteria` / `## Prompt` sections). The
125
- * dispatcher writes the frontmatter (slug/title/`covers: []`, NO `prd:`) carrying
125
+ * dispatcher writes the frontmatter (slug/title/`covers: []`, NO `spec:`) carrying
126
126
  * the lone-task `issue: N` closure link itself; the agent never writes
127
127
  * git-visible files.
128
128
  */
@@ -151,7 +151,7 @@ export interface IntakeVerdict {
151
151
  specBody?: string;
152
152
  /**
153
153
  * The spec's gate axes (`spec` outcome) AS THE PROMPT JUDGED THEM — surfaced onto
154
- * the emitted spec frontmatter (prd `issue-intake` US #8: "the emitted artifact
154
+ * the emitted spec frontmatter (spec `issue-intake` US #8: "the emitted artifact
155
155
  * carries … its own gate axes"). Both omitted (undeclared) by default; the prompt
156
156
  * sets `specHumanOnly: true` when a human should drive the TASKING and/or
157
157
  * `specNeedsAnswers: true` when open questions remain.
@@ -186,16 +186,16 @@ export interface IntakeResult {
186
186
  outcome: IntakeRunOutcome;
187
187
  /** The issue number acted on. */
188
188
  issueNumber: number;
189
- /** The slug of the emitted artifact (task OR prd outcome). */
189
+ /** The slug of the emitted artifact (task OR spec outcome). */
190
190
  emittedSlug?: string;
191
- /** Repo-relative path of the emitted artifact (task OR prd outcome). */
191
+ /** Repo-relative path of the emitted artifact (task OR spec outcome). */
192
192
  emitted?: string;
193
193
  /** True iff a comment was posted on the issue (ask / bounce outcomes). */
194
194
  commented?: boolean;
195
195
  /**
196
196
  * True iff the ISSUE was closed (the BOUNCE outcome — a terminal bounce closes
197
197
  * the issue atomically as `not planned`). Additive (mirrors {@link commented}),
198
- * so CI / callers can observe the close. Never set on ask/task/prd.
198
+ * so CI / callers can observe the close. Never set on ask/task/spec.
199
199
  */
200
200
  closed?: boolean;
201
201
  /** Human-readable summary of the terminal condition. */
@@ -253,10 +253,10 @@ export interface PerformIntakeOptions {
253
253
  /** The HOST-ONLY sessions root for the pi session file. */
254
254
  sessionsDir?: string;
255
255
  /**
256
- * The PER-OUTCOME integration modes (prd `issue-intake` US #9) the emitted artifact integrates
256
+ * The PER-OUTCOME integration modes (spec `issue-intake` US #9) the emitted artifact integrates
257
257
  * THROUGH the shared core with. Because `intake` decides the artifact TYPE at
258
258
  * RUNTIME, the mode is keyed per type: an emitted task integrates with
259
- * `integration.task`, an emitted prd with `integration.prd` (`propose` =
259
+ * `integration.task`, an emitted spec with `integration.spec` (`propose` =
260
260
  * push the `work/<slug>` branch + open a PR, NO `main` touch; `merge` = land on
261
261
  * `main`). The CLI resolves this from the granular + aggregate flags via
262
262
  * {@link resolveIntakeIntegrationModes}; ask/bounce emit nothing, so the modes
@@ -266,8 +266,8 @@ export interface PerformIntakeOptions {
266
266
  /**
267
267
  * **The ORIGIN-TRUST verdict, passed IN** (task
268
268
  * `untrusted-origin-forces-build-propose`; the `--origin-trust <trusted|untrusted>`
269
- * CLI flag). `intake` STAMPS `origin: issue` + this `originTrust` onto every prd/
270
- * task it emits, so the author-trust signal SURVIVES the prd/task merge
269
+ * CLI flag). `intake` STAMPS `origin: issue` + this `originTrust` onto every spec/
270
+ * task it emits, so the author-trust signal SURVIVES the spec/task merge
271
271
  * boundary (a landed-on-main artifact otherwise erases how it was born, the
272
272
  * laundering gap). `intake` does NOT resolve trust itself: the verdict is CI's
273
273
  * POLICY, computed in the `intake.yml` shell from the SAME `author_association`
@@ -285,7 +285,7 @@ export interface PerformIntakeOptions {
285
285
  */
286
286
  noPR?: boolean;
287
287
  /**
288
- * **The per-repo PRD-PLACEMENT default, passed IN** (prd
288
+ * **The per-repo SPEC-PLACEMENT default, passed IN** (spec
289
289
  * `staging-pool-position-gate-and-trust-model` US #2/#5, task
290
290
  * `pre-prd-staging-pool-split-and-untrusted-prd-placement`). The resolved
291
291
  * per-repo default landing for `intake`-authored prds (`pre-proposed` =
@@ -293,8 +293,8 @@ export interface PerformIntakeOptions {
293
293
  * into the shared placement resolver (`src/placement.ts`). The resolver
294
294
  * overlays an EXPLICIT operator flag ({@link explicitSpecsLandIn}, top) and
295
295
  * the UNTRUSTED-ORIGIN force (`originTrust: untrusted` ⇒ staging) on top.
296
- * Unset ⇒ the resolver's built-in floor applies (`staging` = `prds/proposed/`,
297
- * the conservative landing). The PRD TWIN of `tasksLandIn` on the tasker
296
+ * Unset ⇒ the resolver's built-in floor applies (`staging` = `specs/proposed/`,
297
+ * the conservative landing). The SPEC TWIN of `tasksLandIn` on the tasker
298
298
  * path — one resolver, two lifecycles.
299
299
  */
300
300
  specsLandIn?: SpecsLandIn;
@@ -325,6 +325,19 @@ export interface PerformIntakeOptions {
325
325
  * must not act as the bot. Absent ⇒ ambient (today's behaviour).
326
326
  */
327
327
  identity?: Identity;
328
+ /**
329
+ * **The cross-job merge-serialiser CAS-retry cap** (config `mergeRetries`, spec
330
+ * `land-time-reverify-and-parallel-merge-ceiling` Story 5 / Applied Answer q1
331
+ * (a)). Threaded VERBATIM into the shared integrate core so a wide-matrix CI's
332
+ * raised cap reaches intake's task/spec emit land tail too (task
333
+ * `thread-merge-retries-cross-task-and-ratify-default`). Resolved ONCE at the
334
+ * entry point (the CLI) through the env + per-repo layers of the gate-family
335
+ * precedence chain — the `intake` command has NO `--merge-retries` flag today
336
+ * (the flag layer legitimately does not apply here; intake is
337
+ * unattended-CI-first, env + per-repo cover the need). Unset ⇒ the engine's
338
+ * `DEFAULT_MERGE_RETRIES = 1000` (byte-for-byte unchanged).
339
+ */
340
+ mergeRetries?: number;
328
341
  /** Environment for child git/agent processes (the AGENT-launch ambient env). */
329
342
  env?: NodeJS.ProcessEnv;
330
343
  /** Sink for human-readable progress notes. */
@@ -334,15 +347,15 @@ export interface PerformIntakeOptions {
334
347
  const DEFAULT_ARBITER = 'origin';
335
348
 
336
349
  /**
337
- * **The STAGED-prds dir** (prd `staging-pool-position-gate-and-trust-model`,
350
+ * **The STAGED-prds dir** (spec `staging-pool-position-gate-and-trust-model`,
338
351
  * task `pre-prd-staging-pool-split-and-untrusted-prd-placement`, governing
339
352
  * ADR `placement-is-runner-deterministic-humanonly-is-agent-judgement`). When
340
353
  * the runner-deterministic placement resolver picks the staging side for an
341
- * `intake`-authored prd, the runner writes the prd file HERE instead of in
342
- * `work/prds/ready/`. An item born in `prds/proposed/` is durable + readable but NOT in
343
- * the tasking candidate POOL (`work/prds/ready/` is the pool). A runner/human-owned promotion
344
- * ({@link promoteFromPreSpec} in `needs-attention.ts`) moves an approved prd
345
- * `prds/proposed/ → prds/ready/` to make it taskable.
354
+ * `intake`-authored spec, the runner writes the spec file HERE instead of in
355
+ * `work/specs/ready/`. An item born in `specs/proposed/` is durable + readable but NOT in
356
+ * the tasking candidate POOL (`work/specs/ready/` is the pool). A runner/human-owned promotion
357
+ * ({@link promoteFromPreSpec} in `needs-attention.ts`) moves an approved spec
358
+ * `specs/proposed/ → specs/ready/` to make it taskable.
346
359
  */
347
360
  export const STAGED_SPECS_DIR = workFolderRel('specs-proposed');
348
361
 
@@ -377,19 +390,19 @@ function specLandingToSide(
377
390
 
378
391
  /**
379
392
  * The emitted artifact TYPE `intake` decides at RUNTIME — a `task` verdict emits
380
- * `work/backlog/<slug>.md`, a `prd` verdict emits the prd file (`work/prds/ready/<slug>.md`). The two
393
+ * `work/backlog/<slug>.md`, a `spec` verdict emits the spec file (`work/specs/ready/<slug>.md`). The two
381
394
  * granular flag axes (`--merge-task`/`--propose-task` vs `--merge-spec`/
382
395
  * `--propose-spec`) are keyed on this. (ask/bounce emit NOTHING, so the modes are
383
396
  * no-ops for them.)
384
397
  */
385
398
  export type IntakeArtifactType = 'task' | 'spec';
386
- // prd → spec cutover (MIGRATE batch): `'spec'` is the CANONICAL artifact type;
387
- // `'prd'` stays as an accepted ALIAS until the contract task removes it.
399
+ // ''prd'' → `spec` HARD CUTOVER: `'spec'` is the ONLY spec artifact type value; the
400
+ // legacy ''prd'' alias is GONE (the contract task removed it).
388
401
 
389
402
  /**
390
- * The PER-OUTCOME integration mode FLAG SET (prd `issue-intake` US #9). Because
403
+ * The PER-OUTCOME integration mode FLAG SET (spec `issue-intake` US #9). Because
391
404
  * `intake` decides the artifact TYPE at runtime, a single `--merge`/`--propose`
392
- * cannot express a type-conditional policy ("merge a prd but propose a task") —
405
+ * cannot express a type-conditional policy ("merge a spec but propose a task") —
393
406
  * hence the four GRANULAR per-type flags layered over the two AGGREGATES:
394
407
  *
395
408
  * - **granular:** `--merge-spec`/`--propose-spec` apply iff the outcome is a spec;
@@ -400,9 +413,9 @@ export type IntakeArtifactType = 'task' | 'spec';
400
413
  * author-trust) is CI's POLICY, authored in `runner-in-ci` — NOT here.
401
414
  */
402
415
  export interface IntakeIntegrationFlags {
403
- /** Aggregate: merge BOTH a task and a prd (the broad knob, overridden per type). */
416
+ /** Aggregate: merge BOTH a task and a spec (the broad knob, overridden per type). */
404
417
  merge?: boolean;
405
- /** Aggregate: propose BOTH a task and a prd. */
418
+ /** Aggregate: propose BOTH a task and a spec. */
406
419
  propose?: boolean;
407
420
  /** Granular: merge a spec (overrides the aggregate for the spec outcome). */
408
421
  mergeSpec?: boolean;
@@ -419,7 +432,7 @@ export interface IntakeIntegrationModes {
419
432
  /** The mode an EMITTED task integrates with. */
420
433
  task: IntegrationMode;
421
434
  /**
422
- * The mode an EMITTED spec integrates with. `spec` is the CANONICAL key (prd →
435
+ * The mode an EMITTED spec integrates with. `spec` is the CANONICAL key (spec →
423
436
  * spec cutover); the user-facing `--merge-spec`/`--propose-spec` flags that FEED
424
437
  * it carry the same `spec` spelling (the cli-flag rename landed in batch 4f).
425
438
  */
@@ -453,10 +466,10 @@ function granularFromFlags(
453
466
  }
454
467
 
455
468
  /**
456
- * The PURE per-outcome integration mode resolution (prd `issue-intake` US #9 —
469
+ * The PURE per-outcome integration mode resolution (spec `issue-intake` US #9 —
457
470
  * the canonical table). Given ONLY the flag set, resolve BOTH per-type modes in
458
471
  * one eager pass (so a usage error is caught before the runtime verdict is even
459
- * known). The rules, all decided in the prd:
472
+ * known). The rules, all decided in the spec:
460
473
  *
461
474
  * - **unset ⇒ propose for BOTH** (conservative default; matches `do`).
462
475
  * - **aggregates:** `--merge` ⇒ merge both; `--propose` ⇒ propose both (this axis
@@ -574,7 +587,7 @@ export async function performIntake(
574
587
  return {exitCode: 1, outcome: 'usage-error', issueNumber, message};
575
588
  }
576
589
 
577
- // 2. ACQUIRE the `processing` LOCK (prd `issue-intake` US #10): a TRANSIENT concurrency mutex
590
+ // 2. ACQUIRE the `processing` LOCK (spec `issue-intake` US #10): a TRANSIENT concurrency mutex
578
591
  // that serialises two concurrent runs on the SAME issue. Read the labels; if
579
592
  // the lock is ALREADY present, BACK OFF (do nothing — another run owns it). The
580
593
  // winner ADDS the label and proceeds; the label is REMOVED on finish (success
@@ -815,12 +828,12 @@ async function decideAndDispatch(
815
828
  return {exitCode: 1, outcome: 'agent-failed', issueNumber, message};
816
829
  }
817
830
 
818
- // DISPATCH on the verdict — the FULL four-outcome decision table (prd
831
+ // DISPATCH on the verdict — the FULL four-outcome decision table (spec
819
832
  // `issue-intake`). The agent only DRAFTED the verdict; the runner owns every
820
833
  // git/seam side-effect below (the in-band boundary): the write + integrate
821
- // (task/prd) and the `postIssueComment` (ask/bounce).
834
+ // (task/spec) and the `postIssueComment` (ask/bounce).
822
835
  //
823
- // PER-OUTCOME integration (prd `issue-intake` US #9): the resolved mode is keyed on the runtime
836
+ // PER-OUTCOME integration (spec `issue-intake` US #9): the resolved mode is keyed on the runtime
824
837
  // artifact TYPE — a `task` verdict integrates with the task mode, a `spec`
825
838
  // verdict with the spec mode. Unset ⇒ propose for both. ask/bounce never
826
839
  // integrate, so the modes are no-ops for them.
@@ -837,6 +850,9 @@ async function decideAndDispatch(
837
850
  cwd,
838
851
  arbiter,
839
852
  integration: modes.task,
853
+ // The resolved cross-job CAS-retry cap (config `mergeRetries`) — threaded so
854
+ // intake's lone-task emit lands under the same per-repo cap the build path uses.
855
+ mergeRetries: options.mergeRetries,
840
856
  // The origin-trust STAMP, passed IN (not resolved here): the emitted task
841
857
  // carries `origin: issue` + this verdict so the becomes-code checkpoint is
842
858
  // not laundered. Unset ⇒ unstamped (a local intake ⇒ human/trusted).
@@ -855,7 +871,7 @@ async function decideAndDispatch(
855
871
  note,
856
872
  });
857
873
  // The `spec` outcome is the parent-spec verdict; it dispatches through
858
- // `modes.spec`. HARD CUTOVER: the legacy `prd` outcome case is GONE.
874
+ // `modes.spec`. HARD CUTOVER: the legacy ''prd'' outcome case is GONE.
859
875
  case 'spec':
860
876
  return dispatchSpec({
861
877
  verdict,
@@ -863,7 +879,10 @@ async function decideAndDispatch(
863
879
  cwd,
864
880
  arbiter,
865
881
  integration: modes.spec,
866
- // Same origin-trust stamp on the prd outcome (propagated onto its tasks
882
+ // The resolved cross-job CAS-retry cap (config `mergeRetries`) — threaded so
883
+ // intake's spec emit lands under the same per-repo cap the build path uses.
884
+ mergeRetries: options.mergeRetries,
885
+ // Same origin-trust stamp on the spec outcome (propagated onto its tasks
867
886
  // later by the tasker). Passed IN; not resolved here.
868
887
  originTrust: options.originTrust,
869
888
  noPR: options.noPR,
@@ -871,7 +890,7 @@ async function decideAndDispatch(
871
890
  // `pre-prd-staging-pool-split-and-untrusted-prd-placement`): the
872
891
  // configured-default + explicit-flag rungs, fed into the SHARED placement
873
892
  // resolver alongside the `originTrust` stamp above. The resolver decides
874
- // `prds/proposed/` (staging) vs `prds/ready/` (the tasking pool); `intake` never
893
+ // `specs/proposed/` (staging) vs `specs/ready/` (the tasking pool); `intake` never
875
894
  // places itself.
876
895
  specsLandIn: options.specsLandIn,
877
896
  explicitSpecsLandIn: options.explicitSpecsLandIn,
@@ -931,7 +950,7 @@ async function decideAndDispatch(
931
950
  *
932
951
  * - **ask** (non-terminal): `postIssueComment` the drafted question, emit NOTHING,
933
952
  * and LEAVE THE ISSUE OPEN — it waits for the thread to be answered (a later run
934
- * resumes from it). The task/prd path also never closes (CI's close-job does,
953
+ * resumes from it). The task/spec path also never closes (CI's close-job does,
935
954
  * via the `issue:` field). Intake closes ONLY on BOUNCE.
936
955
  * - **bounce** (TERMINAL): the asks are unrelated and must be re-filed, so an OPEN
937
956
  * issue is a dishonest "still in play" signal. Intake CLOSES the issue
@@ -1028,7 +1047,7 @@ async function dispatchComment(params: {
1028
1047
 
1029
1048
  /**
1030
1049
  * DISPATCH the `task` outcome: derive a content-derived slug, write
1031
- * `work/backlog/<slug>.md` (`covers: []`, NO `prd:`) carrying `issue: N` (the
1050
+ * `work/backlog/<slug>.md` (`covers: []`, NO `spec:`) carrying `issue: N` (the
1032
1051
  * lone-task closure link, NOT `Fixes #N`), and integrate via {@link
1033
1052
  * performIntegration}. The runner owns the git: it onboards a
1034
1053
  * `work/<slug>` branch off fresh `<arbiter>/main`, then the lifecycle `stage`
@@ -1041,6 +1060,8 @@ async function dispatchTask(params: {
1041
1060
  cwd: string;
1042
1061
  arbiter: string;
1043
1062
  integration: IntegrationMode;
1063
+ /** The resolved cross-job CAS-retry cap (undefined ⇒ engine default). */
1064
+ mergeRetries: number | undefined;
1044
1065
  /** The origin-trust stamp passed IN (unset ⇒ emit unstamped ⇒ human/trusted). */
1045
1066
  originTrust: OriginTrust | undefined;
1046
1067
  noPR: boolean | undefined;
@@ -1063,6 +1084,7 @@ async function dispatchTask(params: {
1063
1084
  cwd,
1064
1085
  arbiter,
1065
1086
  integration,
1087
+ mergeRetries,
1066
1088
  originTrust,
1067
1089
  noPR,
1068
1090
  providerInstance,
@@ -1074,7 +1096,7 @@ async function dispatchTask(params: {
1074
1096
  note,
1075
1097
  } = params;
1076
1098
 
1077
- // A content-derived slug — NEVER a counter (prd `issue-intake` US #8). Prefer the drafted
1099
+ // A content-derived slug — NEVER a counter (spec `issue-intake` US #8). Prefer the drafted
1078
1100
  // `taskSlug`, else derive from the drafted title; sanitise either through
1079
1101
  // `paramCase` so the filename + frontmatter slug are well-formed.
1080
1102
  const slug = resolveSlug(verdict);
@@ -1089,7 +1111,7 @@ async function dispatchTask(params: {
1089
1111
 
1090
1112
  // BOUNDED INTERNAL REVIEW (observation
1091
1113
  // `intake-lone-task-skips-adversarial-review-the-prd-path-gets`, rulings A/B/C):
1092
- // the `do prd:` path gets `runTaskReviewLoop`; the lone-TASK path got NOTHING.
1114
+ // the `do spec:` path gets `runTaskReviewLoop`; the lone-TASK path got NOTHING.
1093
1115
  // AFTER the `task` verdict and BEFORE the write/integrate, run a bounded (3-round,
1094
1116
  // HARD-CAPPED) adversarial self-review on the SINGLE drafted task. It mutates the
1095
1117
  // candidate body IN MEMORY (no `work/backlog/` write pre-convergence). A launch/
@@ -1185,6 +1207,12 @@ async function dispatchTask(params: {
1185
1207
  // EXPLICITLY-chosen mode proceeds as-is: a future `--merge-task` lands on main
1186
1208
  // (`merge` IS the auto-land mode, never downgraded).
1187
1209
  mode: integration,
1210
+ // The cross-job merge-serialiser CAS-retry cap (config `mergeRetries`) — the
1211
+ // git-alone floor of the cross-job land queue, resolved through the gate-
1212
+ // family precedence chain in the CLI and threaded here so intake's lone-task
1213
+ // emit lands under the same per-repo cap the build path uses. Unset ⇒ the
1214
+ // engine default (byte-for-byte unchanged).
1215
+ mergeRetries,
1188
1216
  noPR,
1189
1217
  providerInstance,
1190
1218
  type: 'feat',
@@ -1217,8 +1245,8 @@ async function dispatchTask(params: {
1217
1245
  }
1218
1246
 
1219
1247
  /**
1220
- * DISPATCH the `spec` outcome (canonical; the legacy `prd` outcome routes here too
1221
- * through the cutover): derive a content-derived slug, write the spec file
1248
+ * DISPATCH the `spec` outcome (the SOLE parent-spec outcome after the HARD CUTOVER;
1249
+ * the legacy ''prd'' outcome token is GONE): derive a content-derived slug, write the spec file
1222
1250
  * (`work/specs/ready/<slug>.md`) carrying `issue: N` (the loop-closure linkage the
1223
1251
  * close JOB reaches via `task.spec: → spec issue:`; on a fanned spec the number
1224
1252
  * lives ONLY on the spec — a fanned task uses `spec:`, NOT its own `issue:`, which
@@ -1234,6 +1262,8 @@ async function dispatchSpec(params: {
1234
1262
  cwd: string;
1235
1263
  arbiter: string;
1236
1264
  integration: IntegrationMode;
1265
+ /** The resolved cross-job CAS-retry cap (undefined ⇒ engine default). */
1266
+ mergeRetries: number | undefined;
1237
1267
  /** The origin-trust stamp passed IN (unset ⇒ emit unstamped ⇒ human/trusted). */
1238
1268
  originTrust: OriginTrust | undefined;
1239
1269
  noPR: boolean | undefined;
@@ -1255,6 +1285,7 @@ async function dispatchSpec(params: {
1255
1285
  cwd,
1256
1286
  arbiter,
1257
1287
  integration,
1288
+ mergeRetries,
1258
1289
  originTrust,
1259
1290
  noPR,
1260
1291
  specsLandIn,
@@ -1266,7 +1297,7 @@ async function dispatchSpec(params: {
1266
1297
  note,
1267
1298
  } = params;
1268
1299
 
1269
- // A content-derived slug — NEVER a counter (prd `issue-intake` US #8). Prefer the drafted
1300
+ // A content-derived slug — NEVER a counter (spec `issue-intake` US #8). Prefer the drafted
1270
1301
  // `specSlug`, else derive from the drafted title.
1271
1302
  const slug = resolveSpecSlug(verdict);
1272
1303
  if (slug === '') {
@@ -1279,7 +1310,7 @@ async function dispatchSpec(params: {
1279
1310
  // RUNNER-DETERMINISTIC PLACEMENT (task
1280
1311
  // `pre-prd-staging-pool-split-and-untrusted-prd-placement`, governing ADR
1281
1312
  // `placement-is-runner-deterministic-humanonly-is-agent-judgement`). Resolve
1282
- // which folder the runner writes the intake-authored prd into BEFORE handing
1313
+ // which folder the runner writes the intake-authored spec into BEFORE handing
1283
1314
  // it to the shared integrate band: the SAME precedence chain the tasker uses
1284
1315
  // (`explicit > untrusted-origin ⇒ staging > specsLandIn > built-in (staging)`),
1285
1316
  // the SAME shared resolver — only the lifecycle SLOTS differ. The agent
@@ -1317,16 +1348,20 @@ async function dispatchSpec(params: {
1317
1348
  slug,
1318
1349
  source: 'in-progress',
1319
1350
  recovering: false,
1320
- // An intake-emitted prd has no `verify` floor of its own (it is a new spec,
1351
+ // An intake-emitted spec has no `verify` floor of its own (it is a new spec,
1321
1352
  // not a build), exactly as the task branch + the tasking transition skip it.
1322
1353
  skipVerify: true,
1323
1354
  mode: integration,
1355
+ // The cross-job merge-serialiser CAS-retry cap (config `mergeRetries`) — same
1356
+ // rationale as the lone-task emit above; threaded so intake's spec emit lands
1357
+ // under the same per-repo cap. Unset ⇒ the engine default (byte-for-byte).
1358
+ mergeRetries,
1324
1359
  noPR,
1325
1360
  providerInstance,
1326
1361
  type: 'feat',
1327
1362
  lifecycle: {
1328
- // The emitted prd IS the title source. Pass the DRAFTED title EXPLICITLY (same
1329
- // race as the task path: `stage()` writes the prd file AFTER the title
1363
+ // The emitted spec IS the title source. Pass the DRAFTED title EXPLICITLY (same
1364
+ // race as the task path: `stage()` writes the spec file AFTER the title
1330
1365
  // read). `titlePath` stays set but is IGNORED while `title` is present.
1331
1366
  titlePath: join(cwd, relPath),
1332
1367
  title: verdict.specTitle ?? slug,
@@ -1384,9 +1419,9 @@ async function integrationToIntakeResult(
1384
1419
  core.integration?.mode === 'merge'
1385
1420
  ? 'landed it on the arbiter main'
1386
1421
  : 'opened a PR carrying it (main untouched)';
1387
- // Both a lone task and a prd carry `issue: N` as their closure link (the task
1388
- // closes its own issue; a prd is reached via `task.prd: → prd issue:`). On the
1389
- // task/prd path `intake` never closes the issue (CI's close-job does, via the
1422
+ // Both a lone task and a spec carry `issue: N` as their closure link (the task
1423
+ // closes its own issue; a spec is reached via `task.spec: → spec issue:`). On the
1424
+ // task/spec path `intake` never closes the issue (CI's close-job does, via the
1390
1425
  // `issue:` field; intake closes ONLY on BOUNCE) and emits no `Fixes #N` (a
1391
1426
  // deferred GitHub-only optimisation).
1392
1427
  const link = `issue: ${issueNumber}`;
@@ -1456,7 +1491,7 @@ async function integrationToIntakeResult(
1456
1491
  * `commit` (the additive {@link IntegrateResult.commit}) in merge. A degraded
1457
1492
  * propose (no `url`) or a failed merge-tip read (no `commit`) simply OMITS the
1458
1493
  * link — the comment still confirms what was created (the artifact is safe on the
1459
- * branch/main regardless). No prd link beyond the slug.
1494
+ * branch/main regardless). No spec link beyond the slug.
1460
1495
  * - carries the FULL intake MARKER via the SHARED {@link stampIntakeMarker} helper
1461
1496
  * (`kind=created slug=<slug> seen=<id>,…`) so the triage's `already-terminal`
1462
1497
  * branch consumes it — the comment cannot re-trigger intake.
@@ -1497,7 +1532,7 @@ export function composeIntakeCompletionComment(params: {
1497
1532
  * does, via the `issue:` field); this comment changes NO issue state.
1498
1533
  * - LINKS the artifact by INTEGRATION MODE: the PR `url` in propose, the landed
1499
1534
  * `commit` (the additive {@link IntegrateResult.commit} this task surfaces) in
1500
- * merge. No prd link beyond the slug.
1535
+ * merge. No spec link beyond the slug.
1501
1536
  * - carries the FULL intake MARKER via the SHARED {@link stampIntakeMarker} helper
1502
1537
  * (`kind=created slug=<slug> seen=<id>,…`). `kind=created` is TERMINAL, so the
1503
1538
  * triage's `already-terminal` branch then treats the issue as already-transformed
@@ -1558,7 +1593,7 @@ async function postCompletionComment(params: {
1558
1593
  }
1559
1594
 
1560
1595
  /**
1561
- * Resolve a content-derived slug from the verdict — NEVER a counter (prd `issue-intake` US #8).
1596
+ * Resolve a content-derived slug from the verdict — NEVER a counter (spec `issue-intake` US #8).
1562
1597
  * Prefer the drafted `taskSlug`, else derive from the drafted title; both go
1563
1598
  * through `paramCase` (the brand case-transform) so the result is a clean
1564
1599
  * lowercase-`-`-joined slug. An empty result (no slug AND no title) signals the
@@ -1573,7 +1608,7 @@ function resolveSlug(verdict: IntakeVerdict): string {
1573
1608
  }
1574
1609
 
1575
1610
  /**
1576
- * Resolve a content-derived slug for the spec outcome — NEVER a counter (prd `issue-intake` US #8).
1611
+ * Resolve a content-derived slug for the spec outcome — NEVER a counter (spec `issue-intake` US #8).
1577
1612
  * Prefer the drafted `specSlug`, else derive from the drafted spec title; both go
1578
1613
  * through `paramCase`. An empty result signals the caller to refuse.
1579
1614
  */
@@ -1587,13 +1622,13 @@ function resolveSpecSlug(verdict: IntakeVerdict): string {
1587
1622
 
1588
1623
  /**
1589
1624
  * Render the backlog task file: the frontmatter (`title`/`slug`/`covers: []`, NO
1590
- * `prd:` — its own source of truth, prd `issue-intake` decision table) carrying the lone-task
1625
+ * `spec:` — its own source of truth, spec `issue-intake` decision table) carrying the lone-task
1591
1626
  * `issue: N` closure link + the drafted body. The task closes its source issue
1592
1627
  * via its `issue:` field (the provider-agnostic link a FUTURE CI close-job reads
1593
1628
  * from folder + field state); it carries NO `Fixes #N` (a deferred GitHub-only
1594
1629
  * optimisation, structurally unplaceable on the `--merge` path). The number is
1595
- * the task's own closure path — `issue:` XOR `prd:`; a lone task never carries a
1596
- * `prd:` (prd `issue-intake` decision table). When the agent drafted no body, a thin default
1630
+ * the task's own closure path — `issue:` XOR `spec:`; a lone task never carries a
1631
+ * `spec:` (spec `issue-intake` decision table). When the agent drafted no body, a thin default
1597
1632
  * scaffold keeps the file a valid task.
1598
1633
  */
1599
1634
  export function renderBacklogTask(params: {
@@ -1623,7 +1658,7 @@ export function renderBacklogTask(params: {
1623
1658
  const frontmatter = lines.join('\n');
1624
1659
  // The drafted body (agent-authored, headings and all) is wrapped VERBATIM.
1625
1660
  // Only the empty-body DEFAULT SCAFFOLD is sourced from the shared section
1626
- // skeleton owner (`renderTaskBody`, prd
1661
+ // skeleton owner (`renderTaskBody`, spec
1627
1662
  // `centralize-buildable-task-renderer-shared-by-intake-and-promotion` US #2),
1628
1663
  // so intake's fallback and promotion's body cannot drift on section
1629
1664
  // names/order. The shared renderer ends its body with a trailing newline (its
@@ -1642,16 +1677,16 @@ export function renderBacklogTask(params: {
1642
1677
  }
1643
1678
 
1644
1679
  /**
1645
- * Render the emitted prd file: the frontmatter (`title`/`slug` + the loop-closure
1646
- * `issue: N` + the gate axes the prompt JUDGED) followed by the drafted prd body.
1647
- * For a FANNED prd the `issue: N` lives ONLY on the prd — never duplicated across
1648
- * the N fanned tasks, which reach it via `task.prd: → prd issue:` (a fanned
1649
- * task carries `prd:`, NOT its own `issue:`; the lone-task outcome is the only
1650
- * one that puts `issue:` on a task). The close JOB reaches the prd's number via
1651
- * `task.prd: → prd issue:`. The gate axes (`humanOnly`/`needsAnswers`) are emitted ONLY when the
1680
+ * Render the emitted spec file: the frontmatter (`title`/`slug` + the loop-closure
1681
+ * `issue: N` + the gate axes the prompt JUDGED) followed by the drafted spec body.
1682
+ * For a FANNED spec the `issue: N` lives ONLY on the spec — never duplicated across
1683
+ * the N fanned tasks, which reach it via `task.spec: → spec issue:` (a fanned
1684
+ * task carries `spec:`, NOT its own `issue:`; the lone-task outcome is the only
1685
+ * one that puts `issue:` on a task). The close JOB reaches the spec's number via
1686
+ * `task.spec: → spec issue:`. The gate axes (`humanOnly`/`needsAnswers`) are emitted ONLY when the
1652
1687
  * verdict declared them `true` — an omitted axis is `undefined` (undeclared), the
1653
1688
  * same convention `frontmatter.ts` parses. When the agent drafted no body, a thin
1654
- * default scaffold keeps the file a valid prd that `do prd:` can later task.
1689
+ * default scaffold keeps the file a valid spec that `do spec:` can later task.
1655
1690
  */
1656
1691
  export function renderSpec(params: {
1657
1692
  slug: string;
@@ -1682,7 +1717,7 @@ export function renderSpec(params: {
1682
1717
  if (originTrust !== undefined) {
1683
1718
  lines.push('origin: issue', `originTrust: ${originTrust}`);
1684
1719
  }
1685
- // Surface the gate axes AS THE PROMPT JUDGED THEM (prd `issue-intake` US #8). Only emit a `true`
1720
+ // Surface the gate axes AS THE PROMPT JUDGED THEM (spec `issue-intake` US #8). Only emit a `true`
1686
1721
  // axis — an undeclared axis stays absent (parsed as `undefined`).
1687
1722
  if (humanOnly === true) {
1688
1723
  lines.push('humanOnly: true');
@@ -1692,11 +1727,11 @@ export function renderSpec(params: {
1692
1727
  }
1693
1728
  lines.push('---');
1694
1729
  const frontmatter = lines.join('\n');
1695
- // As with `renderBacklogTask`: the drafted PRD body is wrapped VERBATIM; only
1730
+ // As with `renderBacklogTask`: the drafted SPEC body is wrapped VERBATIM; only
1696
1731
  // the empty-body DEFAULT SCAFFOLD is sourced from the shared section skeleton
1697
- // owner (`renderSpecBody` with `solution` + `userStories`, prd
1732
+ // owner (`renderSpecBody` with `solution` + `userStories`, spec
1698
1733
  // `centralize-buildable-task-renderer-shared-by-intake-and-promotion` US #2),
1699
- // so intake's PRD fallback and promotion's PRD body cannot drift. `trimEnd()`
1734
+ // so intake's SPEC fallback and promotion's SPEC body cannot drift. `trimEnd()`
1700
1735
  // drops the renderer's trailing blank line so intake's single trailing `\n`
1701
1736
  // (owned by the join below) keeps the bytes identical to the pre-rewire literal.
1702
1737
  const drafted =
@@ -1704,7 +1739,7 @@ export function renderSpec(params: {
1704
1739
  ? body.trim()
1705
1740
  : renderSpecBody({
1706
1741
  problemStatement: `Transformed from issue #${issueNumber}: ${title}`,
1707
- solution: '(to be detailed; this prd needs tasking via `do prd:`).',
1742
+ solution: '(to be detailed; this spec needs tasking via `do spec:`).',
1708
1743
  userStories: `1. As a user, I want issue #${issueNumber} addressed.`,
1709
1744
  }).trimEnd();
1710
1745
  return `${frontmatter}\n\n${drafted}\n`;
@@ -1737,7 +1772,7 @@ async function stageIntakeContent(params: {
1737
1772
  * `intake-` PRODUCER prefix keeps this short-lived "create the item" branch
1738
1773
  * DISTINCT from the later build branch (`work/task-<slug>`) for the same slug
1739
1774
  * — the firing `intake` × `do task:` collision the observation traced. The
1740
- * task-emit path passes `'task'`, the prd-emit path `'prd'`. A pre-existing
1775
+ * task-emit path passes `'task'`, the spec-emit path `'spec'`. A pre-existing
1741
1776
  * local branch (a re-run) is force-recreated off fresh main.
1742
1777
  */
1743
1778
  async function switchToWorkBranch(
@@ -1782,7 +1817,7 @@ async function runDecision(
1782
1817
  if (options.decide) {
1783
1818
  return options.decide({cwd, issue, comments, prompt, env: options.env});
1784
1819
  }
1785
- // PRODUCTION: launch the harness with the decision prd, then PARSE the verdict
1820
+ // PRODUCTION: launch the harness with the decision spec, then PARSE the verdict
1786
1821
  // the agent emitted out of its ANSWER channel (`launched.output`) — the SAME wire
1787
1822
  // the review gate runs (launch → `parseReviewVerdict(readOutput(launched.output))`;
1788
1823
  // `harnessReviewGate`). The agent emits a single fenced ```json block (the OUTPUT
@@ -1860,7 +1895,7 @@ export function parseIntakeVerdict(output: string): IntakeVerdict {
1860
1895
  outcome !== 'bounce'
1861
1896
  ) {
1862
1897
  // The prompt teaches the LLM to emit `spec`, so the accepted outcome set is
1863
- // `ask|task|spec|bounce`. HARD CUTOVER: the legacy `prd` outcome token is
1898
+ // `ask|task|spec|bounce`. HARD CUTOVER: the legacy ''prd'' outcome token is
1864
1899
  // fully gone (rejected here + removed from the `IntakeOutcome` type + the
1865
1900
  // dispatch `case`).
1866
1901
  throw new Error(
@@ -1905,7 +1940,7 @@ export function parseIntakeVerdict(output: string): IntakeVerdict {
1905
1940
  // The LONE-TASK bounded internal review (observation
1906
1941
  // `intake-lone-task-skips-adversarial-review-the-prd-path-gets`, rulings A/B/C).
1907
1942
  //
1908
- // Give intake's lone-TASK outcome the adversarial refinement the `do prd:` path
1943
+ // Give intake's lone-TASK outcome the adversarial refinement the `do spec:` path
1909
1944
  // already gets — but as a small intake-NATIVE bounded review, NOT by integrating
1910
1945
  // the tasker loop. This is a NEW prompt + a small loop + an injectable gate seam,
1911
1946
  // MIRRORING the tasker loop's verdict/output CONVENTIONS (fenced JSON
@@ -2293,20 +2328,20 @@ export function buildLoneTaskReviewPrompt(
2293
2328
  export const parseLoneTaskReviewVerdict = parseReviewVerdict;
2294
2329
 
2295
2330
  /**
2296
- * Build the intake decision PRD (an inline prompt builder, like `buildTaskingPrd`
2331
+ * Build the intake decision SPEC (an inline prompt builder, like `buildTaskingPrd`
2297
2332
  * in `tasking.ts` / the reviewer prompts in `review-gate.ts` — NOT a standalone
2298
2333
  * asset/`.md` file; no such convention exists in this package). It encodes the FULL
2299
- * four-outcome decision table (prd `issue-intake` — the source of truth) and the
2334
+ * four-outcome decision table (spec `issue-intake` — the source of truth) and the
2300
2335
  * three DECISION AIDS stated once there:
2301
2336
  *
2302
2337
  * 1. the **"clear?" bar** = `to-task`/`needsAnswers`' "would I build the wrong
2303
2338
  * thing if I guessed?" — if a material requirement/scope/acceptance question is
2304
2339
  * unanswered, ASK (never guess a spec from a vague issue);
2305
2340
  * 2. the **"one task?" bar** = `to-task`' tracer-bullet test (one thin end-to-end
2306
- * path, demoable on its own) — fits → TASK, needs splitting → PRD;
2307
- * 3. **PRD vs BOUNCE** turns on a **SHARED VISION**: coupled (even if small) → PRD;
2341
+ * path, demoable on its own) — fits → TASK, needs splitting → SPEC;
2342
+ * 3. **SPEC vs BOUNCE** turns on a **SHARED VISION**: coupled (even if small) → SPEC;
2308
2343
  * genuinely unrelated → BOUNCE. Size NEVER forces a bounce — only unrelatedness
2309
- * (the over-bounce guard: a coupled-but-small pair gets a light PRD, never a
2344
+ * (the over-bounce guard: a coupled-but-small pair gets a light SPEC, never a
2310
2345
  * bounce).
2311
2346
  *
2312
2347
  * The prompt anchors to `to-task`/`to-spec` for the task/spec SHAPES it drafts. Its
@@ -2328,7 +2363,7 @@ export function buildIntakeDecisionSpec(
2328
2363
  `#${i + 1} ${c.author ? `@${c.author}` : '(unknown)'}: ${c.body}`,
2329
2364
  )
2330
2365
  .join('\n\n');
2331
- // TRIAGE ENRICHMENT (prd `issue-intake`): on the raced PROCEED path the prompt is
2366
+ // TRIAGE ENRICHMENT (spec `issue-intake`): on the raced PROCEED path the prompt is
2332
2367
  // told which comment(s) PRE-DATE intake's last turn (context for a prior state,
2333
2368
  // not necessarily a fresh answer) and — only then — how many previously-SEEN
2334
2369
  // comments were DELETED (a flag + count; the bodies are gone, so do not name them).
@@ -2378,42 +2413,42 @@ export function buildIntakeDecisionSpec(
2378
2413
  ' (a single thin end-to-end path, demoable on its own — `to-task`’ criterion).',
2379
2414
  ' Draft that ONE task in the `to-task` shape (a `## What to build`,',
2380
2415
  ' `## Acceptance criteria`, and `## Prompt`). The runner writes',
2381
- ' `work/backlog/<slug>.md` (`covers: []`, NO `prd:`) carrying `issue: N` (the',
2416
+ ' `work/backlog/<slug>.md` (`covers: []`, NO `spec:`) carrying `issue: N` (the',
2382
2417
  ' lone-task closure link, NOT `Fixes #N`) and integrates it.',
2383
2418
  '',
2384
- '- **PRD** — the issue is CLEAR *and* coherent but needs MORE THAN ONE task (it',
2419
+ '- **SPEC** — the issue is CLEAR *and* coherent but needs MORE THAN ONE task (it',
2385
2420
  ' cannot be one tracer-bullet path — it splits for scope/architecture). >1 task',
2386
2421
  ' ⟺ a shared vision worth recording ⟺ a spec. Draft a spec in the `to-spec` shape',
2387
2422
  ' (`## Problem Statement`, `## Solution`, `## User Stories`, `## Out of Scope`).',
2388
- ' The runner writes the prd file (`work/prds/ready/<slug>.md`) with `issue: N` and integrates it;',
2389
- ' TASKING the prd is a SEPARATE later step (`do prd:`) — do not task it here.',
2423
+ ` The runner writes the spec file (\`${workFolderPrefix('specs-ready')}<slug>.md\`) with \`issue: N\` and integrates it;`,
2424
+ ' TASKING the spec is a SEPARATE later step (`do spec:`) — do not task it here.',
2390
2425
  ' **INCLUDES a coupled-but-SMALL pair: if two asks share a vision they get a',
2391
- ' (light) prd — they are NEVER bounced.**',
2426
+ ' (light) spec — they are NEVER bounced.**',
2392
2427
  '',
2393
2428
  '- **BOUNCE** — the issue is really MULTIPLE UNRELATED concerns wearing one issue:',
2394
2429
  ' you cannot articulate a SINGLE shared vision tying them together. Draft a short',
2395
2430
  ' message asking the author to file separate issues. A bounce is TERMINAL, so the',
2396
2431
  ' runner CLOSES the issue ATOMICALLY — your message as the closing comment +',
2397
2432
  ' reason "not planned" (the honest signal that the asks must be re-filed). Intake',
2398
- ' closes on BOUNCE only; never on task/prd (CI’s close-job) / ask.',
2433
+ ' closes on BOUNCE only; never on task/spec (CI’s close-job) / ask.',
2399
2434
  '',
2400
2435
  '## The three decision aids (apply them in order)',
2401
2436
  '',
2402
2437
  '1. **"clear?"** (ASK vs the rest): the `needsAnswers` bar — would acting now risk',
2403
2438
  ' building the wrong thing? If yes → ASK. Otherwise it is clear; continue.',
2404
- '2. **"one task?"** (TASK vs PRD): the `to-task` tracer-bullet test — one thin',
2405
- ' end-to-end path, demoable alone? Fits → TASK; needs splitting → PRD.',
2406
- '3. **"shared vision?"** (PRD vs BOUNCE): coupled (even if small) → PRD; genuinely',
2439
+ '2. **"one task?"** (TASK vs SPEC): the `to-task` tracer-bullet test — one thin',
2440
+ ' end-to-end path, demoable alone? Fits → TASK; needs splitting → SPEC.',
2441
+ '3. **"shared vision?"** (SPEC vs BOUNCE): coupled (even if small) → SPEC; genuinely',
2407
2442
  ' unrelated → BOUNCE. SIZE NEVER forces a bounce — only UNRELATEDNESS does. Do',
2408
- ' not over-bounce a small coupled pair: it is a light prd.',
2443
+ ' not over-bounce a small coupled pair: it is a light spec.',
2409
2444
  '',
2410
2445
  '## Boundary',
2411
2446
  '',
2412
- 'You only DRAFT the verdict + its content (the task/prd body, or the comment',
2447
+ 'You only DRAFT the verdict + its content (the task/spec body, or the comment',
2413
2448
  'text). You do NOT perform ANY git operation and you do NOT post any comment — the',
2414
- 'runner owns every git/seam side-effect (write, integrate, postComment). For a prd',
2449
+ 'runner owns every git/seam side-effect (write, integrate, postComment). For a spec',
2415
2450
  'verdict, also judge its gate axes (humanOnly / needsAnswers) so the runner can',
2416
- 'surface them on the emitted prd.',
2451
+ 'surface them on the emitted spec.',
2417
2452
  '',
2418
2453
  '## Output — hand the verdict back as ONE fenced JSON block',
2419
2454
  '',