dorfl 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (619) hide show
  1. package/dist/advance-ci-template.d.ts +73 -0
  2. package/dist/advance-ci-template.d.ts.map +1 -0
  3. package/dist/advance-ci-template.js +104 -0
  4. package/dist/advance-ci-template.js.map +1 -0
  5. package/dist/advance-classify.d.ts +132 -0
  6. package/dist/advance-classify.d.ts.map +1 -0
  7. package/dist/advance-classify.js +120 -0
  8. package/dist/advance-classify.js.map +1 -0
  9. package/dist/advance-drivers.d.ts +182 -0
  10. package/dist/advance-drivers.d.ts.map +1 -0
  11. package/dist/advance-drivers.js +231 -0
  12. package/dist/advance-drivers.js.map +1 -0
  13. package/dist/advance-isolated.d.ts +156 -0
  14. package/dist/advance-isolated.d.ts.map +1 -0
  15. package/dist/advance-isolated.js +256 -0
  16. package/dist/advance-isolated.js.map +1 -0
  17. package/dist/advance-lifecycle-template.d.ts +107 -0
  18. package/dist/advance-lifecycle-template.d.ts.map +1 -0
  19. package/dist/advance-lifecycle-template.js +668 -0
  20. package/dist/advance-lifecycle-template.js.map +1 -0
  21. package/dist/advance-loop-driver.d.ts +325 -0
  22. package/dist/advance-loop-driver.d.ts.map +1 -0
  23. package/dist/advance-loop-driver.js +437 -0
  24. package/dist/advance-loop-driver.js.map +1 -0
  25. package/dist/advance-treeless-publish.d.ts +108 -0
  26. package/dist/advance-treeless-publish.d.ts.map +1 -0
  27. package/dist/advance-treeless-publish.js +71 -0
  28. package/dist/advance-treeless-publish.js.map +1 -0
  29. package/dist/advance.d.ts +340 -0
  30. package/dist/advance.d.ts.map +1 -0
  31. package/dist/advance.js +1122 -0
  32. package/dist/advance.js.map +1 -0
  33. package/dist/advancing-lock.d.ts +294 -0
  34. package/dist/advancing-lock.d.ts.map +1 -0
  35. package/dist/advancing-lock.js +594 -0
  36. package/dist/advancing-lock.js.map +1 -0
  37. package/dist/agent-launch.d.ts +79 -0
  38. package/dist/agent-launch.d.ts.map +1 -0
  39. package/dist/agent-launch.js +61 -0
  40. package/dist/agent-launch.js.map +1 -0
  41. package/dist/agent-stop.d.ts +149 -0
  42. package/dist/agent-stop.d.ts.map +1 -0
  43. package/dist/agent-stop.js +307 -0
  44. package/dist/agent-stop.js.map +1 -0
  45. package/dist/apply-decide.d.ts +127 -0
  46. package/dist/apply-decide.d.ts.map +1 -0
  47. package/dist/apply-decide.js +176 -0
  48. package/dist/apply-decide.js.map +1 -0
  49. package/dist/apply-merge-action.d.ts +206 -0
  50. package/dist/apply-merge-action.d.ts.map +1 -0
  51. package/dist/apply-merge-action.js +307 -0
  52. package/dist/apply-merge-action.js.map +1 -0
  53. package/dist/apply-persist.d.ts +174 -0
  54. package/dist/apply-persist.d.ts.map +1 -0
  55. package/dist/apply-persist.js +359 -0
  56. package/dist/apply-persist.js.map +1 -0
  57. package/dist/arbiter.d.ts +120 -0
  58. package/dist/arbiter.d.ts.map +1 -0
  59. package/dist/arbiter.js +255 -0
  60. package/dist/arbiter.js.map +1 -0
  61. package/dist/brand.d.ts +70 -0
  62. package/dist/brand.d.ts.map +1 -0
  63. package/dist/brand.js +84 -0
  64. package/dist/brand.js.map +1 -0
  65. package/dist/buildable-body.d.ts +132 -0
  66. package/dist/buildable-body.d.ts.map +1 -0
  67. package/dist/buildable-body.js +131 -0
  68. package/dist/buildable-body.js.map +1 -0
  69. package/dist/categorise.d.ts +66 -0
  70. package/dist/categorise.d.ts.map +1 -0
  71. package/dist/categorise.js +106 -0
  72. package/dist/categorise.js.map +1 -0
  73. package/dist/claim-cas.d.ts +117 -0
  74. package/dist/claim-cas.d.ts.map +1 -0
  75. package/dist/claim-cas.js +312 -0
  76. package/dist/claim-cas.js.map +1 -0
  77. package/dist/cli-spinner.d.ts +112 -0
  78. package/dist/cli-spinner.d.ts.map +1 -0
  79. package/dist/cli-spinner.js +157 -0
  80. package/dist/cli-spinner.js.map +1 -0
  81. package/dist/cli.d.ts +11 -0
  82. package/dist/cli.d.ts.map +1 -0
  83. package/dist/cli.js +3094 -0
  84. package/dist/cli.js.map +1 -0
  85. package/dist/close-job-template.d.ts +70 -0
  86. package/dist/close-job-template.d.ts.map +1 -0
  87. package/dist/close-job-template.js +180 -0
  88. package/dist/close-job-template.js.map +1 -0
  89. package/dist/close-job.d.ts +95 -0
  90. package/dist/close-job.d.ts.map +1 -0
  91. package/dist/close-job.js +226 -0
  92. package/dist/close-job.js.map +1 -0
  93. package/dist/complete.d.ts +361 -0
  94. package/dist/complete.d.ts.map +1 -0
  95. package/dist/complete.js +885 -0
  96. package/dist/complete.js.map +1 -0
  97. package/dist/concurrency.d.ts +68 -0
  98. package/dist/concurrency.d.ts.map +1 -0
  99. package/dist/concurrency.js +112 -0
  100. package/dist/concurrency.js.map +1 -0
  101. package/dist/config-override.d.ts +76 -0
  102. package/dist/config-override.d.ts.map +1 -0
  103. package/dist/config-override.js +50 -0
  104. package/dist/config-override.js.map +1 -0
  105. package/dist/config.d.ts +668 -0
  106. package/dist/config.d.ts.map +1 -0
  107. package/dist/config.js +241 -0
  108. package/dist/config.js.map +1 -0
  109. package/dist/continue-branch.d.ts +249 -0
  110. package/dist/continue-branch.d.ts.map +1 -0
  111. package/dist/continue-branch.js +389 -0
  112. package/dist/continue-branch.js.map +1 -0
  113. package/dist/cwd-section.d.ts +186 -0
  114. package/dist/cwd-section.d.ts.map +1 -0
  115. package/dist/cwd-section.js +209 -0
  116. package/dist/cwd-section.js.map +1 -0
  117. package/dist/decision-engine.d.ts +170 -0
  118. package/dist/decision-engine.d.ts.map +1 -0
  119. package/dist/decision-engine.js +136 -0
  120. package/dist/decision-engine.js.map +1 -0
  121. package/dist/detect.d.ts +17 -0
  122. package/dist/detect.d.ts.map +1 -0
  123. package/dist/detect.js +118 -0
  124. package/dist/detect.js.map +1 -0
  125. package/dist/do-autopick.d.ts +85 -0
  126. package/dist/do-autopick.d.ts.map +1 -0
  127. package/dist/do-autopick.js +112 -0
  128. package/dist/do-autopick.js.map +1 -0
  129. package/dist/do-config.d.ts +312 -0
  130. package/dist/do-config.d.ts.map +1 -0
  131. package/dist/do-config.js +358 -0
  132. package/dist/do-config.js.map +1 -0
  133. package/dist/do-remote-auto.d.ts +75 -0
  134. package/dist/do-remote-auto.d.ts.map +1 -0
  135. package/dist/do-remote-auto.js +111 -0
  136. package/dist/do-remote-auto.js.map +1 -0
  137. package/dist/do.d.ts +621 -0
  138. package/dist/do.d.ts.map +1 -0
  139. package/dist/do.js +1882 -0
  140. package/dist/do.js.map +1 -0
  141. package/dist/drop-source.d.ts +96 -0
  142. package/dist/drop-source.d.ts.map +1 -0
  143. package/dist/drop-source.js +91 -0
  144. package/dist/drop-source.js.map +1 -0
  145. package/dist/eligibility.d.ts +46 -0
  146. package/dist/eligibility.d.ts.map +1 -0
  147. package/dist/eligibility.js +34 -0
  148. package/dist/eligibility.js.map +1 -0
  149. package/dist/env-config.d.ts +51 -0
  150. package/dist/env-config.d.ts.map +1 -0
  151. package/dist/env-config.js +272 -0
  152. package/dist/env-config.js.map +1 -0
  153. package/dist/failure-cause.d.ts +70 -0
  154. package/dist/failure-cause.d.ts.map +1 -0
  155. package/dist/failure-cause.js +126 -0
  156. package/dist/failure-cause.js.map +1 -0
  157. package/dist/format.d.ts +43 -0
  158. package/dist/format.d.ts.map +1 -0
  159. package/dist/format.js +256 -0
  160. package/dist/format.js.map +1 -0
  161. package/dist/frontmatter.d.ts +215 -0
  162. package/dist/frontmatter.d.ts.map +1 -0
  163. package/dist/frontmatter.js +345 -0
  164. package/dist/frontmatter.js.map +1 -0
  165. package/dist/gate-readiness.d.ts +84 -0
  166. package/dist/gate-readiness.d.ts.map +1 -0
  167. package/dist/gate-readiness.js +103 -0
  168. package/dist/gate-readiness.js.map +1 -0
  169. package/dist/gc.d.ts +165 -0
  170. package/dist/gc.d.ts.map +1 -0
  171. package/dist/gc.js +313 -0
  172. package/dist/gc.js.map +1 -0
  173. package/dist/gh-failure.d.ts +42 -0
  174. package/dist/gh-failure.d.ts.map +1 -0
  175. package/dist/gh-failure.js +49 -0
  176. package/dist/gh-failure.js.map +1 -0
  177. package/dist/git.d.ts +75 -0
  178. package/dist/git.d.ts.map +1 -0
  179. package/dist/git.js +130 -0
  180. package/dist/git.js.map +1 -0
  181. package/dist/github.d.ts +187 -0
  182. package/dist/github.d.ts.map +1 -0
  183. package/dist/github.js +343 -0
  184. package/dist/github.js.map +1 -0
  185. package/dist/harness.d.ts +242 -0
  186. package/dist/harness.d.ts.map +1 -0
  187. package/dist/harness.js +157 -0
  188. package/dist/harness.js.map +1 -0
  189. package/dist/identity.d.ts +167 -0
  190. package/dist/identity.d.ts.map +1 -0
  191. package/dist/identity.js +231 -0
  192. package/dist/identity.js.map +1 -0
  193. package/dist/index.d.ts +147 -0
  194. package/dist/index.d.ts.map +1 -0
  195. package/dist/index.js +76 -0
  196. package/dist/index.js.map +1 -0
  197. package/dist/install-ci-branch-protection.d.ts +147 -0
  198. package/dist/install-ci-branch-protection.d.ts.map +1 -0
  199. package/dist/install-ci-branch-protection.js +166 -0
  200. package/dist/install-ci-branch-protection.js.map +1 -0
  201. package/dist/install-ci-capabilities/advance-lifecycle.d.ts +15 -0
  202. package/dist/install-ci-capabilities/advance-lifecycle.d.ts.map +1 -0
  203. package/dist/install-ci-capabilities/advance-lifecycle.js +28 -0
  204. package/dist/install-ci-capabilities/advance-lifecycle.js.map +1 -0
  205. package/dist/install-ci-capabilities/close-job.d.ts +13 -0
  206. package/dist/install-ci-capabilities/close-job.d.ts.map +1 -0
  207. package/dist/install-ci-capabilities/close-job.js +26 -0
  208. package/dist/install-ci-capabilities/close-job.js.map +1 -0
  209. package/dist/install-ci-capabilities/example-noop.d.ts +16 -0
  210. package/dist/install-ci-capabilities/example-noop.d.ts.map +1 -0
  211. package/dist/install-ci-capabilities/example-noop.js +23 -0
  212. package/dist/install-ci-capabilities/example-noop.js.map +1 -0
  213. package/dist/install-ci-capabilities/intake.d.ts +15 -0
  214. package/dist/install-ci-capabilities/intake.d.ts.map +1 -0
  215. package/dist/install-ci-capabilities/intake.js +28 -0
  216. package/dist/install-ci-capabilities/intake.js.map +1 -0
  217. package/dist/install-ci-capabilities/verify.d.ts +14 -0
  218. package/dist/install-ci-capabilities/verify.d.ts.map +1 -0
  219. package/dist/install-ci-capabilities/verify.js +27 -0
  220. package/dist/install-ci-capabilities/verify.js.map +1 -0
  221. package/dist/install-ci-core.d.ts +446 -0
  222. package/dist/install-ci-core.d.ts.map +1 -0
  223. package/dist/install-ci-core.js +760 -0
  224. package/dist/install-ci-core.js.map +1 -0
  225. package/dist/install-ci-github.d.ts +167 -0
  226. package/dist/install-ci-github.d.ts.map +1 -0
  227. package/dist/install-ci-github.js +315 -0
  228. package/dist/install-ci-github.js.map +1 -0
  229. package/dist/install-ci.d.ts +105 -0
  230. package/dist/install-ci.d.ts.map +1 -0
  231. package/dist/install-ci.js +363 -0
  232. package/dist/install-ci.js.map +1 -0
  233. package/dist/intake-event.d.ts +88 -0
  234. package/dist/intake-event.d.ts.map +1 -0
  235. package/dist/intake-event.js +66 -0
  236. package/dist/intake-event.js.map +1 -0
  237. package/dist/intake-marker.d.ts +95 -0
  238. package/dist/intake-marker.d.ts.map +1 -0
  239. package/dist/intake-marker.js +127 -0
  240. package/dist/intake-marker.js.map +1 -0
  241. package/dist/intake-triage.d.ts +48 -0
  242. package/dist/intake-triage.d.ts.map +1 -0
  243. package/dist/intake-triage.js +95 -0
  244. package/dist/intake-triage.js.map +1 -0
  245. package/dist/intake-trigger-template.d.ts +185 -0
  246. package/dist/intake-trigger-template.d.ts.map +1 -0
  247. package/dist/intake-trigger-template.js +449 -0
  248. package/dist/intake-trigger-template.js.map +1 -0
  249. package/dist/intake.d.ts +569 -0
  250. package/dist/intake.d.ts.map +1 -0
  251. package/dist/intake.js +1628 -0
  252. package/dist/intake.js.map +1 -0
  253. package/dist/integration-core.d.ts +539 -0
  254. package/dist/integration-core.d.ts.map +1 -0
  255. package/dist/integration-core.js +2195 -0
  256. package/dist/integration-core.js.map +1 -0
  257. package/dist/integrator.d.ts +343 -0
  258. package/dist/integrator.d.ts.map +1 -0
  259. package/dist/integrator.js +400 -0
  260. package/dist/integrator.js.map +1 -0
  261. package/dist/isolation.d.ts +219 -0
  262. package/dist/isolation.d.ts.map +1 -0
  263. package/dist/isolation.js +261 -0
  264. package/dist/isolation.js.map +1 -0
  265. package/dist/issue-provider.d.ts +349 -0
  266. package/dist/issue-provider.d.ts.map +1 -0
  267. package/dist/issue-provider.js +360 -0
  268. package/dist/issue-provider.js.map +1 -0
  269. package/dist/item-lock.d.ts +626 -0
  270. package/dist/item-lock.d.ts.map +1 -0
  271. package/dist/item-lock.js +1381 -0
  272. package/dist/item-lock.js.map +1 -0
  273. package/dist/item-path.d.ts +49 -0
  274. package/dist/item-path.d.ts.map +1 -0
  275. package/dist/item-path.js +66 -0
  276. package/dist/item-path.js.map +1 -0
  277. package/dist/ledger-lint.d.ts +129 -0
  278. package/dist/ledger-lint.d.ts.map +1 -0
  279. package/dist/ledger-lint.js +249 -0
  280. package/dist/ledger-lint.js.map +1 -0
  281. package/dist/ledger-read.d.ts +357 -0
  282. package/dist/ledger-read.d.ts.map +1 -0
  283. package/dist/ledger-read.js +442 -0
  284. package/dist/ledger-read.js.map +1 -0
  285. package/dist/ledger-write.d.ts +330 -0
  286. package/dist/ledger-write.d.ts.map +1 -0
  287. package/dist/ledger-write.js +411 -0
  288. package/dist/ledger-write.js.map +1 -0
  289. package/dist/lifecycle-gather.d.ts +30 -0
  290. package/dist/lifecycle-gather.d.ts.map +1 -0
  291. package/dist/lifecycle-gather.js +205 -0
  292. package/dist/lifecycle-gather.js.map +1 -0
  293. package/dist/lifecycle-pools.d.ts +180 -0
  294. package/dist/lifecycle-pools.d.ts.map +1 -0
  295. package/dist/lifecycle-pools.js +78 -0
  296. package/dist/lifecycle-pools.js.map +1 -0
  297. package/dist/merge-question-surfacer.d.ts +166 -0
  298. package/dist/merge-question-surfacer.d.ts.map +1 -0
  299. package/dist/merge-question-surfacer.js +297 -0
  300. package/dist/merge-question-surfacer.js.map +1 -0
  301. package/dist/mint-adr.d.ts +126 -0
  302. package/dist/mint-adr.d.ts.map +1 -0
  303. package/dist/mint-adr.js +257 -0
  304. package/dist/mint-adr.js.map +1 -0
  305. package/dist/mirror-pool-scan.d.ts +125 -0
  306. package/dist/mirror-pool-scan.d.ts.map +1 -0
  307. package/dist/mirror-pool-scan.js +104 -0
  308. package/dist/mirror-pool-scan.js.map +1 -0
  309. package/dist/needs-attention.d.ts +341 -0
  310. package/dist/needs-attention.d.ts.map +1 -0
  311. package/dist/needs-attention.js +900 -0
  312. package/dist/needs-attention.js.map +1 -0
  313. package/dist/orphan-sidecar.d.ts +79 -0
  314. package/dist/orphan-sidecar.d.ts.map +1 -0
  315. package/dist/orphan-sidecar.js +71 -0
  316. package/dist/orphan-sidecar.js.map +1 -0
  317. package/dist/output.d.ts +48 -0
  318. package/dist/output.d.ts.map +1 -0
  319. package/dist/output.js +66 -0
  320. package/dist/output.js.map +1 -0
  321. package/dist/pi-harness.d.ts +179 -0
  322. package/dist/pi-harness.d.ts.map +1 -0
  323. package/dist/pi-harness.js +342 -0
  324. package/dist/pi-harness.js.map +1 -0
  325. package/dist/placement.d.ts +99 -0
  326. package/dist/placement.d.ts.map +1 -0
  327. package/dist/placement.js +67 -0
  328. package/dist/placement.js.map +1 -0
  329. package/dist/prd-to-spec.d.ts +315 -0
  330. package/dist/prd-to-spec.d.ts.map +1 -0
  331. package/dist/prd-to-spec.js +684 -0
  332. package/dist/prd-to-spec.js.map +1 -0
  333. package/dist/prepare.d.ts +121 -0
  334. package/dist/prepare.d.ts.map +1 -0
  335. package/dist/prepare.js +140 -0
  336. package/dist/prepare.js.map +1 -0
  337. package/dist/prompt.d.ts +360 -0
  338. package/dist/prompt.d.ts.map +1 -0
  339. package/dist/prompt.js +499 -0
  340. package/dist/prompt.js.map +1 -0
  341. package/dist/protocol/ADR-FORMAT.md +47 -0
  342. package/dist/protocol/CLAIM-PROTOCOL.md +217 -0
  343. package/dist/protocol/REVIEW-PROTOCOL.md +119 -0
  344. package/dist/protocol/SURFACE-PROTOCOL.md +121 -0
  345. package/dist/protocol/TASKING-PROTOCOL.md +122 -0
  346. package/dist/protocol/WORK-CONTRACT.md +276 -0
  347. package/dist/protocol/spec-template.md +71 -0
  348. package/dist/protocol/task-template.md +65 -0
  349. package/dist/readiness.d.ts +66 -0
  350. package/dist/readiness.d.ts.map +1 -0
  351. package/dist/readiness.js +36 -0
  352. package/dist/readiness.js.map +1 -0
  353. package/dist/reap-branches.d.ts +102 -0
  354. package/dist/reap-branches.d.ts.map +1 -0
  355. package/dist/reap-branches.js +149 -0
  356. package/dist/reap-branches.js.map +1 -0
  357. package/dist/recover-isolated.d.ts +72 -0
  358. package/dist/recover-isolated.d.ts.map +1 -0
  359. package/dist/recover-isolated.js +188 -0
  360. package/dist/recover-isolated.js.map +1 -0
  361. package/dist/registry.d.ts +172 -0
  362. package/dist/registry.d.ts.map +1 -0
  363. package/dist/registry.js +296 -0
  364. package/dist/registry.js.map +1 -0
  365. package/dist/repo-config.d.ts +201 -0
  366. package/dist/repo-config.d.ts.map +1 -0
  367. package/dist/repo-config.js +414 -0
  368. package/dist/repo-config.js.map +1 -0
  369. package/dist/repo-key.d.ts +20 -0
  370. package/dist/repo-key.d.ts.map +1 -0
  371. package/dist/repo-key.js +68 -0
  372. package/dist/repo-key.js.map +1 -0
  373. package/dist/repo-mirror.d.ts +177 -0
  374. package/dist/repo-mirror.d.ts.map +1 -0
  375. package/dist/repo-mirror.js +271 -0
  376. package/dist/repo-mirror.js.map +1 -0
  377. package/dist/retry-backoff.d.ts +90 -0
  378. package/dist/retry-backoff.d.ts.map +1 -0
  379. package/dist/retry-backoff.js +98 -0
  380. package/dist/retry-backoff.js.map +1 -0
  381. package/dist/review-gate.d.ts +173 -0
  382. package/dist/review-gate.d.ts.map +1 -0
  383. package/dist/review-gate.js +261 -0
  384. package/dist/review-gate.js.map +1 -0
  385. package/dist/review-verdict.d.ts +149 -0
  386. package/dist/review-verdict.d.ts.map +1 -0
  387. package/dist/review-verdict.js +332 -0
  388. package/dist/review-verdict.js.map +1 -0
  389. package/dist/run.d.ts +221 -0
  390. package/dist/run.d.ts.map +1 -0
  391. package/dist/run.js +963 -0
  392. package/dist/run.js.map +1 -0
  393. package/dist/scan.d.ts +308 -0
  394. package/dist/scan.d.ts.map +1 -0
  395. package/dist/scan.js +374 -0
  396. package/dist/scan.js.map +1 -0
  397. package/dist/select-order.d.ts +75 -0
  398. package/dist/select-order.d.ts.map +1 -0
  399. package/dist/select-order.js +108 -0
  400. package/dist/select-order.js.map +1 -0
  401. package/dist/select-priority.d.ts +188 -0
  402. package/dist/select-priority.d.ts.map +1 -0
  403. package/dist/select-priority.js +80 -0
  404. package/dist/select-priority.js.map +1 -0
  405. package/dist/select.d.ts +25 -0
  406. package/dist/select.d.ts.map +1 -0
  407. package/dist/select.js +43 -0
  408. package/dist/select.js.map +1 -0
  409. package/dist/session-path.d.ts +36 -0
  410. package/dist/session-path.d.ts.map +1 -0
  411. package/dist/session-path.js +129 -0
  412. package/dist/session-path.js.map +1 -0
  413. package/dist/sidecar-apply.d.ts +83 -0
  414. package/dist/sidecar-apply.d.ts.map +1 -0
  415. package/dist/sidecar-apply.js +111 -0
  416. package/dist/sidecar-apply.js.map +1 -0
  417. package/dist/sidecar.d.ts +245 -0
  418. package/dist/sidecar.d.ts.map +1 -0
  419. package/dist/sidecar.js +481 -0
  420. package/dist/sidecar.js.map +1 -0
  421. package/dist/slug-namespace.d.ts +204 -0
  422. package/dist/slug-namespace.d.ts.map +1 -0
  423. package/dist/slug-namespace.js +229 -0
  424. package/dist/slug-namespace.js.map +1 -0
  425. package/dist/spec-complete.d.ts +44 -0
  426. package/dist/spec-complete.d.ts.map +1 -0
  427. package/dist/spec-complete.js +69 -0
  428. package/dist/spec-complete.js.map +1 -0
  429. package/dist/start.d.ts +97 -0
  430. package/dist/start.d.ts.map +1 -0
  431. package/dist/start.js +633 -0
  432. package/dist/start.js.map +1 -0
  433. package/dist/status.d.ts +199 -0
  434. package/dist/status.d.ts.map +1 -0
  435. package/dist/status.js +228 -0
  436. package/dist/status.js.map +1 -0
  437. package/dist/surface-gate.d.ts +162 -0
  438. package/dist/surface-gate.d.ts.map +1 -0
  439. package/dist/surface-gate.js +206 -0
  440. package/dist/surface-gate.js.map +1 -0
  441. package/dist/surface-persist.d.ts +86 -0
  442. package/dist/surface-persist.d.ts.map +1 -0
  443. package/dist/surface-persist.js +129 -0
  444. package/dist/surface-persist.js.map +1 -0
  445. package/dist/tasker-review-loop.d.ts +249 -0
  446. package/dist/tasker-review-loop.d.ts.map +1 -0
  447. package/dist/tasker-review-loop.js +369 -0
  448. package/dist/tasker-review-loop.js.map +1 -0
  449. package/dist/tasking-eligibility.d.ts +74 -0
  450. package/dist/tasking-eligibility.d.ts.map +1 -0
  451. package/dist/tasking-eligibility.js +52 -0
  452. package/dist/tasking-eligibility.js.map +1 -0
  453. package/dist/tasking-lock.d.ts +111 -0
  454. package/dist/tasking-lock.d.ts.map +1 -0
  455. package/dist/tasking-lock.js +256 -0
  456. package/dist/tasking-lock.js.map +1 -0
  457. package/dist/tasking.d.ts +275 -0
  458. package/dist/tasking.d.ts.map +1 -0
  459. package/dist/tasking.js +952 -0
  460. package/dist/tasking.js.map +1 -0
  461. package/dist/triage-gate.d.ts +127 -0
  462. package/dist/triage-gate.d.ts.map +1 -0
  463. package/dist/triage-gate.js +139 -0
  464. package/dist/triage-gate.js.map +1 -0
  465. package/dist/triage-persist.d.ts +163 -0
  466. package/dist/triage-persist.d.ts.map +1 -0
  467. package/dist/triage-persist.js +387 -0
  468. package/dist/triage-persist.js.map +1 -0
  469. package/dist/verdict-json.d.ts +32 -0
  470. package/dist/verdict-json.d.ts.map +1 -0
  471. package/dist/verdict-json.js +74 -0
  472. package/dist/verdict-json.js.map +1 -0
  473. package/dist/verify-workflow-template.d.ts +60 -0
  474. package/dist/verify-workflow-template.d.ts.map +1 -0
  475. package/dist/verify-workflow-template.js +126 -0
  476. package/dist/verify-workflow-template.js.map +1 -0
  477. package/dist/verify.d.ts +60 -0
  478. package/dist/verify.d.ts.map +1 -0
  479. package/dist/verify.js +62 -0
  480. package/dist/verify.js.map +1 -0
  481. package/dist/watch-session.d.ts +112 -0
  482. package/dist/watch-session.d.ts.map +1 -0
  483. package/dist/watch-session.js +347 -0
  484. package/dist/watch-session.js.map +1 -0
  485. package/dist/work-layout.d.ts +198 -0
  486. package/dist/work-layout.d.ts.map +1 -0
  487. package/dist/work-layout.js +217 -0
  488. package/dist/work-layout.js.map +1 -0
  489. package/dist/work-on.d.ts +154 -0
  490. package/dist/work-on.d.ts.map +1 -0
  491. package/dist/work-on.js +387 -0
  492. package/dist/work-on.js.map +1 -0
  493. package/dist/workspace.d.ts +224 -0
  494. package/dist/workspace.d.ts.map +1 -0
  495. package/dist/workspace.js +325 -0
  496. package/dist/workspace.js.map +1 -0
  497. package/package.json +46 -2
  498. package/src/advance-ci-template.ts +203 -0
  499. package/src/advance-classify.ts +197 -0
  500. package/src/advance-drivers.ts +414 -0
  501. package/src/advance-isolated.ts +432 -0
  502. package/src/advance-lifecycle-template.ts +791 -0
  503. package/src/advance-loop-driver.ts +745 -0
  504. package/src/advance-treeless-publish.ts +177 -0
  505. package/src/advance.ts +1564 -0
  506. package/src/advancing-lock.ts +988 -0
  507. package/src/agent-launch.ts +137 -0
  508. package/src/agent-stop.ts +361 -0
  509. package/src/apply-decide.ts +242 -0
  510. package/src/apply-merge-action.ts +502 -0
  511. package/src/apply-persist.ts +518 -0
  512. package/src/arbiter.ts +372 -0
  513. package/src/brand.ts +111 -0
  514. package/src/buildable-body.ts +196 -0
  515. package/src/categorise.ts +158 -0
  516. package/src/claim-cas.ts +513 -0
  517. package/src/cli-spinner.ts +225 -0
  518. package/src/cli.ts +4369 -0
  519. package/src/close-job-template.ts +236 -0
  520. package/src/close-job.ts +319 -0
  521. package/src/complete.ts +1379 -0
  522. package/src/concurrency.ts +151 -0
  523. package/src/config-override.ts +116 -0
  524. package/src/config.ts +883 -0
  525. package/src/continue-branch.ts +542 -0
  526. package/src/cwd-section.ts +392 -0
  527. package/src/decision-engine.ts +272 -0
  528. package/src/detect.ts +124 -0
  529. package/src/do-autopick.ts +223 -0
  530. package/src/do-config.ts +589 -0
  531. package/src/do-remote-auto.ts +197 -0
  532. package/src/do.ts +2623 -0
  533. package/src/drop-source.ts +194 -0
  534. package/src/eligibility.ts +79 -0
  535. package/src/env-config.ts +305 -0
  536. package/src/failure-cause.ts +142 -0
  537. package/src/format.ts +313 -0
  538. package/src/frontmatter.ts +485 -0
  539. package/src/gate-readiness.ts +147 -0
  540. package/src/gc.ts +510 -0
  541. package/src/gh-failure.ts +53 -0
  542. package/src/git.ts +186 -0
  543. package/src/github.ts +468 -0
  544. package/src/harness.ts +355 -0
  545. package/src/identity.ts +322 -0
  546. package/src/index.ts +785 -0
  547. package/src/install-ci-branch-protection.ts +255 -0
  548. package/src/install-ci-capabilities/advance-lifecycle.ts +34 -0
  549. package/src/install-ci-capabilities/close-job.ts +32 -0
  550. package/src/install-ci-capabilities/example-noop.ts +24 -0
  551. package/src/install-ci-capabilities/intake.ts +34 -0
  552. package/src/install-ci-capabilities/verify.ts +33 -0
  553. package/src/install-ci-core.ts +1088 -0
  554. package/src/install-ci-github.ts +376 -0
  555. package/src/install-ci.ts +552 -0
  556. package/src/intake-event.ts +102 -0
  557. package/src/intake-marker.ts +195 -0
  558. package/src/intake-triage.ts +138 -0
  559. package/src/intake-trigger-template.ts +591 -0
  560. package/src/intake.ts +2445 -0
  561. package/src/integration-core.ts +3065 -0
  562. package/src/integrator.ts +771 -0
  563. package/src/isolation.ts +484 -0
  564. package/src/issue-provider.ts +733 -0
  565. package/src/item-lock.ts +1858 -0
  566. package/src/item-path.ts +75 -0
  567. package/src/ledger-lint.ts +332 -0
  568. package/src/ledger-read.ts +924 -0
  569. package/src/ledger-write.ts +865 -0
  570. package/src/lifecycle-gather.ts +298 -0
  571. package/src/lifecycle-pools.ts +250 -0
  572. package/src/merge-question-surfacer.ts +496 -0
  573. package/src/mint-adr.ts +362 -0
  574. package/src/mirror-pool-scan.ts +240 -0
  575. package/src/needs-attention.ts +1506 -0
  576. package/src/orphan-sidecar.ts +150 -0
  577. package/src/output.ts +89 -0
  578. package/src/pi-harness.ts +403 -0
  579. package/src/placement.ts +131 -0
  580. package/src/prd-to-spec.ts +1023 -0
  581. package/src/prepare.ts +230 -0
  582. package/src/prompt.ts +760 -0
  583. package/src/readiness.ts +98 -0
  584. package/src/reap-branches.ts +278 -0
  585. package/src/recover-isolated.ts +276 -0
  586. package/src/registry.ts +475 -0
  587. package/src/repo-config.ts +550 -0
  588. package/src/repo-key.ts +74 -0
  589. package/src/repo-mirror.ts +367 -0
  590. package/src/retry-backoff.ts +130 -0
  591. package/src/review-gate.ts +389 -0
  592. package/src/review-verdict.ts +422 -0
  593. package/src/run.ts +1430 -0
  594. package/src/scan.ts +611 -0
  595. package/src/select-order.ts +143 -0
  596. package/src/select-priority.ts +266 -0
  597. package/src/select.ts +62 -0
  598. package/src/session-path.ts +153 -0
  599. package/src/sidecar-apply.ts +216 -0
  600. package/src/sidecar.ts +700 -0
  601. package/src/slug-namespace.ts +367 -0
  602. package/src/spec-complete.ts +118 -0
  603. package/src/start.ts +974 -0
  604. package/src/status.ts +441 -0
  605. package/src/surface-gate.ts +337 -0
  606. package/src/surface-persist.ts +241 -0
  607. package/src/tasker-review-loop.ts +671 -0
  608. package/src/tasking-eligibility.ts +114 -0
  609. package/src/tasking-lock.ts +416 -0
  610. package/src/tasking.ts +1438 -0
  611. package/src/triage-gate.ts +248 -0
  612. package/src/triage-persist.ts +570 -0
  613. package/src/verdict-json.ts +73 -0
  614. package/src/verify-workflow-template.ts +159 -0
  615. package/src/verify.ts +123 -0
  616. package/src/watch-session.ts +397 -0
  617. package/src/work-layout.ts +262 -0
  618. package/src/work-on.ts +660 -0
  619. package/src/workspace.ts +502 -0
@@ -0,0 +1,137 @@
1
+ import {type Harness, type LaunchResult} from './harness.js';
2
+ import {PiHarness} from './pi-harness.js';
3
+ import {SessionTailer} from './watch-session.js';
4
+ import {generateSessionPath} from './session-path.js';
5
+
6
+ /**
7
+ * The SHARED launch-with-optional-watch helper (task `watch-review-session`).
8
+ *
9
+ * This is the ONE codepath both the BUILD launch (`do.ts`'s `runDoAgent`) and the
10
+ * REVIEW launch (`review-gate.ts`'s `harnessReviewGate`) use to run an agent
11
+ * through the harness seam, optionally tailing its pi session `.jsonl` live. It
12
+ * was EXTRACTED from `do.ts` (where the watch wiring — `generateSessionPath` →
13
+ * `SessionTailer` → `start()` → `launchAsync` → `finally stop()`, else sync
14
+ * `launch` — used to live INLINE) so the review path can tail its OWN session
15
+ * without COPYING that block (the run/do duplication anti-pattern; copying would
16
+ * fork the watch wiring into a second implementation, and `run.ts` would become a
17
+ * third). One implementation, two callers.
18
+ *
19
+ * What it owns (the parts that were inline in `do.ts`):
20
+ *
21
+ * - **A known session path per launch**, generated up-front via
22
+ * {@link generateSessionPath} from `sessionId` (+ `sessionsDir`/`dir`), so the
23
+ * tailer follows the EXACT file (no newest-by-mtime guessing). Distinct callers
24
+ * pass distinct `sessionId`s (the build uses the slug; the review uses
25
+ * `<slug>-review`) so their sessions never collide.
26
+ * - **Tail when `watch` is on** (and the harness is a {@link PiHarness}): start a
27
+ * {@link SessionTailer} on that known path, launch NON-BLOCKING via
28
+ * `launchAsync`, and `finally stop()` the tailer (one final drain + the
29
+ * `\u2713 agent finished` line), EXACTLY as the build path did before. A non-pi
30
+ * harness with `watch` on falls through to the sync `launch` (the caller is
31
+ * responsible for rejecting `--watch` on a non-pi harness up-front, as `do`
32
+ * does); this helper degrades safely rather than tailing a log that does not
33
+ * exist.
34
+ * - **OFF the watch path** (or a non-pi harness): a plain synchronous
35
+ * `harness.launch(...)` — BYTE-IDENTICAL to the pre-extraction behaviour, so no
36
+ * tailer is created and the {@link LaunchResult} is unchanged.
37
+ *
38
+ * It is OBSERVABILITY ONLY: the returned {@link LaunchResult} is identical whether
39
+ * or not `watch` is on (the tailer is a pure reader), so it never changes a run's
40
+ * outcome, gate, routing, git, or exit code.
41
+ */
42
+ export interface LaunchWithOptionalWatchInput {
43
+ /** The harness seam to launch through (pi enables the live tail). */
44
+ harness: Harness;
45
+ /** The working directory the agent runs in (the worktree/checkout). */
46
+ dir: string;
47
+ /** The slug being processed (for adapters that name/log per slug). */
48
+ slug: string;
49
+ /** The command the null/shell adapter shells out to (ignored by pi). */
50
+ command: string;
51
+ /** The prompt fed to the agent on stdin. */
52
+ prompt: string;
53
+ /** The model routing intent forwarded to the harness (ADR \u00a713). */
54
+ model?: string;
55
+ /**
56
+ * The human-readable id for the session-FILE stem (made unique per launch
57
+ * inside {@link generateSessionPath}). DISTINCT per caller so two launches in
58
+ * one run never collide: the build passes the slug; the review passes
59
+ * `<slug>-review`.
60
+ */
61
+ sessionId: string;
62
+ /**
63
+ * The HOST-ONLY sessions root (resolved `config.sessionsDir`). `undefined` \u21d2
64
+ * pi's default per-cwd folder for {@link dir} (see {@link generateSessionPath}).
65
+ */
66
+ sessionsDir?: string;
67
+ /** Tail the session `.jsonl` live (pi harness only). */
68
+ watch?: boolean;
69
+ /** Where the tailed high-signal lines are written (defaults to stderr). */
70
+ watchSink?: (line: string) => void;
71
+ /** Emit ANSI colour in the tailed lines (the caller's TTY/`NO_COLOR` decision). */
72
+ color?: boolean;
73
+ /** Environment for the child agent process. */
74
+ env?: NodeJS.ProcessEnv;
75
+ }
76
+
77
+ /**
78
+ * Launch the agent through the harness, optionally tailing its pi session log
79
+ * live. Returns the {@link LaunchResult} unchanged on either path (the tailer is
80
+ * a pure observer). See {@link LaunchWithOptionalWatchInput} for the watch-on vs
81
+ * watch-off behaviour (the latter is byte-identical to a plain `harness.launch`).
82
+ */
83
+ export async function launchWithOptionalWatch(
84
+ input: LaunchWithOptionalWatchInput,
85
+ ): Promise<LaunchResult> {
86
+ const {harness} = input;
87
+
88
+ // Generate the full pi session-FILE path ONCE here (caller-generates) so the
89
+ // adapter and the `--watch` tailer cannot disagree, and so the tailer knows it
90
+ // BEFORE pi starts (task `session-path-pi-default`). `sessionsDir` unset \u21d2
91
+ // pi's per-cwd default folder. The non-pi null adapter ignores `session`, but
92
+ // generating it unconditionally keeps ONE path for BOTH the watch and
93
+ // non-watch branches.
94
+ const session = generateSessionPath({
95
+ sessionsDir: input.sessionsDir,
96
+ cwd: input.dir,
97
+ id: input.sessionId,
98
+ });
99
+
100
+ // `--watch` (pi only): launch async + tail the KNOWN session .jsonl path
101
+ // concurrently. The caller is responsible for rejecting `--watch` on a non-pi
102
+ // harness up-front (as `do` does); a non-pi harness here falls through to the
103
+ // sync launch below rather than tailing a log that will never exist.
104
+ if (input.watch === true && harness instanceof PiHarness) {
105
+ const tailer = new SessionTailer({
106
+ sessionFile: session,
107
+ color: input.color ?? false,
108
+ sink: input.watchSink,
109
+ });
110
+ tailer.start();
111
+ try {
112
+ return await harness.launchAsync({
113
+ dir: input.dir,
114
+ slug: input.slug,
115
+ command: input.command,
116
+ prompt: input.prompt,
117
+ model: input.model,
118
+ session,
119
+ env: input.env,
120
+ });
121
+ } finally {
122
+ // Always release the tailer (one final drain) — even on a launch error —
123
+ // so the observer never outlives the run or leaks a handle.
124
+ await tailer.stop();
125
+ }
126
+ }
127
+
128
+ return harness.launch({
129
+ dir: input.dir,
130
+ slug: input.slug,
131
+ command: input.command,
132
+ prompt: input.prompt,
133
+ model: input.model,
134
+ session,
135
+ env: input.env,
136
+ });
137
+ }
@@ -0,0 +1,361 @@
1
+ import {runAsync} from './git.js';
2
+ import {JOB_RECORD_FILENAME} from './workspace.js';
3
+
4
+ /**
5
+ * **The build-agent → runner REPORTING CHANNEL** (task `agent-stop-signal`).
6
+ *
7
+ * A build agent reports back to the runner on ONE channel: its FINAL OUTPUT
8
+ * (`LaunchResult.output`, captured as `agent.output`). This module defines the
9
+ * two machine-recognisable verdicts an agent can raise on that channel and the
10
+ * deterministic backstop the runner uses when the agent stopped without one:
11
+ *
12
+ * 1. A HARD **STOP** sentinel ({@link STOP_SENTINEL_OPEN} … {@link
13
+ * STOP_SENTINEL_CLOSE}): the task DRIFTED / is ambiguous / rests on a stale
14
+ * premise, so the agent could not build it. The runner routes the item to
15
+ * `work/needs-attention/` (the agent's reason VERBATIM) and SKIPS the
16
+ * acceptance gate + the Gate-2 review (a clean STOP is not a build that
17
+ * changed nothing). See {@link parseStopSentinel}.
18
+ * 2. A SOFT **`## Decisions`** block ({@link extractDecisionsBlock}): the agent
19
+ * PROCEEDED but made a non-obvious in-scope decision the task did not
20
+ * specify (a cross-task interaction / a new error/refusal / a user-visible
21
+ * default). This does NOT stop the build — it just makes the choice visible
22
+ * for Gate-2 + the human to ratify (it rides the same `agent.output` → PR-body
23
+ * path the propose-mode summary uses).
24
+ *
25
+ * The sentinel form is documented IN-BAND next to the existing "STOP and report"
26
+ * instruction in the CLAIM-PROTOCOL wrapper (`skills/setup/protocol/CLAIM-PROTOCOL.md`)
27
+ * so the agent emits the EXACT shape this module parses — the same "agent edits,
28
+ * runner does git" in-band discipline the rest of the protocol uses.
29
+ */
30
+
31
+ /** The exact opening marker line of the STOP sentinel block. */
32
+ export const STOP_SENTINEL_OPEN = '=== TASK-STOP ===';
33
+ /** The exact closing marker line of the STOP sentinel block. */
34
+ export const STOP_SENTINEL_CLOSE = '=== END TASK-STOP ===';
35
+
36
+ /** A parsed STOP verdict raised by the build agent on its output channel. */
37
+ export interface StopSentinel {
38
+ /**
39
+ * The human-readable STOP reason from INSIDE the block (the specific drift
40
+ * report). Recorded VERBATIM as the needs-attention reason. Trimmed; never
41
+ * empty (a sentinel with an empty body still yields a default reason — see
42
+ * {@link parseStopSentinel}).
43
+ */
44
+ reason: string;
45
+ }
46
+
47
+ /**
48
+ * Detect the STOP sentinel in an agent's final output and extract its reason.
49
+ *
50
+ * The sentinel is a line `{@link STOP_SENTINEL_OPEN}` followed by the reason prose
51
+ * and a closing `{@link STOP_SENTINEL_CLOSE}` line. The markers must each be on
52
+ * their OWN line (leading/trailing whitespace tolerated) so a passing mention of
53
+ * the marker inside ordinary prose does not trip it. The agent may surround the
54
+ * block with other prose; we read the FIRST complete block.
55
+ *
56
+ * Returns `undefined` when no complete sentinel block is present (the common
57
+ * case: a normal build, a `## Decisions`-only report, or an empty result). When a
58
+ * block is present but its body is empty, the reason degrades to a stable default
59
+ * so the runner still routes honestly.
60
+ */
61
+ export function parseStopSentinel(
62
+ output: string | undefined,
63
+ ): StopSentinel | undefined {
64
+ if (output === undefined || output === '') {
65
+ return undefined;
66
+ }
67
+ const lines = output.replace(/\r\n/g, '\n').split('\n');
68
+ let open = -1;
69
+ for (let i = 0; i < lines.length; i++) {
70
+ if (lines[i].trim() === STOP_SENTINEL_OPEN) {
71
+ open = i;
72
+ break;
73
+ }
74
+ }
75
+ if (open === -1) {
76
+ return undefined;
77
+ }
78
+ let close = -1;
79
+ for (let i = open + 1; i < lines.length; i++) {
80
+ if (lines[i].trim() === STOP_SENTINEL_CLOSE) {
81
+ close = i;
82
+ break;
83
+ }
84
+ }
85
+ if (close === -1) {
86
+ return undefined; // an unterminated marker is not a complete sentinel.
87
+ }
88
+ const reason = lines
89
+ .slice(open + 1, close)
90
+ .join('\n')
91
+ .trim();
92
+ return {
93
+ reason:
94
+ reason === ''
95
+ ? 'the agent raised a TASK-STOP with no reason (the task could not be ' +
96
+ 'built as written — re-scope or re-claim).'
97
+ : reason,
98
+ };
99
+ }
100
+
101
+ /** The heading that opens the soft `## Decisions` block in an agent's output. */
102
+ const DECISIONS_HEADING = '## Decisions';
103
+
104
+ /**
105
+ * Extract the body of the soft `## Decisions` block from an agent's final output:
106
+ * the prose under a `## Decisions` heading, up to the next `## ` heading or EOF,
107
+ * trimmed. Returns `undefined` when the agent reported no such block (the common
108
+ * case). This is purely informational — it NEVER blocks the build; it is surfaced
109
+ * for review (it already rides the `agent.output` → PR-body path; the caller may
110
+ * also fold it into the review-nits observation).
111
+ */
112
+ export function extractDecisionsBlock(
113
+ output: string | undefined,
114
+ ): string | undefined {
115
+ if (output === undefined || output === '') {
116
+ return undefined;
117
+ }
118
+ const lines = output.replace(/\r\n/g, '\n').split('\n');
119
+ let start = -1;
120
+ for (let i = 0; i < lines.length; i++) {
121
+ if (lines[i].trim() === DECISIONS_HEADING) {
122
+ start = i + 1;
123
+ break;
124
+ }
125
+ }
126
+ if (start === -1) {
127
+ return undefined;
128
+ }
129
+ const body: string[] = [];
130
+ for (let i = start; i < lines.length; i++) {
131
+ if (/^##\s/.test(lines[i])) {
132
+ break;
133
+ }
134
+ body.push(lines[i]);
135
+ }
136
+ const text = body.join('\n').trim();
137
+ return text === '' ? undefined : text;
138
+ }
139
+
140
+ /**
141
+ * The DETERMINISTIC backstop for the STOP sentinel: did the agent leave NO source
142
+ * change at all? An `agent.ok` run that changed NOTHING is NEVER a successful
143
+ * build — treat it as an implicit STOP/no-op and route to needs-attention WITHOUT
144
+ * paying for the gate + Gate-2, even when the agent stopped without (or with a
145
+ * malformed) sentinel.
146
+ *
147
+ * The check has TWO independent signals; the build is empty IFF BOTH say "no
148
+ * source change":
149
+ *
150
+ * 1. **The WORKING TREE** (the primary signal, the common FRESH-build path). At
151
+ * this point in the pipeline (after the agent returns, BEFORE the gate /
152
+ * done-move) the runner has committed nothing of the agent's work — for a
153
+ * FRESH build the work branch HEAD is still the CLAIM commit, so the agent's
154
+ * output sits ENTIRELY in the WORKING TREE (tracked modifications OR
155
+ * brand-new untracked files; the agent does no git):
156
+ * - tracked modifications: `git status --porcelain` reports any modified/
157
+ * added/deleted TRACKED path;
158
+ * - untracked files: `--porcelain` also lists `??` untracked paths (a new
159
+ * source file the agent created), which a `git diff` would MISS.
160
+ *
161
+ * 2. **SOURCE COMMITS on the branch ahead of `<arbiter>/main`** (the additional
162
+ * condition that honours a `requeue` CONTINUE-FROM-TIP). The working-tree-only
163
+ * assumption — "HEAD is still the claim commit" — is FALSE for a `requeue`
164
+ * keep+continue: the kept `work/<slug>` branch's prior work is a chain of
165
+ * COMMITTED commits ahead of main, with a legitimately CLEAN working tree.
166
+ * Such a continue is NOT a no-op, so we ALSO ask: does any commit in
167
+ * `git rev-list <arbiter>/main..HEAD` touch a NON-`work/` path? If so the
168
+ * branch carries real source work and the build is NOT empty, even though the
169
+ * current session's working tree is clean.
170
+ *
171
+ * TWO things are filtered out of BOTH signals so they do not read as a build: the
172
+ * `work/` ledger (the runner's own claim move, the ONLY thing in the tree — and
173
+ * the ONLY thing the claim commit touches — on a clean STOP) and the runner's own
174
+ * `.dorfl-job.json` record (a job-worktree leaves one — the SAME line
175
+ * `gc`'s `isWorktreeClean` filters). The build is empty IFF nothing else remains
176
+ * in EITHER signal. Best-effort: a plumbing failure in EITHER check is treated as
177
+ * NON-empty (the safe direction — never short-circuit a genuine build by mistake).
178
+ *
179
+ * `arbiter` (already threaded for call-site symmetry) is used by signal 2 to
180
+ * resolve `<arbiter>/main`; we fetch it first (mirroring the integration band) so
181
+ * the remote-tracking ref exists / is current even in a bare-mirror job worktree.
182
+ */
183
+ export async function isWorkBranchDiffEmpty(params: {
184
+ cwd: string;
185
+ arbiter: string;
186
+ env?: NodeJS.ProcessEnv;
187
+ }): Promise<boolean> {
188
+ const {cwd, arbiter, env} = params;
189
+ if (await hasUncommittedSourceChanges({cwd, env})) {
190
+ return false; // the working tree carries source change ⇒ a real build.
191
+ }
192
+ // Working tree is clean. It is STILL a real build if the branch carries source
193
+ // COMMITS ahead of `<arbiter>/main` (a `requeue` continue-from-tip). Only when
194
+ // there are none is this a genuine no-op.
195
+ return !(await hasSourceCommitsAhead({cwd, arbiter, env}));
196
+ }
197
+
198
+ /**
199
+ * The WORKING-TREE-DIRTY predicate (the first half of {@link
200
+ * isWorkBranchDiffEmpty}): does the working tree carry any uncommitted source
201
+ * change — tracked modifications, deletions, OR brand-new untracked files —
202
+ * outside `work/` and outside the runner's `.dorfl-job.json` record?
203
+ *
204
+ * This is a **best-effort** check in the SAFE direction (a git plumbing failure
205
+ * reads as TRUE: "dirty" / "has source") so an unknown can never short-circuit a
206
+ * genuine build by mistake.
207
+ *
208
+ * Two consumers share this seam, so they NEVER drift on what "the agent left
209
+ * uncommitted source work in the tree" means:
210
+ *
211
+ * - {@link isWorkBranchDiffEmpty} (the STOP backstop): empty IFF this is FALSE
212
+ * AND `<arbiter>/main..HEAD` has no source commits.
213
+ *
214
+ * - `complete.ts`'s stranded-done auto-recover gate (task
215
+ * `recover-autodetect-gated-on-nothing-to-commit`): on the autonomous path,
216
+ * `committedRecovery` (the folder-shape stranded-done auto-detect) fires only
217
+ * when this is FALSE. A dirty tree on a done-stranded branch means the agent
218
+ * produced new uncommitted work THIS run (a CONTINUE, not a finished strand),
219
+ * so the recover must NOT mis-fire and silently discard it.
220
+ *
221
+ * DELIBERATELY NOT used at the complete.ts gate point: (1) the core's
222
+ * `nothingStaged` (`git diff --cached --quiet`) — that is INDEX-only and reads
223
+ * empty BEFORE the core's later `git add -A`, so it would miss the agent's
224
+ * unstaged edits; (2) the FULL `isWorkBranchDiffEmpty` — its commits-ahead half
225
+ * is true for a GENUINE FINISHED STRAND too (the kept tip carries source commits
226
+ * ahead of main), which would wrongly block the legitimate recover.
227
+ */
228
+ export async function hasUncommittedSourceChanges(params: {
229
+ cwd: string;
230
+ env?: NodeJS.ProcessEnv;
231
+ }): Promise<boolean> {
232
+ const {cwd, env} = params;
233
+ // Count ANY uncommitted tracked change (mods, deletions, untracked), dropping
234
+ // ONLY the runner's own `.dorfl-job.json` record (a job worktree leaves it).
235
+ //
236
+ // It does NOT exclude `work/`: a `work/` change is frequently the GENUINE
237
+ // DELIVERABLE of a task (extend an idea, transcribe a `## Decisions` block into a
238
+ // done-record, ratify in a protocol doc, author an ADR-note). Excluding `work/`
239
+ // wholesale mis-classified every DOCS-ONLY task as an empty-diff no-op and
240
+ // FALSE-bounced completed, correct work (observation
241
+ // `runner-empty-diff-false-positive-bounces-completed-work-2026-07-09`). The
242
+ // old exclusion existed for a claim BOOKKEEPING commit that touched `work/`
243
+ // only — but the per-item-lock claim writes NOTHING (`claim-cas.ts`: "there is
244
+ // NO claim commit"), so the exclusion now only over-drops real deliverables.
245
+ // Genuine bookkeeping is excluded by TRAILER at the commits-ahead check, not by
246
+ // path here (the working tree carries no bookkeeping — the agent's edits are
247
+ // its deliverable).
248
+ const status = await runAsync('git', ['status', '--porcelain'], cwd, {env});
249
+ if (status.status !== 0) {
250
+ return true; // plumbing error ⇒ treat as DIRTY (the safe direction).
251
+ }
252
+ // Each porcelain line is `XY <path>` (path from column 3).
253
+ const remaining = status.stdout
254
+ .split('\n')
255
+ .map((line) => line.trimEnd())
256
+ .filter((line) => line !== '')
257
+ .filter((line) => line.slice(3).trim() !== JOB_RECORD_FILENAME);
258
+ return remaining.length > 0;
259
+ }
260
+
261
+ /**
262
+ * Does the work branch have at least one GENUINE-WORK commit in
263
+ * `<arbiter>/main..HEAD` (a commit that is NOT a runner bookkeeping commit,
264
+ * identified by its `Dorfl-Bookkeeping` trailer)? Fetches `<arbiter>/main` first
265
+ * (mirroring the integration band) so the ref resolves even in a bare-mirror job
266
+ * worktree. Best-effort / SAFE direction: any plumbing failure (the fetch, the
267
+ * rev-list, an unresolvable ref) reads as TRUE ("has source") — the same
268
+ * never-short-circuit-a-genuine-build stance the working-tree check takes, so an
269
+ * unknown can never collapse a real continue-from-tip into a no-op.
270
+ */
271
+ async function hasSourceCommitsAhead(params: {
272
+ cwd: string;
273
+ arbiter: string;
274
+ env?: NodeJS.ProcessEnv;
275
+ }): Promise<boolean> {
276
+ const {cwd, arbiter, env} = params;
277
+ // Refresh `<arbiter>/main` so the range resolves (a bare-mirror job worktree
278
+ // has no fetch refspec; a regular clone gets the same harmless explicit ref).
279
+ const fetched = await runAsync(
280
+ 'git',
281
+ [
282
+ 'fetch',
283
+ '--quiet',
284
+ arbiter,
285
+ `+refs/heads/main:refs/remotes/${arbiter}/main`,
286
+ ],
287
+ cwd,
288
+ {env},
289
+ );
290
+ if (fetched.status !== 0) {
291
+ return true; // could not refresh the ref ⇒ NON-empty (safe direction).
292
+ }
293
+ // Enumerate the commits in `<arbiter>/main..HEAD` and count those that carry
294
+ // GENUINE work — i.e. NOT a runner BOOKKEEPING commit. A bookkeeping commit is
295
+ // identified by its recorded `Dorfl-Bookkeeping` trailer (task
296
+ // `identify-bookkeeping-commits-by-trailer-not-rendered-todo-text`), NOT by a
297
+ // `work/` path: a `work/` change is frequently the real deliverable of a
298
+ // docs/protocol/observation task, so a path-based `:(exclude)work` here
299
+ // FALSE-bounced completed docs-only work (observation
300
+ // `runner-empty-diff-false-positive-bounces-completed-work-2026-07-09`). Read
301
+ // each commit's sha + bookkeeping trailer via plumbing (NUL-delimited, one
302
+ // record per commit); a commit with a non-empty `Dorfl-Bookkeeping` trailer is
303
+ // bookkeeping and does not count; any other commit is genuine work.
304
+ // Per commit: its sha + its `Dorfl-Bookkeeping` trailer value, NUL-delimited
305
+ // then a record separator, so we can inspect each commit's files too.
306
+ const log = await runAsync(
307
+ 'git',
308
+ [
309
+ 'log',
310
+ '--format=%H%x00%(trailers:key=Dorfl-Bookkeeping,valueonly)%x1e',
311
+ `${arbiter}/main..HEAD`,
312
+ ],
313
+ cwd,
314
+ {env},
315
+ );
316
+ if (log.status !== 0) {
317
+ return true; // could not compute the range ⇒ NON-empty (safe direction).
318
+ }
319
+ const records = log.stdout
320
+ .split('\x1e')
321
+ .map((r) => r.trim())
322
+ .filter((r) => r !== '');
323
+ for (const record of records) {
324
+ const [sha, bookkeepingTrailer = ''] = record.split('\0');
325
+ // A bookkeeping-trailered commit is not genuine work.
326
+ if (bookkeepingTrailer.trim() !== '') {
327
+ continue;
328
+ }
329
+ // A commit whose ONLY touched path is the runner's own job-record is
330
+ // bookkeeping too (no trailer, but not the agent's deliverable).
331
+ const files = await runAsync(
332
+ 'git',
333
+ ['show', '--name-only', '--format=', sha],
334
+ cwd,
335
+ {env},
336
+ );
337
+ const touched =
338
+ files.status === 0
339
+ ? files.stdout
340
+ .split('\n')
341
+ .map((p) => p.trim())
342
+ .filter((p) => p !== '')
343
+ : [];
344
+ const jobRecordOnly =
345
+ touched.length > 0 && touched.every((p) => p === JOB_RECORD_FILENAME);
346
+ if (jobRecordOnly) {
347
+ continue;
348
+ }
349
+ // A non-bookkeeping commit that touches real files ⇒ genuine work.
350
+ return true;
351
+ }
352
+ return false;
353
+ }
354
+
355
+ /** The needs-attention reason for the deterministic empty-diff backstop. */
356
+ export function emptyDiffStopReason(slug: string): string {
357
+ return (
358
+ `the agent produced no source change building '${slug}' (empty diff vs the ` +
359
+ 'arbiter main); treating as a no-op/stop — re-scope or re-claim.'
360
+ );
361
+ }