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/start.ts CHANGED
@@ -78,7 +78,7 @@ export interface StartOptions {
78
78
  */
79
79
  override?: boolean;
80
80
  /**
81
- * `--allow-backlog` (prd
81
+ * `--allow-backlog` (spec
82
82
  * `do-allow-backlog-drive-staged-tasks-without-promotion`): recognise a
83
83
  * `tasks/backlog/`-resident body (staging) as a valid start/onboard residence,
84
84
  * so the no-checkout `do --remote/--isolated … --allow-backlog` flow (which
@@ -122,7 +122,8 @@ class StartUsageError extends Error {}
122
122
  /**
123
123
  * Raised for a deliberate REFUSAL (exit 1, outcome 'refused') — distinct from a
124
124
  * usage/environment error. Used when the item exists but start declines to act
125
- * (an in-progress item without --resume). The decision is folder-based.
125
+ * (an in-progress item without --resume). The decision is LOCK-based (a held
126
+ * `active` per-item lock), not a `work/in-progress/` folder read.
126
127
  */
127
128
  class StartRefusal extends Error {}
128
129
 
@@ -236,7 +237,7 @@ async function runStart(
236
237
  * resume the lock `stuck → active`, onboard).
237
238
  * Everything else dispatches by folder unchanged.
238
239
  *
239
- * Under `--allow-backlog` (prd
240
+ * Under `--allow-backlog` (spec
240
241
  * `do-allow-backlog-drive-staged-tasks-without-promotion`) a body resting in
241
242
  * `tasks/backlog/` (staging) is treated EXACTLY like the pool for this re-key
242
243
  * (held active ⇒ in-progress; held stuck ⇒ needs-attention; else the backlog
@@ -262,11 +263,11 @@ async function dispatchFolder(
262
263
  if (!inPool) {
263
264
  return folder;
264
265
  }
265
- // In the pool/staging: claimed-ness + stuck-ness are the per-item lock, not the folder.
266
+ // In the pool/staging: claimed-ness is the per-item lock (not the folder).
267
+ // Post-`retire-stuck-lock-state` there is no `stuck` state — a parked item is
268
+ // a `needsAnswers:true` pool item on `main` (rendered by status/scan and
269
+ // drained by the apply rung), NEVER a lock re-key.
266
270
  const lock = await readItemLock({item: `task:${slug}`, cwd, arbiter, env});
267
- if (lock && lock.state === 'stuck') {
268
- return 'needs-attention';
269
- }
270
271
  if (lock && lock.state === 'active') {
271
272
  return 'in-progress';
272
273
  }
@@ -404,7 +405,7 @@ async function continueConflictResult(params: {
404
405
  }
405
406
  const message =
406
407
  `Could not continue '${params.slug}': the kept work branch did not rebase ` +
407
- `cleanly onto ${params.arbiter}/main; routed to work/needs-attention/ ` +
408
+ `cleanly onto ${params.arbiter}/main; marked stuck on its per-item lock ` +
408
409
  '(surfaced by status). Resolve against the latest main, or `requeue --reset` ' +
409
410
  'to discard and start fresh.';
410
411
  return {
@@ -438,8 +439,8 @@ async function continuePushFailureResult(params: {
438
439
  }
439
440
  const message =
440
441
  `Could not continue '${params.slug}': publishing the rebased work branch to ` +
441
- `${params.arbiter} failed terminally (${params.pushFailure}); routed to ` +
442
- 'work/needs-attention/ (surfaced by status), the kept branch left intact on ' +
442
+ `${params.arbiter} failed terminally (${params.pushFailure}); marked stuck ` +
443
+ 'on its per-item lock (surfaced by status), the kept branch left intact on ' +
443
444
  'the arbiter (recoverable). `requeue` to retry once the churn settles.';
444
445
  return {
445
446
  exitCode: 1,
@@ -465,42 +466,17 @@ async function startFromNeedsAttention(params: {
465
466
  }): Promise<StartResult> {
466
467
  const {slug, arbiter, cwd, env, note} = params;
467
468
 
468
- // Surface the recorded reason for the human, read from the STUCK LOCK ENTRY
469
- // (task `cutover-needs-attention-becomes-lock-stuck-recovery-surface`: the lock
470
- // is the sole stuck record no `needs-attention/` folder file). The full reason
471
- // prose + any surfaced questions ride on the lock entry body.
472
- const stuck = await readItemLock({item: `task:${slug}`, cwd, arbiter, env});
473
- if (stuck?.reason) {
474
- note(`'${slug}' is stuck (needs-attention): ${stuck.reason}`);
475
- } else {
476
- note(`'${slug}' is stuck (needs-attention)picking it up.`);
477
- }
478
- if (stuck?.questions && stuck.questions.length > 0) {
479
- note('Surfaced questions:');
480
- for (const q of stuck.questions) {
481
- note(` - ${q}`);
482
- }
483
- }
484
-
485
- // Resume the lock `stuck → active` THROUGH the write seam (a pure lock amend, NO
486
- // `main` write, NO temp checkout — the body already rests in `backlog/` and the
487
- // work stays on the kept `work/<slug>` branch), then onboard onto work/<slug>.
488
- const resolved = await ledgerWrite.applyResolveNeedsAttentionTransition({
489
- cwd,
490
- slug,
491
- arbiter,
492
- env,
493
- note,
494
- });
495
- if (!resolved.moved) {
496
- throw new StartUsageError(
497
- resolved.reasonNotMoved ??
498
- `could not resolve '${slug}' from needs-attention.`,
499
- );
500
- }
469
+ // Post-`retire-stuck-lock-state`: the `stuck` lock state is gone; a parked
470
+ // item is a `needsAnswers:true` pool item on `main` drained by the apply
471
+ // rung (answer the sidecar). This branch fires only when a LEGACY
472
+ // `needs-attention/` folder body still exists on `<arbiter>/main` (no
473
+ // live path lands one). Onboard the human onto the kept work branch — no
474
+ // lock amend, no reason/questions read from the lock (those live on the
475
+ // surfaced sidecar now).
476
+ note(
477
+ `'${slug}' is in the legacy needs-attention/ folder onboarding onto its work branch; answer any question sidecar on main to drain it.`,
478
+ );
501
479
 
502
- // The lock is back to active (the human owns it). Onboard onto the work branch:
503
- // CONTINUE from a kept arbiter work/<slug> when present, else fresh off main.
504
480
  const switched = await switchToWorkBranch({slug, arbiter, cwd, env, note});
505
481
  if (switched.rebaseConflict) {
506
482
  return continueConflictResult({slug, arbiter, cwd, env, note});
@@ -522,10 +498,14 @@ async function startFromNeedsAttention(params: {
522
498
  }
523
499
 
524
500
  /**
525
- * In-progress → already claimed (it is no longer in backlog, so the CAS cannot
526
- * apply). Refuse by default. With --resume the human explicitly asserts
501
+ * In-progress → already claimed (the per-item LOCK is held `active`, so the CAS
502
+ * cannot apply). Refuse by default. With --resume the human explicitly asserts
527
503
  * ownership, so we switch to the work branch WITHOUT claiming. The decision is
528
- * folder-based; we never read the advisory `claimed_by` to guess ownership.
504
+ * LOCK-based: `dispatchFolder` reaches here only when the lock is held `active`
505
+ * (the body rests in the pool/staging, NOT a `work/in-progress/` folder file —
506
+ * the folder cutover retired that path,
507
+ * `finish-in-progress-folder-cutover-remove-legacy-recovery-readers`). We never
508
+ * read the advisory `claimed_by` to guess ownership.
529
509
  */
530
510
  async function startFromInProgress(params: {
531
511
  slug: string;
@@ -538,10 +518,11 @@ async function startFromInProgress(params: {
538
518
  const {slug, arbiter, cwd, env, resume, note} = params;
539
519
 
540
520
  if (!resume) {
541
- // The folder drove the decision (WORK-CONTRACT rule 6: the folder + git
542
- // history are the source of truth). We do NOT name the claimer in the
543
- // message; whoever holds it is read from git history
544
- // (`git log work/in-progress/<slug>.md`).
521
+ // The held LOCK drove the decision (the per-item lock is the source of truth
522
+ // for liveness now the body stays in the pool, no `work/in-progress/` file).
523
+ // We do NOT name the claimer in the message; whoever holds it is read from git
524
+ // history (`git log` over the item's `work/tasks/ready/<slug>.md` + the lock
525
+ // ref history).
545
526
  throw new StartRefusal(
546
527
  `'${slug}' is already in-progress; see \`git log\` for who claimed it; ` +
547
528
  'if this is your own work, re-run with --resume.',
@@ -620,7 +601,7 @@ async function switchToWorkBranch(params: {
620
601
  }): Promise<SwitchResult> {
621
602
  const {slug, arbiter, cwd, env, note} = params;
622
603
  // `start` is a TASK-only command: the branch is the task-namespaced
623
- // `work/task-<slug>` (distinct from a same-slug prd-tasking branch).
604
+ // `work/task-<slug>` (distinct from a same-slug spec-tasking branch).
624
605
  const branch = workBranchRef('task', slug);
625
606
 
626
607
  await gitHard(['fetch', '--quiet', arbiter], cwd, env);
@@ -816,8 +797,9 @@ function surfaceUnmovedStartResult(params: {
816
797
  * TREE-LESS (`#89` mechanism), the SAME-PROFILE sibling of
817
798
  * {@link routeContinuePushFailure}: the rebase was ABORTED, so the REAL continued
818
799
  * `work/<slug>` is already on the arbiter from the prior requeue, untouched
819
- * (after-commit, durable, recoverable). The surface is PURELY the one-file
820
- * `in-progress/ needs-attention/` ledger `.md` move + reason we publish it via
800
+ * (after-commit, durable, recoverable). The surface is PURELY the lock amend to
801
+ * `state: stuck` with the reason (post lock-cutoverno `in-progress/
802
+ * needs-attention/` folder move) — we publish it via
821
803
  * the tree-less surface CAS (the SAME no-checkout primitive `requeue` uses for the
822
804
  * reverse direction), NO temp-branch switch/restore, NO `pushBranch`, NO worktree.
823
805
  */
@@ -831,8 +813,10 @@ async function routeContinueConflict(params: {
831
813
  const {slug, arbiter, cwd, env, note} = params;
832
814
  const reason =
833
815
  `continuing the kept ${arbiter}/${workBranchRef('task', slug)}: rebase onto ` +
834
- `${arbiter}/main conflicted (aborted, never auto-resolved) — resolve ` +
835
- 'against the latest main, or `requeue --reset` to discard and start fresh';
816
+ `${arbiter}/main conflicted (aborted, never auto-resolved) — run ` +
817
+ '`requeue --reconcile` to non-destructively re-sync the mirror and retry ' +
818
+ 'the rebase (keeps the work). Last resort: `requeue --reset` ' +
819
+ 'DESTRUCTIVELY discards the branch and starts fresh.';
836
820
  note(reason);
837
821
  // PROPAGATE the {moved, reasonNotMoved} result to the caller so a `moved:false`
838
822
  // (the surface did NOT reach main — lost the CAS race) is surfaced honestly
@@ -857,8 +841,9 @@ async function routeContinueConflict(params: {
857
841
  * TREE-LESS (`#89` mechanism): the recoverable artifact — the kept `work/<slug>`
858
842
  * — is ALREADY on the arbiter from the prior requeue (our local rebased tip is
859
843
  * what FAILED to push, so it is not the cross-machine truth), and the work is
860
- * already committed. So the surface is PURELY the one-file `in-progress/
861
- * needs-attention/` ledger `.md` move + reason: we publish it via the tree-less
844
+ * already committed. So the surface is PURELY the lock amend to `state: stuck`
845
+ * with the reason (post lock-cutover no `in-progress/ needs-attention/`
846
+ * folder move): we publish it via the tree-less
862
847
  * surface CAS (the SAME no-checkout primitive `requeue` uses for the reverse
863
848
  * direction) — NO temp-branch switch/restore, NO `pushBranch`, NO worktree. A
864
849
  * `requeue` then continues from the kept arbiter tip.
@@ -875,8 +860,10 @@ async function routeContinuePushFailure(params: {
875
860
  const reason =
876
861
  `continuing the kept ${arbiter}/${workBranchRef('task', slug)}: publishing ` +
877
862
  `the rebased work branch to ${arbiter} failed terminally (${pushFailure}) — ` +
878
- 'the kept branch is left intact on the arbiter (recoverable); `requeue` to ' +
879
- 'retry once the churn settles, or `requeue --reset` to discard and start fresh';
863
+ 'the kept branch is left intact on the arbiter (recoverable); `requeue ' +
864
+ '--reconcile` to non-destructively re-sync the mirror and retry once the ' +
865
+ 'churn settles (keeps the work). Last resort: `requeue --reset` ' +
866
+ 'DESTRUCTIVELY discards the branch and starts fresh.';
880
867
  note(reason);
881
868
  // PROPAGATE the {moved, reasonNotMoved} result to the caller so a `moved:false`
882
869
  // (the surface did NOT reach main — lost the CAS race) is surfaced honestly
@@ -909,7 +896,7 @@ async function inferSlugFromBranch(
909
896
 
910
897
  /**
911
898
  * Which work/ folder the slug currently lives in on `<arbiter>/main`. Under
912
- * `--allow-backlog` (prd `do-allow-backlog-drive-staged-tasks-without-promotion`)
899
+ * `--allow-backlog` (spec `do-allow-backlog-drive-staged-tasks-without-promotion`)
913
900
  * it ALSO recognises `tasks/backlog/` (staging) at LOWEST priority — after the
914
901
  * pool — so a same-slug pool copy still wins; otherwise staging is invisible.
915
902
  */
@@ -936,7 +923,14 @@ async function folderOnArbiterMain(
936
923
  )[] = [
937
924
  'tasks-ready',
938
925
  ...(allowBacklog ? (['tasks-backlog'] as const) : []),
939
- 'in-progress',
926
+ // NOTE: `work/in-progress/` is NOT probed (task
927
+ // `finish-in-progress-folder-cutover-remove-legacy-recovery-readers`): the
928
+ // per-item-lock cutover moved claim OFF writing that folder, so nothing lands a
929
+ // body there. A claimed-and-in-flight item RESTS in the pool/staging on `main`
930
+ // with the held lock as its liveness — `dispatchFolder` re-keys THAT to the
931
+ // `in-progress` dispatch off the LOCK (`state: active`), never a folder read.
932
+ // (`needs-attention/` is likewise the lock `state: stuck`; its retained probe is
933
+ // a separate cutover's concern, left untouched here.)
940
934
  'needs-attention',
941
935
  'done',
942
936
  ];
package/src/status.ts CHANGED
@@ -81,7 +81,7 @@ export interface JobStatus {
81
81
  }
82
82
 
83
83
  /**
84
- * One repo's PER-ITEM LOCK refs, surfaced for the dashboard (prd
84
+ * One repo's PER-ITEM LOCK refs, surfaced for the dashboard (spec
85
85
  * `ledger-status-per-item-lock-refs` US #8; task
86
86
  * `needs-attention-as-stuck-lock-state`). The in-flight view read from the lock
87
87
  * refs — held (`active` = in-progress) and stuck (`needs-attention`) entries +
@@ -111,7 +111,7 @@ export interface StatusReport {
111
111
  /** Stuck (needs-attention), crashed (running-but-dead), or un-reaped (done) jobs. */
112
112
  attention: JobStatus[];
113
113
  /**
114
- * The PER-ITEM LOCK in-flight view (prd `ledger-status-per-item-lock-refs` US
114
+ * The PER-ITEM LOCK in-flight view (spec `ledger-status-per-item-lock-refs` US
115
115
  * #8; task `needs-attention-as-stuck-lock-state`): per registered hub mirror,
116
116
  * the held lock entries read from the mirror's `refs/dorfl/lock/*` refs —
117
117
  * `active` holds (in-progress) and `stuck` holds (needs-attention) + reasons.
@@ -124,7 +124,7 @@ export interface StatusReport {
124
124
  */
125
125
  lockHeld?: RepoLockEntries[];
126
126
  /**
127
- * The one-slug-one-folder LINT (prd `ledger-integrity` story 3): per registered
127
+ * The one-slug-one-folder LINT (spec `ledger-integrity` story 3): per registered
128
128
  * hub mirror, any slug present in MORE THAN ONE `work/` status folder (a corrupt
129
129
  * ledger). Read from the mirror's bare `main` ref (the SAME `ls-tree` source the
130
130
  * needs-attention surface uses). Only repos WITH a duplicate appear. `status`
@@ -235,7 +235,7 @@ export async function status(options: StatusOptions): Promise<StatusReport> {
235
235
  // reflects the remote truth. Never fatal — a failed fetch WARNS and falls back
236
236
  // to the mirror's last-known `main`.
237
237
  fetchMirrorMainOrWarn({mirrorPath, warn: options.warn, env: options.env});
238
- // The PER-ITEM LOCK in-flight view (prd US #8): read the mirror's lock refs to
238
+ // The PER-ITEM LOCK in-flight view (spec US #8): read the mirror's lock refs to
239
239
  // surface held (`active` = in-progress) and stuck (`needs-attention`) entries +
240
240
  // reasons/questions. A bare hub mirror's arbiter is its `origin` (the SAME
241
241
  // handle the `scan` held-slug subtraction reads). Best-effort: a fetch/read
@@ -249,7 +249,7 @@ export async function status(options: StatusOptions): Promise<StatusReport> {
249
249
  if (entries.length > 0) {
250
250
  lockHeld.push({repoPath: mirrorPath, entries});
251
251
  }
252
- // The one-slug-one-folder LINT (prd story 3): derive any slug residing in >1
252
+ // The one-slug-one-folder LINT (spec story 3): derive any slug residing in >1
253
253
  // status folder from the SAME freshly-fetched `main` ref, surfaced LOUDLY.
254
254
  const dups = lintRefLedger('main', mirrorPath, options.env);
255
255
  if (dups.length > 0) {
@@ -359,7 +359,7 @@ export function formatStatus(report: StatusReport): string {
359
359
  }
360
360
  }
361
361
 
362
- // The PER-ITEM LOCK in-flight view (prd US #8; task
362
+ // The PER-ITEM LOCK in-flight view (spec US #8; task
363
363
  // `cutover-needs-attention-becomes-lock-stuck-recovery-surface`): the held lock
364
364
  // refs read from each mirror — `active` holds (in-progress) and `stuck` holds
365
365
  // (needs-attention) + their reasons/questions. This is the SOLE stuck-state
@@ -377,7 +377,7 @@ export function formatStatus(report: StatusReport): string {
377
377
  }
378
378
  }
379
379
 
380
- // The one-slug-one-folder LINT (prd `ledger-integrity` story 3): WARN LOUDLY
380
+ // The one-slug-one-folder LINT (spec `ledger-integrity` story 3): WARN LOUDLY
381
381
  // about every slug residing in >1 status folder of a registered mirror's ledger
382
382
  // (a corrupt ledger — never a silent pass). A human must resolve each.
383
383
  if (dupCount > 0) {
@@ -6,7 +6,7 @@ import {parseableJsonContractPrompt} from './review-verdict.js';
6
6
  import type {NewQuestion} from './sidecar.js';
7
7
 
8
8
  /**
9
- * The **SURFACE gate** (prd `advance-loop`, task `advance-rung-surface`,
9
+ * The **SURFACE gate** (spec `advance-loop`, task `advance-rung-surface`,
10
10
  * US #32/33) — the surface-question rung's fresh-context spawn, the DIRECT mirror
11
11
  * of the PR/code review gate ({@link import('./review-gate.js')}). On
12
12
  * `classify=surface`, the advance engine spawns a FRESH-CONTEXT agent with the
@@ -70,7 +70,7 @@ export interface SurfaceEmit {
70
70
 
71
71
  /** What the surface gate needs to launch a fresh-context surface of one item. */
72
72
  export interface SurfaceGateInput {
73
- /** The namespaced identity the surface is for (`task:foo` / `prd:bar` / `observation:baz`). */
73
+ /** The namespaced identity the surface is for (`task:foo` / `spec:bar` / `observation:baz`). */
74
74
  item: string;
75
75
  /** The working clone/checkout the gate runs in. */
76
76
  cwd: string;
@@ -252,9 +252,16 @@ export function buildSurfacePrompt(item: string): string {
252
252
  ` "note": "… (optional; your reasoning / findings prose lives HERE, not outside the object)"}`,
253
253
  '```',
254
254
  ``,
255
- `An EMPTY \`questions\` array is a VALID, honest result (no open judgement) —`,
256
- `emit the object with \`"questions": []\` (put WHY in \`note\`); do NOT replace`,
257
- `it with a prose explanation. Absence of the field is NOT valid.`,
255
+ `RULE empty is VALID, absence is NOT. When there is nothing to ask (no open`,
256
+ `judgement to surface), you MUST STILL emit the JSON object, with`,
257
+ `\`"questions": []\` (an empty array); put any explanation of WHY in the`,
258
+ `\`note\` field INSIDE the object. Do NOT replace the object with a prose`,
259
+ `sentence like "no open questions", do NOT skip the emit, and do NOT drop the`,
260
+ `\`questions\` field. The parser (\`parseSurfaceEmit\`) enforces this: an empty`,
261
+ `\`questions\` array is a valid, honest "no open judgement" result; ABSENCE of`,
262
+ `the \`questions\` field is rejected as an unparseable emit — that failure is`,
263
+ `what strands the surface rung. Emitting \`{"questions": [], "note": "…"}\` is`,
264
+ `ALWAYS the safe, honest close for a nothing-to-ask item.`,
258
265
  ``,
259
266
  // The SHARED defensive-JSON contract (the same hardening Gate-2's verdict
260
267
  // prompt carries) — the surface rung hit the IDENTICAL unparseable-emit
@@ -13,7 +13,7 @@ import {
13
13
  } from './sidecar.js';
14
14
 
15
15
  /**
16
- * The engine-owned SURFACE PERSIST (prd `advance-loop`, task
16
+ * The engine-owned SURFACE PERSIST (spec `advance-loop`, task
17
17
  * `advance-rung-surface`, US #15/33) — the half of the surface rung the ENGINE
18
18
  * owns (the skill JUDGES, the engine PERSISTS). Given the questions the
19
19
  * `surface-questions` skill EMITTED (gathered by `surface-gate.ts`'s spawn), the
@@ -53,7 +53,7 @@ import {
53
53
  export interface SurfacePersistOptions {
54
54
  /** Working clone/worktree the persist commits in. */
55
55
  cwd: string;
56
- /** The namespaced item identity (`task:foo` / `prd:bar` / `observation:baz`). */
56
+ /** The namespaced item identity (`task:foo` / `spec:bar` / `observation:baz`). */
57
57
  item: string;
58
58
  /**
59
59
  * The item file path RELATIVE to `cwd` (e.g. `work/backlog/foo.md`). The
@@ -192,7 +192,7 @@ export function persistSurfacedQuestions(
192
192
 
193
193
  // Write the appended/created sidecar.
194
194
  mkdirSync(dirname(sidecarAbs), {recursive: true});
195
- writeFileSync(sidecarAbs, serialiseSidecar(model));
195
+ writeFileSync(sidecarAbs, serialiseSidecar(model, {repoRoot: cwd}));
196
196
 
197
197
  // Stage exactly the two paths and commit them TOGETHER (one atomic commit) —
198
198
  // the sidecar write + the `needsAnswers:true` flip land in the SAME commit, so
@@ -29,9 +29,9 @@ export {parseReviewVerdict as parseTaskReviewVerdict} from './review-verdict.js'
29
29
 
30
30
  /**
31
31
  * **The tasker review→edit→re-review→converge LOOP** (`slicer-review-edit-loop`,
32
- * GATES prd `work/prds/ready/review.md` RESOLVED DESIGN — Shape 2 / insertion point A).
32
+ * GATES spec `work/specs/ready/review.md` RESOLVED DESIGN — Shape 2 / insertion point A).
33
33
  *
34
- * On the `do prd:<slug>` tasking path (`tasking.ts`/`performTask`), AFTER the
34
+ * On the `do spec:<slug>` tasking path (`tasking.ts`/`performTask`), AFTER the
35
35
  * agent produces a candidate set of `work/tasks/backlog/<slug>.md` tasks and BEFORE the
36
36
  * runner finalises/lands them, this loop RUNS the `review` SKILL
37
37
  * (`skills/review/SKILL.md`), APPLIES its findings as EDITS to the candidate task
@@ -47,12 +47,12 @@ export {parseReviewVerdict as parseTaskReviewVerdict} from './review-verdict.js'
47
47
  * N so the loop can never run forever.
48
48
  *
49
49
  * ⚠️ ASPIRATION-VS-BUILT (2026-06-10): the "single context" wording above is the
50
- * prd's ASPIRATION, NOT what this module does at runtime. The ACTUAL N loop is
50
+ * spec's ASPIRATION, NOT what this module does at runtime. The ACTUAL N loop is
51
51
  * RUNNER-DRIVEN and PER-PASS: `runOneExecution` does `for (pass …) { gate(…);
52
52
  * applyEdits(…to disk…) }` — ONE agent LAUNCH per pass, the runner writing the
53
53
  * agent's edits to the candidate task FILES (`work/tasks/backlog/`) between passes, the
54
54
  * next pass's agent re-reading the edited files. Accumulation is via DISK +
55
- * re-launch, NOT one agent retaining context. `prd/review.md` §Shape 2 is internally
55
+ * re-launch, NOT one agent retaining context. `spec/review.md` §Shape 2 is internally
56
56
  * contradictory on this (single-context headline vs "edit the files" operative spec);
57
57
  * this code implements the operative reading. See
58
58
  * `work/findings/review-edit-loop-single-context-is-unbuilt-aspiration-vs-per-pass-disk-impl.md`.
@@ -75,8 +75,9 @@ export {parseReviewVerdict as parseTaskReviewVerdict} from './review-verdict.js'
75
75
  * - **a specific uncertain task** → emit it `needsAnswers: true` with the
76
76
  * questions in its body (created, not agent-buildable until a human answers).
77
77
  * - **the whole decomposition unclear / `taskerLoopMax` exhausted with blockers** →
78
- * route the prd to `work/needs-attention/<slug>.md` with the questions as the
79
- * reason, emitting NO guessed tasks.
78
+ * mark the spec stuck on its per-item lock (post lock-cutover `state: stuck`
79
+ * with the questions as the reason, no `work/needs-attention/` folder write),
80
+ * emitting NO guessed tasks.
80
81
  *
81
82
  * The verdict sink itself (the git transitions for those three outcomes) is the
82
83
  * caller's (`tasking.ts`): this module decides WHICH outcome and prepares the
@@ -101,7 +102,7 @@ export type TaskReviewVerdict = ReviewVerdict;
101
102
 
102
103
  /** What the review gate needs to launch a fresh-context review+edit pass. */
103
104
  export interface TaskReviewGateInput {
104
- /** The prd slug whose candidate tasks are under review. */
105
+ /** The spec slug whose candidate tasks are under review. */
105
106
  slug: string;
106
107
  /** The working clone/checkout the loop runs in (candidate tasks live here). */
107
108
  cwd: string;
@@ -141,7 +142,7 @@ export type LoopOutcome =
141
142
  | 'converged'
142
143
  /** `taskerLoopMax` hit with blockers → specific uncertain task(s) → needsAnswers. */
143
144
  | 'uncertain-tasks'
144
- /** `taskerLoopMax` hit / decomposition unclear → route the prd to needs-attention. */
145
+ /** `taskerLoopMax` hit / decomposition unclear → route the spec to needs-attention. */
145
146
  | 'decomposition-unclear';
146
147
 
147
148
  /** The result of running the loop — the disposition the caller's sink routes. */
@@ -174,7 +175,7 @@ export interface RunTaskReviewLoopResult {
174
175
  }
175
176
 
176
177
  export interface RunTaskReviewLoopOptions {
177
- /** The prd slug whose candidate tasks are being improved. */
178
+ /** The spec slug whose candidate tasks are being improved. */
178
179
  slug: string;
179
180
  /** The working clone/checkout the loop runs in. */
180
181
  cwd: string;
@@ -226,7 +227,7 @@ export interface RunTaskReviewLoopOptions {
226
227
  * to the candidate task files, then re-review — until `verdict === 'approve'` (no
227
228
  * NEW blocking issue → converged) or the pass count reaches `taskerLoopMax`. On the cap
228
229
  * with a still-`block` verdict, ROUTE per the verdict's channels:
229
- * - `decompositionUnclear` set ⇒ `decomposition-unclear` (prd → needs-attention,
230
+ * - `decompositionUnclear` set ⇒ `decomposition-unclear` (spec → needs-attention,
230
231
  * no guessed tasks);
231
232
  * - else `uncertainTasks` (or, as a floor, every candidate task) ⇒
232
233
  * `uncertain-tasks` (those tasks emitted `needsAnswers: true` + questions).
@@ -296,7 +297,7 @@ export async function runTaskReviewLoop(
296
297
  note(
297
298
  `Tasker review loop did not converge within taskerLoopMax=${taskerLoopMax} ` +
298
299
  `across ${executions} fresh context(s); the whole decomposition is ` +
299
- 'unclear — routing the prd to needs-attention (no guessed tasks).',
300
+ 'unclear — routing the spec to needs-attention (no guessed tasks).',
300
301
  );
301
302
  return {
302
303
  outcome: 'decomposition-unclear',
@@ -308,7 +309,7 @@ export async function runTaskReviewLoop(
308
309
  message:
309
310
  `The decomposition of '${options.slug}' is still unclear after ` +
310
311
  `taskerLoopMax=${taskerLoopMax} review pass(es) across ${executions} fresh ` +
311
- 'context(s); routing the prd to needs-attention with the open ' +
312
+ 'context(s); routing the spec to needs-attention with the open ' +
312
313
  'questions, emitting no guessed tasks.',
313
314
  };
314
315
  }
@@ -617,18 +618,18 @@ export function buildTaskReviewPrompt(input: TaskReviewGateInput): string {
617
618
  const list = input.candidateTasks.map((p) => ` - ${p}`).join('\n');
618
619
  return [
619
620
  `You are a FRESH-CONTEXT reviewer in the TASKER review→edit→converge LOOP`,
620
- `(insertion point A). Review the CANDIDATE TASKS just produced for the prd`,
621
+ `(insertion point A). Review the CANDIDATE TASKS just produced for the spec`,
621
622
  `"${input.slug}":`,
622
623
  list || ' (no candidate tasks found)',
623
624
  ``,
624
625
  reviewDisciplinePrompt(),
625
626
  ``,
626
- `Read the source prd (work/prds/ready/${input.slug}.md) and review the candidate`,
627
+ `Read the source spec (${workItemRel('specs-ready', `${input.slug}.md`)}) and review the candidate`,
627
628
  `decomposition ADVERSARIALLY. Review the WHOLE SET — graph coherence / gaps /`,
628
629
  `overlap / goal-composition (dependency-graph coherence, set-level gaps,`,
629
- `overlapping/duplicated tasks, and "does the set compose into the prd goal")`,
630
+ `overlapping/duplicated tasks, and "does the set compose into the spec goal")`,
630
631
  `— not just per-task well-formedness. The DESTINATION CHECK ("if every task`,
631
- `is built exactly as written, do we end up with the system the prd describes?")`,
632
+ `is built exactly as written, do we end up with the system the spec describes?")`,
632
633
  `is PART OF this pass and may ITSELF trigger edits — that is why this is a`,
633
634
  `loop, not a one-shot gate.`,
634
635
  ``,
@@ -645,7 +646,7 @@ export function buildTaskReviewPrompt(input: TaskReviewGateInput): string {
645
646
  ` can FIX a finding by editing (the natural improver step).`,
646
647
  ` - "uncertainTasks" — specific tasks you cannot make buildable (each gets`,
647
648
  ` \`needsAnswers: true\` with the questions in its body).`,
648
- ` - "decompositionUnclear" — the WHOLE decomposition is unsound (the prd is`,
649
+ ` - "decompositionUnclear" — the WHOLE decomposition is unsound (the spec is`,
649
650
  ` routed to needs-attention; emit no guessed tasks).`,
650
651
  `Do NOT fill "review" / "edit" / "questions" — those are other callers'`,
651
652
  `channels. Flag, do not guess: a flagged question costs one human glance; a`,
@@ -1,46 +1,46 @@
1
1
  /**
2
2
  * Pure tasking-eligibility resolution — the auto-task decision layer, one level
3
- * UP from the build gate (`eligibility.ts`). No I/O: callers pass in the prd's
3
+ * UP from the build gate (`eligibility.ts`). No I/O: callers pass in the spec's
4
4
  * two autonomy axes (`humanOnly`, `needsAnswers`), the repo's `autoTask` policy,
5
- * the prd's `taskedAfter` slugs, and the set of slugs whose prds are already
6
- * TASKED (resolved against `work/prds/tasked/` residence, NOT `work/done/`).
5
+ * the spec's `taskedAfter` slugs, and the set of slugs whose prds are already
6
+ * TASKED (resolved against `work/specs/tasked/` residence, NOT `work/done/`).
7
7
  *
8
8
  * This mirrors the build-gate shape deliberately (CONTEXT.md / the `auto-slice`
9
- * prd): the same `needsAnswers !== true && humanOnly !== true && <repo policy>`
10
- * predicate, applied to a prd's two axes + the repo's `autoTask` toggle — and a
11
- * cross-prd ordering check that resolves against tasked-ness rather than done-ness.
9
+ * spec): the same `needsAnswers !== true && humanOnly !== true && <repo policy>`
10
+ * predicate, applied to a spec's two axes + the repo's `autoTask` toggle — and a
11
+ * cross-spec ordering check that resolves against tasked-ness rather than done-ness.
12
12
  */
13
13
 
14
14
  import type {HumanOnlyGate} from './eligibility.js';
15
15
 
16
16
  export type {HumanOnlyGate};
17
17
 
18
- /** Resolution of a prd's `taskedAfter` against the set of already-tasked prds. */
18
+ /** Resolution of a spec's `taskedAfter` against the set of already-tasked prds. */
19
19
  export interface TaskedAfterResult {
20
- /** True when every listed prd is already tasked. */
20
+ /** True when every listed spec is already tasked. */
21
21
  satisfied: boolean;
22
- /** Listed prd slugs not yet tasked, in declaration order. */
22
+ /** Listed spec slugs not yet tasked, in declaration order. */
23
23
  missing: string[];
24
24
  }
25
25
 
26
26
  export interface TaskingEligibilityInput {
27
- /** Autonomy axis 1 (DECIDED): a human must drive THIS prd's tasking. */
27
+ /** Autonomy axis 1 (DECIDED): a human must drive THIS spec's tasking. */
28
28
  humanOnly: HumanOnlyGate;
29
- /** Autonomy axis 2 (DISCOVERED): the prd has unresolved questions. */
29
+ /** Autonomy axis 2 (DISCOVERED): the spec has unresolved questions. */
30
30
  needsAnswers: HumanOnlyGate;
31
- /** Cross-prd order: prd slugs that must already be tasked before this one. */
31
+ /** Cross-spec order: spec slugs that must already be tasked before this one. */
32
32
  taskedAfter: string[];
33
- /** Slugs of prds that are already TASKED (residence in `work/prds/tasked/`). */
33
+ /** Slugs of prds that are already TASKED (residence in `work/specs/tasked/`). */
34
34
  taskedSlugs: Set<string>;
35
35
  /** Per-repo policy: may an agent auto-task *undeclared* prds in this repo? */
36
36
  autoTask: boolean;
37
37
  /**
38
- * The target was named EXPLICITLY by the operator (`do prd:<slug>`), so the
39
- * `autoTask` POLICY is already satisfied — naming the prd IS the authorization,
38
+ * The target was named EXPLICITLY by the operator (`do spec:<slug>`), so the
39
+ * `autoTask` POLICY is already satisfied — naming the spec IS the authorization,
40
40
  * exactly as `do <task>` builds a named task regardless of `autoBuild` (the
41
41
  * `autoBuild` precedent: the pool/scan gates the policy, the explicit claim path
42
42
  * never re-checks it). When `true`, the policy term drops from the gate and ONLY
43
- * the prd's own readiness axes (`humanOnly`/`needsAnswers`) + `taskedAfter` bind.
43
+ * the spec's own readiness axes (`humanOnly`/`needsAnswers`) + `taskedAfter` bind.
44
44
  * Defaults `false` (the AUTO-PICK pool path, where the `autoTask` policy DOES
45
45
  * gate). The pool is the single policy-enforcement point; the per-invocation gate
46
46
  * applies the policy only when NOT explicit.
@@ -49,7 +49,7 @@ export interface TaskingEligibilityInput {
49
49
  }
50
50
 
51
51
  export interface TaskingEligibilityResult {
52
- /** Taskable now = gate passes AND every `taskedAfter` prd is already tasked. */
52
+ /** Taskable now = gate passes AND every `taskedAfter` spec is already tasked. */
53
53
  taskable: boolean;
54
54
  /** Whether the autonomy gate alone passes (agent-taskable on its own axes). */
55
55
  gatePass: boolean;
@@ -61,7 +61,7 @@ export interface TaskingEligibilityResult {
61
61
  * `true` AND `humanOnly` is not `true` AND the repo's `autoTask` POLICY is
62
62
  * satisfied — where the policy is satisfied either by the repo's `autoTask`
63
63
  * toggle being on (the AUTO-PICK pool path) OR by the target being named
64
- * EXPLICITLY (`explicit: true` — `do prd:<slug>`, where naming IS the
64
+ * EXPLICITLY (`explicit: true` — `do spec:<slug>`, where naming IS the
65
65
  * authorization, mirroring `do <task>` vs `autoBuild`). Both readiness axes
66
66
  * block orthogonally and are never agent-taskable regardless of policy; a human
67
67
  * is never bound by either. The exact mirror of `resolveGate` (the build gate),
@@ -82,9 +82,9 @@ export function resolveTaskGate(
82
82
  }
83
83
 
84
84
  /**
85
- * Resolve a prd's `taskedAfter` against the slugs of prds already TASKED (NOT
86
- * `done/`): satisfied iff every listed prd is present in `taskedSlugs`. An
87
- * untasked blocker ⇒ not yet taskable (so this prd's emitted tasks can
85
+ * Resolve a spec's `taskedAfter` against the slugs of prds already TASKED (NOT
86
+ * `done/`): satisfied iff every listed spec is present in `taskedSlugs`. An
87
+ * untasked blocker ⇒ not yet taskable (so this spec's emitted tasks can
88
88
  * reference the real slugs of those prds' tasks).
89
89
  */
90
90
  export function resolveTaskedAfter(