dorfl 0.1.1 → 0.1.2

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 (313) hide show
  1. package/dist/advance-ci-template.d.ts +3 -3
  2. package/dist/advance-ci-template.js +1 -1
  3. package/dist/advance-ci-template.js.map +1 -1
  4. package/dist/advance-classify.d.ts +5 -5
  5. package/dist/advance-classify.d.ts.map +1 -1
  6. package/dist/advance-classify.js +4 -4
  7. package/dist/advance-drivers.d.ts +7 -7
  8. package/dist/advance-drivers.d.ts.map +1 -1
  9. package/dist/advance-drivers.js +5 -5
  10. package/dist/advance-drivers.js.map +1 -1
  11. package/dist/advance-isolated.d.ts +3 -3
  12. package/dist/advance-isolated.d.ts.map +1 -1
  13. package/dist/advance-isolated.js +1 -1
  14. package/dist/advance-lifecycle-template.d.ts +2 -2
  15. package/dist/advance-lifecycle-template.js +9 -9
  16. package/dist/advance-lifecycle-template.js.map +1 -1
  17. package/dist/advance-loop-driver.d.ts +3 -3
  18. package/dist/advance-loop-driver.d.ts.map +1 -1
  19. package/dist/advance-loop-driver.js +1 -1
  20. package/dist/advance-treeless-publish.d.ts +1 -1
  21. package/dist/advance.d.ts +11 -11
  22. package/dist/advance.d.ts.map +1 -1
  23. package/dist/advance.js +21 -21
  24. package/dist/advance.js.map +1 -1
  25. package/dist/advancing-lock.d.ts +1 -1
  26. package/dist/advancing-lock.js +5 -5
  27. package/dist/apply-decide.d.ts +2 -2
  28. package/dist/apply-decide.js +2 -2
  29. package/dist/apply-merge-action.d.ts +4 -4
  30. package/dist/apply-merge-action.js +2 -2
  31. package/dist/apply-persist.d.ts +5 -5
  32. package/dist/apply-persist.d.ts.map +1 -1
  33. package/dist/apply-persist.js +7 -7
  34. package/dist/apply-persist.js.map +1 -1
  35. package/dist/buildable-body.d.ts +14 -14
  36. package/dist/buildable-body.js +9 -9
  37. package/dist/claim-cas.d.ts +3 -3
  38. package/dist/claim-cas.js +1 -1
  39. package/dist/claim-cas.js.map +1 -1
  40. package/dist/cli.d.ts.map +1 -1
  41. package/dist/cli.js +76 -76
  42. package/dist/cli.js.map +1 -1
  43. package/dist/close-job-template.d.ts +3 -3
  44. package/dist/close-job-template.js +8 -8
  45. package/dist/close-job.d.ts +8 -8
  46. package/dist/close-job.js +25 -25
  47. package/dist/close-job.js.map +1 -1
  48. package/dist/complete.d.ts +3 -3
  49. package/dist/complete.js +8 -8
  50. package/dist/complete.js.map +1 -1
  51. package/dist/concurrency.d.ts +1 -1
  52. package/dist/concurrency.js +1 -1
  53. package/dist/config.d.ts +32 -32
  54. package/dist/config.js +5 -5
  55. package/dist/config.js.map +1 -1
  56. package/dist/continue-branch.d.ts +1 -1
  57. package/dist/continue-branch.js +1 -1
  58. package/dist/cwd-section.js +1 -1
  59. package/dist/cwd-section.js.map +1 -1
  60. package/dist/decision-engine.d.ts +2 -2
  61. package/dist/do-autopick.d.ts +6 -6
  62. package/dist/do-autopick.d.ts.map +1 -1
  63. package/dist/do-autopick.js +5 -5
  64. package/dist/do-autopick.js.map +1 -1
  65. package/dist/do-config.d.ts +3 -3
  66. package/dist/do-config.js +3 -3
  67. package/dist/do-config.js.map +1 -1
  68. package/dist/do-remote-auto.d.ts +2 -2
  69. package/dist/do-remote-auto.js +1 -1
  70. package/dist/do.d.ts +25 -25
  71. package/dist/do.d.ts.map +1 -1
  72. package/dist/do.js +20 -20
  73. package/dist/do.js.map +1 -1
  74. package/dist/drop-source.d.ts +2 -2
  75. package/dist/env-config.js +8 -8
  76. package/dist/env-config.js.map +1 -1
  77. package/dist/format.js +3 -3
  78. package/dist/format.js.map +1 -1
  79. package/dist/frontmatter.d.ts +14 -13
  80. package/dist/frontmatter.d.ts.map +1 -1
  81. package/dist/frontmatter.js +12 -24
  82. package/dist/frontmatter.js.map +1 -1
  83. package/dist/install-ci-branch-protection.d.ts +1 -1
  84. package/dist/install-ci-branch-protection.js +1 -1
  85. package/dist/install-ci-capabilities/advance-lifecycle.d.ts +1 -1
  86. package/dist/install-ci-capabilities/advance-lifecycle.js +1 -1
  87. package/dist/install-ci-capabilities/close-job.d.ts +1 -1
  88. package/dist/install-ci-capabilities/close-job.js +1 -1
  89. package/dist/install-ci-capabilities/example-noop.d.ts +1 -1
  90. package/dist/install-ci-capabilities/example-noop.js +1 -1
  91. package/dist/install-ci-capabilities/intake.d.ts +2 -2
  92. package/dist/install-ci-capabilities/intake.js +2 -2
  93. package/dist/install-ci-capabilities/verify.d.ts +1 -1
  94. package/dist/install-ci-capabilities/verify.js +1 -1
  95. package/dist/install-ci-core.d.ts +3 -3
  96. package/dist/install-ci-core.js +2 -2
  97. package/dist/install-ci-core.js.map +1 -1
  98. package/dist/install-ci-github.d.ts +1 -1
  99. package/dist/install-ci-github.js +1 -1
  100. package/dist/install-ci.d.ts +1 -1
  101. package/dist/install-ci.js +4 -4
  102. package/dist/install-ci.js.map +1 -1
  103. package/dist/intake-event.d.ts +6 -6
  104. package/dist/intake-event.js +6 -6
  105. package/dist/intake-marker.d.ts +3 -3
  106. package/dist/intake-marker.d.ts.map +1 -1
  107. package/dist/intake-triage.d.ts +1 -1
  108. package/dist/intake-triage.js +2 -2
  109. package/dist/intake-trigger-template.d.ts +8 -8
  110. package/dist/intake-trigger-template.d.ts.map +1 -1
  111. package/dist/intake-trigger-template.js +16 -16
  112. package/dist/intake-trigger-template.js.map +1 -1
  113. package/dist/intake.d.ts +50 -50
  114. package/dist/intake.d.ts.map +1 -1
  115. package/dist/intake.js +70 -70
  116. package/dist/intake.js.map +1 -1
  117. package/dist/integration-core.d.ts +17 -17
  118. package/dist/integration-core.js +17 -17
  119. package/dist/integration-core.js.map +1 -1
  120. package/dist/isolation.d.ts +3 -3
  121. package/dist/issue-provider.d.ts +4 -4
  122. package/dist/issue-provider.js +1 -1
  123. package/dist/item-lock.d.ts +21 -21
  124. package/dist/item-lock.d.ts.map +1 -1
  125. package/dist/item-lock.js +16 -16
  126. package/dist/item-path.d.ts +2 -2
  127. package/dist/item-path.js +2 -2
  128. package/dist/ledger-lint.d.ts +9 -9
  129. package/dist/ledger-lint.js +9 -9
  130. package/dist/ledger-read.d.ts +57 -57
  131. package/dist/ledger-read.d.ts.map +1 -1
  132. package/dist/ledger-read.js +24 -24
  133. package/dist/ledger-read.js.map +1 -1
  134. package/dist/ledger-write.d.ts +2 -2
  135. package/dist/ledger-write.js +1 -1
  136. package/dist/lifecycle-gather.d.ts +1 -1
  137. package/dist/lifecycle-gather.js +16 -16
  138. package/dist/lifecycle-gather.js.map +1 -1
  139. package/dist/lifecycle-pools.d.ts +4 -4
  140. package/dist/lifecycle-pools.js +1 -1
  141. package/dist/merge-question-surfacer.d.ts +3 -3
  142. package/dist/merge-question-surfacer.js +2 -2
  143. package/dist/merge-question-surfacer.js.map +1 -1
  144. package/dist/mint-adr.js +4 -4
  145. package/dist/mirror-pool-scan.d.ts +2 -2
  146. package/dist/mirror-pool-scan.js +3 -3
  147. package/dist/mirror-pool-scan.js.map +1 -1
  148. package/dist/needs-attention.d.ts +13 -13
  149. package/dist/needs-attention.d.ts.map +1 -1
  150. package/dist/needs-attention.js +11 -11
  151. package/dist/needs-attention.js.map +1 -1
  152. package/dist/orphan-sidecar.d.ts +2 -2
  153. package/dist/placement.d.ts +6 -6
  154. package/dist/placement.js +2 -2
  155. package/dist/prompt.d.ts +16 -19
  156. package/dist/prompt.d.ts.map +1 -1
  157. package/dist/prompt.js +17 -19
  158. package/dist/prompt.js.map +1 -1
  159. package/dist/readiness.d.ts +1 -1
  160. package/dist/recover-isolated.js +1 -1
  161. package/dist/repo-config.js +12 -12
  162. package/dist/repo-config.js.map +1 -1
  163. package/dist/review-gate.d.ts +3 -3
  164. package/dist/review-gate.d.ts.map +1 -1
  165. package/dist/review-gate.js +11 -10
  166. package/dist/review-gate.js.map +1 -1
  167. package/dist/review-verdict.d.ts +2 -2
  168. package/dist/review-verdict.d.ts.map +1 -1
  169. package/dist/review-verdict.js +1 -1
  170. package/dist/run.d.ts +1 -1
  171. package/dist/run.js +4 -4
  172. package/dist/run.js.map +1 -1
  173. package/dist/scan.d.ts +10 -10
  174. package/dist/scan.d.ts.map +1 -1
  175. package/dist/scan.js +8 -8
  176. package/dist/scan.js.map +1 -1
  177. package/dist/select-order.d.ts +1 -1
  178. package/dist/select-priority.d.ts +12 -12
  179. package/dist/select-priority.d.ts.map +1 -1
  180. package/dist/select-priority.js +5 -5
  181. package/dist/select-priority.js.map +1 -1
  182. package/dist/sidecar.d.ts +2 -2
  183. package/dist/sidecar.js +2 -2
  184. package/dist/sidecar.js.map +1 -1
  185. package/dist/slug-namespace.d.ts +1 -1
  186. package/dist/slug-namespace.js +3 -3
  187. package/dist/slug-namespace.js.map +1 -1
  188. package/dist/spec-complete.js +2 -2
  189. package/dist/spec-complete.js.map +1 -1
  190. package/dist/start.d.ts +1 -1
  191. package/dist/start.js +3 -3
  192. package/dist/start.js.map +1 -1
  193. package/dist/status.d.ts +3 -3
  194. package/dist/status.js +4 -4
  195. package/dist/status.js.map +1 -1
  196. package/dist/surface-gate.d.ts +2 -2
  197. package/dist/surface-gate.d.ts.map +1 -1
  198. package/dist/surface-persist.d.ts +2 -2
  199. package/dist/surface-persist.d.ts.map +1 -1
  200. package/dist/tasker-review-loop.d.ts +8 -8
  201. package/dist/tasker-review-loop.d.ts.map +1 -1
  202. package/dist/tasker-review-loop.js +8 -8
  203. package/dist/tasker-review-loop.js.map +1 -1
  204. package/dist/tasking-eligibility.d.ts +21 -21
  205. package/dist/tasking-eligibility.d.ts.map +1 -1
  206. package/dist/tasking-eligibility.js +10 -10
  207. package/dist/tasking-lock.d.ts +8 -8
  208. package/dist/tasking-lock.d.ts.map +1 -1
  209. package/dist/tasking-lock.js +20 -21
  210. package/dist/tasking-lock.js.map +1 -1
  211. package/dist/tasking.d.ts +33 -33
  212. package/dist/tasking.d.ts.map +1 -1
  213. package/dist/tasking.js +88 -86
  214. package/dist/tasking.js.map +1 -1
  215. package/dist/triage-gate.d.ts +1 -1
  216. package/dist/triage-persist.d.ts +5 -5
  217. package/dist/triage-persist.js +15 -15
  218. package/dist/triage-persist.js.map +1 -1
  219. package/dist/verify-workflow-template.d.ts +1 -1
  220. package/dist/verify-workflow-template.js +2 -2
  221. package/dist/work-layout.d.ts +9 -7
  222. package/dist/work-layout.d.ts.map +1 -1
  223. package/dist/work-layout.js +9 -7
  224. package/dist/work-layout.js.map +1 -1
  225. package/dist/workspace.d.ts +1 -1
  226. package/package.json +1 -1
  227. package/src/advance-ci-template.ts +4 -4
  228. package/src/advance-classify.ts +5 -5
  229. package/src/advance-drivers.ts +10 -10
  230. package/src/advance-isolated.ts +3 -3
  231. package/src/advance-lifecycle-template.ts +9 -9
  232. package/src/advance-loop-driver.ts +3 -3
  233. package/src/advance-treeless-publish.ts +1 -1
  234. package/src/advance.ts +30 -30
  235. package/src/advancing-lock.ts +6 -6
  236. package/src/apply-decide.ts +2 -2
  237. package/src/apply-merge-action.ts +5 -5
  238. package/src/apply-persist.ts +8 -8
  239. package/src/buildable-body.ts +14 -14
  240. package/src/claim-cas.ts +4 -4
  241. package/src/cli.ts +83 -83
  242. package/src/close-job-template.ts +8 -8
  243. package/src/close-job.ts +26 -26
  244. package/src/complete.ts +11 -11
  245. package/src/concurrency.ts +1 -1
  246. package/src/config.ts +37 -37
  247. package/src/continue-branch.ts +1 -1
  248. package/src/cwd-section.ts +1 -1
  249. package/src/decision-engine.ts +3 -3
  250. package/src/do-autopick.ts +9 -9
  251. package/src/do-config.ts +6 -6
  252. package/src/do-remote-auto.ts +2 -2
  253. package/src/do.ts +47 -47
  254. package/src/drop-source.ts +2 -2
  255. package/src/env-config.ts +8 -8
  256. package/src/format.ts +3 -3
  257. package/src/frontmatter.ts +23 -33
  258. package/src/install-ci-branch-protection.ts +1 -1
  259. package/src/install-ci-capabilities/advance-lifecycle.ts +1 -1
  260. package/src/install-ci-capabilities/close-job.ts +1 -1
  261. package/src/install-ci-capabilities/example-noop.ts +1 -1
  262. package/src/install-ci-capabilities/intake.ts +2 -2
  263. package/src/install-ci-capabilities/verify.ts +1 -1
  264. package/src/install-ci-core.ts +4 -4
  265. package/src/install-ci-github.ts +1 -1
  266. package/src/install-ci.ts +4 -4
  267. package/src/intake-event.ts +6 -6
  268. package/src/intake-marker.ts +3 -3
  269. package/src/intake-triage.ts +2 -2
  270. package/src/intake-trigger-template.ts +17 -17
  271. package/src/intake.ts +97 -97
  272. package/src/integration-core.ts +35 -35
  273. package/src/isolation.ts +3 -3
  274. package/src/issue-provider.ts +4 -4
  275. package/src/item-lock.ts +21 -21
  276. package/src/item-path.ts +2 -2
  277. package/src/ledger-lint.ts +9 -9
  278. package/src/ledger-read.ts +81 -81
  279. package/src/ledger-write.ts +3 -3
  280. package/src/lifecycle-gather.ts +16 -16
  281. package/src/lifecycle-pools.ts +4 -4
  282. package/src/merge-question-surfacer.ts +4 -4
  283. package/src/mint-adr.ts +4 -4
  284. package/src/mirror-pool-scan.ts +5 -5
  285. package/src/needs-attention.ts +22 -22
  286. package/src/orphan-sidecar.ts +2 -2
  287. package/src/placement.ts +6 -6
  288. package/src/prompt.ts +20 -25
  289. package/src/readiness.ts +1 -1
  290. package/src/recover-isolated.ts +1 -1
  291. package/src/repo-config.ts +12 -12
  292. package/src/review-gate.ts +12 -11
  293. package/src/review-verdict.ts +2 -2
  294. package/src/run.ts +5 -5
  295. package/src/scan.ts +15 -15
  296. package/src/select-order.ts +1 -1
  297. package/src/select-priority.ts +13 -13
  298. package/src/sidecar.ts +3 -3
  299. package/src/slug-namespace.ts +3 -3
  300. package/src/spec-complete.ts +2 -2
  301. package/src/start.ts +4 -4
  302. package/src/status.ts +7 -7
  303. package/src/surface-gate.ts +2 -2
  304. package/src/surface-persist.ts +2 -2
  305. package/src/tasker-review-loop.ts +15 -15
  306. package/src/tasking-eligibility.ts +21 -21
  307. package/src/tasking-lock.ts +27 -28
  308. package/src/tasking.ts +123 -121
  309. package/src/triage-gate.ts +1 -1
  310. package/src/triage-persist.ts +16 -16
  311. package/src/verify-workflow-template.ts +2 -2
  312. package/src/work-layout.ts +9 -7
  313. package/src/workspace.ts +1 -1
package/src/tasking.ts CHANGED
@@ -48,44 +48,44 @@ import {
48
48
  import type {ReviewGate} from './review-gate.js';
49
49
 
50
50
  /**
51
- * The **`do prd:<slug>` tasking path** (prd `auto-slice`, task
51
+ * The **`do spec:<slug>` tasking path** (spec `auto-slice`, task
52
52
  * `autoslice-command`) — the orchestration that ties the tasking GATE
53
53
  * (`tasking-eligibility.ts`) and the tasking LOCK (`tasking-lock.ts`) together to
54
- * task a prd into `work/tasks/backlog/` STAGED items (task
54
+ * task a spec into `work/tasks/backlog/` STAGED items (task
55
55
  * `pre-backlog-staging-folder-and-promote-step-a` — the runner-owned promotion
56
56
  * moves them `pre-backlog/ → backlog/` later), with the RUNNER owning every git-state
57
- * transition. This is the prd branch of the `do` worker (ADR
57
+ * transition. This is the spec branch of the `do` worker (ADR
58
58
  * `command-surface-and-journeys.md` §3/§3a), NOT a standalone `task` command;
59
- * `do.ts` dispatches `resolved.namespace === 'prd'` here.
59
+ * `do.ts` dispatches `resolved.namespace === 'spec'` here.
60
60
  *
61
61
  * The end-to-end flow (mirroring the `do`/`run` runner-owns-git discipline — the
62
62
  * agent only EDITS files, the runner does ALL git):
63
63
  *
64
- * 1. **Resolve the gate** (agent path): refuse to task a prd that is
65
- * `humanOnly`/`needsAnswers`, or whose `taskedAfter` prds are not yet tasked.
64
+ * 1. **Resolve the gate** (agent path): refuse to task a spec that is
65
+ * `humanOnly`/`needsAnswers`, or whose `taskedAfter` specs are not yet tasked.
66
66
  * The repo's `autoTask` POLICY also refuses on the AUTO-PICK pool path, but
67
- * NOT when the prd was named EXPLICITLY (`do prd:<slug>`, `explicit: true`):
67
+ * NOT when the spec was named EXPLICITLY (`do spec:<slug>`, `explicit: true`):
68
68
  * naming it IS the authorization, exactly as `do <task>` builds regardless of
69
69
  * `autoBuild` (the pool, not the explicit claim, gates the policy). The HUMAN
70
70
  * path is unbound by the gate entirely.
71
71
  * 2. **Acquire the lock** (agent path) via the unified per-item lock CAS —
72
- * serialising concurrent taskers on the `prd:<slug>` ref (the body STAYS in
73
- * `work/prds/ready/`; the lock no longer moves it). The HUMAN path with no contention
72
+ * serialising concurrent taskers on the `spec:<slug>` ref (the body STAYS in
73
+ * `work/specs/ready/`; the lock no longer moves it). The HUMAN path with no contention
74
74
  * may task on `main` directly WITHOUT the lock.
75
- * 3. **Invoke the agent harness** with the `to-task` prd — the agent runs the
75
+ * 3. **Invoke the agent harness** with the `to-task` spec — the agent runs the
76
76
  * tasker methodology and produces `work/tasks/backlog/<slug>.md` FILES ONLY; it does
77
77
  * NOT commit/push/move (the same in-band boundary as the build agent).
78
78
  * 4. **The runner integrates the COMPLETING transition through the SHARED core**
79
79
  * (`performIntegration`, task `slice-output-through-integration`): the agent's
80
80
  * tasking runs on a `work/<slug>` branch cut from `<arbiter>/main` (whose base
81
- * holds the prd in `work/prds/ready/`), and the produced backlog tasks + the durable
82
- * prd lifecycle move (`work/prds/ready/ → work/prds/tasked/`)
81
+ * holds the spec in `work/specs/ready/`), and the produced backlog tasks + the durable
82
+ * spec lifecycle move (`work/specs/ready/ → work/specs/tasked/`)
83
83
  * integrate via the band honoring `--propose` (push the branch + open a
84
84
  * PR, NO `main` touch) / `--merge` (land on `main`). Because the integrate-time
85
85
  * args resolve ONCE in the shared core, EVERY `do task:` integrate arg applies
86
- * to `do prd:` by construction. A content-identity STALE CHECK (the lock's
86
+ * to `do spec:` by construction. A content-identity STALE CHECK (the lock's
87
87
  * read-stability backstop) fires FIRST against the acquire-time `lockedBlob`,
88
- * so a concurrent edit of the held prd still fails loud (`stale`).
88
+ * so a concurrent edit of the held spec still fails loud (`stale`).
89
89
  *
90
90
  * The tasking LOCK (`tasking-lock.ts`, `acquireTaskingLock`/`releaseTaskingLock`)
91
91
  * is the UNIFIED per-item lock (`refs/dorfl/lock/<entry>`, `action: task`)
@@ -98,20 +98,20 @@ import type {ReviewGate} from './review-gate.js';
98
98
  * owned by `slicer-review-edit-loop`; this path produces + integrates the tasks.
99
99
  */
100
100
 
101
- /** The terminal status of one `do prd:<slug>` tasking run. */
101
+ /** The terminal status of one `do spec:<slug>` tasking run. */
102
102
  export type TaskOutcome =
103
103
  | 'tasked' // gate passed (agent) / unbound (human) → lock → agent → committed
104
104
  | 'gate-refused' // the agent gate refused (humanOnly/needsAnswers/autoTask/taskedAfter)
105
105
  | 'lock-lost' // the lock was lost/contended (another tasker holds it)
106
106
  | 'agent-failed' // the agent invocation itself errored
107
- | 'stale' // the held prd was edited under the lock → the tasking is stale
108
- | 'needs-attention' // the tasker edit loop found the decomposition unclear → prd routed to needs-attention (no tasks)
109
- | 'usage-error'; // usage / environment problem (missing prd, bad release, …)
107
+ | 'stale' // the held spec was edited under the lock → the tasking is stale
108
+ | 'needs-attention' // the tasker edit loop found the decomposition unclear → spec routed to needs-attention (no tasks)
109
+ | 'usage-error'; // usage / environment problem (missing spec, bad release, …)
110
110
 
111
111
  export interface TaskResult {
112
112
  exitCode: 0 | 1 | 2 | 3 | 4;
113
113
  outcome: TaskOutcome;
114
- /** The prd slug acted on. */
114
+ /** The spec slug acted on. */
115
115
  slug: string;
116
116
  /** Repo-relative paths of the backlog tasks the runner committed. */
117
117
  emitted?: string[];
@@ -119,7 +119,7 @@ export interface TaskResult {
119
119
  * The tasker review→edit LOOP's disposition (`slicer-review-edit-loop`), when
120
120
  * the loop ran. `converged` = the improved tasks landed; `uncertain-tasks` =
121
121
  * the cap was hit and specific tasks landed `needsAnswers: true`; absent when
122
- * no loop ran or the prd was routed to needs-attention (`outcome:
122
+ * no loop ran or the spec was routed to needs-attention (`outcome:
123
123
  * 'needs-attention'`).
124
124
  */
125
125
  loop?: 'converged' | 'uncertain-tasks';
@@ -128,8 +128,8 @@ export interface TaskResult {
128
128
  }
129
129
 
130
130
  /**
131
- * The agent invocation: runs the `to-task` prd in `cwd`, WRITING
132
- * `work/tasks/backlog/<slug>.md` task files (and trimming the prd). It does NO git —
131
+ * The agent invocation: runs the `to-task` spec in `cwd`, WRITING
132
+ * `work/tasks/backlog/<slug>.md` task files (and trimming the spec). It does NO git —
133
133
  * the runner captures the produced files and commits them.
134
134
  */
135
135
  export type TaskDorfl = (input: {
@@ -155,7 +155,7 @@ const DEFAULT_LOCK_SEAM: TaskingLockSeam = {
155
155
  };
156
156
 
157
157
  export interface PerformTaskOptions {
158
- /** The prd slug to task (`work/prds/ready/<slug>.md`). */
158
+ /** The spec slug to task (`work/specs/ready/<slug>.md`). */
159
159
  slug: string;
160
160
  /** The working clone/checkout the tasking runs in. */
161
161
  cwd: string;
@@ -170,16 +170,16 @@ export interface PerformTaskOptions {
170
170
  /** Per-repo `autoTask` policy (resolved by `autoslice-gate`). Agent path only. */
171
171
  autoTask?: boolean;
172
172
  /**
173
- * The prd was named EXPLICITLY by the operator (`do prd:<slug>`), so the
174
- * `autoTask` POLICY is already satisfied — naming the prd IS the authorization,
173
+ * The spec was named EXPLICITLY by the operator (`do spec:<slug>`), so the
174
+ * `autoTask` POLICY is already satisfied — naming the spec IS the authorization,
175
175
  * EXACTLY as `do <task>` builds a named task regardless of `autoBuild` (the
176
176
  * build path's precedent: `autoBuild` gates the scan/selection POOL only, never
177
177
  * `performDo`'s explicit claim). When `true`, the agent tasking gate drops the
178
- * `autoTask` policy term and binds ONLY the prd's own readiness axes
178
+ * `autoTask` policy term and binds ONLY the spec's own readiness axes
179
179
  * (`humanOnly`/`needsAnswers`) + `taskedAfter`. Defaults `false`. Both the
180
- * explicit `do prd:` dispatch AND the auto-pick path pass `true` here: the
180
+ * explicit `do spec:` dispatch AND the auto-pick path pass `true` here: the
181
181
  * auto-pick POOL (`do-autopick.ts`) is the single `autoTask`-enforcement point
182
- * (a pool-ineligible prd is never selected), so once a prd is dispatched its
182
+ * (a pool-ineligible spec is never selected), so once a spec is dispatched its
183
183
  * policy is already settled. Agent path only.
184
184
  */
185
185
  explicit?: boolean;
@@ -201,7 +201,7 @@ export interface PerformTaskOptions {
201
201
  * with (task `slice-output-through-integration`): `propose` (default — push the
202
202
  * `work/<slug>` branch + open a PR carrying the tasks, NO `main` touch) or
203
203
  * `merge` (land them on `main`). Resolved ONCE in {@link performIntegration},
204
- * so EVERY `do task:` integrate-time arg applies to `do prd:` by construction.
204
+ * so EVERY `do task:` integrate-time arg applies to `do spec:` by construction.
205
205
  * The AGENT path only; the human path commits its own output. Defaults to the
206
206
  * system default (`propose`).
207
207
  */
@@ -226,7 +226,7 @@ export interface PerformTaskOptions {
226
226
  * task-path mirror of the build Gate-2, riding {@link performIntegration}'s
227
227
  * review-before-integrate block. When `review` resolves on, a FRESH-CONTEXT
228
228
  * agent reviews the WHOLE produced task SET (coherence / dependency graph /
229
- * gaps + overlap / prd-goal correct-if-implemented) BEFORE the tasks integrate;
229
+ * gaps + overlap / spec-goal correct-if-implemented) BEFORE the tasks integrate;
230
230
  * `approve` lands them, `block` routes the set to needs-attention. It is
231
231
  * controlled by the BUILD `--review`/`--no-review`/`--review-model` family (ONE
232
232
  * gate-configuration story shared with the build path) and is ONE-SHOT —
@@ -247,7 +247,7 @@ export interface PerformTaskOptions {
247
247
  /** Injectable lock seam (tests stub acquire/release). Defaults to the real CAS. */
248
248
  lock?: TaskingLockSeam;
249
249
  /**
250
- * **The per-repo TASK-PLACEMENT default** (prd
250
+ * **The per-repo TASK-PLACEMENT default** (spec
251
251
  * `staging-pool-position-gate-and-trust-model` US #5, task
252
252
  * `runner-deterministic-slice-placement-policy-and-precedence`). The
253
253
  * resolved per-repo default landing for the tasker's emitted tasks, fed as
@@ -270,13 +270,13 @@ export interface PerformTaskOptions {
270
270
  */
271
271
  explicitTasksLandIn?: 'pre-backlog' | 'ready';
272
272
  /**
273
- * **The tasker review→edit→converge LOOP** (`slicer-review-edit-loop`, GATES prd
274
- * `work/prds/ready/review.md` RESOLVED DESIGN — Shape 2 / insertion point A). When
273
+ * **The tasker review→edit→converge LOOP** (`slicer-review-edit-loop`, GATES spec
274
+ * `work/specs/ready/review.md` RESOLVED DESIGN — Shape 2 / insertion point A). When
275
275
  * provided, AFTER the agent produces candidate tasks (step 3) and BEFORE the
276
276
  * runner finalises them (step 4), run the `review` SKILL as a review→edit→
277
277
  * re-review loop that IMPROVES the candidate tasks in place, then routes the
278
278
  * verdict through the three outcomes (converge→land / uncertain-task→
279
- * needsAnswers / decomposition-unclear→prd-to-needs-attention). The seam is the
279
+ * needsAnswers / decomposition-unclear→spec-to-needs-attention). The seam is the
280
280
  * review+edit gate (tests inject a canned verdict+edits; production:
281
281
  * {@link harnessTaskReviewGate}). Omitted ⇒ NO loop (the candidate tasks land
282
282
  * as-is — the pre-loop behaviour). The HUMAN path is unaffected (the loop runs
@@ -318,7 +318,7 @@ export interface PerformTaskOptions {
318
318
  const DEFAULT_ARBITER = 'origin';
319
319
 
320
320
  /**
321
- * **The STAGED-TASKS dir** (prd `staging-pool-position-gate-and-trust-model`,
321
+ * **The STAGED-TASKS dir** (spec `staging-pool-position-gate-and-trust-model`,
322
322
  * task `pre-backlog-staging-folder-and-promote-step-a`, governing ADR
323
323
  * `placement-is-runner-deterministic-humanonly-is-agent-judgement`). The runner
324
324
  * lands the tasker's emitted task files HERE, NOT in `work/tasks/ready/`: an item
@@ -336,7 +336,7 @@ export const STAGED_TASKS_DIR = workFolderRel('tasks-backlog');
336
336
  * origin, or an `--tasks-land-in ready` operator override). The agent NEVER
337
337
  * writes here — it always writes to {@link STAGED_TASKS_DIR}; the runner
338
338
  * redirects the emitted files to the resolved destination at integrate-stage
339
- * time. prd US #4 / the governing ADR: the agent cannot self-place into the
339
+ * time. spec US #4 / the governing ADR: the agent cannot self-place into the
340
340
  * pool. Task `runner-deterministic-slice-placement-policy-and-precedence`.
341
341
  */
342
342
  const POOL_TASKS_DIR = workFolderRel('tasks-ready');
@@ -369,7 +369,7 @@ function stagedTaskPath(name: string): string {
369
369
  }
370
370
 
371
371
  /**
372
- * Run the `do prd:<slug>` tasking path end-to-end. Never throws for the expected
372
+ * Run the `do spec:<slug>` tasking path end-to-end. Never throws for the expected
373
373
  * gate-refused / lock-lost / agent-failed / stale cases — those are returned with
374
374
  * the appropriate exit code and outcome. The runner owns all git; the agent only
375
375
  * writes task files.
@@ -389,11 +389,11 @@ export async function performTask(
389
389
  const doer = options.doer ?? 'agent';
390
390
  const lock = options.lock ?? DEFAULT_LOCK_SEAM;
391
391
 
392
- // 0. The prd must exist in the checkout (`work/prds/ready/<slug>.md`) — it is the
392
+ // 0. The spec must exist in the checkout (`work/specs/ready/<slug>.md`) — it is the
393
393
  // source the agent tasks + the file the lock holds.
394
394
  const specPath = workItemPath(cwd, 'specs-ready', slug);
395
395
  if (!existsSync(specPath)) {
396
- const message = `no prd '${slug}' found at ${workFolderRel('specs-ready')}/${slug}.md.`;
396
+ const message = `no spec '${slug}' found at ${workFolderRel('specs-ready')}/${slug}.md.`;
397
397
  note(message);
398
398
  return {exitCode: 1, outcome: 'usage-error', slug, message};
399
399
  }
@@ -401,7 +401,7 @@ export async function performTask(
401
401
  const specFm = parseFrontmatter(specContent);
402
402
 
403
403
  // 1. RESOLVE THE GATE (agent path only). The human path is UNBOUND — a human
404
- // decides for themselves whether a prd is taskable.
404
+ // decides for themselves whether a spec is taskable.
405
405
  if (doer === 'agent') {
406
406
  const eligibility = resolveAgentGate(
407
407
  cwd,
@@ -452,9 +452,9 @@ export async function performTask(
452
452
 
453
453
  // 2b. ONBOARD the agent's tasking work onto a `work/<slug>` BRANCH cut from the
454
454
  // freshly-fetched `<arbiter>/main` (task `slice-output-through-integration`).
455
- // The prd body rests in `work/prds/ready/<slug>.md` on `<arbiter>/main` (the lock no
456
- // longer moves it), so the branch's base HOLDS the held prd — the lifecycle
457
- // stage below moves it `prd/ → prd-tasked/` ON THIS BRANCH and the shared integrate core (`--propose`
455
+ // The spec body rests in `work/specs/ready/<slug>.md` on `<arbiter>/main` (the lock no
456
+ // longer moves it), so the branch's base HOLDS the held spec — the lifecycle
457
+ // stage below moves it `specs/ready/specs/tasked/` ON THIS BRANCH and the shared integrate core (`--propose`
458
458
  // PR / `--merge` main) lands the whole transition, WITHOUT the lock release
459
459
  // committing tasks straight to `main`. The agent runs IN-PLACE on this branch
460
460
  // (branch ≠ worktree; the isolation seam upgrades it). The HUMAN path stays on
@@ -463,7 +463,7 @@ export async function performTask(
463
463
  await switchToWorkBranch(cwd, arbiter, slug, env);
464
464
  }
465
465
 
466
- // 3. INVOKE THE AGENT with the to-task prd. It WRITES
466
+ // 3. INVOKE THE AGENT with the to-task spec. It WRITES
467
467
  // `work/tasks/backlog/*.md` task files (the STAGED area — NOT `work/tasks/ready/`,
468
468
  // which is the agent-eligible pool the runner owns the promotion into; task
469
469
  // `pre-backlog-staging-folder-and-promote-step-a`); it does NO git. We
@@ -472,10 +472,10 @@ export async function performTask(
472
472
  const before = snapshotStagedTasks(cwd);
473
473
  // Also snapshot the POOL `work/tasks/ready/` BEFORE the agent runs: the runner's
474
474
  // final commit must scrub any agent writes there (an attempt to self-place into
475
- // the pool, prd US #4) before `git add -A` would sweep them in.
475
+ // the pool, spec US #4) before `git add -A` would sweep them in.
476
476
  const poolBefore = snapshotPool(cwd);
477
477
  // Read the parent-spec self-pointer off `specFm.spec` (populated from the
478
- // `spec:` key or the legacy `prd:` back-compat alias).
478
+ // `spec:` key).
479
479
  const prompt = buildTaskingSpec(slug, specFm.spec);
480
480
  let agent: {ok: boolean; detail?: string};
481
481
  try {
@@ -521,10 +521,10 @@ export async function performTask(
521
521
  env: agentEnv,
522
522
  note,
523
523
  });
524
- // DECOMPOSITION UNCLEAR: emit NO guessed tasks — route the held prd to
524
+ // DECOMPOSITION UNCLEAR: emit NO guessed tasks — route the held spec to
525
525
  // needs-attention with the questions as the reason. The lock release amends the
526
- // `prd:<slug>` unified lock `active → stuck` (the tasking needs-attention surface
527
- // is the stuck lock now — NO folder write; the prd body stays in `work/prds/ready/`).
526
+ // `spec:<slug>` unified lock `active → stuck` (the tasking needs-attention surface
527
+ // is the stuck lock now — NO folder write; the spec body stays in `work/specs/ready/`).
528
528
  if (loopDisposition.outcome === 'decomposition-unclear') {
529
529
  const reason = decompositionUnclearReason(
530
530
  slug,
@@ -563,7 +563,7 @@ export async function performTask(
563
563
  }
564
564
 
565
565
  // 4. The RUNNER commits the COMPLETING transition: drop the produced backlog
566
- // tasks IN + move the prd tasking/ -> prd-tasked/ (residence = tasked-ness) — now
566
+ // tasks IN + move the spec specs/ready/ -> specs/tasked/ (residence = tasked-ness) — now
567
567
  // through the SHARED integrate core (`--propose` PR / `--merge` main), NOT a
568
568
  // direct commit to `main`. The agent never does git. (The backlog snapshot is
569
569
  // taken AFTER any loop edits, so the runner integrates the IMPROVED tasks,
@@ -574,7 +574,7 @@ export async function performTask(
574
574
  // `runner-deterministic-slice-placement-policy-and-precedence`). Resolve which
575
575
  // folder the runner lands the emitted tasks in BEFORE handing them to the
576
576
  // shared integrate band: precedence `explicit > untrusted-origin ⇒ staging >
577
- // tasksLandIn > built-in (staging)`, all from unforgeable inputs (the prd's
577
+ // tasksLandIn > built-in (staging)`, all from unforgeable inputs (the spec's
578
578
  // stamped `originTrust:` + the resolved per-repo default + the operator's
579
579
  // explicit flag). The agent NEVER influences this; it always writes to
580
580
  // `work/tasks/backlog/`, and the runner redirects at `stage()` time.
@@ -602,11 +602,11 @@ export async function performTask(
602
602
  if (useLock) {
603
603
  // READ-STABILITY BACKSTOP (the lock's content-identity check, now owned at the
604
604
  // integrate seam): the OUTPUT no longer rides the lock release, so the band
605
- // below would otherwise rebase a concurrent edit of the held prd body CLEANLY
606
- // into prd/ (a rename+edit merge) while the tasks were cut from the OLD body —
605
+ // below would otherwise rebase a concurrent edit of the held spec body CLEANLY
606
+ // into spec/ (a rename+edit merge) while the tasks were cut from the OLD body —
607
607
  // the exact silent stale-task drift the lock forbids
608
- // (`work/notes/observations/tasking-lock-does-not-stabilise-prd-content.md`). So we
609
- // compare the CURRENTLY held `work/prds/ready/<slug>.md` blob on the arbiter against
608
+ // (`work/notes/observations/tasking-lock-does-not-stabilise-spec-content.md`). So we
609
+ // compare the CURRENTLY held `work/specs/ready/<slug>.md` blob on the arbiter against
610
610
  // the snapshot the lock TOOK (`lockedBlob`); ANY change ⇒ STALE ⇒ fail loud,
611
611
  // touch NOTHING (the lock stays held; a human re-tasks or routes to
612
612
  // needs-attention). It is the SAME content-identity check `releaseTaskingLock`
@@ -616,17 +616,17 @@ export async function performTask(
616
616
  if (stale) {
617
617
  const specRel = workItemRel('specs-ready', `${slug}.md`);
618
618
  const message =
619
- `RELEASE CONFLICT for '${slug}': the prd was edited (${specRel} ` +
619
+ `RELEASE CONFLICT for '${slug}': the spec was edited (${specRel} ` +
620
620
  `changed on ${arbiter}/main) while the tasking lock was held. The tasking is ` +
621
- `STALE — re-task from the edited prd or route it to needs-attention. ` +
621
+ `STALE — re-task from the edited spec or route it to needs-attention. ` +
622
622
  `The arbiter was NOT modified (lock still held).`;
623
623
  note(message);
624
624
  return {exitCode: 4, outcome: 'stale', slug, message};
625
625
  }
626
626
 
627
627
  // Route the OUTPUT through the SHARED integrate back-half (task
628
- // `slice-output-through-integration`): the produced backlog tasks + the prd
629
- // lifecycle move (`work/prds/ready/ -> work/prds/tasked/`, residence = tasked-ness) integrate
628
+ // `slice-output-through-integration`): the produced backlog tasks + the spec
629
+ // lifecycle move (`work/specs/ready/ -> work/specs/tasked/`, residence = tasked-ness) integrate
630
630
  // via `performIntegration` honoring `--propose` (push the work branch + open a
631
631
  // PR, NO `main` touch) / `--merge` (land on `main`). Because the integrate-time
632
632
  // args resolve ONCE in the shared core, every `do task:` arg applies here by
@@ -666,13 +666,13 @@ export async function performTask(
666
666
  // path's merge-vs-propose decision is the `integration` mode the user typed;
667
667
  // `merge` IS the auto-land mode, so a resolved `merge` is never downgraded.
668
668
  // The task gate family is `--review`/`--no-review`/`--review-model` only
669
- // (prd US #6).
669
+ // (spec US #6).
670
670
  mode: options.integration ?? 'propose',
671
671
  noPR: options.noPR,
672
672
  providerInstance: options.providerInstance,
673
673
  type: 'tasking',
674
674
  lifecycle: {
675
- // Read the PR title / commit summary from the held prd (before it moves).
675
+ // Read the PR title / commit summary from the held spec (before it moves).
676
676
  titlePath: workItemPath(cwd, 'specs-ready', slug),
677
677
  commitTag: 'tasked',
678
678
  stage: () =>
@@ -699,9 +699,9 @@ export async function performTask(
699
699
  // the review BEFORE the stage/integrate and did NOT integrate the tasks
700
700
  // (correct). The CORRECT task-path destination is the SAME needs-attention
701
701
  // route the lock release owns for the decomposition-unclear verdict: it amends
702
- // the `prd:<slug>` unified lock `active -> stuck` with the block reason (the
702
+ // the `spec:<slug>` unified lock `active -> stuck` with the block reason (the
703
703
  // tasking needs-attention surface is the stuck lock now — NO folder write; the
704
- // prd body stays in `work/prds/ready/`). So on a block we route the held prd to
704
+ // spec body stays in `work/specs/ready/`). So on a block we route the held spec to
705
705
  // needs-attention THROUGH the lock release — the set never lands.
706
706
  if (core.outcome === 'review-blocked') {
707
707
  const reason = taskGateBlockedReason(slug, core.reviewBlockReason);
@@ -729,9 +729,9 @@ export async function performTask(
729
729
  }
730
730
  if (core.outcome === 'review-unparseable') {
731
731
  // The task-set acceptance gate RAN but its verdict was UNPARSEABLE (malformed
732
- // JSON). Route the held prd to needs-attention through the SAME lock-release
732
+ // JSON). Route the held spec to needs-attention through the SAME lock-release
733
733
  // seam the block path uses (the tasking needs-attention surface is the stuck
734
- // `prd:<slug>` lock; no folder write). It is NOT a block (the gate output was
734
+ // `spec:<slug>` lock; no folder write). It is NOT a block (the gate output was
735
735
  // unreadable) — record it as the transient-infra-class re-run signal so the
736
736
  // stuck reason reads correctly; nothing landed.
737
737
  const reason =
@@ -760,8 +760,8 @@ export async function performTask(
760
760
  };
761
761
  }
762
762
  if (core.outcome === 'completed') {
763
- // The durable `prdprd-tasked` `main` move landed through the shared integrate
764
- // core (the body moved straight from `work/prds/ready/` — no transient `tasking/`
763
+ // The durable `specs/readyspecs/tasked` `main` move landed through the shared integrate
764
+ // core (the body moved straight from `work/specs/ready/` — no transient `tasking/`
765
765
  // marker). The completing commit is owned by the integrate band, NOT
766
766
  // `releaseTaskingLock`, so the unified per-item lock that `acquireTaskingLock`
767
767
  // took is released HERE (delete the ref). A
@@ -779,13 +779,13 @@ export async function performTask(
779
779
  }
780
780
 
781
781
  // HUMAN, no-lock path: the human commits on `main` directly (the runner does
782
- // not own the human's git). We report the produced tasks; moving the prd into
783
- // `work/prds/tasked/` (residence = tasked-ness) and committing is the human's to
782
+ // not own the human's git). We report the produced tasks; moving the spec into
783
+ // `work/specs/tasked/` (residence = tasked-ness) and committing is the human's to
784
784
  // do, as with the human `complete`.
785
785
  const message =
786
786
  `Tasked '${slug}' -> ${emitted.length} backlog task` +
787
787
  `${emitted.length === 1 ? '' : 's'} (human path, no lock). Inspect + commit ` +
788
- `the produced files (and move the prd into work/prds/tasked/) yourself.`;
788
+ `the produced files (and move the spec into work/specs/tasked/) yourself.`;
789
789
  note(message);
790
790
  return {
791
791
  exitCode: 0,
@@ -827,11 +827,11 @@ function releaseFailureToResult(
827
827
  * (propose pushed the work branch + opened a PR / merge landed on `main`) the
828
828
  * tasking is `tasked`. The band's FAILURE outcomes are reported on the tasking
829
829
  * contract: a `rebase-conflict` against a concurrently-advanced `main` maps to
830
- * `stale` (exit 4) — the tasking analogue of "the held prd moved under us"; a
830
+ * `stale` (exit 4) — the tasking analogue of "the held spec moved under us"; a
831
831
  * a `gate-failed` cannot occur (the tasking path passes `skipVerify`) but maps to
832
832
  * a usage error defensively. A `review-blocked` (the task-SET ACCEPTANCE GATE
833
833
  * blocked the set, task `slice-acceptance-gate`) is handled by `performTask`
834
- * BEFORE this mapper — it routes the held prd to needs-attention via
834
+ * BEFORE this mapper — it routes the held spec to needs-attention via
835
835
  * the lock release (the task-path needs-attention route) — so it never reaches
836
836
  * here; it is mapped defensively to a usage error if it ever does.
837
837
  */
@@ -852,7 +852,7 @@ function integrationToTaskResult(
852
852
  const message =
853
853
  `Tasked '${slug}' -> ${emitted.length} backlog task` +
854
854
  `${emitted.length === 1 ? '' : 's'}; the runner integrated the transition ` +
855
- `through the shared core (moved work/prds/ready/ -> work/prds/tasked/, the ` +
855
+ `through the shared core (moved work/specs/ready/ -> work/specs/tasked/, the ` +
856
856
  `tasked resting state) and ${landed}.`;
857
857
  return {exitCode: 0, outcome: 'tasked', slug, emitted, loop, message};
858
858
  }
@@ -864,7 +864,7 @@ function integrationToTaskResult(
864
864
  message:
865
865
  core.reason ??
866
866
  `Integrating the tasking of '${slug}' conflicted against the latest ` +
867
- `${slug} main — the tasking is stale; re-task from the current prd.`,
867
+ `${slug} main — the tasking is stale; re-task from the current spec.`,
868
868
  };
869
869
  }
870
870
  return {
@@ -880,9 +880,9 @@ function integrationToTaskResult(
880
880
  /**
881
881
  * ONBOARD the tasking work onto a `work/<slug>` branch cut from the freshly-
882
882
  * fetched `<arbiter>/main` (task `slice-output-through-integration`). Called
883
- * AFTER the tasking lock is held, so the branch's base HOLDS the prd in
884
- * `work/prds/ready/` (the lock no longer moves the body) — the lifecycle stage then moves
885
- * it `prd/ -> prd-tasked/` ON THIS BRANCH and the shared integrate core lands it. A
883
+ * AFTER the tasking lock is held, so the branch's base HOLDS the spec in
884
+ * `work/specs/ready/` (the lock no longer moves the body) — the lifecycle stage then moves
885
+ * it `specs/ready/ -> specs/tasked/` ON THIS BRANCH and the shared integrate core lands it. A
886
886
  * pre-existing local `work/<slug>` (a re-run) is force-recreated off fresh main.
887
887
  * The agent runs in-place on this branch (branch ≠ worktree).
888
888
  */
@@ -894,7 +894,7 @@ async function switchToWorkBranch(
894
894
  ): Promise<void> {
895
895
  // The tasking path is the parent-spec namespace (`do spec:<slug>`): the branch
896
896
  // is `work/spec-<slug>`, distinct from a same-slug task-build's `work/task-<slug>`.
897
- // MIGRATE step (prd `prd-to-spec-vocabulary-cutover-and-migration-command`):
897
+ // MIGRATE step (spec `prd-to-spec-vocabulary-cutover-and-migration-command`):
898
898
  // MINT the work-branch under the `spec` namespace token (`workBranchRef` still
899
899
  // parses the legacy `work/prd-<slug>` form, so in-flight branches keep resolving).
900
900
  const branch = workBranchRef('spec', slug);
@@ -909,8 +909,8 @@ async function switchToWorkBranch(
909
909
  /**
910
910
  * The READ-STABILITY content-identity STALE CHECK (the lock's backstop, owned at
911
911
  * the integrate seam now that the OUTPUT no longer rides the lock release): true
912
- * iff the CURRENTLY held `work/prds/ready/<slug>.md` blob on `<arbiter>/main` DIFFERS
913
- * from the snapshot the lock TOOK (`lockedBlob`, read from `work/prds/ready/<slug>.md` at
912
+ * iff the CURRENTLY held `work/specs/ready/<slug>.md` blob on `<arbiter>/main` DIFFERS
913
+ * from the snapshot the lock TOOK (`lockedBlob`, read from `work/specs/ready/<slug>.md` at
914
914
  * acquire). ANY change = a concurrent edit under the lock = the tasking is STALE.
915
915
  * Stronger than a textual rebase conflict (which a rename+edit merge can apply
916
916
  * CLEANLY). When `lockedBlob` is absent (never, in production) it reads as
@@ -932,7 +932,7 @@ async function heldSpecIsStale(
932
932
  cwd,
933
933
  env,
934
934
  );
935
- // The prd being absent (already tasked/moved) is NOT this check's concern
935
+ // The spec being absent (already tasked/moved) is NOT this check's concern
936
936
  // (the integrate's rebase/push surfaces that); only a CHANGED held blob is stale.
937
937
  if (held.status !== 0) {
938
938
  return false;
@@ -942,18 +942,18 @@ async function heldSpecIsStale(
942
942
 
943
943
  /**
944
944
  * STAGE the tasking lifecycle into the index on the `work/<slug>` branch (the
945
- * {@link performIntegration} lifecycle seam): move the held prd
946
- * `git mv work/prds/ready/<slug>.md -> work/prds/tasked/<slug>.md` (the TASKED resting
945
+ * {@link performIntegration} lifecycle seam): move the held spec
946
+ * `git mv work/specs/ready/<slug>.md -> work/specs/tasked/<slug>.md` (the TASKED resting
947
947
  * state — the build-machine `done/` analogue, the SOURCE OF TRUTH for tasked-ness),
948
948
  * and write+`git add` the produced `work/tasks/backlog/*.md` files. The band's subsequent
949
949
  * `git add -A` + atomic commit folds this AND the agent's uncommitted backlog writes
950
950
  * into ONE runner-owned commit (the agent never does git).
951
951
  *
952
- * TASK `prd-sliced-folder-step-a` (prd `slicing-coherence` US #8): the lifecycle
953
- * destination is `work/prds/tasked/` (NOT back to `work/prds/ready/`) — `prd-tasked/`
952
+ * TASK `prd-sliced-folder-step-a` (spec `slicing-coherence` US #8): the lifecycle
953
+ * destination is `work/specs/tasked/` (NOT back to `work/specs/ready/`) — `specs/tasked/`
954
954
  * residence IS tasked-ness (like `done/` for tasks, with no `done:` marker). The
955
955
  * `tasked:` frontmatter marker was removed entirely in `remove-sliced-marker-step-b`
956
- * (sequenced last): residence in `work/prds/tasked/` is now the sole signal.
956
+ * (sequenced last): residence in `work/specs/tasked/` is now the sole signal.
957
957
  */
958
958
  async function stageTaskingLifecycle(params: {
959
959
  cwd: string;
@@ -964,7 +964,7 @@ async function stageTaskingLifecycle(params: {
964
964
  * The runner-resolved destination folder (task
965
965
  * `runner-deterministic-slice-placement-policy-and-precedence`). Computed
966
966
  * ONCE in `performTask` via the shared {@link resolvePlacement} from the
967
- * prd's `originTrust:` stamp + the configured `tasksLandIn` default + the
967
+ * spec's `originTrust:` stamp + the configured `tasksLandIn` default + the
968
968
  * operator's explicit override, then passed in here — so the call site sees
969
969
  * exactly where the emitted tasks landed (the placement decision is not
970
970
  * buried in the stage closure).
@@ -992,10 +992,10 @@ async function stageTaskingLifecycle(params: {
992
992
  const spec = workItemRel('specs-ready', `${slug}.md`);
993
993
  const specTasked = workItemRel('specs-tasked', `${slug}.md`);
994
994
  // PROPAGATE the origin-trust PROVENANCE (task
995
- // `untrusted-origin-forces-build-propose`): read the held prd's `origin`/
995
+ // `untrusted-origin-forces-build-propose`): read the held spec's `origin`/
996
996
  // `originTrust` stamp BEFORE the move, so each emitted task can carry it. A
997
997
  // task's risk is its BUILD; the stamp must reach the task so the build
998
- // transition can force `propose` for untrusted-origin work. An UNSTAMPED prd (a
998
+ // transition can force `propose` for untrusted-origin work. An UNSTAMPED spec (a
999
999
  // human/local-authored one ⇒ trusted) propagates nothing — the normal path is
1000
1000
  // untouched.
1001
1001
  const specAbs = join(cwd, spec);
@@ -1004,19 +1004,19 @@ async function stageTaskingLifecycle(params: {
1004
1004
  : {origin: undefined, originTrust: undefined};
1005
1005
  if (placementReason === 'untrusted-origin') {
1006
1006
  note(
1007
- `Untrusted-origin prd '${slug}': forcing the emitted tasks STAGED ` +
1007
+ `Untrusted-origin spec '${slug}': forcing the emitted tasks STAGED ` +
1008
1008
  `(${placementDir}/) regardless of tasksLandIn (a human promotes ` +
1009
1009
  'them into work/tasks/ready/). Pass --tasks-land-in <where> to override.',
1010
1010
  );
1011
1011
  }
1012
- // Move the held prd prd/ -> prd-tasked/ (the TASKED resting state — folder =
1013
- // source of truth, like done/ for tasks). This is the DURABLE `prdprd-tasked`
1012
+ // Move the held spec specs/ready/ -> specs/tasked/ (the TASKED resting state — folder =
1013
+ // source of truth, like done/ for tasks). This is the DURABLE `specs/readyspecs/tasked`
1014
1014
  // success move, owned by THIS transition's commit (the lock no longer moved the
1015
- // body, so the source is `work/prds/ready/`, never `work/tasking/`).
1015
+ // body, so the source is `work/specs/ready/`, never `work/tasking/`).
1016
1016
  mkdirSync(dirname(join(cwd, specTasked)), {recursive: true});
1017
1017
  await gitHard(['mv', spec, specTasked], cwd, env);
1018
1018
  await gitHard(['add', '--', specTasked], cwd, env);
1019
- // **POOL-PLACEMENT FENCE (prd US #4 / governing ADR
1019
+ // **POOL-PLACEMENT FENCE (spec US #4 / governing ADR
1020
1020
  // `placement-is-runner-deterministic-humanonly-is-agent-judgement`).** The
1021
1021
  // agent ALWAYS writes to the STAGING folder (`work/tasks/backlog/`); the POOL
1022
1022
  // (`work/tasks/ready/`) is the agent-eligible pool the runner owns the promotion
@@ -1054,7 +1054,7 @@ async function stageTaskingLifecycle(params: {
1054
1054
  * Revert any change/addition the agent made to the POOL `work/tasks/ready/` during a
1055
1055
  * tasking run. The agent's STAGING folder is `work/tasks/backlog/`; a write to the
1056
1056
  * pool is an attempt to self-place into the agent-eligible pool the runner owns
1057
- * the promotion into (prd US #4 / governing ADR). Compared to the `poolBefore`
1057
+ * the promotion into (spec US #4 / governing ADR). Compared to the `poolBefore`
1058
1058
  * snapshot (the branch-base state of `work/tasks/ready/`, taken BEFORE the agent
1059
1059
  * ran), any new file is removed from the worktree and any changed file is
1060
1060
  * checked back out to HEAD — so the subsequent `git add -A` cannot land it. The
@@ -1122,7 +1122,7 @@ async function gitHard(
1122
1122
  /**
1123
1123
  * Build the needs-attention REASON for a task-SET ACCEPTANCE GATE block (task
1124
1124
  * `slice-acceptance-gate`): the fresh-context review of the produced set returned
1125
- * `block`, so the prd is routed to `work/needs-attention/` with the review's
1125
+ * `block`, so the spec is routed to `work/needs-attention/` with the review's
1126
1126
  * blocking findings as the body prose and NO tasks landed. Takes the core's
1127
1127
  * structured `reviewBlockReason` (the gate's blocking findings); falls back to a
1128
1128
  * generic line when absent. DISTINCT from the improver loop's
@@ -1134,20 +1134,20 @@ function taskGateBlockedReason(
1134
1134
  ): string {
1135
1135
  const head =
1136
1136
  `The task acceptance gate (fresh-context review of the produced SET) blocked ` +
1137
- `'${slug}'. The prd is routed to needs-attention with no tasks landed; a human ` +
1137
+ `'${slug}'. The spec is routed to needs-attention with no tasks landed; a human ` +
1138
1138
  `must resolve the blocking findings, then re-task.`;
1139
1139
  return findingsReason ? `${head}\n\n${findingsReason}` : head;
1140
1140
  }
1141
1141
 
1142
1142
  /**
1143
1143
  * Build the needs-attention REASON for a decomposition-unclear loop verdict (the
1144
- * prd is routed to `work/needs-attention/` with these open questions, no guessed
1145
- * tasks). Prose only — recorded as the prd's needs-attention body block.
1144
+ * spec is routed to `work/needs-attention/` with these open questions, no guessed
1145
+ * tasks). Prose only — recorded as the spec's needs-attention body block.
1146
1146
  */
1147
1147
  function decompositionUnclearReason(slug: string, questions: string[]): string {
1148
1148
  const head =
1149
1149
  `The tasker review→edit loop could not converge on a sound decomposition of ` +
1150
- `'${slug}' (--tasker-loop-max exhausted with unresolved blockers). The prd is routed ` +
1150
+ `'${slug}' (--tasker-loop-max exhausted with unresolved blockers). The spec is routed ` +
1151
1151
  `to needs-attention with no guessed tasks; a human must resolve:`;
1152
1152
  const body =
1153
1153
  questions.length > 0
@@ -1209,8 +1209,8 @@ function appendQuestionsBlock(content: string, questions: string[]): string {
1209
1209
  /**
1210
1210
  * Resolve the AGENT tasking gate for `slug`: the pure predicate
1211
1211
  * (`needsAnswers !== true && humanOnly !== true && autoTask`) plus the
1212
- * cross-prd `taskedAfter` ordering, resolved against `work/prds/tasked/` residence of
1213
- * the prds present in the checkout.
1212
+ * cross-spec `taskedAfter` ordering, resolved against `work/specs/tasked/` residence of
1213
+ * the specs present in the checkout.
1214
1214
  */
1215
1215
  function resolveAgentGate(
1216
1216
  cwd: string,
@@ -1229,7 +1229,7 @@ function resolveAgentGate(
1229
1229
  });
1230
1230
  }
1231
1231
 
1232
- /** Build an HONEST gate-refusal message naming WHY the agent skipped the prd. */
1232
+ /** Build an HONEST gate-refusal message naming WHY the agent skipped the spec. */
1233
1233
  function gateRefusalReason(
1234
1234
  slug: string,
1235
1235
  specFm: {humanOnly?: boolean; needsAnswers?: boolean},
@@ -1238,15 +1238,15 @@ function gateRefusalReason(
1238
1238
  ): string {
1239
1239
  const reasons: string[] = [];
1240
1240
  if (specFm.humanOnly === true) {
1241
- reasons.push('the prd is humanOnly (a human must drive its tasking)');
1241
+ reasons.push('the spec is humanOnly (a human must drive its tasking)');
1242
1242
  }
1243
1243
  if (specFm.needsAnswers === true) {
1244
1244
  reasons.push(
1245
- 'the prd has needsAnswers (open questions block auto-tasking)',
1245
+ 'the spec has needsAnswers (open questions block auto-tasking)',
1246
1246
  );
1247
1247
  }
1248
1248
  // The autoTask POLICY only refuses on the NON-explicit (auto-pick pool) path:
1249
- // an explicitly-named `do prd:<slug>` is authorized by the naming itself (the
1249
+ // an explicitly-named `do spec:<slug>` is authorized by the naming itself (the
1250
1250
  // build path's autoBuild precedent), so the policy is never the reason there.
1251
1251
  if (
1252
1252
  options.explicit !== true &&
@@ -1258,7 +1258,7 @@ function gateRefusalReason(
1258
1258
  }
1259
1259
  if (!eligibility.taskedAfter.satisfied) {
1260
1260
  reasons.push(
1261
- `taskedAfter prd(s) not yet tasked: ${eligibility.taskedAfter.missing.join(', ')}`,
1261
+ `taskedAfter spec(s) not yet tasked: ${eligibility.taskedAfter.missing.join(', ')}`,
1262
1262
  );
1263
1263
  }
1264
1264
  const why =
@@ -1267,12 +1267,12 @@ function gateRefusalReason(
1267
1267
  }
1268
1268
 
1269
1269
  /**
1270
- * Read the set of slugs whose prds are already TASKED in this checkout — RESIDENCE
1271
- * in `work/prds/tasked/` (the tasked resting state, task `prd-sliced-folder-step-a`
1272
- * / prd `slicing-coherence` US #9), the build-machine `done/` analogue. The FOLDER
1270
+ * Read the set of slugs whose specs are already TASKED in this checkout — RESIDENCE
1271
+ * in `work/specs/tasked/` (the tasked resting state, task `prd-sliced-folder-step-a`
1272
+ * / spec `slicing-coherence` US #9), the build-machine `done/` analogue. The FOLDER
1273
1273
  * is the source of truth; the `tasked:` frontmatter marker was removed entirely in
1274
1274
  * `remove-sliced-marker-step-b` and is NOT consulted. So `taskedAfter` resolves
1275
- * against `prd-tasked/` residence
1275
+ * against `specs/tasked/` residence
1276
1276
  * (mirroring `blockedBy` -> `done/`). A missing folder reads as empty. The slug is
1277
1277
  * read from each file's frontmatter `slug:`, falling back to the filename — the same
1278
1278
  * shape the task readers use.
@@ -1291,7 +1291,7 @@ function readTaskedSlugs(cwd: string): Set<string> {
1291
1291
  /**
1292
1292
  * Build the tasking PROMPT: instruct a fresh-context agent to apply the
1293
1293
  * **tasking discipline** (`work/protocol/TASKING-PROTOCOL.md`) to the held
1294
- * prd at `work/prds/ready/<slug>.md` and to EMIT tracer-bullet vertical
1294
+ * spec at `work/specs/ready/<slug>.md` and to EMIT tracer-bullet vertical
1295
1295
  * tasks under `work/tasks/backlog/`. The discipline body (the tracer-bullet
1296
1296
  * rules, the two-axis gate guidance, the confidence check, file-orthogonality,
1297
1297
  * the emitted task shape) lives in `TASKING-PROTOCOL.md` — NOT inlined here
@@ -1300,24 +1300,26 @@ function readTaskedSlugs(cwd: string): Set<string> {
1300
1300
  * task-template.md`); the doc DESCRIBES it (D2).
1301
1301
  *
1302
1302
  * This builder owns ONLY the PER-BUILDER framing: who you are (a fresh-context
1303
- * tasker for ONE prd), where the held prd is, where the emitted task files
1303
+ * tasker for ONE spec), where the held spec is, where the emitted task files
1304
1304
  * MUST land (the staging folder, never the pool), and the runner-owns-git
1305
1305
  * boundary on the agent path. The shared discipline body is NOT duplicated
1306
1306
  * here.
1307
1307
  */
1308
1308
  function buildTaskingSpec(slug: string, _spec: string | undefined): string {
1309
+ const specReady = workFolderRel('specs-ready');
1310
+ const specTasked = workFolderRel('specs-tasked');
1309
1311
  return [
1310
- `You are a FRESH-CONTEXT tasker for the prd \`work/prds/ready/${slug}.md\`.`,
1312
+ `You are a FRESH-CONTEXT tasker for the spec \`${specReady}/${slug}.md\`.`,
1311
1313
  `Apply the tasking discipline defined in \`work/protocol/TASKING-PROTOCOL.md\``,
1312
1314
  `(the in-band, protocol-native tasking protocol every set-up repo carries; the`,
1313
- `human-facing pointer is \`skills/to-task/SKILL.md\`) to this ONE prd:`,
1315
+ `human-facing pointer is \`skills/to-task/SKILL.md\`) to this ONE spec:`,
1314
1316
  `decompose it into independently-grabbable, tracer-bullet vertical tasks.`,
1315
- `Read the prd fully first.`,
1317
+ `Read the spec fully first.`,
1316
1318
  ``,
1317
1319
  `The discipline rules — the tracer-bullet test, the two-axis gate guidance`,
1318
1320
  `(\`humanOnly\` is NARROW; \`needsAnswers\` flags genuine uncertainty), the`,
1319
1321
  `confidence check that REPLACES the human-quiz step when no human is present,`,
1320
- `the file-orthogonality preference, the prd-vs-task gate disjointness, and`,
1322
+ `the file-orthogonality preference, the spec-vs-task gate disjointness, and`,
1321
1323
  `the emitted task shape — ALL live in that doc. Read them there.`,
1322
1324
  ``,
1323
1325
  `No human is present, so apply the CONFIDENCE CHECK (\`TASKING-PROTOCOL.md\``,
@@ -1325,7 +1327,7 @@ function buildTaskingSpec(slug: string, _spec: string | undefined): string {
1325
1327
  `granularity, dependency order, a gate, or a seam is genuinely unresolved, set`,
1326
1328
  `\`needsAnswers: true\` on the specific uncertain task (questions in its body)`,
1327
1329
  `rather than guessing — or, if the whole decomposition is unclear, stop and`,
1328
- `route the prd to needs-attention with the questions.`,
1330
+ `route the spec to needs-attention with the questions.`,
1329
1331
  ``,
1330
1332
  `WRITE EVERY emitted task file under \`${STAGED_TASKS_DIR}/\` (the STAGING folder)`,
1331
1333
  `— NEVER \`work/tasks/ready/\`. \`work/tasks/ready/\` is the agent-eligible POOL and`,
@@ -1333,12 +1335,12 @@ function buildTaskingSpec(slug: string, _spec: string | undefined): string {
1333
1335
  `folder is \`work/tasks/backlog/\`. A write outside the staging folder is dropped`,
1334
1336
  `by the runner-deterministic placement resolver.`,
1335
1337
  ``,
1336
- `Set each task's \`prd:\` field to the source prd slug (\`${slug}\`) so the`,
1337
- `link back to the prd survives.`,
1338
+ `Set each task's \`spec:\` field to the source spec slug (\`${slug}\`) so the`,
1339
+ `link back to the spec survives.`,
1338
1340
  ``,
1339
1341
  `Do NOT perform any git operations — do not stage, commit, push, or move any`,
1340
1342
  `files. The RUNNER owns every git-state transition (it commits the produced`,
1341
- `tasks, releases the tasking lock, and moves the prd into \`work/prds/tasked/\`).`,
1343
+ `tasks, releases the tasking lock, and moves the spec into \`${specTasked}/\`).`,
1342
1344
  ].join('\n');
1343
1345
  }
1344
1346