dorfl 0.1.0 → 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 (324) 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 +83 -77
  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 +22 -22
  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 +33 -39
  80. package/dist/frontmatter.d.ts.map +1 -1
  81. package/dist/frontmatter.js +18 -31
  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/prd-to-spec.d.ts +15 -1
  156. package/dist/prd-to-spec.d.ts.map +1 -1
  157. package/dist/prd-to-spec.js +36 -14
  158. package/dist/prd-to-spec.js.map +1 -1
  159. package/dist/prompt.d.ts +24 -24
  160. package/dist/prompt.d.ts.map +1 -1
  161. package/dist/prompt.js +29 -31
  162. package/dist/prompt.js.map +1 -1
  163. package/dist/protocol/CLAIM-PROTOCOL.md +4 -4
  164. package/dist/protocol/REVIEW-PROTOCOL.md +1 -1
  165. package/dist/protocol/TASKING-PROTOCOL.md +12 -12
  166. package/dist/protocol/WORK-CONTRACT.md +39 -39
  167. package/dist/protocol/spec-template.md +1 -1
  168. package/dist/protocol/task-template.md +3 -3
  169. package/dist/readiness.d.ts +1 -1
  170. package/dist/recover-isolated.js +1 -1
  171. package/dist/repo-config.js +12 -12
  172. package/dist/repo-config.js.map +1 -1
  173. package/dist/review-gate.d.ts +3 -3
  174. package/dist/review-gate.d.ts.map +1 -1
  175. package/dist/review-gate.js +11 -10
  176. package/dist/review-gate.js.map +1 -1
  177. package/dist/review-verdict.d.ts +2 -2
  178. package/dist/review-verdict.d.ts.map +1 -1
  179. package/dist/review-verdict.js +1 -1
  180. package/dist/run.d.ts +1 -1
  181. package/dist/run.js +5 -5
  182. package/dist/run.js.map +1 -1
  183. package/dist/scan.d.ts +10 -10
  184. package/dist/scan.d.ts.map +1 -1
  185. package/dist/scan.js +8 -8
  186. package/dist/scan.js.map +1 -1
  187. package/dist/select-order.d.ts +1 -1
  188. package/dist/select-priority.d.ts +12 -12
  189. package/dist/select-priority.d.ts.map +1 -1
  190. package/dist/select-priority.js +5 -5
  191. package/dist/select-priority.js.map +1 -1
  192. package/dist/sidecar.d.ts +2 -2
  193. package/dist/sidecar.js +2 -2
  194. package/dist/sidecar.js.map +1 -1
  195. package/dist/slug-namespace.d.ts +1 -1
  196. package/dist/slug-namespace.js +3 -3
  197. package/dist/slug-namespace.js.map +1 -1
  198. package/dist/spec-complete.js +2 -2
  199. package/dist/spec-complete.js.map +1 -1
  200. package/dist/start.d.ts +1 -1
  201. package/dist/start.js +3 -3
  202. package/dist/start.js.map +1 -1
  203. package/dist/status.d.ts +3 -3
  204. package/dist/status.js +4 -4
  205. package/dist/status.js.map +1 -1
  206. package/dist/surface-gate.d.ts +2 -2
  207. package/dist/surface-gate.d.ts.map +1 -1
  208. package/dist/surface-persist.d.ts +2 -2
  209. package/dist/surface-persist.d.ts.map +1 -1
  210. package/dist/tasker-review-loop.d.ts +8 -8
  211. package/dist/tasker-review-loop.d.ts.map +1 -1
  212. package/dist/tasker-review-loop.js +8 -8
  213. package/dist/tasker-review-loop.js.map +1 -1
  214. package/dist/tasking-eligibility.d.ts +21 -21
  215. package/dist/tasking-eligibility.d.ts.map +1 -1
  216. package/dist/tasking-eligibility.js +10 -10
  217. package/dist/tasking-lock.d.ts +8 -8
  218. package/dist/tasking-lock.d.ts.map +1 -1
  219. package/dist/tasking-lock.js +20 -21
  220. package/dist/tasking-lock.js.map +1 -1
  221. package/dist/tasking.d.ts +33 -33
  222. package/dist/tasking.d.ts.map +1 -1
  223. package/dist/tasking.js +89 -88
  224. package/dist/tasking.js.map +1 -1
  225. package/dist/triage-gate.d.ts +1 -1
  226. package/dist/triage-persist.d.ts +5 -5
  227. package/dist/triage-persist.js +15 -15
  228. package/dist/triage-persist.js.map +1 -1
  229. package/dist/verify-workflow-template.d.ts +1 -1
  230. package/dist/verify-workflow-template.js +2 -2
  231. package/dist/work-layout.d.ts +9 -7
  232. package/dist/work-layout.d.ts.map +1 -1
  233. package/dist/work-layout.js +9 -7
  234. package/dist/work-layout.js.map +1 -1
  235. package/dist/workspace.d.ts +1 -1
  236. package/package.json +1 -1
  237. package/src/advance-ci-template.ts +4 -4
  238. package/src/advance-classify.ts +5 -5
  239. package/src/advance-drivers.ts +10 -10
  240. package/src/advance-isolated.ts +3 -3
  241. package/src/advance-lifecycle-template.ts +9 -9
  242. package/src/advance-loop-driver.ts +3 -3
  243. package/src/advance-treeless-publish.ts +1 -1
  244. package/src/advance.ts +30 -30
  245. package/src/advancing-lock.ts +6 -6
  246. package/src/apply-decide.ts +2 -2
  247. package/src/apply-merge-action.ts +5 -5
  248. package/src/apply-persist.ts +8 -8
  249. package/src/buildable-body.ts +14 -14
  250. package/src/claim-cas.ts +4 -4
  251. package/src/cli.ts +94 -84
  252. package/src/close-job-template.ts +8 -8
  253. package/src/close-job.ts +26 -26
  254. package/src/complete.ts +11 -11
  255. package/src/concurrency.ts +1 -1
  256. package/src/config.ts +37 -37
  257. package/src/continue-branch.ts +1 -1
  258. package/src/cwd-section.ts +1 -1
  259. package/src/decision-engine.ts +3 -3
  260. package/src/do-autopick.ts +9 -9
  261. package/src/do-config.ts +6 -6
  262. package/src/do-remote-auto.ts +2 -2
  263. package/src/do.ts +49 -49
  264. package/src/drop-source.ts +2 -2
  265. package/src/env-config.ts +8 -8
  266. package/src/format.ts +3 -3
  267. package/src/frontmatter.ts +42 -60
  268. package/src/install-ci-branch-protection.ts +1 -1
  269. package/src/install-ci-capabilities/advance-lifecycle.ts +1 -1
  270. package/src/install-ci-capabilities/close-job.ts +1 -1
  271. package/src/install-ci-capabilities/example-noop.ts +1 -1
  272. package/src/install-ci-capabilities/intake.ts +2 -2
  273. package/src/install-ci-capabilities/verify.ts +1 -1
  274. package/src/install-ci-core.ts +4 -4
  275. package/src/install-ci-github.ts +1 -1
  276. package/src/install-ci.ts +4 -4
  277. package/src/intake-event.ts +6 -6
  278. package/src/intake-marker.ts +3 -3
  279. package/src/intake-triage.ts +2 -2
  280. package/src/intake-trigger-template.ts +17 -17
  281. package/src/intake.ts +97 -97
  282. package/src/integration-core.ts +35 -35
  283. package/src/isolation.ts +3 -3
  284. package/src/issue-provider.ts +4 -4
  285. package/src/item-lock.ts +21 -21
  286. package/src/item-path.ts +2 -2
  287. package/src/ledger-lint.ts +9 -9
  288. package/src/ledger-read.ts +81 -81
  289. package/src/ledger-write.ts +3 -3
  290. package/src/lifecycle-gather.ts +16 -16
  291. package/src/lifecycle-pools.ts +4 -4
  292. package/src/merge-question-surfacer.ts +4 -4
  293. package/src/mint-adr.ts +4 -4
  294. package/src/mirror-pool-scan.ts +5 -5
  295. package/src/needs-attention.ts +22 -22
  296. package/src/orphan-sidecar.ts +2 -2
  297. package/src/placement.ts +6 -6
  298. package/src/prd-to-spec.ts +51 -15
  299. package/src/prompt.ts +33 -35
  300. package/src/readiness.ts +1 -1
  301. package/src/recover-isolated.ts +1 -1
  302. package/src/repo-config.ts +12 -12
  303. package/src/review-gate.ts +12 -11
  304. package/src/review-verdict.ts +2 -2
  305. package/src/run.ts +6 -6
  306. package/src/scan.ts +15 -15
  307. package/src/select-order.ts +1 -1
  308. package/src/select-priority.ts +13 -13
  309. package/src/sidecar.ts +3 -3
  310. package/src/slug-namespace.ts +3 -3
  311. package/src/spec-complete.ts +2 -2
  312. package/src/start.ts +4 -4
  313. package/src/status.ts +7 -7
  314. package/src/surface-gate.ts +2 -2
  315. package/src/surface-persist.ts +2 -2
  316. package/src/tasker-review-loop.ts +15 -15
  317. package/src/tasking-eligibility.ts +21 -21
  318. package/src/tasking-lock.ts +27 -28
  319. package/src/tasking.ts +124 -123
  320. package/src/triage-gate.ts +1 -1
  321. package/src/triage-persist.ts +16 -16
  322. package/src/verify-workflow-template.ts +2 -2
  323. package/src/work-layout.ts +9 -7
  324. package/src/workspace.ts +1 -1
package/src/intake.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import {existsSync, mkdirSync, readFileSync, writeFileSync} from 'node:fs';
2
2
  import {dirname, join} from 'node:path';
3
3
  import {runAsync, type RunResult} from './git.js';
4
- import {workFolderRel, workItemRel} from './work-layout.js';
4
+ import {workFolderRel, workFolderPrefix, workItemRel} from './work-layout.js';
5
5
  import {paramCase} from './brand.js';
6
6
  import {
7
7
  performIntegration,
@@ -48,7 +48,7 @@ import {triageIntake, type IntakeTriageDecision} from './intake-triage.js';
48
48
  import {renderTaskBody, renderSpecBody} from './buildable-body.js';
49
49
 
50
50
  /**
51
- * **`intake <N>`** (prd `issue-intake`, task `intake-tracer-slice-outcome`): the
51
+ * **`intake <N>`** (spec `issue-intake`, task `intake-tracer-slice-outcome`): the
52
52
  * KEYSTONE of the issue front-door. A new, GATE-FREE command — explicit invocation
53
53
  * IS the authorization (precedent: `explicit-do-prd-not-gated-by-autoslice`), so
54
54
  * `autoTask`/`autoBuild` config does NOT apply — that reads a GitHub issue + its
@@ -62,24 +62,24 @@ import {renderTaskBody, renderSpecBody} from './buildable-body.js';
62
62
  * prompt's JUDGEMENT is NOT unit-tested (like the review prompt's is not); only the
63
63
  * dispatch is.
64
64
  *
65
- * The dispatcher implements the FULL four-outcome decision table (prd
65
+ * The dispatcher implements the FULL four-outcome decision table (spec
66
66
  * `issue-intake` — the source of truth):
67
67
  * - **ASK** (not clear enough to act on): `postIssueComment` the next clarifying
68
68
  * question; emit NOTHING; STOP.
69
69
  * - **TASK** (clear AND fits ONE tracer-bullet task): write
70
- * `work/backlog/<slug>.md` (`covers: []`, NO `prd:`) carrying `issue: N` (the
70
+ * `work/backlog/<slug>.md` (`covers: []`, NO `spec:`) carrying `issue: N` (the
71
71
  * lone-task closure link, NOT `Fixes #N`), integrate via {@link
72
72
  * performIntegration} (default `propose`).
73
- * - **PRD** (clear AND coherent but >1 task — INCLUDING a coupled-but-SMALL pair,
74
- * which is NEVER bounced): write the prd file (`work/prds/ready/<slug>.md`) with `issue: N` (+ the gate
75
- * axes the verdict carried), integrate, STOP (tasking is the separate `do prd:`
73
+ * - **SPEC** (clear AND coherent but >1 task — INCLUDING a coupled-but-SMALL pair,
74
+ * which is NEVER bounced): write the spec file (`work/specs/ready/<slug>.md`) with `issue: N` (+ the gate
75
+ * axes the verdict carried), integrate, STOP (tasking is the separate `do spec:`
76
76
  * step).
77
77
  * - **BOUNCE** (genuinely UNRELATED concerns — no shared vision): the bounce is
78
78
  * TERMINAL (the asks are unrelated and must be re-filed), so intake CLOSES the
79
79
  * issue ATOMICALLY — the "file separate issues" text as the closing comment +
80
80
  * `reason: not planned` (the honest GitHub-native signal) in ONE `closeIssue`
81
81
  * call; emit NOTHING. Intake closes on BOUNCE (as not planned); NEVER on
82
- * task/prd (CI's close-job closes those via the `issue:` field) / ask.
82
+ * task/spec (CI's close-job closes those via the `issue:` field) / ask.
83
83
  *
84
84
  * The per-outcome integration KNOBS, the processing LOCK, and event-classification
85
85
  * are LATER tasks and are NOT built here (default `propose` is fine here).
@@ -92,7 +92,7 @@ import {renderTaskBody, renderSpecBody} from './buildable-body.js';
92
92
 
93
93
  /**
94
94
  * The four outcomes the decision prompt classifies an issue into (the decision
95
- * table). EXPAND step (prd
95
+ * table). EXPAND step (spec
96
96
  * `prd-to-spec-vocabulary-cutover-and-migration-command`): the `spec` outcome
97
97
  * names the "clear + coherent but >1 task" classification (a parent SPEC). HARD
98
98
  * CUTOVER (contract step): the legacy `prd` outcome token is GONE — the prompt
@@ -122,7 +122,7 @@ export interface IntakeVerdict {
122
122
  /**
123
123
  * The drafted task BODY (`task` outcome) — the markdown AFTER the frontmatter
124
124
  * (the `## What to build` / `## Acceptance criteria` / `## Prompt` sections). The
125
- * dispatcher writes the frontmatter (slug/title/`covers: []`, NO `prd:`) carrying
125
+ * dispatcher writes the frontmatter (slug/title/`covers: []`, NO `spec:`) carrying
126
126
  * the lone-task `issue: N` closure link itself; the agent never writes
127
127
  * git-visible files.
128
128
  */
@@ -151,7 +151,7 @@ export interface IntakeVerdict {
151
151
  specBody?: string;
152
152
  /**
153
153
  * The spec's gate axes (`spec` outcome) AS THE PROMPT JUDGED THEM — surfaced onto
154
- * the emitted spec frontmatter (prd `issue-intake` US #8: "the emitted artifact
154
+ * the emitted spec frontmatter (spec `issue-intake` US #8: "the emitted artifact
155
155
  * carries … its own gate axes"). Both omitted (undeclared) by default; the prompt
156
156
  * sets `specHumanOnly: true` when a human should drive the TASKING and/or
157
157
  * `specNeedsAnswers: true` when open questions remain.
@@ -186,16 +186,16 @@ export interface IntakeResult {
186
186
  outcome: IntakeRunOutcome;
187
187
  /** The issue number acted on. */
188
188
  issueNumber: number;
189
- /** The slug of the emitted artifact (task OR prd outcome). */
189
+ /** The slug of the emitted artifact (task OR spec outcome). */
190
190
  emittedSlug?: string;
191
- /** Repo-relative path of the emitted artifact (task OR prd outcome). */
191
+ /** Repo-relative path of the emitted artifact (task OR spec outcome). */
192
192
  emitted?: string;
193
193
  /** True iff a comment was posted on the issue (ask / bounce outcomes). */
194
194
  commented?: boolean;
195
195
  /**
196
196
  * True iff the ISSUE was closed (the BOUNCE outcome — a terminal bounce closes
197
197
  * the issue atomically as `not planned`). Additive (mirrors {@link commented}),
198
- * so CI / callers can observe the close. Never set on ask/task/prd.
198
+ * so CI / callers can observe the close. Never set on ask/task/spec.
199
199
  */
200
200
  closed?: boolean;
201
201
  /** Human-readable summary of the terminal condition. */
@@ -253,10 +253,10 @@ export interface PerformIntakeOptions {
253
253
  /** The HOST-ONLY sessions root for the pi session file. */
254
254
  sessionsDir?: string;
255
255
  /**
256
- * The PER-OUTCOME integration modes (prd `issue-intake` US #9) the emitted artifact integrates
256
+ * The PER-OUTCOME integration modes (spec `issue-intake` US #9) the emitted artifact integrates
257
257
  * THROUGH the shared core with. Because `intake` decides the artifact TYPE at
258
258
  * RUNTIME, the mode is keyed per type: an emitted task integrates with
259
- * `integration.task`, an emitted prd with `integration.prd` (`propose` =
259
+ * `integration.task`, an emitted spec with `integration.prd` (`propose` =
260
260
  * push the `work/<slug>` branch + open a PR, NO `main` touch; `merge` = land on
261
261
  * `main`). The CLI resolves this from the granular + aggregate flags via
262
262
  * {@link resolveIntakeIntegrationModes}; ask/bounce emit nothing, so the modes
@@ -266,7 +266,7 @@ export interface PerformIntakeOptions {
266
266
  /**
267
267
  * **The ORIGIN-TRUST verdict, passed IN** (task
268
268
  * `untrusted-origin-forces-build-propose`; the `--origin-trust <trusted|untrusted>`
269
- * CLI flag). `intake` STAMPS `origin: issue` + this `originTrust` onto every prd/
269
+ * CLI flag). `intake` STAMPS `origin: issue` + this `originTrust` onto every spec/
270
270
  * task it emits, so the author-trust signal SURVIVES the prd/task merge
271
271
  * boundary (a landed-on-main artifact otherwise erases how it was born, the
272
272
  * laundering gap). `intake` does NOT resolve trust itself: the verdict is CI's
@@ -285,7 +285,7 @@ export interface PerformIntakeOptions {
285
285
  */
286
286
  noPR?: boolean;
287
287
  /**
288
- * **The per-repo PRD-PLACEMENT default, passed IN** (prd
288
+ * **The per-repo SPEC-PLACEMENT default, passed IN** (spec
289
289
  * `staging-pool-position-gate-and-trust-model` US #2/#5, task
290
290
  * `pre-prd-staging-pool-split-and-untrusted-prd-placement`). The resolved
291
291
  * per-repo default landing for `intake`-authored prds (`pre-proposed` =
@@ -293,8 +293,8 @@ export interface PerformIntakeOptions {
293
293
  * into the shared placement resolver (`src/placement.ts`). The resolver
294
294
  * overlays an EXPLICIT operator flag ({@link explicitSpecsLandIn}, top) and
295
295
  * the UNTRUSTED-ORIGIN force (`originTrust: untrusted` ⇒ staging) on top.
296
- * Unset ⇒ the resolver's built-in floor applies (`staging` = `prds/proposed/`,
297
- * the conservative landing). The PRD TWIN of `tasksLandIn` on the tasker
296
+ * Unset ⇒ the resolver's built-in floor applies (`staging` = `specs/proposed/`,
297
+ * the conservative landing). The SPEC TWIN of `tasksLandIn` on the tasker
298
298
  * path — one resolver, two lifecycles.
299
299
  */
300
300
  specsLandIn?: SpecsLandIn;
@@ -334,15 +334,15 @@ export interface PerformIntakeOptions {
334
334
  const DEFAULT_ARBITER = 'origin';
335
335
 
336
336
  /**
337
- * **The STAGED-prds dir** (prd `staging-pool-position-gate-and-trust-model`,
337
+ * **The STAGED-prds dir** (spec `staging-pool-position-gate-and-trust-model`,
338
338
  * task `pre-prd-staging-pool-split-and-untrusted-prd-placement`, governing
339
339
  * ADR `placement-is-runner-deterministic-humanonly-is-agent-judgement`). When
340
340
  * the runner-deterministic placement resolver picks the staging side for an
341
- * `intake`-authored prd, the runner writes the prd file HERE instead of in
342
- * `work/prds/ready/`. An item born in `prds/proposed/` is durable + readable but NOT in
343
- * the tasking candidate POOL (`work/prds/ready/` is the pool). A runner/human-owned promotion
344
- * ({@link promoteFromPreSpec} in `needs-attention.ts`) moves an approved prd
345
- * `prds/proposed/ → prds/ready/` to make it taskable.
341
+ * `intake`-authored spec, the runner writes the spec file HERE instead of in
342
+ * `work/specs/ready/`. An item born in `specs/proposed/` is durable + readable but NOT in
343
+ * the tasking candidate POOL (`work/specs/ready/` is the pool). A runner/human-owned promotion
344
+ * ({@link promoteFromPreSpec} in `needs-attention.ts`) moves an approved spec
345
+ * `specs/proposed/ → specs/ready/` to make it taskable.
346
346
  */
347
347
  export const STAGED_SPECS_DIR = workFolderRel('specs-proposed');
348
348
 
@@ -377,19 +377,19 @@ function specLandingToSide(
377
377
 
378
378
  /**
379
379
  * The emitted artifact TYPE `intake` decides at RUNTIME — a `task` verdict emits
380
- * `work/backlog/<slug>.md`, a `prd` verdict emits the prd file (`work/prds/ready/<slug>.md`). The two
380
+ * `work/backlog/<slug>.md`, a `prd` verdict emits the spec file (`work/specs/ready/<slug>.md`). The two
381
381
  * granular flag axes (`--merge-task`/`--propose-task` vs `--merge-spec`/
382
382
  * `--propose-spec`) are keyed on this. (ask/bounce emit NOTHING, so the modes are
383
383
  * no-ops for them.)
384
384
  */
385
385
  export type IntakeArtifactType = 'task' | 'spec';
386
- // prd → spec cutover (MIGRATE batch): `'spec'` is the CANONICAL artifact type;
387
- // `'prd'` stays as an accepted ALIAS until the contract task removes it.
386
+ // `prd``spec` HARD CUTOVER: `'spec'` is the ONLY spec artifact type value; the
387
+ // legacy `'prd'` alias is GONE (the contract task removed it).
388
388
 
389
389
  /**
390
- * The PER-OUTCOME integration mode FLAG SET (prd `issue-intake` US #9). Because
390
+ * The PER-OUTCOME integration mode FLAG SET (spec `issue-intake` US #9). Because
391
391
  * `intake` decides the artifact TYPE at runtime, a single `--merge`/`--propose`
392
- * cannot express a type-conditional policy ("merge a prd but propose a task") —
392
+ * cannot express a type-conditional policy ("merge a spec but propose a task") —
393
393
  * hence the four GRANULAR per-type flags layered over the two AGGREGATES:
394
394
  *
395
395
  * - **granular:** `--merge-spec`/`--propose-spec` apply iff the outcome is a spec;
@@ -400,9 +400,9 @@ export type IntakeArtifactType = 'task' | 'spec';
400
400
  * author-trust) is CI's POLICY, authored in `runner-in-ci` — NOT here.
401
401
  */
402
402
  export interface IntakeIntegrationFlags {
403
- /** Aggregate: merge BOTH a task and a prd (the broad knob, overridden per type). */
403
+ /** Aggregate: merge BOTH a task and a spec (the broad knob, overridden per type). */
404
404
  merge?: boolean;
405
- /** Aggregate: propose BOTH a task and a prd. */
405
+ /** Aggregate: propose BOTH a task and a spec. */
406
406
  propose?: boolean;
407
407
  /** Granular: merge a spec (overrides the aggregate for the spec outcome). */
408
408
  mergeSpec?: boolean;
@@ -419,7 +419,7 @@ export interface IntakeIntegrationModes {
419
419
  /** The mode an EMITTED task integrates with. */
420
420
  task: IntegrationMode;
421
421
  /**
422
- * The mode an EMITTED spec integrates with. `spec` is the CANONICAL key (prd
422
+ * The mode an EMITTED spec integrates with. `spec` is the CANONICAL key (spec
423
423
  * spec cutover); the user-facing `--merge-spec`/`--propose-spec` flags that FEED
424
424
  * it carry the same `spec` spelling (the cli-flag rename landed in batch 4f).
425
425
  */
@@ -453,10 +453,10 @@ function granularFromFlags(
453
453
  }
454
454
 
455
455
  /**
456
- * The PURE per-outcome integration mode resolution (prd `issue-intake` US #9 —
456
+ * The PURE per-outcome integration mode resolution (spec `issue-intake` US #9 —
457
457
  * the canonical table). Given ONLY the flag set, resolve BOTH per-type modes in
458
458
  * one eager pass (so a usage error is caught before the runtime verdict is even
459
- * known). The rules, all decided in the prd:
459
+ * known). The rules, all decided in the spec:
460
460
  *
461
461
  * - **unset ⇒ propose for BOTH** (conservative default; matches `do`).
462
462
  * - **aggregates:** `--merge` ⇒ merge both; `--propose` ⇒ propose both (this axis
@@ -574,7 +574,7 @@ export async function performIntake(
574
574
  return {exitCode: 1, outcome: 'usage-error', issueNumber, message};
575
575
  }
576
576
 
577
- // 2. ACQUIRE the `processing` LOCK (prd `issue-intake` US #10): a TRANSIENT concurrency mutex
577
+ // 2. ACQUIRE the `processing` LOCK (spec `issue-intake` US #10): a TRANSIENT concurrency mutex
578
578
  // that serialises two concurrent runs on the SAME issue. Read the labels; if
579
579
  // the lock is ALREADY present, BACK OFF (do nothing — another run owns it). The
580
580
  // winner ADDS the label and proceeds; the label is REMOVED on finish (success
@@ -815,12 +815,12 @@ async function decideAndDispatch(
815
815
  return {exitCode: 1, outcome: 'agent-failed', issueNumber, message};
816
816
  }
817
817
 
818
- // DISPATCH on the verdict — the FULL four-outcome decision table (prd
818
+ // DISPATCH on the verdict — the FULL four-outcome decision table (spec
819
819
  // `issue-intake`). The agent only DRAFTED the verdict; the runner owns every
820
820
  // git/seam side-effect below (the in-band boundary): the write + integrate
821
- // (task/prd) and the `postIssueComment` (ask/bounce).
821
+ // (task/spec) and the `postIssueComment` (ask/bounce).
822
822
  //
823
- // PER-OUTCOME integration (prd `issue-intake` US #9): the resolved mode is keyed on the runtime
823
+ // PER-OUTCOME integration (spec `issue-intake` US #9): the resolved mode is keyed on the runtime
824
824
  // artifact TYPE — a `task` verdict integrates with the task mode, a `spec`
825
825
  // verdict with the spec mode. Unset ⇒ propose for both. ask/bounce never
826
826
  // integrate, so the modes are no-ops for them.
@@ -863,7 +863,7 @@ async function decideAndDispatch(
863
863
  cwd,
864
864
  arbiter,
865
865
  integration: modes.spec,
866
- // Same origin-trust stamp on the prd outcome (propagated onto its tasks
866
+ // Same origin-trust stamp on the spec outcome (propagated onto its tasks
867
867
  // later by the tasker). Passed IN; not resolved here.
868
868
  originTrust: options.originTrust,
869
869
  noPR: options.noPR,
@@ -871,7 +871,7 @@ async function decideAndDispatch(
871
871
  // `pre-prd-staging-pool-split-and-untrusted-prd-placement`): the
872
872
  // configured-default + explicit-flag rungs, fed into the SHARED placement
873
873
  // resolver alongside the `originTrust` stamp above. The resolver decides
874
- // `prds/proposed/` (staging) vs `prds/ready/` (the tasking pool); `intake` never
874
+ // `specs/proposed/` (staging) vs `specs/ready/` (the tasking pool); `intake` never
875
875
  // places itself.
876
876
  specsLandIn: options.specsLandIn,
877
877
  explicitSpecsLandIn: options.explicitSpecsLandIn,
@@ -931,7 +931,7 @@ async function decideAndDispatch(
931
931
  *
932
932
  * - **ask** (non-terminal): `postIssueComment` the drafted question, emit NOTHING,
933
933
  * and LEAVE THE ISSUE OPEN — it waits for the thread to be answered (a later run
934
- * resumes from it). The task/prd path also never closes (CI's close-job does,
934
+ * resumes from it). The task/spec path also never closes (CI's close-job does,
935
935
  * via the `issue:` field). Intake closes ONLY on BOUNCE.
936
936
  * - **bounce** (TERMINAL): the asks are unrelated and must be re-filed, so an OPEN
937
937
  * issue is a dishonest "still in play" signal. Intake CLOSES the issue
@@ -1028,7 +1028,7 @@ async function dispatchComment(params: {
1028
1028
 
1029
1029
  /**
1030
1030
  * DISPATCH the `task` outcome: derive a content-derived slug, write
1031
- * `work/backlog/<slug>.md` (`covers: []`, NO `prd:`) carrying `issue: N` (the
1031
+ * `work/backlog/<slug>.md` (`covers: []`, NO `spec:`) carrying `issue: N` (the
1032
1032
  * lone-task closure link, NOT `Fixes #N`), and integrate via {@link
1033
1033
  * performIntegration}. The runner owns the git: it onboards a
1034
1034
  * `work/<slug>` branch off fresh `<arbiter>/main`, then the lifecycle `stage`
@@ -1074,7 +1074,7 @@ async function dispatchTask(params: {
1074
1074
  note,
1075
1075
  } = params;
1076
1076
 
1077
- // A content-derived slug — NEVER a counter (prd `issue-intake` US #8). Prefer the drafted
1077
+ // A content-derived slug — NEVER a counter (spec `issue-intake` US #8). Prefer the drafted
1078
1078
  // `taskSlug`, else derive from the drafted title; sanitise either through
1079
1079
  // `paramCase` so the filename + frontmatter slug are well-formed.
1080
1080
  const slug = resolveSlug(verdict);
@@ -1089,7 +1089,7 @@ async function dispatchTask(params: {
1089
1089
 
1090
1090
  // BOUNDED INTERNAL REVIEW (observation
1091
1091
  // `intake-lone-task-skips-adversarial-review-the-prd-path-gets`, rulings A/B/C):
1092
- // the `do prd:` path gets `runTaskReviewLoop`; the lone-TASK path got NOTHING.
1092
+ // the `do spec:` path gets `runTaskReviewLoop`; the lone-TASK path got NOTHING.
1093
1093
  // AFTER the `task` verdict and BEFORE the write/integrate, run a bounded (3-round,
1094
1094
  // HARD-CAPPED) adversarial self-review on the SINGLE drafted task. It mutates the
1095
1095
  // candidate body IN MEMORY (no `work/backlog/` write pre-convergence). A launch/
@@ -1266,7 +1266,7 @@ async function dispatchSpec(params: {
1266
1266
  note,
1267
1267
  } = params;
1268
1268
 
1269
- // A content-derived slug — NEVER a counter (prd `issue-intake` US #8). Prefer the drafted
1269
+ // A content-derived slug — NEVER a counter (spec `issue-intake` US #8). Prefer the drafted
1270
1270
  // `specSlug`, else derive from the drafted title.
1271
1271
  const slug = resolveSpecSlug(verdict);
1272
1272
  if (slug === '') {
@@ -1279,7 +1279,7 @@ async function dispatchSpec(params: {
1279
1279
  // RUNNER-DETERMINISTIC PLACEMENT (task
1280
1280
  // `pre-prd-staging-pool-split-and-untrusted-prd-placement`, governing ADR
1281
1281
  // `placement-is-runner-deterministic-humanonly-is-agent-judgement`). Resolve
1282
- // which folder the runner writes the intake-authored prd into BEFORE handing
1282
+ // which folder the runner writes the intake-authored spec into BEFORE handing
1283
1283
  // it to the shared integrate band: the SAME precedence chain the tasker uses
1284
1284
  // (`explicit > untrusted-origin ⇒ staging > specsLandIn > built-in (staging)`),
1285
1285
  // the SAME shared resolver — only the lifecycle SLOTS differ. The agent
@@ -1317,7 +1317,7 @@ async function dispatchSpec(params: {
1317
1317
  slug,
1318
1318
  source: 'in-progress',
1319
1319
  recovering: false,
1320
- // An intake-emitted prd has no `verify` floor of its own (it is a new spec,
1320
+ // An intake-emitted spec has no `verify` floor of its own (it is a new spec,
1321
1321
  // not a build), exactly as the task branch + the tasking transition skip it.
1322
1322
  skipVerify: true,
1323
1323
  mode: integration,
@@ -1325,8 +1325,8 @@ async function dispatchSpec(params: {
1325
1325
  providerInstance,
1326
1326
  type: 'feat',
1327
1327
  lifecycle: {
1328
- // The emitted prd IS the title source. Pass the DRAFTED title EXPLICITLY (same
1329
- // race as the task path: `stage()` writes the prd file AFTER the title
1328
+ // The emitted spec IS the title source. Pass the DRAFTED title EXPLICITLY (same
1329
+ // race as the task path: `stage()` writes the spec file AFTER the title
1330
1330
  // read). `titlePath` stays set but is IGNORED while `title` is present.
1331
1331
  titlePath: join(cwd, relPath),
1332
1332
  title: verdict.specTitle ?? slug,
@@ -1384,9 +1384,9 @@ async function integrationToIntakeResult(
1384
1384
  core.integration?.mode === 'merge'
1385
1385
  ? 'landed it on the arbiter main'
1386
1386
  : 'opened a PR carrying it (main untouched)';
1387
- // Both a lone task and a prd carry `issue: N` as their closure link (the task
1388
- // closes its own issue; a prd is reached via `task.prd: → prd issue:`). On the
1389
- // task/prd path `intake` never closes the issue (CI's close-job does, via the
1387
+ // Both a lone task and a spec carry `issue: N` as their closure link (the task
1388
+ // closes its own issue; a spec is reached via `task.spec: → spec issue:`). On the
1389
+ // task/spec path `intake` never closes the issue (CI's close-job does, via the
1390
1390
  // `issue:` field; intake closes ONLY on BOUNCE) and emits no `Fixes #N` (a
1391
1391
  // deferred GitHub-only optimisation).
1392
1392
  const link = `issue: ${issueNumber}`;
@@ -1456,7 +1456,7 @@ async function integrationToIntakeResult(
1456
1456
  * `commit` (the additive {@link IntegrateResult.commit}) in merge. A degraded
1457
1457
  * propose (no `url`) or a failed merge-tip read (no `commit`) simply OMITS the
1458
1458
  * link — the comment still confirms what was created (the artifact is safe on the
1459
- * branch/main regardless). No prd link beyond the slug.
1459
+ * branch/main regardless). No spec link beyond the slug.
1460
1460
  * - carries the FULL intake MARKER via the SHARED {@link stampIntakeMarker} helper
1461
1461
  * (`kind=created slug=<slug> seen=<id>,…`) so the triage's `already-terminal`
1462
1462
  * branch consumes it — the comment cannot re-trigger intake.
@@ -1497,7 +1497,7 @@ export function composeIntakeCompletionComment(params: {
1497
1497
  * does, via the `issue:` field); this comment changes NO issue state.
1498
1498
  * - LINKS the artifact by INTEGRATION MODE: the PR `url` in propose, the landed
1499
1499
  * `commit` (the additive {@link IntegrateResult.commit} this task surfaces) in
1500
- * merge. No prd link beyond the slug.
1500
+ * merge. No spec link beyond the slug.
1501
1501
  * - carries the FULL intake MARKER via the SHARED {@link stampIntakeMarker} helper
1502
1502
  * (`kind=created slug=<slug> seen=<id>,…`). `kind=created` is TERMINAL, so the
1503
1503
  * triage's `already-terminal` branch then treats the issue as already-transformed
@@ -1558,7 +1558,7 @@ async function postCompletionComment(params: {
1558
1558
  }
1559
1559
 
1560
1560
  /**
1561
- * Resolve a content-derived slug from the verdict — NEVER a counter (prd `issue-intake` US #8).
1561
+ * Resolve a content-derived slug from the verdict — NEVER a counter (spec `issue-intake` US #8).
1562
1562
  * Prefer the drafted `taskSlug`, else derive from the drafted title; both go
1563
1563
  * through `paramCase` (the brand case-transform) so the result is a clean
1564
1564
  * lowercase-`-`-joined slug. An empty result (no slug AND no title) signals the
@@ -1573,7 +1573,7 @@ function resolveSlug(verdict: IntakeVerdict): string {
1573
1573
  }
1574
1574
 
1575
1575
  /**
1576
- * Resolve a content-derived slug for the spec outcome — NEVER a counter (prd `issue-intake` US #8).
1576
+ * Resolve a content-derived slug for the spec outcome — NEVER a counter (spec `issue-intake` US #8).
1577
1577
  * Prefer the drafted `specSlug`, else derive from the drafted spec title; both go
1578
1578
  * through `paramCase`. An empty result signals the caller to refuse.
1579
1579
  */
@@ -1587,13 +1587,13 @@ function resolveSpecSlug(verdict: IntakeVerdict): string {
1587
1587
 
1588
1588
  /**
1589
1589
  * Render the backlog task file: the frontmatter (`title`/`slug`/`covers: []`, NO
1590
- * `prd:` — its own source of truth, prd `issue-intake` decision table) carrying the lone-task
1590
+ * `spec:` — its own source of truth, spec `issue-intake` decision table) carrying the lone-task
1591
1591
  * `issue: N` closure link + the drafted body. The task closes its source issue
1592
1592
  * via its `issue:` field (the provider-agnostic link a FUTURE CI close-job reads
1593
1593
  * from folder + field state); it carries NO `Fixes #N` (a deferred GitHub-only
1594
1594
  * optimisation, structurally unplaceable on the `--merge` path). The number is
1595
- * the task's own closure path — `issue:` XOR `prd:`; a lone task never carries a
1596
- * `prd:` (prd `issue-intake` decision table). When the agent drafted no body, a thin default
1595
+ * the task's own closure path — `issue:` XOR `spec:`; a lone task never carries a
1596
+ * `spec:` (spec `issue-intake` decision table). When the agent drafted no body, a thin default
1597
1597
  * scaffold keeps the file a valid task.
1598
1598
  */
1599
1599
  export function renderBacklogTask(params: {
@@ -1623,7 +1623,7 @@ export function renderBacklogTask(params: {
1623
1623
  const frontmatter = lines.join('\n');
1624
1624
  // The drafted body (agent-authored, headings and all) is wrapped VERBATIM.
1625
1625
  // Only the empty-body DEFAULT SCAFFOLD is sourced from the shared section
1626
- // skeleton owner (`renderTaskBody`, prd
1626
+ // skeleton owner (`renderTaskBody`, spec
1627
1627
  // `centralize-buildable-task-renderer-shared-by-intake-and-promotion` US #2),
1628
1628
  // so intake's fallback and promotion's body cannot drift on section
1629
1629
  // names/order. The shared renderer ends its body with a trailing newline (its
@@ -1642,16 +1642,16 @@ export function renderBacklogTask(params: {
1642
1642
  }
1643
1643
 
1644
1644
  /**
1645
- * Render the emitted prd file: the frontmatter (`title`/`slug` + the loop-closure
1646
- * `issue: N` + the gate axes the prompt JUDGED) followed by the drafted prd body.
1647
- * For a FANNED prd the `issue: N` lives ONLY on the prd — never duplicated across
1648
- * the N fanned tasks, which reach it via `task.prd: → prd issue:` (a fanned
1649
- * task carries `prd:`, NOT its own `issue:`; the lone-task outcome is the only
1650
- * one that puts `issue:` on a task). The close JOB reaches the prd's number via
1651
- * `task.prd: → prd issue:`. The gate axes (`humanOnly`/`needsAnswers`) are emitted ONLY when the
1645
+ * Render the emitted spec file: the frontmatter (`title`/`slug` + the loop-closure
1646
+ * `issue: N` + the gate axes the prompt JUDGED) followed by the drafted spec body.
1647
+ * For a FANNED spec the `issue: N` lives ONLY on the spec — never duplicated across
1648
+ * the N fanned tasks, which reach it via `task.spec: → spec issue:` (a fanned
1649
+ * task carries `spec:`, NOT its own `issue:`; the lone-task outcome is the only
1650
+ * one that puts `issue:` on a task). The close JOB reaches the spec's number via
1651
+ * `task.spec: → spec issue:`. The gate axes (`humanOnly`/`needsAnswers`) are emitted ONLY when the
1652
1652
  * verdict declared them `true` — an omitted axis is `undefined` (undeclared), the
1653
1653
  * same convention `frontmatter.ts` parses. When the agent drafted no body, a thin
1654
- * default scaffold keeps the file a valid prd that `do prd:` can later task.
1654
+ * default scaffold keeps the file a valid spec that `do spec:` can later task.
1655
1655
  */
1656
1656
  export function renderSpec(params: {
1657
1657
  slug: string;
@@ -1682,7 +1682,7 @@ export function renderSpec(params: {
1682
1682
  if (originTrust !== undefined) {
1683
1683
  lines.push('origin: issue', `originTrust: ${originTrust}`);
1684
1684
  }
1685
- // Surface the gate axes AS THE PROMPT JUDGED THEM (prd `issue-intake` US #8). Only emit a `true`
1685
+ // Surface the gate axes AS THE PROMPT JUDGED THEM (spec `issue-intake` US #8). Only emit a `true`
1686
1686
  // axis — an undeclared axis stays absent (parsed as `undefined`).
1687
1687
  if (humanOnly === true) {
1688
1688
  lines.push('humanOnly: true');
@@ -1692,11 +1692,11 @@ export function renderSpec(params: {
1692
1692
  }
1693
1693
  lines.push('---');
1694
1694
  const frontmatter = lines.join('\n');
1695
- // As with `renderBacklogTask`: the drafted PRD body is wrapped VERBATIM; only
1695
+ // As with `renderBacklogTask`: the drafted SPEC body is wrapped VERBATIM; only
1696
1696
  // the empty-body DEFAULT SCAFFOLD is sourced from the shared section skeleton
1697
- // owner (`renderSpecBody` with `solution` + `userStories`, prd
1697
+ // owner (`renderSpecBody` with `solution` + `userStories`, spec
1698
1698
  // `centralize-buildable-task-renderer-shared-by-intake-and-promotion` US #2),
1699
- // so intake's PRD fallback and promotion's PRD body cannot drift. `trimEnd()`
1699
+ // so intake's SPEC fallback and promotion's SPEC body cannot drift. `trimEnd()`
1700
1700
  // drops the renderer's trailing blank line so intake's single trailing `\n`
1701
1701
  // (owned by the join below) keeps the bytes identical to the pre-rewire literal.
1702
1702
  const drafted =
@@ -1704,7 +1704,7 @@ export function renderSpec(params: {
1704
1704
  ? body.trim()
1705
1705
  : renderSpecBody({
1706
1706
  problemStatement: `Transformed from issue #${issueNumber}: ${title}`,
1707
- solution: '(to be detailed; this prd needs tasking via `do prd:`).',
1707
+ solution: '(to be detailed; this spec needs tasking via `do spec:`).',
1708
1708
  userStories: `1. As a user, I want issue #${issueNumber} addressed.`,
1709
1709
  }).trimEnd();
1710
1710
  return `${frontmatter}\n\n${drafted}\n`;
@@ -1737,7 +1737,7 @@ async function stageIntakeContent(params: {
1737
1737
  * `intake-` PRODUCER prefix keeps this short-lived "create the item" branch
1738
1738
  * DISTINCT from the later build branch (`work/task-<slug>`) for the same slug
1739
1739
  * — the firing `intake` × `do task:` collision the observation traced. The
1740
- * task-emit path passes `'task'`, the prd-emit path `'prd'`. A pre-existing
1740
+ * task-emit path passes `'task'`, the spec-emit path `'prd'`. A pre-existing
1741
1741
  * local branch (a re-run) is force-recreated off fresh main.
1742
1742
  */
1743
1743
  async function switchToWorkBranch(
@@ -1782,7 +1782,7 @@ async function runDecision(
1782
1782
  if (options.decide) {
1783
1783
  return options.decide({cwd, issue, comments, prompt, env: options.env});
1784
1784
  }
1785
- // PRODUCTION: launch the harness with the decision prd, then PARSE the verdict
1785
+ // PRODUCTION: launch the harness with the decision spec, then PARSE the verdict
1786
1786
  // the agent emitted out of its ANSWER channel (`launched.output`) — the SAME wire
1787
1787
  // the review gate runs (launch → `parseReviewVerdict(readOutput(launched.output))`;
1788
1788
  // `harnessReviewGate`). The agent emits a single fenced ```json block (the OUTPUT
@@ -1905,7 +1905,7 @@ export function parseIntakeVerdict(output: string): IntakeVerdict {
1905
1905
  // The LONE-TASK bounded internal review (observation
1906
1906
  // `intake-lone-task-skips-adversarial-review-the-prd-path-gets`, rulings A/B/C).
1907
1907
  //
1908
- // Give intake's lone-TASK outcome the adversarial refinement the `do prd:` path
1908
+ // Give intake's lone-TASK outcome the adversarial refinement the `do spec:` path
1909
1909
  // already gets — but as a small intake-NATIVE bounded review, NOT by integrating
1910
1910
  // the tasker loop. This is a NEW prompt + a small loop + an injectable gate seam,
1911
1911
  // MIRRORING the tasker loop's verdict/output CONVENTIONS (fenced JSON
@@ -2293,20 +2293,20 @@ export function buildLoneTaskReviewPrompt(
2293
2293
  export const parseLoneTaskReviewVerdict = parseReviewVerdict;
2294
2294
 
2295
2295
  /**
2296
- * Build the intake decision PRD (an inline prompt builder, like `buildTaskingPrd`
2296
+ * Build the intake decision SPEC (an inline prompt builder, like `buildTaskingPrd`
2297
2297
  * in `tasking.ts` / the reviewer prompts in `review-gate.ts` — NOT a standalone
2298
2298
  * asset/`.md` file; no such convention exists in this package). It encodes the FULL
2299
- * four-outcome decision table (prd `issue-intake` — the source of truth) and the
2299
+ * four-outcome decision table (spec `issue-intake` — the source of truth) and the
2300
2300
  * three DECISION AIDS stated once there:
2301
2301
  *
2302
2302
  * 1. the **"clear?" bar** = `to-task`/`needsAnswers`' "would I build the wrong
2303
2303
  * thing if I guessed?" — if a material requirement/scope/acceptance question is
2304
2304
  * unanswered, ASK (never guess a spec from a vague issue);
2305
2305
  * 2. the **"one task?" bar** = `to-task`' tracer-bullet test (one thin end-to-end
2306
- * path, demoable on its own) — fits → TASK, needs splitting → PRD;
2307
- * 3. **PRD vs BOUNCE** turns on a **SHARED VISION**: coupled (even if small) → PRD;
2306
+ * path, demoable on its own) — fits → TASK, needs splitting → SPEC;
2307
+ * 3. **SPEC vs BOUNCE** turns on a **SHARED VISION**: coupled (even if small) → SPEC;
2308
2308
  * genuinely unrelated → BOUNCE. Size NEVER forces a bounce — only unrelatedness
2309
- * (the over-bounce guard: a coupled-but-small pair gets a light PRD, never a
2309
+ * (the over-bounce guard: a coupled-but-small pair gets a light SPEC, never a
2310
2310
  * bounce).
2311
2311
  *
2312
2312
  * The prompt anchors to `to-task`/`to-spec` for the task/spec SHAPES it drafts. Its
@@ -2328,7 +2328,7 @@ export function buildIntakeDecisionSpec(
2328
2328
  `#${i + 1} ${c.author ? `@${c.author}` : '(unknown)'}: ${c.body}`,
2329
2329
  )
2330
2330
  .join('\n\n');
2331
- // TRIAGE ENRICHMENT (prd `issue-intake`): on the raced PROCEED path the prompt is
2331
+ // TRIAGE ENRICHMENT (spec `issue-intake`): on the raced PROCEED path the prompt is
2332
2332
  // told which comment(s) PRE-DATE intake's last turn (context for a prior state,
2333
2333
  // not necessarily a fresh answer) and — only then — how many previously-SEEN
2334
2334
  // comments were DELETED (a flag + count; the bodies are gone, so do not name them).
@@ -2378,42 +2378,42 @@ export function buildIntakeDecisionSpec(
2378
2378
  ' (a single thin end-to-end path, demoable on its own — `to-task`’ criterion).',
2379
2379
  ' Draft that ONE task in the `to-task` shape (a `## What to build`,',
2380
2380
  ' `## Acceptance criteria`, and `## Prompt`). The runner writes',
2381
- ' `work/backlog/<slug>.md` (`covers: []`, NO `prd:`) carrying `issue: N` (the',
2381
+ ' `work/backlog/<slug>.md` (`covers: []`, NO `spec:`) carrying `issue: N` (the',
2382
2382
  ' lone-task closure link, NOT `Fixes #N`) and integrates it.',
2383
2383
  '',
2384
- '- **PRD** — the issue is CLEAR *and* coherent but needs MORE THAN ONE task (it',
2384
+ '- **SPEC** — the issue is CLEAR *and* coherent but needs MORE THAN ONE task (it',
2385
2385
  ' cannot be one tracer-bullet path — it splits for scope/architecture). >1 task',
2386
2386
  ' ⟺ a shared vision worth recording ⟺ a spec. Draft a spec in the `to-spec` shape',
2387
2387
  ' (`## Problem Statement`, `## Solution`, `## User Stories`, `## Out of Scope`).',
2388
- ' The runner writes the prd file (`work/prds/ready/<slug>.md`) with `issue: N` and integrates it;',
2389
- ' TASKING the prd is a SEPARATE later step (`do prd:`) — do not task it here.',
2388
+ ` The runner writes the spec file (\`${workFolderPrefix('specs-ready')}<slug>.md\`) with \`issue: N\` and integrates it;`,
2389
+ ' TASKING the spec is a SEPARATE later step (`do spec:`) — do not task it here.',
2390
2390
  ' **INCLUDES a coupled-but-SMALL pair: if two asks share a vision they get a',
2391
- ' (light) prd — they are NEVER bounced.**',
2391
+ ' (light) spec — they are NEVER bounced.**',
2392
2392
  '',
2393
2393
  '- **BOUNCE** — the issue is really MULTIPLE UNRELATED concerns wearing one issue:',
2394
2394
  ' you cannot articulate a SINGLE shared vision tying them together. Draft a short',
2395
2395
  ' message asking the author to file separate issues. A bounce is TERMINAL, so the',
2396
2396
  ' runner CLOSES the issue ATOMICALLY — your message as the closing comment +',
2397
2397
  ' reason "not planned" (the honest signal that the asks must be re-filed). Intake',
2398
- ' closes on BOUNCE only; never on task/prd (CI’s close-job) / ask.',
2398
+ ' closes on BOUNCE only; never on task/spec (CI’s close-job) / ask.',
2399
2399
  '',
2400
2400
  '## The three decision aids (apply them in order)',
2401
2401
  '',
2402
2402
  '1. **"clear?"** (ASK vs the rest): the `needsAnswers` bar — would acting now risk',
2403
2403
  ' building the wrong thing? If yes → ASK. Otherwise it is clear; continue.',
2404
- '2. **"one task?"** (TASK vs PRD): the `to-task` tracer-bullet test — one thin',
2405
- ' end-to-end path, demoable alone? Fits → TASK; needs splitting → PRD.',
2406
- '3. **"shared vision?"** (PRD vs BOUNCE): coupled (even if small) → PRD; genuinely',
2404
+ '2. **"one task?"** (TASK vs SPEC): the `to-task` tracer-bullet test — one thin',
2405
+ ' end-to-end path, demoable alone? Fits → TASK; needs splitting → SPEC.',
2406
+ '3. **"shared vision?"** (SPEC vs BOUNCE): coupled (even if small) → SPEC; genuinely',
2407
2407
  ' unrelated → BOUNCE. SIZE NEVER forces a bounce — only UNRELATEDNESS does. Do',
2408
- ' not over-bounce a small coupled pair: it is a light prd.',
2408
+ ' not over-bounce a small coupled pair: it is a light spec.',
2409
2409
  '',
2410
2410
  '## Boundary',
2411
2411
  '',
2412
- 'You only DRAFT the verdict + its content (the task/prd body, or the comment',
2412
+ 'You only DRAFT the verdict + its content (the task/spec body, or the comment',
2413
2413
  'text). You do NOT perform ANY git operation and you do NOT post any comment — the',
2414
- 'runner owns every git/seam side-effect (write, integrate, postComment). For a prd',
2414
+ 'runner owns every git/seam side-effect (write, integrate, postComment). For a spec',
2415
2415
  'verdict, also judge its gate axes (humanOnly / needsAnswers) so the runner can',
2416
- 'surface them on the emitted prd.',
2416
+ 'surface them on the emitted spec.',
2417
2417
  '',
2418
2418
  '## Output — hand the verdict back as ONE fenced JSON block',
2419
2419
  '',