dorfl 0.1.2 → 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 (364) hide show
  1. package/dist/advance-drivers.d.ts +1 -1
  2. package/dist/advance-drivers.d.ts.map +1 -1
  3. package/dist/advance-drivers.js +15 -3
  4. package/dist/advance-drivers.js.map +1 -1
  5. package/dist/advance-lifecycle-template.d.ts.map +1 -1
  6. package/dist/advance-lifecycle-template.js +76 -4
  7. package/dist/advance-lifecycle-template.js.map +1 -1
  8. package/dist/advance-treeless-publish.d.ts +23 -0
  9. package/dist/advance-treeless-publish.d.ts.map +1 -1
  10. package/dist/advance-treeless-publish.js +41 -0
  11. package/dist/advance-treeless-publish.js.map +1 -1
  12. package/dist/advance.d.ts +59 -7
  13. package/dist/advance.d.ts.map +1 -1
  14. package/dist/advance.js +389 -82
  15. package/dist/advance.js.map +1 -1
  16. package/dist/advancing-lock.d.ts +30 -2
  17. package/dist/advancing-lock.d.ts.map +1 -1
  18. package/dist/advancing-lock.js +50 -0
  19. package/dist/advancing-lock.js.map +1 -1
  20. package/dist/agent-launch.d.ts +12 -0
  21. package/dist/agent-launch.d.ts.map +1 -1
  22. package/dist/agent-launch.js +22 -12
  23. package/dist/agent-launch.js.map +1 -1
  24. package/dist/agent-stop.d.ts +40 -2
  25. package/dist/agent-stop.d.ts.map +1 -1
  26. package/dist/agent-stop.js +30 -2
  27. package/dist/agent-stop.js.map +1 -1
  28. package/dist/apply-decide.d.ts +17 -3
  29. package/dist/apply-decide.d.ts.map +1 -1
  30. package/dist/apply-decide.js +36 -7
  31. package/dist/apply-decide.js.map +1 -1
  32. package/dist/apply-merge-action.d.ts +17 -5
  33. package/dist/apply-merge-action.d.ts.map +1 -1
  34. package/dist/apply-merge-action.js +43 -8
  35. package/dist/apply-merge-action.js.map +1 -1
  36. package/dist/apply-persist.d.ts +57 -26
  37. package/dist/apply-persist.d.ts.map +1 -1
  38. package/dist/apply-persist.js +166 -37
  39. package/dist/apply-persist.js.map +1 -1
  40. package/dist/apply-stuck-action.d.ts +151 -0
  41. package/dist/apply-stuck-action.d.ts.map +1 -0
  42. package/dist/apply-stuck-action.js +125 -0
  43. package/dist/apply-stuck-action.js.map +1 -0
  44. package/dist/brand.d.ts +12 -1
  45. package/dist/brand.d.ts.map +1 -1
  46. package/dist/brand.js +2 -1
  47. package/dist/brand.js.map +1 -1
  48. package/dist/cli-spinner.d.ts +1 -1
  49. package/dist/cli-spinner.js +1 -1
  50. package/dist/cli.d.ts +10 -0
  51. package/dist/cli.d.ts.map +1 -1
  52. package/dist/cli.js +320 -63
  53. package/dist/cli.js.map +1 -1
  54. package/dist/close-job-template.js +1 -1
  55. package/dist/complete.d.ts +6 -3
  56. package/dist/complete.d.ts.map +1 -1
  57. package/dist/complete.js +91 -37
  58. package/dist/complete.js.map +1 -1
  59. package/dist/config.d.ts +55 -9
  60. package/dist/config.d.ts.map +1 -1
  61. package/dist/config.js +56 -4
  62. package/dist/config.js.map +1 -1
  63. package/dist/continue-branch.d.ts.map +1 -1
  64. package/dist/continue-branch.js +22 -0
  65. package/dist/continue-branch.js.map +1 -1
  66. package/dist/decision-engine.d.ts +38 -10
  67. package/dist/decision-engine.d.ts.map +1 -1
  68. package/dist/decision-engine.js +10 -6
  69. package/dist/decision-engine.js.map +1 -1
  70. package/dist/do-autopick.d.ts.map +1 -1
  71. package/dist/do-autopick.js +11 -1
  72. package/dist/do-autopick.js.map +1 -1
  73. package/dist/do-config.d.ts +1 -1
  74. package/dist/do.d.ts +49 -56
  75. package/dist/do.d.ts.map +1 -1
  76. package/dist/do.js +419 -30
  77. package/dist/do.js.map +1 -1
  78. package/dist/env-config.d.ts.map +1 -1
  79. package/dist/env-config.js +12 -4
  80. package/dist/env-config.js.map +1 -1
  81. package/dist/failure-cause.d.ts +3 -2
  82. package/dist/failure-cause.d.ts.map +1 -1
  83. package/dist/failure-cause.js +28 -1
  84. package/dist/failure-cause.js.map +1 -1
  85. package/dist/format.d.ts +6 -6
  86. package/dist/format.d.ts.map +1 -1
  87. package/dist/format.js +10 -27
  88. package/dist/format.js.map +1 -1
  89. package/dist/frontmatter.d.ts +16 -4
  90. package/dist/frontmatter.d.ts.map +1 -1
  91. package/dist/frontmatter.js +27 -1
  92. package/dist/frontmatter.js.map +1 -1
  93. package/dist/gc.d.ts +65 -6
  94. package/dist/gc.d.ts.map +1 -1
  95. package/dist/gc.js +126 -9
  96. package/dist/gc.js.map +1 -1
  97. package/dist/github.d.ts +14 -0
  98. package/dist/github.d.ts.map +1 -1
  99. package/dist/github.js +73 -0
  100. package/dist/github.js.map +1 -1
  101. package/dist/harness.d.ts +25 -0
  102. package/dist/harness.d.ts.map +1 -1
  103. package/dist/harness.js.map +1 -1
  104. package/dist/index.d.ts +4 -1
  105. package/dist/index.d.ts.map +1 -1
  106. package/dist/index.js +2 -1
  107. package/dist/index.js.map +1 -1
  108. package/dist/install-ci-branch-protection.d.ts +132 -38
  109. package/dist/install-ci-branch-protection.d.ts.map +1 -1
  110. package/dist/install-ci-branch-protection.js +190 -48
  111. package/dist/install-ci-branch-protection.js.map +1 -1
  112. package/dist/install-ci-core.d.ts +21 -1
  113. package/dist/install-ci-core.d.ts.map +1 -1
  114. package/dist/install-ci-core.js +10 -3
  115. package/dist/install-ci-core.js.map +1 -1
  116. package/dist/install-ci-github.d.ts +32 -0
  117. package/dist/install-ci-github.d.ts.map +1 -1
  118. package/dist/install-ci-github.js +73 -0
  119. package/dist/install-ci-github.js.map +1 -1
  120. package/dist/install-skills.d.ts +123 -0
  121. package/dist/install-skills.d.ts.map +1 -0
  122. package/dist/install-skills.js +100 -0
  123. package/dist/install-skills.js.map +1 -0
  124. package/dist/intake-trigger-template.js +1 -1
  125. package/dist/intake.d.ts +17 -4
  126. package/dist/intake.d.ts.map +1 -1
  127. package/dist/intake.js +23 -7
  128. package/dist/intake.js.map +1 -1
  129. package/dist/integration-core.d.ts +10 -7
  130. package/dist/integration-core.d.ts.map +1 -1
  131. package/dist/integration-core.js +174 -60
  132. package/dist/integration-core.js.map +1 -1
  133. package/dist/integrator.d.ts +1 -1
  134. package/dist/integrator.d.ts.map +1 -1
  135. package/dist/integrator.js +19 -3
  136. package/dist/integrator.js.map +1 -1
  137. package/dist/isolation.d.ts +2 -2
  138. package/dist/isolation.d.ts.map +1 -1
  139. package/dist/isolation.js +9 -0
  140. package/dist/isolation.js.map +1 -1
  141. package/dist/item-lock.d.ts +196 -129
  142. package/dist/item-lock.d.ts.map +1 -1
  143. package/dist/item-lock.js +329 -254
  144. package/dist/item-lock.js.map +1 -1
  145. package/dist/ledger-write.d.ts +31 -26
  146. package/dist/ledger-write.d.ts.map +1 -1
  147. package/dist/ledger-write.js +100 -122
  148. package/dist/ledger-write.js.map +1 -1
  149. package/dist/lifecycle-gather.d.ts +17 -0
  150. package/dist/lifecycle-gather.d.ts.map +1 -1
  151. package/dist/lifecycle-gather.js +7 -1
  152. package/dist/lifecycle-gather.js.map +1 -1
  153. package/dist/lifecycle-pools.d.ts +40 -3
  154. package/dist/lifecycle-pools.d.ts.map +1 -1
  155. package/dist/lifecycle-pools.js +26 -6
  156. package/dist/lifecycle-pools.js.map +1 -1
  157. package/dist/merge-question-surfacer.d.ts +15 -1
  158. package/dist/merge-question-surfacer.d.ts.map +1 -1
  159. package/dist/merge-question-surfacer.js +18 -3
  160. package/dist/merge-question-surfacer.js.map +1 -1
  161. package/dist/migrate-stuck-locks.d.ts +129 -0
  162. package/dist/migrate-stuck-locks.d.ts.map +1 -0
  163. package/dist/migrate-stuck-locks.js +355 -0
  164. package/dist/migrate-stuck-locks.js.map +1 -0
  165. package/dist/needs-attention.d.ts +293 -16
  166. package/dist/needs-attention.d.ts.map +1 -1
  167. package/dist/needs-attention.js +532 -57
  168. package/dist/needs-attention.js.map +1 -1
  169. package/dist/orphan-sidecar.d.ts +8 -4
  170. package/dist/orphan-sidecar.d.ts.map +1 -1
  171. package/dist/orphan-sidecar.js +35 -2
  172. package/dist/orphan-sidecar.js.map +1 -1
  173. package/dist/pi-harness.d.ts +16 -0
  174. package/dist/pi-harness.d.ts.map +1 -1
  175. package/dist/pi-harness.js +82 -2
  176. package/dist/pi-harness.js.map +1 -1
  177. package/dist/placement.d.ts +3 -3
  178. package/dist/placement.js +1 -1
  179. package/dist/prd-to-spec.d.ts.map +1 -1
  180. package/dist/prd-to-spec.js +9 -5
  181. package/dist/prd-to-spec.js.map +1 -1
  182. package/dist/protocol/CLAIM-PROTOCOL.md +17 -10
  183. package/dist/protocol/REVIEW-PROTOCOL.md +4 -1
  184. package/dist/protocol/SURFACE-PROTOCOL.md +16 -2
  185. package/dist/protocol/TASKING-PROTOCOL.md +3 -1
  186. package/dist/protocol/WORK-CONTRACT.md +22 -18
  187. package/dist/protocol/task-template.md +1 -1
  188. package/dist/reap-branches.d.ts +12 -9
  189. package/dist/reap-branches.d.ts.map +1 -1
  190. package/dist/reap-branches.js +25 -7
  191. package/dist/reap-branches.js.map +1 -1
  192. package/dist/recover-isolated.d.ts +12 -0
  193. package/dist/recover-isolated.d.ts.map +1 -1
  194. package/dist/recover-isolated.js +5 -0
  195. package/dist/recover-isolated.js.map +1 -1
  196. package/dist/repo-config.d.ts +23 -2
  197. package/dist/repo-config.d.ts.map +1 -1
  198. package/dist/repo-config.js +53 -7
  199. package/dist/repo-config.js.map +1 -1
  200. package/dist/repo-mirror.d.ts.map +1 -1
  201. package/dist/repo-mirror.js +18 -2
  202. package/dist/repo-mirror.js.map +1 -1
  203. package/dist/review-verdict.js +1 -1
  204. package/dist/review-verdict.js.map +1 -1
  205. package/dist/run.d.ts +1 -1
  206. package/dist/run.d.ts.map +1 -1
  207. package/dist/run.js +54 -19
  208. package/dist/run.js.map +1 -1
  209. package/dist/scan.d.ts +17 -8
  210. package/dist/scan.d.ts.map +1 -1
  211. package/dist/scan.js +22 -8
  212. package/dist/scan.js.map +1 -1
  213. package/dist/select-priority.d.ts +2 -2
  214. package/dist/select-priority.js +1 -1
  215. package/dist/select-priority.js.map +1 -1
  216. package/dist/sidecar-apply.js +1 -1
  217. package/dist/sidecar-apply.js.map +1 -1
  218. package/dist/sidecar.d.ts +45 -10
  219. package/dist/sidecar.d.ts.map +1 -1
  220. package/dist/sidecar.js +82 -2
  221. package/dist/sidecar.js.map +1 -1
  222. package/dist/skills/answer-questions/SKILL.md +89 -0
  223. package/dist/skills/capture-signal/SKILL.md +52 -0
  224. package/dist/skills/convert-from-prd-to-spec/SKILL.md +90 -0
  225. package/dist/skills/drive-tasks/SKILL.md +218 -0
  226. package/dist/skills/from-idea/SKILL.md +83 -0
  227. package/dist/skills/merge-prs/SKILL.md +70 -0
  228. package/dist/skills/orchestrate/SKILL.md +101 -0
  229. package/dist/skills/promote/SKILL.md +35 -0
  230. package/dist/skills/review/SKILL.md +16 -0
  231. package/dist/skills/setup/SKILL.md +258 -0
  232. package/dist/skills/setup/protocol/ADR-FORMAT.md +47 -0
  233. package/dist/skills/setup/protocol/CLAIM-PROTOCOL.md +224 -0
  234. package/dist/skills/setup/protocol/REVIEW-PROTOCOL.md +122 -0
  235. package/dist/skills/setup/protocol/SURFACE-PROTOCOL.md +135 -0
  236. package/dist/skills/setup/protocol/TASKING-PROTOCOL.md +124 -0
  237. package/dist/skills/setup/protocol/WORK-CONTRACT.md +280 -0
  238. package/dist/skills/setup/protocol/spec-template.md +71 -0
  239. package/dist/skills/setup/protocol/task-template.md +65 -0
  240. package/dist/skills/surface-questions/SKILL.md +16 -0
  241. package/dist/skills/to-spec/SKILL.md +34 -0
  242. package/dist/skills/to-task/SKILL.md +19 -0
  243. package/dist/skills/triage-observations/SKILL.md +78 -0
  244. package/dist/skills/work/SKILL.md +51 -0
  245. package/dist/slug-namespace.d.ts +5 -5
  246. package/dist/slug-namespace.js +5 -5
  247. package/dist/slug-namespace.js.map +1 -1
  248. package/dist/spec-complete.d.ts.map +1 -1
  249. package/dist/spec-complete.js +2 -3
  250. package/dist/spec-complete.js.map +1 -1
  251. package/dist/start.d.ts.map +1 -1
  252. package/dist/start.js +51 -57
  253. package/dist/start.js.map +1 -1
  254. package/dist/surface-gate.d.ts.map +1 -1
  255. package/dist/surface-gate.js +10 -3
  256. package/dist/surface-gate.js.map +1 -1
  257. package/dist/surface-persist.js +1 -1
  258. package/dist/surface-persist.js.map +1 -1
  259. package/dist/tasker-review-loop.d.ts +4 -3
  260. package/dist/tasker-review-loop.d.ts.map +1 -1
  261. package/dist/tasker-review-loop.js.map +1 -1
  262. package/dist/tasking-lock.d.ts +2 -2
  263. package/dist/tasking-lock.d.ts.map +1 -1
  264. package/dist/tasking-lock.js +53 -32
  265. package/dist/tasking-lock.js.map +1 -1
  266. package/dist/tasking.d.ts +40 -6
  267. package/dist/tasking.d.ts.map +1 -1
  268. package/dist/tasking.js +224 -12
  269. package/dist/tasking.js.map +1 -1
  270. package/dist/triage-persist.d.ts +10 -6
  271. package/dist/triage-persist.d.ts.map +1 -1
  272. package/dist/triage-persist.js +34 -4
  273. package/dist/triage-persist.js.map +1 -1
  274. package/dist/vendor/incur/agents.d.ts +58 -0
  275. package/dist/vendor/incur/agents.d.ts.map +1 -0
  276. package/dist/vendor/incur/agents.js +343 -0
  277. package/dist/vendor/incur/agents.js.map +1 -0
  278. package/dist/verify-workflow-template.js +1 -1
  279. package/dist/watch-session.d.ts +11 -3
  280. package/dist/watch-session.d.ts.map +1 -1
  281. package/dist/watch-session.js +94 -7
  282. package/dist/watch-session.js.map +1 -1
  283. package/dist/work-layout.d.ts +7 -3
  284. package/dist/work-layout.d.ts.map +1 -1
  285. package/dist/work-layout.js +6 -3
  286. package/dist/work-layout.js.map +1 -1
  287. package/dist/workspace.d.ts +1 -1
  288. package/package.json +2 -2
  289. package/src/advance-drivers.ts +16 -3
  290. package/src/advance-lifecycle-template.ts +89 -4
  291. package/src/advance-treeless-publish.ts +45 -0
  292. package/src/advance.ts +467 -87
  293. package/src/advancing-lock.ts +96 -1
  294. package/src/agent-launch.ts +37 -12
  295. package/src/agent-stop.ts +60 -2
  296. package/src/apply-decide.ts +36 -7
  297. package/src/apply-merge-action.ts +45 -7
  298. package/src/apply-persist.ts +228 -54
  299. package/src/apply-stuck-action.ts +260 -0
  300. package/src/brand.ts +14 -2
  301. package/src/cli-spinner.ts +1 -1
  302. package/src/cli.ts +401 -70
  303. package/src/close-job-template.ts +1 -1
  304. package/src/complete.ts +110 -52
  305. package/src/config.ts +107 -13
  306. package/src/continue-branch.ts +22 -0
  307. package/src/decision-engine.ts +55 -17
  308. package/src/do-autopick.ts +12 -1
  309. package/src/do-config.ts +1 -1
  310. package/src/do.ts +511 -38
  311. package/src/env-config.ts +12 -4
  312. package/src/failure-cause.ts +30 -1
  313. package/src/format.ts +10 -30
  314. package/src/frontmatter.ts +35 -5
  315. package/src/gc.ts +172 -9
  316. package/src/github.ts +78 -0
  317. package/src/harness.ts +25 -0
  318. package/src/index.ts +10 -0
  319. package/src/install-ci-branch-protection.ts +282 -57
  320. package/src/install-ci-core.ts +30 -3
  321. package/src/install-ci-github.ts +86 -0
  322. package/src/install-skills.ts +166 -0
  323. package/src/intake-trigger-template.ts +1 -1
  324. package/src/intake.ts +46 -11
  325. package/src/integration-core.ts +199 -65
  326. package/src/integrator.ts +22 -9
  327. package/src/isolation.ts +11 -2
  328. package/src/item-lock.ts +485 -341
  329. package/src/ledger-write.ts +135 -150
  330. package/src/lifecycle-gather.ts +29 -6
  331. package/src/lifecycle-pools.ts +67 -9
  332. package/src/merge-question-surfacer.ts +28 -4
  333. package/src/migrate-stuck-locks.ts +451 -0
  334. package/src/needs-attention.ts +857 -84
  335. package/src/orphan-sidecar.ts +47 -6
  336. package/src/pi-harness.ts +82 -2
  337. package/src/placement.ts +3 -3
  338. package/src/prd-to-spec.ts +13 -5
  339. package/src/reap-branches.ts +38 -14
  340. package/src/recover-isolated.ts +17 -0
  341. package/src/repo-config.ts +55 -6
  342. package/src/repo-mirror.ts +23 -1
  343. package/src/review-verdict.ts +1 -1
  344. package/src/run.ts +64 -18
  345. package/src/scan.ts +22 -8
  346. package/src/select-priority.ts +3 -3
  347. package/src/sidecar-apply.ts +1 -1
  348. package/src/sidecar.ts +138 -11
  349. package/src/slug-namespace.ts +7 -7
  350. package/src/spec-complete.ts +2 -3
  351. package/src/start.ts +53 -59
  352. package/src/surface-gate.ts +10 -3
  353. package/src/surface-persist.ts +1 -1
  354. package/src/tasker-review-loop.ts +4 -3
  355. package/src/tasking-lock.ts +52 -36
  356. package/src/tasking.ts +261 -17
  357. package/src/triage-persist.ts +56 -12
  358. package/src/vendor/incur/LICENSE +21 -0
  359. package/src/vendor/incur/README.md +19 -0
  360. package/src/vendor/incur/agents.ts +392 -0
  361. package/src/verify-workflow-template.ts +1 -1
  362. package/src/watch-session.ts +102 -7
  363. package/src/work-layout.ts +6 -3
  364. package/src/workspace.ts +1 -1
@@ -0,0 +1,83 @@
1
+ ---
2
+ name: from-idea
3
+ disable-model-invocation: true
4
+ description: 'The from-scratch ON-RAMP: take a raw project idea and end with a scaffolded work/-contract repo where that idea is captured as a spec in work/specs/ready/, ready to task. The front door that owns the idea-interview and sequences setup (scaffold) then to-spec (synthesize). NOT a spec-producer itself — to-spec is the synthesis primitive it calls; NOT adversarial spec-grilling (that is the separate grilling skill).'
5
+ ---
6
+
7
+ # from-idea
8
+
9
+ **The from-scratch entrance to the main flow.** You have a raw idea ("I want to build X") and want ONE move that ends with a contract-ready repo holding that idea as a spec in `work/specs/ready/`, ready to task. This is **rung A of the spec lifecycle's front door** — the on-ramp that wraps the first two steps of the main flow (`setup` then `to-spec`) and adds the one thing neither does: a thin **interview that turns a raw idea into something spec-worthy**.
10
+
11
+ It is an **on-ramp** (per `work/SKILL.md`'s taxonomy — a starting situation that generates work, then merges onto the main flow), not a survey-loop. It is a **thin orchestrator**: its entire net-new surface is the idea interview plus two skill invocations in order plus the plumbing between them. Everything else is borrowed.
12
+
13
+ ## What it is NOT (the boundaries that keep it thin)
14
+
15
+ - **NOT a spec-producer of its own.** `to-spec` writes the spec (it owns the spec shape, the `work/protocol/spec-template.md`, the launch-snapshot banner, the `specs/ready/` target, the two autonomy axes). from-idea is the FRONT DOOR that calls it. Read the two names as a pair: `from-idea` owns the on-ramp (setup + the interview); `to-spec` is the synthesis primitive it hands the conversation to. Do not reimplement any of to-spec here.
16
+ - **NOT a scaffolder of its own.** `setup` owns the `work/` skeleton, the `work/protocol/` docs, `CONTEXT.md`, the `.dorfl.json` `verify`/`prepare` gate, and the empty-vs-populated detection. from-idea CALLS setup; it never hand-rolls a "is this a contract repo?" check or writes `CONTEXT.md` itself (that forks setup's detection and drifts). The one-way direction is fixed: **from-idea calls setup; setup never calls from-idea** (setup stays a focused adoption primitive). setup's empty-repo branch MAY _mention_ from-idea as the next step — a discoverability pointer, never an invocation.
17
+ - **NOT adversarial grilling.** Stress-testing a plan/design before building is the personal `grilling` skill's job. from-idea clarifies only enough to be spec-worthy and DEFERS the rest (see the interview floor below). If the user wants the idea grilled, that is a separate move after the spec lands.
18
+
19
+ ## The sequence (honor BOTH human checkpoints; never auto-commit)
20
+
21
+ ```
22
+ clarify the idea → setup (PLAN → HARD STOP → scaffold) → to-spec (write specs/ready/<slug>.md, unstaged)
23
+ ```
24
+
25
+ `setup` MUST run first: `to-spec` writes to `work/specs/ready/`, which requires `work/` to exist. The flow has **two natural human checkpoints**, and from-idea honors both:
26
+
27
+ 1. **setup's plan-confirm HARD STOP** — setup presents the proposed description + detected `verify`/`prepare` gate (+ any Phase-B mapping) and STOPS for the user to ratify before writing the judgement-heavy parts. Do NOT bulldoze this; it is a real stop. Let setup own its arc.
28
+ 2. **The spec landing unstaged in `specs/ready/`** — `to-spec` leaves the file in the working tree for the human to review; it does not stage/commit. from-idea inherits that etiquette: **never stage/commit/push** at any step.
29
+
30
+ ## Step 1 — Clarify the idea (the ONE net-new piece): just enough to be spec-worthy
31
+
32
+ This is the only doing from-idea adds. Run a SHORT interview to lift the raw idea to the floor a spec needs — no further.
33
+
34
+ **The interview floor (the stop condition).** Clarify enough that `to-spec` can write a coherent launch snapshot. Borrow to-spec's own spine — a spec-worthy idea has:
35
+
36
+ - **(a) the problem / intent** — what is this for, what pain or opportunity does it address;
37
+ - **(b) the rough shape of success** — what does "it works" look like, who/what uses it, what it integrates with;
38
+ - **(c) the obvious seams / constraints** — the highest seams the feature would be tested at, and any hard constraints (stack, platform, external systems) the user already knows.
39
+
40
+ That is the FLOOR, not "everything resolved." Ask a small number of focused questions (think 2–5, batched), then stop.
41
+
42
+ **The no-grill / defer rule (do not become a second grilling skill).** Genuine design forks, unknowns, and "we'll decide later" calls are NOT interview rounds — they are recorded by `to-spec` as `needsAnswers: true` with the open questions in the spec body, and DEFERRED. The auto-tasker then refuses to task until a human resolves them. Be honest: a spec flagged `needsAnswers` is the correct output of a real but unresolved idea, far better than over-interviewing to force a false resolution. When in doubt, defer rather than grill. (If the idea is so thin it is barely a wish, say so and offer to capture it as a `notes/ideas/` note instead of pushing it through to a spec.)
43
+
44
+ **One interview, two consumers.** The answers you gather here feed BOTH downstream skills — do not let them re-ask:
45
+
46
+ - the one-to-two-sentence **project description** (problem + intent) is what setup's A2 step needs for `CONTEXT.md`;
47
+ - the fuller **problem + shape + seams + open questions** is what to-spec synthesizes into the spec.
48
+
49
+ So you interview ONCE. When setup's A2 asks "what is this repo about?", you already have the description — supply it, do not re-interview (that same-session double-ask is exactly the drift the on-ramp pattern forbids). setup (not from-idea) writes `CONTEXT.md` from that description.
50
+
51
+ ## Step 2 — Run setup (always; let its idempotency decide depth)
52
+
53
+ **Always invoke `setup`** — do NOT hand-roll a `test -d work/` to decide whether to. setup's A1 already detects empty-vs-populated and does the right thing in each case, and re-running it on an existing contract repo **re-syncs the `work/protocol/` docs** (the one legitimate clobber) so the repo picks up protocol updates. Skipping setup would skip that refresh and fork its detection logic.
54
+
55
+ - **Empty / new repo (the common from-idea case):** setup does Phase A — scaffolds `work/`, copies `work/protocol/`, writes `CONTEXT.md` (from the description you gathered in step 1) and `.dorfl.json` (the `verify`/`prepare` gate it detects, presented for confirmation at its HARD STOP). Phase B is empty.
56
+ - **Existing contract repo (adding a new idea to a repo already set up):** setup's Phase A is a near-no-op + protocol re-sync; the scaffold already exists. You then go straight to step 3. **Flag the Phase-B-hijack seam:** if the repo is populated with convertible material, be explicit that the intent is "scaffold/refresh and accept a NEW idea", not "migrate everything" — do not let setup's Phase-B conversion hijack the from-idea session. (A new idea is not migration of existing material.)
57
+
58
+ Honor setup's HARD STOP: present the plan, wait for confirmation, then it scaffolds. Feed it the description from step 1 so its A2 does not re-ask.
59
+
60
+ ## Step 3 — Hand the conversation to to-spec
61
+
62
+ Once `work/` exists (setup's scaffold confirmed and written), invoke `to-spec`. It synthesizes the SAME conversation you have been having — the idea, the clarifications from step 1, the codebase understanding setup just established — into `work/specs/ready/<slug>.md`:
63
+
64
+ - to-spec targets **`specs/ready/`** (the auto-task pool) — that is its written target and the goal of this on-ramp. from-idea does NOT route the spec into `specs/proposed/` (staging): there is no grilling/promotion gate here (grilling is scoped out), so the review gate is simply the **unstaged file** a human reviews before tasking. (If a session later wants the idea grilled before it is trusted, that is a separate move — and `specs/proposed/` is where a review-first spec would live — but from-idea's deliberate target is `ready/`.)
65
+ - to-spec sets the two autonomy axes from what the interview resolved: `humanOnly` if a human must drive the tasking, and `needsAnswers: true` (with the questions in the body) for everything step 1 deliberately deferred.
66
+ - to-spec writes the file UNSTAGED and reports the path. from-idea does not commit it.
67
+
68
+ ## Report + hand off
69
+
70
+ Tell the user, concisely:
71
+
72
+ - the repo is now contract-ready (what setup scaffolded / re-synced, the `verify` gate configured);
73
+ - the spec written, by path — `work/specs/ready/<slug>.md` — left UNSTAGED for review, plus any `needsAnswers` questions it carries that a human must resolve before tasking;
74
+ - **what's next on the main flow:** review the spec, then task it with `to-task` (or `dorfl do spec:<slug>` once the runner is installed and the spec is agent-safe). If the idea has real design forks worth pressure-testing first, point at the `grilling` skill — explicitly NOT part of this on-ramp.
75
+
76
+ **Git etiquette:** never stage, commit, or push — leave both setup's scaffold and to-spec's spec in the working tree for the user to inspect and commit (the producer-skill convention setup and to-spec both follow).
77
+
78
+ ## Boundary (what from-idea does NOT do)
79
+
80
+ - It does NOT reimplement detection (setup A1), the gate (setup A3/A3b), `CONTEXT.md` (setup A2), the spec shape / banner / target (to-spec + `spec-template.md`). Its only net-new surface is the idea interview + ordering the two calls + feeding the description to setup.
81
+ - It does NOT grill the idea adversarially (the `grilling` skill), force-resolve genuine unknowns (they become `needsAnswers`), or push a barely-a-wish idea onto the spec board (offer `notes/ideas/` instead).
82
+ - It is NOT called BY setup (one-way: from-idea → setup). setup may _mention_ it; it never invokes it.
83
+ - It NEVER auto-commits, and it never bulldozes setup's plan-confirm HARD STOP.
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: merge-prs
3
+ disable-model-invocation: true
4
+ description: "Review the open work/ PRs and land them EFFICIENTLY: partition into conflict-free clusters, gate each cluster's combined tip ONCE, then merge the cluster; PRs that don't cleanly combine fall out to their own gate. The batch-landing sibling of drive-tasks (which builds+merges one task at a time). Requires gh + a GitHub arbiter in propose mode."
5
+ ---
6
+
7
+ # merge-prs
8
+
9
+ **Land the already-built, not build the not-yet-built.** `drive-tasks` is the conductor that _builds_ ready tasks one at a time and merges each PR as it opens. `merge-prs` starts one step LATER: a set of work PRs is already OPEN (they came from `dorfl do --propose`, `run`, CI intake, or a `drive-tasks` pass you didn't merge), and the job is to review them and get them ONTO `main` with the fewest possible gate runs.
10
+
11
+ The trick is **batching by conflict-free clustering**. Instead of one review then gate then merge per PR (N gate runs), partition the approved PRs into clusters that touch disjoint files, combine each cluster onto a scratch branch, run the repo's `verify` gate ONCE against that combined tip, and merge the whole cluster. N PRs that don't overlap become 1 gate run, not N.
12
+
13
+ It is a **methodology skill** (prose you follow), like `review` and `drive-tasks`, NOT a runner command. **Precondition:** it operates over **open GitHub PRs** on a repo using the **`work/` contract**, in **`propose` integration mode**, with **`gh`** available. If the arbiter is not GitHub, or integration is `merge` (no PRs), this skill does not apply as written (see [Provider assumption](#provider-assumption)). It composes:
14
+
15
+ - **`review`** (`skills/review/`): the diff-vs-criteria discipline, applied PER PR before it is eligible to join a cluster. A PR that fails review never enters the batch.
16
+ - **`drive-tasks`** (`skills/drive-tasks/`): the sibling conductor. Its [accumulate-don't-block rule](../drive-tasks/SKILL.md) and its **never-touch-the-target-checkout** rule (golden rule 7) apply here UNCHANGED. A PR you can't cleanly land goes in the stuck-set and you move on; all combining/gating happens in a scratch worktree/clone you own, never the human checkout.
17
+
18
+ ## When to use vs. not
19
+
20
+ - **Use** when several work PRs are already open and you want to land the sound ones in as few gate runs as possible; after a `run`/CI burst left a pile of green-gated PRs awaiting a human merge; when you'd rather review-and-land a backlog of PRs than build new tasks.
21
+ - **Do NOT use** to BUILD tasks; that is `drive-tasks` (or `dorfl do`). If there are zero open PRs, there is nothing to do here. If integration mode is `merge` (direct-to-main, no PR), there is no PR surface to batch, because the landing already happened at build time.
22
+
23
+ ## The one correctness rule (why clustering, not just "gate the combine")
24
+
25
+ The whole value is "gate once for N PRs", but a combined gate is only HONEST if **what you gated is what actually lands**. Two ways to break that, and the rule that avoids both:
26
+
27
+ - Under `gh pr merge`, each PR squash-merges onto the CURRENT `main`, so after the first merge the tree GitHub produces for the second PR is NOT byte-identical to the combined tip you gated. If two PRs touch the **same file**, a green combined gate can still yield a broken/conflicted `main`.
28
+ - So a combined gate over OVERLAPPING PRs is necessary-but-not-sufficient. It can lie.
29
+
30
+ **The rule: only ever batch PRs whose file-sets are DISJOINT.** Within a conflict-free cluster there is no overlap for a later merge to invalidate, so the combined green gate genuinely predicts each per-PR merge. Concretely: partition by "do these PRs' changed-file sets intersect?" A PR that overlaps any other lands in its OWN singleton cluster (gate it alone, merge it alone). You lose the batching win for that one, but never the honesty. This is the "combine only the PRs that make sense" instinct, made a hard invariant.
31
+
32
+ > Overlap is judged on **changed files** (`gh pr diff <n> --name-only`), which is a conservative proxy: two PRs can touch the same file on non-adjacent lines and still merge cleanly, so file-level disjointness may over-split (extra singletons) but never under-splits into a dishonest batch. That trade is deliberate: prefer an extra gate run over a lying one. (If you want tighter packing later, upgrade the test to an actual trial `git merge`/`rebase` in the scratch tree and treat a clean 3-way merge as non-conflicting; until then, file-set disjointness is the safe default.)
33
+
34
+ ## The loop
35
+
36
+ Run from ANYWHERE: you need only the arbiter (a URL/remote) plus `gh` plus a scratch area. Resolve the arbiter EXPLICITLY; if `cwd` is the human's checkout, treat it as READ-ONLY (drive-tasks golden rule 7).
37
+
38
+ **0. Enumerate the open work PRs.** `gh pr list --state open --json number,title,headRefName,url`. Keep only the ones that are work-branch PRs (dorfl pushes `work/<slug>` head branches, so filter on `headRefName` prefix / your repo's convention). Map each PR back to its task slug and the `work/tasks/**/<slug>.md` it done-moves, so review has the acceptance criteria to check against.
39
+
40
+ **1. Per-PR review (the eligibility gate).** For EACH PR, apply the `review` discipline (`skills/review/`) to its diff vs. its task's criteria. This is the same Gate-3 diff-vs-criteria pass `drive-tasks` step 4 does, just done up front for all PRs:
41
+
42
+ - clear **APPROVE** → the PR is eligible to be batched.
43
+ - clear **BLOCK** (a drift note violated, an acceptance criterion unmet, an empty/vacuous diff) → drop it from the batch, record the blocking finding (post it as a PR comment leading with `BLOCK`, per drive-tasks step 4), and do NOT land it.
44
+ - genuine **judgement call** (maybe-blocking nit, ambiguously-met criterion) → that is a WALL, so stuck-set it and skip, per the [accumulate-don't-block rule](../drive-tasks/SKILL.md). Never merge on a coin-flip.
45
+
46
+ **2. Cluster the approved PRs by conflict-freedom.** For each approved PR collect its changed-file set (`gh pr diff <n> --name-only`). Group PRs so that within a group every pair has DISJOINT file-sets (the [one correctness rule](#the-one-correctness-rule-why-clustering-not-just-gate-the-combine)). Any PR overlapping another becomes its own singleton cluster. Note that dorfl PRs each done-move their OWN `work/tasks/…/<slug>.md` (distinct paths) and edit distinct code, so in practice most PRs land in one big disjoint cluster and overlaps are the exception.
47
+
48
+ **3. Per cluster: combine → gate ONCE → merge the cluster.** In a scratch worktree/clone you own (NEVER the human checkout):
49
+
50
+ - fetch the arbiter, create a scratch integration branch off the current `main`, and merge each PR's head branch into it (`git merge --no-ff <headRef>` or cherry-pick the PR range). A merge that CONFLICTS despite the file-set proxy (rare, but possible) → pull that PR OUT of the cluster into a singleton and re-form the cluster; do not force it.
51
+ - run the repo's **`verify` gate** ONCE against the combined tip. In this repo that is `pnpm -r build && pnpm -r test && pnpm format:check` (the `dorfl verify` equivalent; see AGENTS.md. Do NOT invent a gate, read the repo's `dorfl.json` `verify`).
52
+ - **green** → merge every PR in the cluster: `gh pr comment <n> --body "APPROVE ✅ (batch-gated with #a #b #c)"` then `gh pr merge <n> --squash --delete-branch` for each. Because the file-sets are disjoint, the sequential squash-merges reproduce the tip you gated.
53
+ - **red** → the cluster is NOT landable as a batch. Do NOT merge any of it on a batch coin-flip. Bisect by falling back to gating the cluster's PRs INDIVIDUALLY (singleton gate each), land the green ones, and stuck-set the red one with the failing gate output. A batch red almost always means one bad PR poisoning the combine, and the singleton pass isolates it.
54
+
55
+ **4. Recompute and continue.** Each cluster merge lands `work/tasks/done/<slug>.md` for its PRs on `main`. Fetch, re-enumerate open PRs (new ones may have appeared; a PR blocked-by a now-merged one may have become reviewable), and repeat from step 0 until no open work PR can advance.
56
+
57
+ **5. Surface the residue in ONE batch.** When nothing more can land, deal with the stuck-set exactly as drive-tasks does: **human present** → present the blocked/judgement-call PRs as one batched set of questions, take answers, resume; **no human reachable** → stop and report the stuck-set plus the landed/blocked summary. Never dribble questions one at a time.
58
+
59
+ ## Confirm the run mode first
60
+
61
+ At the START, CONFIRM with the user (mirrors drive-tasks): squash vs. merge-commit for the `gh pr merge` (default `--squash --delete-branch`), and whether they want you to actually merge or only review-and-report the clusters (a dry-run: emit "these N PRs cluster into these groups, each would gate as one" without merging). Batch-MERGING is mutating and irreversible-ish (branches deleted), so a dry-run first pass is often the right default; offer it.
62
+
63
+ ## Provider assumption
64
+
65
+ The `gh pr comment` + `gh pr merge` flow assumes **`propose` mode + a GitHub arbiter**, the only review-and-land surface dorfl exposes today. There is **no `dorfl` merge/land/approve verb yet** (checked against the CLI: `scan/run/do/advance/complete/promote/requeue/drop/intake/...`, none land a PR), so this skill is GitHub-propose-specific by necessity, same as `drive-tasks` step 5. In `merge` mode there are no PRs to batch. A future provider-agnostic land verb would let this skill drop the `gh` specifics; until then, adapt the merge mechanics to the repo's actual arbiter.
66
+
67
+ ## Relationship to the other conductors
68
+
69
+ - **`drive-tasks`** BUILDS ready tasks (one at a time, build then review then merge). `merge-prs` starts where a build left an OPEN PR and batches the LANDING. Use `drive-tasks` to turn tasks into PRs; use `merge-prs` to turn a pile of PRs into merges cheaply.
70
+ - **`orchestrate`** is the meta-conductor over the whole tree. If it (or `run`) produced a burst of PRs, `merge-prs` is the natural closer to land them in a batch rather than one-by-one.
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: orchestrate
3
+ disable-model-invocation: true
4
+ description: 'The human-in-the-loop meta-conductor: survey the whole work/ tree, advance every autonomous rung, batch the judgement residue to the human, then build the ready tasks via drive-tasks.'
5
+ ---
6
+
7
+ # orchestrate
8
+
9
+ **The conductor of conductors.** `drive-tasks` builds the _ready tasks_. `orchestrate` is the layer above THAT: it looks at the **entire** `work/` tree — observations, ideas, specs, tasks, needs-attention — works out **what can advance and what is stuck on a human**, does every autonomous rung it can, and turns the human into nothing but an **answerer of well-batched questions**, looping until the backlog of ready tasks is drained.
10
+
11
+ It is a **methodology skill** (prose you follow), like `to-task` / `review` — NOT a runner command. It is **protocol-native**: it works the `work/` tree by reading the contract files directly (frontmatter + bodies), not by leaning on runner commands to tell it the state. (The one place runner commands ARE used is building — which it hands to `drive-tasks`, the skill whose job is to drive the `dorfl` CLI.) It composes:
12
+
13
+ - **`drive-tasks`** (`skills/drive-tasks/`) — to BUILD the ready tasks (you load and FOLLOW it for the build loop; it owns the runner-CLI mechanics).
14
+ - **`review`** (`skills/review/`) — to judge any artifact (task / spec / observation / code).
15
+ - **`to-task`** (`skills/to-task/`) — to task a ready spec into tasks (the `tasks/backlog` staging slot).
16
+ - **`promote`** (`skills/promote/`) — to judge a STAGED task/spec (`tasks/backlog/` / `specs/proposed/`) against its acceptance + destination before recommending its promotion into the pool.
17
+ - **`answer-questions`** (`skills/answer-questions/`) — to walk the open `work/questions/` sidecars, DRAFT answers to the factual ones for the human to ratify, and DEFER the genuine-judgement ones into the step-3 batch.
18
+ - **`to-spec`** (`skills/to-spec/`) — when an idea/observation has matured enough to become a spec.
19
+
20
+ ## When to use vs. not
21
+
22
+ - **Use** when you have a populated `work/` and want the system to do _everything it can autonomously_ and then _ask you only at the real judgement residue_ — in one interactive sitting, with full visibility and agency; to answer "what needs me?" across the whole tree; as the human-driven alternative to the autonomous `advance` loop when you want to watch and steer.
23
+ - **Don't** use it just to build already-ready tasks (that's `drive-tasks` directly), just to task one spec (`to-task`), or just to review one artifact (`review`). Don't use it as the unattended daemon (`run`/`advance`). It is **always main-session and conversational** — its defining job is the live Q&A.
24
+
25
+ ## Relationship to the autonomous `advance` engine
26
+
27
+ `orchestrate` is the **interactive, human-in-the-loop** way to drain a `work/` tree: it asks its questions conversationally, in the session, and you answer live. Its autonomous, file-mediated counterpart is the `advance` capability, driven by `run`/CI with `work/questions/` sidecars the human answers whenever they like. Same lifecycle drain, different mode: reach for `orchestrate` when the human is present and wants visibility + agency; the autonomous engine is for unattended draining. They share the same rung contract.
28
+
29
+ ## Core invariant
30
+
31
+ **Advance every rung you can; for everything else, ASK — never invent an answer.** Each `work/` item has autonomous rungs (triage, task, build, promote, surface-question, answer/apply) and a judgement residue (ambiguity, design forks, `needsAnswers`, stale premises). Do the autonomous part; surface the residue as batched questions; apply the answers; repeat. The human's throughput is the only limit; everything else is automatic.
32
+
33
+ ## The loop
34
+
35
+ ### 1. SURVEY the whole tree (one read pass)
36
+
37
+ Read across ALL buckets and build a single picture of state + what each item needs to advance ONE rung:
38
+
39
+ - **`work/notes/observations/`** — untriaged signals. Each wants: promote to a task/spec/ADR? keep as a note? delete? (a judgement rung — compose `review`).
40
+ - **`work/notes/ideas/`** — incubating. Any matured enough to become a spec (`to-spec`)? Most are left alone (no readiness to force) — note them, don't push.
41
+ - **`work/specs/ready/`** — for each spec: is it already tasked (does it RESIDE in `work/specs/tasked/`)? `humanOnly`/`needsAnswers`? `taskedAfter:` satisfied? → **taskable now**, **blocked on a dep**, or **blocked on a human answer**. (Tasked-ness is folder residence, not a `tasked:` marker.)
42
+ - **STAGING** — `work/tasks/backlog/` (review-first tasks) and `work/specs/proposed/` (review-first specs), the items awaiting human promotion into the pool. NOT built/tasked here; they are a **promotion rung** (step 2, compose `promote`). Either folder may be absent when empty per the contract — treat a missing staging folder as "nothing awaiting promotion", not an error.
43
+ - **`work/tasks/ready/`** — the task dependency graph (READY / BLOCKED / GATED), AND each ready task's **freshness** (drifted vs current `tasks/done/`+code — same check `drive-tasks` step 1 does).
44
+ - **`work/questions/`** — open question sidecars (a `<type>-<slug>.md` with an unanswered entry). Each is an item PAUSED on an answer; classify each open question factual-vs-judgement for the answer rung (step 2, compose `answer-questions`). A missing/empty `work/questions/` means "no pending questions", per the empty-folder rule — not an error.
45
+ - **needs-attention** — stuck items (their per-item lock is `state: stuck`) + the recorded reason; each wants a human decision (requeue-continue / requeue-reset / re-scope / drop). Read them via `dorfl status`/`scan` (which read the lock refs).
46
+
47
+ Produce a short **state map**: what's ready to build, what's taskable, what's triageable, and what's parked on a human.
48
+
49
+ ### 2. ADVANCE the non-build rungs (no human needed)
50
+
51
+ Do the autonomous rungs that PREPARE work — i.e. everything EXCEPT building ready tasks (building is step 4, deliberately last, so all gap-filling happens first). In leverage order (the rung that unlocks the most downstream work first):
52
+
53
+ - **Taskable specs** → task them, NAMING the choice between the two paths that meet at the same `work/tasks/*` artifact (don't default to the conversational one by reflex):
54
+ - **`dorfl do spec:<slug>`** — the AUTONOMOUS, unattended path (gate-gated by `autoTask` + the spec's own gates; runner-owns-git; harness/model/gate from dorfl config, don't hardcode). PREFER this for a **ready, agent-safe spec** (`humanOnly: false`, no open `needsAnswers`, `taskedAfter:` satisfied) — and it is the path to use when the intent is to exercise the runner.
55
+ - **`to-task`** (the skill) — the CONVERSATIONAL, human-in-the-loop, protocol-only path (no dorfl dependency). Use it for a **`humanOnly` / unclear / not-yet-ready spec**, or whenever a conversation is wanted. (`to-task` deliberately stays runner-agnostic — it never points BACK at `do spec:`; this routing lives HERE, in the runner-aware conductor, by design.)
56
+ - The choice is "unattended run vs conversation", decided by the spec classification you already did in step 1 (`humanOnly`/`needsAnswers`/`taskedAfter`). A `do spec:` on a spec it cannot take (e.g. `humanOnly`) correctly REFUSES on the agent path — that refusal IS the protocol routing you to `to-task`.
57
+ - Then **review the produced tasks** (compose `review`; the tasker's own review→edit loop also runs on the `do spec:` path). Newly-produced tasks feed back into the survey (they may be READY, or carry their own questions).
58
+ - **Staged items awaiting promotion** (`tasks/backlog/`, `specs/proposed/`) → run the **promotion rung**: for each, compose `promote` (review + freshness + pool-readiness gate) and emit promote / keep-staged / drop. A clear PROMOTE is recommended to the human (you never move it yourself — the runner's `promote` verb / the human does the `git mv`); a KEEP-STAGED with a fixable gap, or a judgement-call promotion, becomes a step-3 question; a clear DROP routes to the regime terminal. Promotion is the human review-gate, so the MOVE is always the human's/runner's — you surface the verdict.
59
+ - **Clearly-resolvable observations** → triage them (compose `triage-observations`: leave / promote into a self-contained task/spec/ADR / direct-delete) where the right outcome is obvious; the ambiguous ones become questions (step 3).
60
+ - **Open question sidecars** (`work/questions/`) → run the **answer rung**: compose `answer-questions` over the pending sidecars. It DRAFTS answers to the factual ones (each cited to its evidence) for the human to RATIFY — a ratified draft is a human-authored answer you then apply — and DEFERS the genuine-judgement ones into the step-3 batch. You never invent/finalise an answer (the human is the clock); you draft for ratification and surface the rest.
61
+ - **Apply any human answers** you already have (ratified drafts from the answer rung, plus answers from earlier in the session) → flip the relevant `needsAnswers`, fill the task/spec gap, which may make new items advanceable (re-run step 1's classification for them).
62
+
63
+ (Ready tasks are NOT built here — they accumulate for step 4, after the residue is resolved.)
64
+
65
+ Commit policy (matches the producer skills): **commit your own `work/notes/observations/` notes and small load-bearing forward-notes you plant in a task body** (these are contract-native protocol edits), plus the runner-owned transitions that `do spec:` / `do` / `complete` make themselves (the tasking transition, done-moves, PR merges). Do NOT hand-author-and-commit a full spec or a fresh TASK SET — producing those is `to-spec`/`to-task`' job, and per their convention they are left UNSTAGED for human review (you surface them; the human commits). Never sweep in unrelated source. Report everything you committed in the final summary. (Tasks that get BUILT are committed/merged by `drive-tasks` via the normal PR flow.)
66
+
67
+ ### 3. ASK the residue — batched, conversational, never invented
68
+
69
+ Everything that needs judgement becomes a **question**. Do NOT ask one at a time and do NOT guess: **regroup all open questions into one efficient batch** (the discipline this skill is named for), each with:
70
+
71
+ - the item + the SPECIFIC question, inline context to answer without opening files, the consequence of each option, and a **suggested default** where you have a view.
72
+ - grouped/ordered by leverage (answer-unblocks-the-most first).
73
+
74
+ Present the batch, take the human's answers, then **apply them** (back to step 2 for the now-unblocked items). Iterate steps 1–3 until the only thing left is _building ready tasks_. Questions the human defers stay parked; you proceed with the rest.
75
+
76
+ > If the human prefers to answer later / asynchronously rather than inline, offer to persist the batch as a question file under `work/questions/<date>-batch.md` (the file-mediated fallback the autonomous `advance` engine also reads). Default is conversational.
77
+
78
+ ### 4. BUILD the ready tasks (follow `drive-tasks`)
79
+
80
+ Once the survey + gap-filling have produced a set of READY tasks, build them by **loading and following the `drive-tasks` skill inline** (you are already in the human's session — `drive-tasks` runs its build→review→merge loop here, asking the human when it stalls, exactly as you do). Hand it the whole ready set; it re-runs its own freshness check + dependency ordering, so you do NOT need to pre-filter or pre-order beyond what your survey established. Its build-loop mechanics (the long `do` process, the interrupt footgun, the diff-review, merge) are ITS to own — don't re-derive them here.
81
+
82
+ Any task `drive-tasks` parks in its stuck-set (a drifted task, a Gate-3 judgement call) comes back to YOUR step 3 batch — same residue, same human.
83
+
84
+ ### 5. LOOP until drained, then SUMMARISE
85
+
86
+ Repeat 1→4 until no rung can advance without a human answer you don't have. Then give the meta report:
87
+
88
+ - **Advanced autonomously** — observations triaged, specs tasked, tasks built+merged (PR numbers from `drive-tasks`'s own report).
89
+ - **What's now unlocked** — new ready tasks, newly-taskable specs, capabilities landed (the whole-tree view only this skill has).
90
+ - **Parked on the human** — the questions still unanswered / deferred, and exactly what each unblocks when answered.
91
+ - **Still stuck** — needs-attention items + the decision each awaits.
92
+ - **Suggested next sitting** — the smallest set of human answers that would unblock the most work.
93
+
94
+ ## Pitfalls
95
+
96
+ - **Don't invent answers.** The one unforgivable move. A confident wrong answer to a judgement question produces drifted tasks that cost far more than asking. Ask.
97
+ - **Don't over-ask either.** Resolve from the code/ADRs what is genuinely a small certain factual gap; only the real judgement residue becomes a question (same discipline `drive-tasks`/the build agents use for tasks).
98
+ - **Commit observations + forward-notes; leave authored artifacts for review.** Your `work/notes/observations/` notes and small planted forward-notes are committed as you go (contract-native) and listed in the summary; a freshly-authored spec or task SET is left UNSTAGED for the human (the producer-skill convention). Don't sweep in unrelated source changes.
99
+ - **Building mechanics live in `drive-tasks`.** When you build (step 4), the long-running `do` process, the interrupt footgun (an abort does NOT kill the spawned agent), generous timeouts, flaky-gate retries, and the Gate-3 diff review are all `drive-tasks`'s — follow that skill for them; don't re-derive them here.
100
+ - **If your OWN run is interrupted, re-orient before resuming.** This loop can run long. On resume, do a fresh step-1 survey (state lives in the `work/` files + `git`, not your memory): re-read the buckets, check what is now in-progress / needs-attention / merged, and continue from the recomputed state — never assume the pre-interrupt picture still holds.
101
+ - **Ideas are incubating.** Don't force `work/notes/ideas/` toward readiness; surface the ripe ones, leave the rest.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: promote
3
+ description: 'The pre-promotion checklist: judge ONE staged work/ item (a task in tasks/backlog/, a spec in specs/proposed/) against its acceptance + destination before a human admits it into the agent pool. Emits a promote / keep-staged / drop recommendation; the human (or the runner promote verb) does the move.'
4
+ ---
5
+
6
+ # promote
7
+
8
+ **Staging is the human review-gate.** In the `work/` contract, `tasks/backlog/` and `specs/proposed/` are STAGING (untrusted / agent-authored output lands here); the agent POOL is `tasks/ready/` and `specs/ready/`. Items enter staging by a runner-deterministic placement decision; they leave it ONLY when a human promotes them. This skill is the **discipline a human applies to ONE staged item before promoting it** — it is the checklist that makes the gate a real review, not a rubber stamp.
9
+
10
+ It is a thin **methodology skill** (prose you follow), a sibling of `review`. It does NOT move anything: the promotion `git mv` (`tasks/backlog/ → tasks/ready/`, `specs/proposed/ → specs/ready/`) is a runner-owned transition (a future `dorfl promote <item>` verb, or the human's own move). You EMIT a verdict; the caller acts on it. Per the contract, an agent never sets position.
11
+
12
+ ## When to use vs. not
13
+
14
+ - **Use** before admitting a staged task/spec into the pool: when reviewing what an agent (tasking / intake) emitted into `tasks/backlog/` or `specs/proposed/`, to decide promote / keep-staged / drop for each. `orchestrate` composes this in its survey (the "awaiting promotion" set); a human also reaches for it directly to clear a staging backlog.
15
+ - **Don't** use it to judge an item already IN the pool (that is plain `review`), to build a ready task (`drive-tasks`), or to task a spec (`to-task`). It is the ONE gate-crossing judgement: staging → pool.
16
+
17
+ ## How to use
18
+
19
+ For each staged item, run the `review` discipline FIRST (it is the body of this check), then add the promotion-specific gate:
20
+
21
+ 1. **Review the artifact** — apply `review` (i.e. `work/protocol/REVIEW-PROTOCOL.md`'s lenses + the destination check) to the staged task/spec exactly as you would any `work/` artifact. This already covers: does it deliver its stated goal, is it coherent, does it match the spec/ADR it descends from.
22
+ 2. **Freshness / drift** — staging items are often agent-authored ahead of time. Spot- check the load-bearing premises against current reality (`tasks/done/` + `src/`): does anything it says is "not yet built / still TODO / has no consumers" already hold? A drifted staged item is NOT promotable as-is — it is keep-staged with the stale premise named (the same drift check `drive-tasks`/`orchestrate` run on ready tasks, applied one step earlier).
23
+ 3. **Pool-readiness gate** — once in the pool, can the item rest there SAFELY? Promote if yes. The bar is "safe in the pool", NOT "claimable this instant":
24
+ - **`blockedBy` is NOT a promotion gate — it is machine-ENFORCED at claim time, so a blocked task is safe in the pool.** Do NOT keep a task staged merely because a `blockedBy` slug has not yet reached `tasks/done/`. The claim predicate already refuses an item whose `blockedBy` is unresolved, so a blocked-but-otherwise-ready task simply WAITS in `tasks/ready/` until its blocker lands, then becomes claimable automatically — no human re-check needed. Holding it in staging for an unresolved dependency duplicates an enforced invariant and needlessly strands ready work behind a human round-trip. (The blocker slug does not even need to exist yet; `blockedBy` resolves lazily against `tasks/done/` whenever a claim is attempted.) Promote a well-formed blocked task NOW; the dependency graph sequences it for you.
25
+ - **Task → the real gates are the UNENFORCED, human-owned ones:** `needsAnswers` is false (no open question a human must answer first — an open question is NOT machine-enforced, so a `needsAnswers:true` task promoted into the pool would be picked up blind), and `humanOnly` is correctly set (off unless never-for-agents-by-nature). A staged task carrying open questions is keep-staged until they are answered, not promoted-then-blocked. (Contrast `blockedBy` above: that one IS enforced, so it is not a reason to keep-stage.)
26
+ - **Spec** → `humanOnly`/`needsAnswers` correct and it is genuinely taskable (not still a design sketch). Like `blockedBy`, `taskedAfter:` is ENFORCED against `specs/tasked/` residence by the auto-tasker, so an unsatisfied `taskedAfter:` is NOT a reason to keep a taskable spec staged — promote it and let the tasker sequence it. An unready (design-sketch / question-bearing) spec stays `specs/proposed/`.
27
+ 4. **No collision / no duplicate** — confirm no item with the same `(umbrella, slug)` already rests in the destination pool or a terminal, and the work isn't already covered by a done item.
28
+ 5. **Verdict** — emit ONE of:
29
+ - **PROMOTE** — review passed, fresh, pool-ready, no collision. State the move the caller should make (`dorfl promote <item>`, or the `git mv`).
30
+ - **KEEP-STAGED** — a fixable gap that is NOT machine-enforced: a drifted premise, an open question (`needsAnswers`), a wrongly-set `humanOnly`, or a spec that is still a design sketch. (An unresolved `blockedBy` / `taskedAfter:` is NOT such a gap — it is enforced, so it is a PROMOTE, not a keep-staged.) State the SPECIFIC gap so it can be resolved, then re-checked.
31
+ - **DROP** — superseded / out-of-scope / duplicate. Route to the regime terminal (`tasks/cancelled/` / `specs/dropped/`) with the `reason:`, per the contract.
32
+
33
+ You WRITE nothing and you MOVE nothing — you surface the verdict; the human or the runner's `promote` verb performs the transition (and a DROP is its own runner-owned move to the terminal). Batch the verdicts when judging several staged items at once, ordered by leverage (what each promotion unblocks downstream).
34
+
35
+ > Why position is human-gated and runner-moved: placement is runner-deterministic on the way IN (the `originTrust` stamp + policy decide STAGING vs POOL); promotion OUT is the human's review-gate. The agent never sets the folder. See `work/protocol/WORK-CONTRACT.md` (staging → pool).
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: review
3
+ description: 'Thoroughly and adversarially review a work/-protocol artifact against the work/ contract, ending in a destination check against the spec/ADR goal. Use before any artifact is trusted: a task before it lands, code in a work PR against its task, a spec before tasking, or a captured note. Emits a verdict; the caller routes it.'
4
+ ---
5
+
6
+ # review
7
+
8
+ **The review discipline lives in `work/protocol/REVIEW-PROTOCOL.md`** (the in-band protocol doc every set-up repo carries; the source-of-truth is `skills/setup/protocol/REVIEW-PROTOCOL.md`). This skill is the **human-facing pointer** to that standard — the operator/agent entry point a person reaches for to invoke the discipline interactively. The standard itself (the lenses, the destination check, the emitted-verdict shape) is stated ONCE in the protocol doc so the autonomous runner and the human caller cannot drift.
9
+
10
+ ## How to use
11
+
12
+ 1. Read `work/protocol/REVIEW-PROTOCOL.md` in the repo you are working in.
13
+ 2. Apply its lenses IN ORDER to the artifact under review, ENDING in the destination check.
14
+ 3. Emit the verdict it specifies (`{verdict, findings, …}`); the caller routes it (you write nothing — see "Your output" in the protocol doc).
15
+
16
+ > Why the standard lives in `work/protocol/`: a `review`-named discipline that the autonomous runner invokes BY NAME must be in-band in every set-up repo, not host-installed. Operator skills (this file) are human-facing and not copied.