nitm-ai-dev-toolkit 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +30 -10
  3. package/bin/cli.js +635 -88
  4. package/package.json +1 -1
  5. package/src/monorepo/.agents/skills/factory/SKILL.md +123 -57
  6. package/src/monorepo/{.claude/agents-snippets/factory-approver.md → .agents/skills/factory/roles/approve.md} +3 -3
  7. package/src/monorepo/{.claude/agents-snippets/factory-builder.md → .agents/skills/factory/roles/build.md} +3 -3
  8. package/src/monorepo/{.claude/agents-snippets/factory-reviewer-code.md → .agents/skills/factory/roles/review-code.md} +5 -5
  9. package/src/{repo/.claude/agents-snippets/factory-reviewer-security.md → monorepo/.agents/skills/factory/roles/review-security.md} +4 -4
  10. package/src/monorepo/{.claude/agents-snippets/factory-reviewer-ui.md → .agents/skills/factory/roles/review-ui.md} +6 -6
  11. package/src/monorepo/{.claude/agents-snippets/factory-reviewer-ux.md → .agents/skills/factory/roles/review-ux.md} +6 -6
  12. package/src/monorepo/{.claude/agents-snippets/factory-spec-writer.md → .agents/skills/factory/roles/spec.md} +2 -2
  13. package/src/monorepo/.claude/agents/implementer.agent.md +1 -1
  14. package/src/monorepo/.claude/agents/planner.agent.md +1 -1
  15. package/src/monorepo/.claude/agents/reviewer.agent.md +1 -1
  16. package/src/monorepo/.claude/commands/assign-tasks.md +1 -0
  17. package/src/monorepo/.claude/commands/factory.md +9 -9
  18. package/src/monorepo/.claude/commands/ponytail-review.md +1 -1
  19. package/src/monorepo/.claude/prompt-snippets/assign-tasks.md +13 -3
  20. package/src/monorepo/.claude/prompt-snippets/bootstrap-patch.md +32 -25
  21. package/src/monorepo/.claude/prompt-snippets/bootstrap-upgrade.md +13 -14
  22. package/src/monorepo/.claude/prompt-snippets/bootstrap.md +12 -12
  23. package/src/monorepo/.claude/prompt-snippets/factory.md +5 -5
  24. package/src/monorepo/.claude/prompt-snippets/implement-feature.md +3 -1
  25. package/src/monorepo/.claude/rules-snippets/subagent-workflow.md +2 -2
  26. package/src/monorepo/.cursor/commands/factory.md +9 -9
  27. package/src/monorepo/.github/prompts/factory.prompt.md +9 -9
  28. package/src/monorepo/.opencode/agents/admin-portal.md +1 -4
  29. package/src/monorepo/.opencode/agents/api-specialist.md +1 -4
  30. package/src/monorepo/.opencode/agents/backend-architect.md +1 -4
  31. package/src/monorepo/.opencode/agents/documenter.md +1 -4
  32. package/src/monorepo/.opencode/agents/feature-builder.md +1 -4
  33. package/src/monorepo/.opencode/agents/frontend-developer.md +1 -4
  34. package/src/monorepo/.opencode/agents/green.md +1 -4
  35. package/src/monorepo/.opencode/agents/implementer.md +1 -4
  36. package/src/monorepo/.opencode/agents/planner.md +1 -4
  37. package/src/monorepo/.opencode/agents/red.md +1 -4
  38. package/src/monorepo/.opencode/agents/refactor.md +1 -4
  39. package/src/monorepo/.opencode/agents/researcher.md +1 -4
  40. package/src/monorepo/.opencode/agents/reviewer.md +1 -4
  41. package/src/monorepo/.opencode/agents/tdd.md +1 -4
  42. package/src/monorepo/.opencode/commands/assign-tasks.md +1 -1
  43. package/src/monorepo/.opencode/commands/bootstrap-patch.md +1 -1
  44. package/src/monorepo/.opencode/commands/bootstrap-upgrade.md +1 -1
  45. package/src/monorepo/.opencode/commands/bootstrap.md +1 -1
  46. package/src/monorepo/.opencode/commands/commit-push.md +1 -1
  47. package/src/monorepo/.opencode/commands/constitution.md +1 -1
  48. package/src/monorepo/.opencode/commands/create-skill.md +1 -1
  49. package/src/monorepo/.opencode/commands/factory.md +9 -9
  50. package/src/monorepo/.opencode/commands/implement-feature.md +1 -1
  51. package/src/monorepo/.opencode/commands/implement-fixes.md +1 -1
  52. package/src/monorepo/.opencode/commands/implement.md +1 -1
  53. package/src/monorepo/.opencode/commands/plan.md +1 -1
  54. package/src/monorepo/.opencode/commands/playwright-test.md +1 -1
  55. package/src/monorepo/.opencode/commands/ponytail-audit.md +1 -1
  56. package/src/monorepo/.opencode/commands/ponytail-debt.md +1 -1
  57. package/src/monorepo/.opencode/commands/ponytail-gain.md +1 -1
  58. package/src/monorepo/.opencode/commands/ponytail-help.md +1 -1
  59. package/src/monorepo/.opencode/commands/ponytail-review.md +1 -1
  60. package/src/monorepo/.opencode/commands/ponytail.md +1 -1
  61. package/src/monorepo/.opencode/commands/release-notes.md +1 -1
  62. package/src/monorepo/.opencode/commands/review-pr.md +1 -1
  63. package/src/monorepo/.opencode/commands/review.md +1 -1
  64. package/src/monorepo/.opencode/commands/specify.md +1 -1
  65. package/src/monorepo/.opencode/commands/tasks.md +1 -1
  66. package/src/monorepo/.opencode/opencode.jsonc +1 -2
  67. package/src/monorepo/.opencode/rules/agent-conduct.md +1 -1
  68. package/src/monorepo/.opencode/rules/api-server.md +1 -1
  69. package/src/monorepo/.opencode/rules/coding-standards.md +1 -1
  70. package/src/monorepo/.opencode/rules/component-structure.md +1 -1
  71. package/src/monorepo/.opencode/rules/core-libraries.md +1 -1
  72. package/src/monorepo/.opencode/rules/environment-tooling.md +1 -1
  73. package/src/monorepo/.opencode/rules/logging-comments.md +1 -1
  74. package/src/monorepo/.opencode/rules/logging.md +1 -1
  75. package/src/monorepo/.opencode/rules/prisma-migrations.md +1 -1
  76. package/src/monorepo/.opencode/rules/project-context.md +1 -1
  77. package/src/monorepo/.opencode/rules/server-client-separation.md +1 -1
  78. package/src/monorepo/.opencode/rules/subagent-workflow.md +1 -1
  79. package/src/monorepo/.opencode/rules/testing-quality.md +1 -1
  80. package/src/monorepo/.opencode/rules/ui-accessibility.md +1 -1
  81. package/src/monorepo/.opencode/rules/version-control.md +1 -1
  82. package/src/monorepo/.opencode/rules/what-to-avoid.md +1 -1
  83. package/src/monorepo/AGENTS.md +4 -4
  84. package/src/monorepo/README.md +5 -5
  85. package/src/monorepo/factory/README.md +51 -24
  86. package/src/monorepo/factory/worktree-bootstrap.md +32 -0
  87. package/src/repo/.agents/skills/factory/SKILL.md +122 -56
  88. package/src/repo/{.claude/agents-snippets/factory-approver.md → .agents/skills/factory/roles/approve.md} +3 -3
  89. package/src/repo/{.claude/agents-snippets/factory-builder.md → .agents/skills/factory/roles/build.md} +3 -3
  90. package/src/repo/{.claude/agents-snippets/factory-reviewer-code.md → .agents/skills/factory/roles/review-code.md} +5 -5
  91. package/src/{monorepo/.claude/agents-snippets/factory-reviewer-security.md → repo/.agents/skills/factory/roles/review-security.md} +4 -4
  92. package/src/repo/{.claude/agents-snippets/factory-reviewer-ui.md → .agents/skills/factory/roles/review-ui.md} +6 -6
  93. package/src/repo/{.claude/agents-snippets/factory-reviewer-ux.md → .agents/skills/factory/roles/review-ux.md} +6 -6
  94. package/src/repo/{.claude/agents-snippets/factory-spec-writer.md → .agents/skills/factory/roles/spec.md} +2 -2
  95. package/src/repo/.claude/agents/implementer.agent.md +1 -1
  96. package/src/repo/.claude/agents/planner.agent.md +1 -1
  97. package/src/repo/.claude/agents/reviewer.agent.md +1 -1
  98. package/src/repo/.claude/commands/assign-tasks.md +1 -0
  99. package/src/repo/.claude/commands/factory.md +9 -9
  100. package/src/repo/.claude/commands/ponytail-review.md +1 -1
  101. package/src/repo/.claude/prompt-snippets/assign-tasks.md +13 -3
  102. package/src/repo/.claude/prompt-snippets/bootstrap-patch.md +32 -25
  103. package/src/repo/.claude/prompt-snippets/bootstrap-upgrade.md +17 -17
  104. package/src/repo/.claude/prompt-snippets/bootstrap.md +12 -12
  105. package/src/repo/.claude/prompt-snippets/factory.md +5 -5
  106. package/src/repo/.claude/prompt-snippets/implement-feature.md +3 -1
  107. package/src/repo/.claude/rules-snippets/subagent-workflow.md +2 -2
  108. package/src/repo/.cursor/commands/factory.md +9 -9
  109. package/src/repo/.github/prompts/factory.prompt.md +9 -9
  110. package/src/repo/.opencode/agents/admin-portal.md +1 -4
  111. package/src/repo/.opencode/agents/api-specialist.md +1 -4
  112. package/src/repo/.opencode/agents/backend-architect.md +1 -4
  113. package/src/repo/.opencode/agents/documenter.md +1 -4
  114. package/src/repo/.opencode/agents/feature-builder.md +1 -4
  115. package/src/repo/.opencode/agents/frontend-developer.md +1 -4
  116. package/src/repo/.opencode/agents/green.md +1 -4
  117. package/src/repo/.opencode/agents/implementer.md +1 -4
  118. package/src/repo/.opencode/agents/planner.md +1 -4
  119. package/src/repo/.opencode/agents/red.md +1 -4
  120. package/src/repo/.opencode/agents/refactor.md +1 -4
  121. package/src/repo/.opencode/agents/researcher.md +1 -4
  122. package/src/repo/.opencode/agents/reviewer.md +1 -4
  123. package/src/repo/.opencode/agents/tdd.md +1 -4
  124. package/src/repo/.opencode/commands/assign-tasks.md +1 -1
  125. package/src/repo/.opencode/commands/bootstrap-patch.md +1 -1
  126. package/src/repo/.opencode/commands/bootstrap-upgrade.md +1 -1
  127. package/src/repo/.opencode/commands/bootstrap.md +1 -1
  128. package/src/repo/.opencode/commands/commit-push.md +1 -1
  129. package/src/repo/.opencode/commands/constitution.md +1 -1
  130. package/src/repo/.opencode/commands/create-skill.md +1 -1
  131. package/src/repo/.opencode/commands/factory.md +9 -9
  132. package/src/repo/.opencode/commands/implement-feature.md +1 -1
  133. package/src/repo/.opencode/commands/implement-fixes.md +1 -1
  134. package/src/repo/.opencode/commands/implement.md +1 -1
  135. package/src/repo/.opencode/commands/plan.md +1 -1
  136. package/src/repo/.opencode/commands/playwright-test.md +1 -1
  137. package/src/repo/.opencode/commands/ponytail-audit.md +1 -1
  138. package/src/repo/.opencode/commands/ponytail-debt.md +1 -1
  139. package/src/repo/.opencode/commands/ponytail-gain.md +1 -1
  140. package/src/repo/.opencode/commands/ponytail-help.md +1 -1
  141. package/src/repo/.opencode/commands/ponytail-review.md +1 -1
  142. package/src/repo/.opencode/commands/ponytail.md +1 -1
  143. package/src/repo/.opencode/commands/release-notes.md +1 -1
  144. package/src/repo/.opencode/commands/review-pr.md +1 -1
  145. package/src/repo/.opencode/commands/review.md +1 -1
  146. package/src/repo/.opencode/commands/specify.md +1 -1
  147. package/src/repo/.opencode/commands/tasks.md +1 -1
  148. package/src/repo/.opencode/opencode.jsonc +1 -2
  149. package/src/repo/.opencode/rules/agent-conduct.md +1 -1
  150. package/src/repo/.opencode/rules/api-server.md +1 -1
  151. package/src/repo/.opencode/rules/coding-standards.md +1 -1
  152. package/src/repo/.opencode/rules/component-structure.md +1 -1
  153. package/src/repo/.opencode/rules/core-libraries.md +1 -1
  154. package/src/repo/.opencode/rules/environment-tooling.md +1 -1
  155. package/src/repo/.opencode/rules/logging-comments.md +1 -1
  156. package/src/repo/.opencode/rules/logging.md +1 -1
  157. package/src/repo/.opencode/rules/prisma-migrations.md +1 -1
  158. package/src/repo/.opencode/rules/project-context.md +1 -1
  159. package/src/repo/.opencode/rules/server-client-separation.md +1 -1
  160. package/src/repo/.opencode/rules/subagent-workflow.md +1 -1
  161. package/src/repo/.opencode/rules/testing-quality.md +1 -1
  162. package/src/repo/.opencode/rules/ui-accessibility.md +1 -1
  163. package/src/repo/.opencode/rules/version-control.md +1 -1
  164. package/src/repo/.opencode/rules/what-to-avoid.md +1 -1
  165. package/src/repo/AGENTS.md +4 -4
  166. package/src/repo/README.md +5 -5
  167. package/src/repo/factory/README.md +44 -23
  168. package/src/repo/factory/worktree-bootstrap.md +32 -0
  169. package/src/monorepo/.claude/agents/factory-approver.agent.md +0 -12
  170. package/src/monorepo/.claude/agents/factory-builder.agent.md +0 -12
  171. package/src/monorepo/.claude/agents/factory-reviewer-code.agent.md +0 -12
  172. package/src/monorepo/.claude/agents/factory-reviewer-security.agent.md +0 -12
  173. package/src/monorepo/.claude/agents/factory-reviewer-ui.agent.md +0 -12
  174. package/src/monorepo/.claude/agents/factory-reviewer-ux.agent.md +0 -12
  175. package/src/monorepo/.claude/agents/factory-spec-writer.agent.md +0 -12
  176. package/src/monorepo/.cursor/agents/factory-approver.agent.md +0 -11
  177. package/src/monorepo/.cursor/agents/factory-builder.agent.md +0 -11
  178. package/src/monorepo/.cursor/agents/factory-reviewer-code.agent.md +0 -11
  179. package/src/monorepo/.cursor/agents/factory-reviewer-security.agent.md +0 -11
  180. package/src/monorepo/.cursor/agents/factory-reviewer-ui.agent.md +0 -11
  181. package/src/monorepo/.cursor/agents/factory-reviewer-ux.agent.md +0 -11
  182. package/src/monorepo/.cursor/agents/factory-spec-writer.agent.md +0 -11
  183. package/src/monorepo/.github/agents/factory-approver.agent.md +0 -11
  184. package/src/monorepo/.github/agents/factory-builder.agent.md +0 -11
  185. package/src/monorepo/.github/agents/factory-reviewer-code.agent.md +0 -11
  186. package/src/monorepo/.github/agents/factory-reviewer-security.agent.md +0 -11
  187. package/src/monorepo/.github/agents/factory-reviewer-ui.agent.md +0 -11
  188. package/src/monorepo/.github/agents/factory-reviewer-ux.agent.md +0 -11
  189. package/src/monorepo/.github/agents/factory-spec-writer.agent.md +0 -11
  190. package/src/monorepo/.opencode/agents/factory-approver.md +0 -20
  191. package/src/monorepo/.opencode/agents/factory-builder.md +0 -20
  192. package/src/monorepo/.opencode/agents/factory-reviewer-code.md +0 -20
  193. package/src/monorepo/.opencode/agents/factory-reviewer-security.md +0 -20
  194. package/src/monorepo/.opencode/agents/factory-reviewer-ui.md +0 -20
  195. package/src/monorepo/.opencode/agents/factory-reviewer-ux.md +0 -20
  196. package/src/monorepo/.opencode/agents/factory-spec-writer.md +0 -20
  197. package/src/repo/.claude/agents/factory-approver.agent.md +0 -12
  198. package/src/repo/.claude/agents/factory-builder.agent.md +0 -12
  199. package/src/repo/.claude/agents/factory-reviewer-code.agent.md +0 -12
  200. package/src/repo/.claude/agents/factory-reviewer-security.agent.md +0 -12
  201. package/src/repo/.claude/agents/factory-reviewer-ui.agent.md +0 -12
  202. package/src/repo/.claude/agents/factory-reviewer-ux.agent.md +0 -12
  203. package/src/repo/.claude/agents/factory-spec-writer.agent.md +0 -12
  204. package/src/repo/.cursor/agents/factory-approver.agent.md +0 -11
  205. package/src/repo/.cursor/agents/factory-builder.agent.md +0 -11
  206. package/src/repo/.cursor/agents/factory-reviewer-code.agent.md +0 -11
  207. package/src/repo/.cursor/agents/factory-reviewer-security.agent.md +0 -11
  208. package/src/repo/.cursor/agents/factory-reviewer-ui.agent.md +0 -11
  209. package/src/repo/.cursor/agents/factory-reviewer-ux.agent.md +0 -11
  210. package/src/repo/.cursor/agents/factory-spec-writer.agent.md +0 -11
  211. package/src/repo/.github/agents/factory-approver.agent.md +0 -11
  212. package/src/repo/.github/agents/factory-builder.agent.md +0 -11
  213. package/src/repo/.github/agents/factory-reviewer-code.agent.md +0 -11
  214. package/src/repo/.github/agents/factory-reviewer-security.agent.md +0 -11
  215. package/src/repo/.github/agents/factory-reviewer-ui.agent.md +0 -11
  216. package/src/repo/.github/agents/factory-reviewer-ux.agent.md +0 -11
  217. package/src/repo/.github/agents/factory-spec-writer.agent.md +0 -11
  218. package/src/repo/.opencode/agents/factory-approver.md +0 -20
  219. package/src/repo/.opencode/agents/factory-builder.md +0 -20
  220. package/src/repo/.opencode/agents/factory-reviewer-code.md +0 -20
  221. package/src/repo/.opencode/agents/factory-reviewer-security.md +0 -20
  222. package/src/repo/.opencode/agents/factory-reviewer-ui.md +0 -20
  223. package/src/repo/.opencode/agents/factory-reviewer-ux.md +0 -20
  224. package/src/repo/.opencode/agents/factory-spec-writer.md +0 -20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nitm-ai-dev-toolkit",
3
- "version": "5.0.0",
3
+ "version": "5.1.0",
4
4
  "description": "Scaffold AI agent config (Cursor, GitHub Copilot, Claude Code, OpenCode, Codex) into any repo, then hand off to your AI agent to finish setup.",
5
5
  "bin": {
6
6
  "nitm-ai-dev-toolkit": "bin/cli.js"
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: factory
3
- description: Opt-in software factory for feature-sized work. Runs one job through intake questions, a spec gate, a plan gate, build in an isolated git worktree (or in place on request), parallel reviews by lens, approval, and a local merge. Feature docs live in docs/features/, job state in factory/jobs/, and tickets (when the project tracks them) follow the job. Invoked as /factory with a request (intake), start, approve, rework, abandon, status, watch, archive, or prune. Quick fixes stay direct.
3
+ description: Opt-in software factory for feature-sized work. Runs one job through intake questions, a spec gate, a plan gate, build in an isolated git worktree (or in place on request), parallel reviews by lens, approval, and then a merge: local, or a merge request on the forge. Feature docs live in the feature folders, job state in factory/jobs/, and tickets (when the project tracks them) follow the job. Invoked as /factory with a request (intake), start, approve, rework, abandon, status, watch, archive, or prune. Quick fixes stay direct.
4
4
  ---
5
5
 
6
6
  # Factory (orchestrator)
7
7
 
8
- One orchestrator session runs a feature through intake → spec → plan → build → review → approve → merge. Agents get their context from files and each agent writes only its own file. You are the orchestrator: you ask the intake questions, dispatch agents, read their files, rewrite `job.json`, run the gates with the operator, handle tickets, and run the merge. You never write code, specs, plans, reviews, or `qa.md` yourself. Exceptions: you write `intake.md` from the operator's answers, `spec-<k>.md` and `plan-<k>.md` from the operator's change requests, `tasks.md` ticket keys, the feature folder rename and copy, the feature docs commit on the job branch, worktree and branch removal, the moves and branch deletions in Archive, `decision.md` with `ESCALATE` when retries run out, `merge-conflict.md` on a merge conflict, and `rework-<k>.md` from the user's note.
8
+ One orchestrator session runs a feature through intake → spec → plan → build → review → approve → merge. Agents get their context from files. Builders and spec writers write their own files; reviewers and the approver return their report, and you save it (see Subagent dispatch). You are the orchestrator: you ask the intake questions, dispatch agents, read their files, rewrite `job.json`, run the gates with the operator, handle tickets, and run the merge. You never write code, specs, plans, reviews, or `qa.md` yourself. Exceptions: you write `intake.md` from the operator's answers, `spec-<k>.md` and `plan-<k>.md` from the operator's change requests, `tasks.md` ticket keys, the feature folder rename and copy, the feature docs commit on the job branch, worktree and branch removal, the moves and branch deletions in Archive, the review files and `decision.md` from the reviewers' and approver's replies (see Subagent dispatch), and `decision.md` with `ESCALATE` when retries run out, `merge-conflict.md` on a merge conflict, `bootstrap.md` on a failed worktree bootstrap step, the push and merge request in `push-mr` mode (see Merge procedure), and `rework-<k>.md` from the user's note.
9
9
 
10
10
  The factory is opt-in and sits alongside Feature Builder and TDD. Nothing runs unless the user invokes `/factory`.
11
11
 
@@ -19,6 +19,8 @@ Bootstrap replaces these when it adopts the template. The names below have no br
19
19
  | FACTORY_PORT_BASE | Base dev-server port for job ports | `5100` |
20
20
  | APPROVAL_MODE | `human` stops at `awaiting-human`; `auto` merges on `APPROVE` | `human` |
21
21
  | FACTORY_REVIEW_LENSES | Comma list drawn from `code, security, ux, ui` | `code, security` |
22
+ | FACTORY_FEATURE_PATHS | Feature-folder roots, comma list, relative to the repo root. A `*` matches one folder name. Intake, Start, and Status search every root. A new feature goes to the first root without `*`, or to a `*` root when its code sits in exactly one app (see Feature folders) | monorepo: `apps/*/docs/features, docs/features`; repo: `docs/features` |
23
+ | MERGE_MODE | `local`: `--no-ff` merge on this machine, never pushed. `push-mr`: push `factory/<id>` and open a merge or pull request with the forge CLI; the forge merges. Any other value is `local` | `local` |
22
24
 
23
25
  ## When to use
24
26
 
@@ -32,20 +34,20 @@ Bootstrap replaces these when it adopts the template. The names below have no br
32
34
  | --- | --- |
33
35
  | `/factory [--in-place] <request>` | Intake (see Intake): read the project, ask only glaring questions, then continue as `start` |
34
36
  | `/factory start [--in-place] <request \| KEY \| slug \| job-id>` | Resolve the feature folder, or resume its open job (see Start). `--in-place` applies only to a new job |
35
- | `/factory approve <job-id>` | Merge a job in `awaiting-human` or `needs-human`; on a `merged` job, move its tickets to Done |
37
+ | `/factory approve <job-id>` | Merge a job in `awaiting-human` or `needs-human` (`local`), or push it and open its merge request (`push-mr`, see Merge procedure). In `push-mr`, approving an `awaiting-human` job whose request is open finishes it once the forge has merged it. On a `merged` job, move its tickets to Done |
36
38
  | `/factory rework <job-id> <note>` | Write a rework note, start a fresh builder, reset the retry budget |
37
39
  | `/factory abandon <job-id>` | Close a job that will not continue. Nothing is merged. The worktree and branch are removed only when the branch has no unmerged commits (see Abandon) |
38
40
  | `/factory status [--all]` | Summarize open jobs from their `job.json` (read-only). Closed jobs are hidden unless `--all` (see Status) |
39
41
  | `/factory watch [--all]` | Show the status table, then the command for the live view to run in a terminal (read-only). `--all` as for status |
40
42
  | `/factory archive [--all] [--dry-run]` | Move closed jobs to `factory/archive/` (see Archive). Open jobs never move |
41
- | `/factory prune [--all] [--abandoned] [--dry-run]` | Permanently delete closed jobs from `factory/jobs/` and `factory/archive/` (see Prune). Open jobs and `docs/features/` are never touched |
43
+ | `/factory prune [--all] [--abandoned] [--dry-run]` | Permanently delete closed jobs from `factory/jobs/` and `factory/archive/` (see Prune). Open jobs and feature folders are never touched |
42
44
 
43
45
  A first argument of `start`, `approve`, `rework`, `abandon`, `status`, `watch`, `archive`, or `prune` selects its row. Anything else is a request for intake. A bare job id that matches an existing `factory/jobs/<id>/` or `factory/archive/<id>/` is not a request: it goes to Start. An archived job is closed. `rework` and `abandon` refuse it. `approve` on an archived `merged` job only moves its tickets to Done, and merges nothing.
44
46
 
45
47
  ## Layout
46
48
 
47
49
  ```
48
- docs/features/<KEY>-<slug>/ tracked by the project; feature docs
50
+ <feature root>/<KEY>-<slug>/ tracked by the project; feature docs (roots: {{FACTORY_FEATURE_PATHS}})
49
51
  spec.md spec-writer, spec mode (from the feature spec template)
50
52
  plan.md spec-writer, plan mode: approach, steps, and the **Size:** line
51
53
  tasks.md spec-writer, plan mode, large work only
@@ -53,6 +55,7 @@ docs/features/<KEY>-<slug>/ tracked by the project; feature docs
53
55
  factory/
54
56
  README.md setup and reference
55
57
  .gitignore ignores jobs/ and archive/
58
+ worktree-bootstrap.md project-owned steps run in each new worktree (see Worktree)
56
59
  jobs/ runtime state, ignored by git
57
60
  <NNN-slug>/
58
61
  job.json orchestrator only; rewrite the whole file
@@ -63,13 +66,25 @@ factory/
63
66
  round-<N>/review-<lens>.md one per configured lens
64
67
  decision.md approver (or you, on escalation)
65
68
  merge-conflict.md you, on a merge conflict (blocks approve)
69
+ bootstrap.md you, on a failed worktree bootstrap step (blocks the build)
66
70
  rework-<k>.md you, from the user's note
67
71
  main-copies/ feature docs moved aside at merge (see Merge procedure)
68
72
  archive/ closed jobs moved here by /factory archive, ignored by git
69
73
  <NNN-slug>/ same layout as jobs/; never resumed
70
74
  ```
71
75
 
72
- `<KEY>` is an issue key in the project's issue key format (`^[A-Z][A-Z0-9]+-\d+$`, as in `PROJ-1234`, the format `AGENTS.md` documents). Without a ticket, the folder is `docs/features/<slug>/` and gets its key later if tracking starts. Feature folders always live in the repository root's `docs/features/`. In a monorepo they are not per app: `apps/<app>/docs/features/` is never used for factory jobs.
76
+ `<KEY>` is an issue key in the project's issue key format (`^[A-Z][A-Z0-9]+-\d+$`, as in `PROJ-1234`, the format `AGENTS.md` documents). Without a ticket, the folder is `<root>/<slug>/` and gets its key later if tracking starts.
77
+
78
+ ### Feature folders
79
+
80
+ Feature folders live under the roots in `{{FACTORY_FEATURE_PATHS}}`, relative to the repository root. Every root is searched. Where a new folder goes:
81
+
82
+ - **Literal root** (no `*`): the first literal root is the home for cross-cutting features. In a single-package repo, that is the only root.
83
+ - **Per-app root** (`apps/*/docs/features`): a new feature goes there when the request's code sits in exactly one app directory the glob matches. Intake or Start names that app, creates `apps/<app>/docs/features/` if it is missing, and says the chosen folder in chat before creating anything. Code in several apps, or none, goes to the first literal root.
84
+ - **Existing folders** keep their place, wherever they were created. A feature is found by its folder name, not by its root.
85
+ - **Feature-root excludes**: git pathspec excludes for the feature folders. For each root, `':(exclude,glob)<root>'`, so `apps/*/docs/features` becomes `':(exclude,glob)apps/*/docs/features'`. Wherever this skill says "feature-root excludes", use one per root.
86
+
87
+ `job.json` records the chosen folder in `feature_dir`.
73
88
 
74
89
  ### job.json
75
90
 
@@ -86,6 +101,7 @@ factory/
86
101
  "branch": "factory/001-onboarding-bootstrap",
87
102
  "worktree": true,
88
103
  "worktree_path": "/abs/path/to/repo-factory/001-onboarding-bootstrap",
104
+ "mr": null,
89
105
  "failed_stage": null,
90
106
  "stage": "awaiting-plan",
91
107
  "round": 1,
@@ -105,10 +121,11 @@ factory/
105
121
  - `tracker_errors`: failed ticket transitions or creations, as short strings. Reported, never blocking.
106
122
  - `worktree`: `true` (default) builds in a git worktree. `false` builds in place in the main checkout (see In-place mode). Set when the job is created; changed only at the plan gate.
107
123
  - `worktree_path`: absolute path of the job's worktree, or `null` for an in-place job and before the build starts.
124
+ - `mr`: URL of the merge or pull request opened in `push-mr` mode, or `null`. Set once; later approvals read its state (see Merge procedure).
108
125
  - `failed_stage`: `spec` or `plan` when the job is `needs-human` because its spec or plan agent failed, else `null`. `/factory start` reruns that stage (see Start).
109
126
  - `reviews` values are `pending`, `PASS`, or `CHANGES`.
110
127
 
111
- Stages, in order: `spec` (spec-writer running), `awaiting-spec` (spec gate), `plan` (plan writer running), `awaiting-plan` (plan gate), `build`, `review`, `approve`, `awaiting-human`, `merged`, `needs-human`. `abandoned` is set by `/factory abandon`, from any open stage. Set `updatedAt` on every write. Use `date -u +%Y-%m-%dT%H:%M:%SZ`.
128
+ Stages, in order: `spec` (spec-writer running), `awaiting-spec` (spec gate), `plan` (plan writer running), `awaiting-plan` (plan gate), `build`, `review`, `approve`, `awaiting-human`, `merged`, `needs-human`. In `push-mr` mode, `awaiting-human` with `mr` set means the request is open on the forge and waiting for its merge. `abandoned` is set by `/factory abandon`, from any open stage. Set `updatedAt` on every write. Use `date -u +%Y-%m-%dT%H:%M:%SZ`.
112
129
 
113
130
  A job is **closed** when its stage is `merged` or `abandoned`. Every other job is **open**, and every open-job check in this skill uses that definition. Closed jobs that `/factory archive` moved to `factory/archive/` are archived (see Archive). A job **holds its build location** when it is open and has reached the build: its stage is `build`, `review`, `approve`, or `awaiting-human`, or `needs-human` with `failed_stage` `null`. A worktree job holds a worktree, and an in-place job holds the main checkout, for as long as it holds its build location.
114
131
 
@@ -116,10 +133,11 @@ A job is **closed** when its stage is `merged` or `abandoned`. Every other job i
116
133
 
117
134
  `/factory <request>` starts here. Intake writes nothing until its questions are answered, so the operator can answer before any folder, job, or spec exists.
118
135
 
119
- 1. **Analyze, read-only.** Read the project's `AGENTS.md`. List `docs/features/` and read the title and Summary of each `spec.md` whose name or text matches the request's keywords, looking for related or overlapping features. Skim the code the request touches with glob and grep. Work out the feature folder the way Start steps 1 and 2 would, without creating anything.
136
+ 1. **Analyze, read-only.** Read the project's `AGENTS.md`. List every feature root in `{{FACTORY_FEATURE_PATHS}}` (a `*` root expands to the app folders that exist) and read the title and Summary of each `spec.md` whose name or text matches the request's keywords, looking for related or overlapping features. Skim the code the request touches with glob and grep, and note which app directories it sits in. Work out the feature folder the way Start steps 1 and 2 would, without creating anything.
120
137
  2. **Ask only glaring questions.** Ask at most five, in chat, as a numbered list, then wait. Ask only when one of these holds:
121
138
  - The scope is ambiguous: two readings lead to different specs.
122
- - The request conflicts with or duplicates an existing feature in `docs/features/`.
139
+ - The request conflicts with or duplicates an existing feature in a feature root.
140
+ - A `*` root in `{{FACTORY_FEATURE_PATHS}}` applies, and the request's code sits in several apps or none, so the folder is not clear (see Feature folders). Ask which folder.
123
141
  - The target user, page, or system is missing.
124
142
  - No acceptance is implied: there is no way to tell when it is done.
125
143
 
@@ -143,8 +161,8 @@ Strip a leading `--in-place` first. It is a flag, not part of the argument. Then
143
161
 
144
162
  1. No argument: ask for a request, key, slug, or job id.
145
163
  2. A job id (`^\d{3,}-[a-z0-9-]+$`) with a folder at `factory/jobs/<id>/`: resume that job, or report that it is closed (see the resume table). A job id with a folder at `factory/archive/<id>/` is archived: say so and stop. Archived jobs are not resumable. To work on the feature again, `/factory start <slug or KEY>` creates a new job.
146
- 3. An issue key (`^[A-Z][A-Z0-9]+-\d+$`): match `docs/features/<KEY>-*/` in the main checkout.
147
- 4. A kebab slug (`^[a-z0-9]+(-[a-z0-9]+)*$`): match `docs/features/<slug>/` or `docs/features/<KEY>-<slug>/`, where `<KEY>` has the key format in step 3.
164
+ 3. An issue key (`^[A-Z][A-Z0-9]+-\d+$`): match `<root>/<KEY>-*/` in every feature root of the main checkout.
165
+ 4. A kebab slug (`^[a-z0-9]+(-[a-z0-9]+)*$`): match `<root>/<slug>/` or `<root>/<KEY>-<slug>/` in every feature root, where `<KEY>` has the key format in step 3.
148
166
  5. Anything else is a free-text request. Derive a 2–4 word kebab slug from it, then match as in step 4.
149
167
 
150
168
  ### 2. Resolve the feature folder
@@ -154,8 +172,8 @@ Whichever way the folder was found, the job's key is the `<KEY>` in its name (`P
154
172
  - **One match:** continue that feature. Its existing `spec.md`, `plan.md`, and `tasks.md` are inputs to the spec writer.
155
173
  - **Several matches:** list them and ask which one.
156
174
  - **None:**
157
- - From a key: read the ticket title through the [issue-tracker](../issue-tracker/SKILL.md) skill (MCP first, CLI fallback). Derive a kebab slug from the title (lowercase, non-alphanumerics to `-`, at most 4 words). Create `docs/features/<KEY>-<slug>/`. If the ticket cannot be read, stop and ask for a slug. Do not guess.
158
- - From a slug or free text: create `docs/features/<slug>/`.
175
+ - From a key: read the ticket title through the [issue-tracker](../issue-tracker/SKILL.md) skill (MCP first, CLI fallback). Derive a kebab slug from the title (lowercase, non-alphanumerics to `-`, at most 4 words). Create `<target>/<KEY>-<slug>/`, where `<target>` is the new-feature folder (see Feature folders). If the ticket cannot be read, stop and ask for a slug. Do not guess.
176
+ - From a slug or free text: create `<target>/<slug>/`, with the same `<target>`.
159
177
 
160
178
  ### 3. Resume or create the job
161
179
 
@@ -169,17 +187,17 @@ Resume by stage:
169
187
 
170
188
  | Stage | Resume action |
171
189
  | --- | --- |
172
- | `spec` | Rerun `factory-spec-writer` in spec mode, then show the spec gate |
190
+ | `spec` | Rerun `planner` in spec mode (brief `roles/spec.md`), then show the spec gate |
173
191
  | `awaiting-spec` | Show the spec gate |
174
- | `plan` | Rerun `factory-spec-writer` in plan mode, then show the plan gate |
192
+ | `plan` | Rerun `planner` in plan mode (brief `roles/spec.md`), then show the plan gate |
175
193
  | `awaiting-plan` | Show the plan gate |
176
- | `build` | Rerun `factory-builder` in the mode the files call for: rework if a `rework-<k>.md` is newer than `build.md`, repair if the last review round has `CHANGES`, otherwise build |
194
+ | `build` | Rerun `implementer` (brief `roles/build.md`) in the mode the files call for: rework if a `rework-<k>.md` is newer than `build.md`, repair if the last review round has `CHANGES`, otherwise build |
177
195
  | `review` | Rerun the review round `round` |
178
- | `approve` | Rerun `factory-approver` |
196
+ | `approve` | Rerun the approval (`reviewer` in approval mode, brief `roles/approve.md`) |
179
197
  | `awaiting-human` | Print the approver's rationale, the suggested checks from `qa.md` (see QA guidance), and the `/factory approve` command |
180
198
  | `needs-human`, `failed_stage` `spec` | Rerun the spec stage (see Spec), then show the spec gate |
181
199
  | `needs-human`, `failed_stage` `plan` | Rerun the plan stage (see Plan), then show the plan gate |
182
- | `needs-human`, otherwise | Print the reason from `decision.md`, `merge-conflict.md`, or `build.md`, and the options: rework, approve, or abandon |
200
+ | `needs-human`, otherwise | Print the reason from `decision.md`, `merge-conflict.md`, `bootstrap.md`, or `build.md`, and the options: rework, approve, or abandon |
183
201
  | `abandoned` | Closed. Say so and stop. To work on the feature again, run `/factory start <slug or KEY>`, which creates a new job |
184
202
  | Archived (in `factory/archive/`, any stage) | Closed. Say so and stop (see Start step 1) |
185
203
 
@@ -198,7 +216,7 @@ A job with no work started (stage before `build`, so no build has begun and no `
198
216
 
199
217
  ## Spec
200
218
 
201
- Set stage `spec`. Dispatch `factory-spec-writer` in spec mode with the paths block, the feature request, and the feature folder. It writes `spec.md`. If `intake.md` is in the paths block, the spec writer reads it, and the operator's answers win over the request text where they conflict. Wait for `spec.md` (see Harness notes). Set stage `awaiting-spec` and show the spec gate.
219
+ Set stage `spec`. Dispatch `planner` in spec mode (brief `roles/spec.md`) with the paths block, the feature request, and the feature folder. It writes `spec.md`. If `intake.md` is in the paths block, the spec writer reads it, and the operator's answers win over the request text where they conflict. Wait for `spec.md` (see Harness notes). Set stage `awaiting-spec` and show the spec gate.
202
220
 
203
221
  ## Spec gate (mandatory)
204
222
 
@@ -214,13 +232,13 @@ Then ask in chat, as a numbered choice:
214
232
  Handle the answer:
215
233
 
216
234
  - **Confirm** → continue to Plan. If decision items are still open, do not continue: list them and ask again.
217
- - **Request changes:** write the operator's text verbatim to `spec-<k>.md` in the job folder (`k` = next free index). Set stage `spec`, rerun `factory-spec-writer` in spec mode with the paths block and `spec-<k>.md`. It updates `spec.md`. Set stage `awaiting-spec` and show the gate again. The spec writer records each answered decision as `[DECIDED] <answer>`.
235
+ - **Request changes:** write the operator's text verbatim to `spec-<k>.md` in the job folder (`k` = next free index). Set stage `spec`, rerun `planner` in spec mode (brief `roles/spec.md`) with the paths block and `spec-<k>.md`. It updates `spec.md`. Set stage `awaiting-spec` and show the gate again. The spec writer records each answered decision as `[DECIDED] <answer>`.
218
236
 
219
237
  If the session ends at this gate, `/factory start <job-id|slug|KEY>` shows it again (see Start).
220
238
 
221
239
  ## Plan
222
240
 
223
- Set stage `plan`. Dispatch `factory-spec-writer` in plan mode with the paths block, and `plan-<k>.md` when a plan change request is pending. It writes `plan.md` in the feature folder, and `tasks.md` for large work (or removes a stale `tasks.md` when the plan is small). It does not change `spec.md`.
241
+ Set stage `plan`. Dispatch `planner` in plan mode (brief `roles/spec.md`) with the paths block, and `plan-<k>.md` when a plan change request is pending. It writes `plan.md` in the feature folder, and `tasks.md` for large work (or removes a stale `tasks.md` when the plan is small). It does not change `spec.md`.
224
242
 
225
243
  Read the `**Size:**` line of `plan.md`:
226
244
 
@@ -252,7 +270,7 @@ Then ask in chat, as a numbered choice:
252
270
  Handle the answer:
253
271
 
254
272
  - **Confirm** with size known → continue to Tracking. If size is still `unclear`, ask again.
255
- - **Request changes:** write the operator's text verbatim to `plan-<k>.md` (`k` = next free index). Set stage `plan`, rerun `factory-spec-writer` in plan mode with the paths block and `plan-<k>.md`. Show the gate again. If the change touches the spec itself, send it through the spec gate instead: write it to `spec-<k>.md`, rerun spec mode, show the spec gate, then plan again.
273
+ - **Request changes:** write the operator's text verbatim to `plan-<k>.md` (`k` = next free index). Set stage `plan`, rerun `planner` in plan mode (brief `roles/spec.md`) with the paths block and `plan-<k>.md`. Show the gate again. If the change touches the spec itself, send it through the spec gate instead: write it to `spec-<k>.md`, rerun spec mode, show the spec gate, then plan again.
256
274
  - **Change size only:** the operator's answer to choice 3 sets `size` in `job.json`. The plan does not change.
257
275
  - **Change tracking only:** update `tracking` in `job.json`. Do not rerun the spec writer.
258
276
  - **Change build mode only:** update `worktree` in `job.json`. Do not rerun the spec writer. In-place is checked when the build starts (see In-place mode).
@@ -267,7 +285,7 @@ Runs once, after the operator confirms the plan and before the build location is
267
285
  2. **Parent.** If `issue_key` is set, that ticket is the parent. Otherwise create the parent ticket. Set `issue_key` to its key.
268
286
  3. **Sub-tasks.** Run the `/assign-tasks` flow on the feature's `tasks.md`, with the issue-tracker skill's epic discovery and the flow's consolidation rules. Create one ticket per `tasks.md` line that has no key yet, under the parent.
269
287
  4. **Write keys.** Append ` — <KEY>` to each line as its ticket is created. Lines that already have a key are skipped.
270
- 5. **Rename.** If the folder had no key, rename `docs/features/<slug>/` to `docs/features/<KEY>-<slug>/`. Use `git mv` when git tracks the folder, `mv` otherwise. Stop if the target exists. Then update `feature_dir` in `job.json`. The rename is committed on the job branch with the feature docs (see Feature docs commit).
288
+ 5. **Rename.** If the folder had no key, rename `<parent>/<slug>/` to `<parent>/<KEY>-<slug>/`, where `<parent>` is the feature root that holds it (the parent of `feature_dir`). Use `git mv` when git tracks the folder, `mv` otherwise. Stop if the target exists. Then update `feature_dir` in `job.json`. The rename is committed on the job branch with the feature docs (see Feature docs commit).
271
289
 
272
290
  If a ticket cannot be created, stop at `awaiting-plan`. Report the lines that have keys and the error, and record it in `tracker_errors`. The operator can fix the cause and run `/factory start <job-id>`, or switch tracking to `none`.
273
291
 
@@ -278,14 +296,23 @@ The default build location. Use the [using-git-worktrees](../using-git-worktrees
278
296
  - Branch `factory/<id>` from `{{DEFAULT_BRANCH}}`.
279
297
  - Path `../<repo-name>-factory/<id>/` relative to the main checkout, where `<repo-name>` is the basename of the main checkout. Record it in `worktree_path`.
280
298
  - Create it at the start of the build stage, after the plan gate and tracking. Reuse it if it exists (rework and repair).
281
- - Copy the job's `spec.md`, `plan.md`, and `tasks.md` (if any) from the main checkout's feature folder into the same relative path in the worktree. The builder ticks `tasks.md` there. Then make the feature docs commit (next section).
299
+ - Copy the job's `spec.md`, `plan.md`, and `tasks.md` (if any) from the main checkout's feature folder into the same relative path in the worktree. The builder ticks `tasks.md` there. Then run the bootstrap (next subsection) and make the feature docs commit.
282
300
  - Job state stays in the main checkout's `factory/jobs/<id>/`, never in the worktree.
283
301
 
302
+ ### Worktree bootstrap
303
+
304
+ Each new worktree needs its own setup: dependencies or vendored packages, local env files, and a database for the job. The project lists those steps in `factory/worktree-bootstrap.md`, one shell command per line, in order. Comment lines are notes, and the default file has no active steps. The project edits the file; this skill only runs it.
305
+
306
+ - Run each step from the worktree root, after the copy above and before the feature docs commit. A reused worktree (rework, repair) reruns the steps, so they must be safe to run again.
307
+ - Each step gets these variables: `FACTORY_JOB_ID` (the job id, for names such as a per-job database), `FACTORY_PORT_BUILDER` (the builder's dev-server port), `FACTORY_WORKTREE` (the worktree path), and `FACTORY_MAIN_CHECKOUT` (the main checkout, where ignored local files such as `.env` live).
308
+ - A step that fails stops the build before the builder is dispatched. Write `bootstrap.md` in the job folder with the step, its exit code, and the last lines of its output; set stage `needs-human`. The worktree stays. The operator fixes the cause, then runs `/factory rework <id>`, which reruns the bootstrap before the builder. Delete `bootstrap.md` once every step passes.
309
+ - In-place builds do not bootstrap. The main checkout is the environment, so run the steps by hand there if it lacks them.
310
+
284
311
  ## Feature docs commit
285
312
 
286
313
  Runs once the job's branch exists, in its build location (the worktree, or the main checkout for an in-place job), before the builder is dispatched. It puts the job's feature docs on the branch, so the main checkout can stay clean and the merge carries them:
287
314
 
288
- 1. Remove the old unkeyed folder when the feature folder was renamed to its keyed name: `git rm -r -q --ignore-unmatch -- docs/features/<slug>`. Skip it when `feature_dir` is `docs/features/<slug>`.
315
+ 1. Remove the old unkeyed folder when the feature folder was renamed to its keyed name: `git rm -r -q --ignore-unmatch -- <parent>/<slug>`, where `<parent>` is the parent of `feature_dir`. Skip it when `feature_dir` is `<parent>/<slug>`.
289
316
  2. `git add -A -- <feature_dir>`.
290
317
  3. `git diff --cached --quiet || git commit -q -m "docs: feature docs for <id>"`. Nothing is committed when nothing is staged.
291
318
 
@@ -298,7 +325,7 @@ Used only when `worktree` is `false`: the operator asked for it with `--in-place
298
325
  Create the branch at build start, after the plan gate and tracking, only when all four checks pass. If one fails, stay at `awaiting-plan` and tell the operator which one:
299
326
 
300
327
  - The main checkout is on `{{DEFAULT_BRANCH}}`.
301
- - `git status --porcelain --untracked-files=no -- . ':(exclude)docs/features'` is empty. The feature docs are excluded because the spec writer and tracking write there, and the feature docs commit carries them onto the branch.
328
+ - `git status --porcelain --untracked-files=no -- . <feature-root excludes>` is empty. The feature docs are excluded because the spec writer and tracking write there, and the feature docs commit carries them onto the branch.
302
329
  - No other job with `worktree` `false` is open (not `merged` or `abandoned`).
303
330
  - No job with `worktree` `true` holds its build location.
304
331
 
@@ -333,28 +360,28 @@ PATHS
333
360
  - Ports: builder <p>, ux <p+1>, ui <p+2>
334
361
  ```
335
362
 
336
- Agents read their inputs and write their one output file by these absolute paths. The spec-writer works in the main-checkout feature folder. Reviewers and the approver read the spec and plan there. The builder reads them there and ticks `tasks.md` in the build location's copy. Reviewers read `qa.md` at the paths block's `qa.md` line, for context only.
363
+ Agents read their inputs by these absolute paths. Builders and spec writers write their output files there; reviewers and the approver return their report instead (see Subagent dispatch). The spec-writer works in the main-checkout feature folder. Reviewers and the approver read the spec and plan there. The builder reads them there and ticks `tasks.md` in the build location's copy. Reviewers read `qa.md` at the paths block's `qa.md` line, for context only.
337
364
 
338
365
  ## Loop
339
366
 
340
367
  Let `N` be the current round, starting at `1` for a new job.
341
368
 
342
- 1. **Spec.** Dispatch `factory-spec-writer` in spec mode (see Spec).
369
+ 1. **Spec.** Dispatch `planner` in spec mode (brief `roles/spec.md`) (see Spec).
343
370
  2. **Spec gate.** Show the gate and wait for the operator's confirmation (see Spec gate). Do not continue until the operator confirms.
344
- 3. **Plan.** Dispatch `factory-spec-writer` in plan mode (see Plan). Set stage `awaiting-plan`.
371
+ 3. **Plan.** Dispatch `planner` in plan mode (brief `roles/spec.md`) (see Plan). Set stage `awaiting-plan`.
345
372
  4. **Plan gate.** Show the gate and wait for the operator's confirmation (see Plan gate). Do not continue until the operator confirms.
346
373
  5. **Tracking and build location.** Run Tracking if `tracking` is `tracked`. Create the build location: the worktree and its copy of the feature docs (see Worktree), or the in-place branch (see In-place mode). Set `worktree_path` if a worktree was made. Set stage `build`. Move any tracked tickets to In Progress (see Ticket lifecycle).
347
- 6. **Build.** Dispatch `factory-builder` in build mode. Wait (see Harness notes), then read the first line of `build.md`:
374
+ 6. **Build.** Dispatch `implementer` (brief `roles/build.md`) in build mode. Wait (see Harness notes), then read the first line of `build.md`:
348
375
  - `STATUS: READY` → continue.
349
376
  - `STATUS: BLOCKED` → stage `needs-human`. Tell the user the reason from `build.md`. Stop.
350
377
  - Anything else → treat as BLOCKED with reason "builder wrote no valid status".
351
378
  7. **Review round N.** Set stage `review`, `round` to `N`, and every configured lens to `pending` in `reviews`. Move tracked tickets to In Review. Dispatch the lenses from `{{FACTORY_REVIEW_LENSES}}` in two stages, each with the paths block:
352
- - **Stage A:** `code` → `factory-reviewer-code` and `security` → `factory-reviewer-security`. Dispatch both in one parallel batch (one message with multiple agent calls) when the harness can.
353
- - **Stage B:** `ux` → `factory-reviewer-ux` and `ui` → `factory-reviewer-ui`, the browser lenses. Start them only after every stage A review is written. The code reviewer's build runs in the shared build location and would clobber the browser lenses' dev servers. The two browser lenses use separate ports and may run in parallel with each other.
379
+ - **Stage A:** `code` → `reviewer` (brief `roles/review-code.md`) and `security` → `reviewer`, in fresh context (brief `roles/review-security.md`). Dispatch both in one parallel batch (one message with multiple agent calls) when the harness can.
380
+ - **Stage B:** `ux` → `reviewer` (brief `roles/review-ux.md`) and `ui` → `reviewer` (brief `roles/review-ui.md`), the browser lenses. Start them only after every stage A review is written. The code reviewer's build runs in the shared build location and would clobber the browser lenses' dev servers. The two browser lenses use separate ports and may run in parallel with each other.
354
381
 
355
382
  If the harness cannot dispatch in parallel, run the lenses one at a time, in the order above.
356
383
 
357
- Wait for every `round-N/review-<lens>.md` (see Harness notes). Each must have a first line `VERDICT: PASS` or `VERDICT: CHANGES`. A reviewer that returns without a valid file is re-dispatched alone, once. If it still fails, stage `needs-human`. Never resume the builder during a review round. Update `reviews` from the verdicts.
384
+ Wait for every reviewer's reply, and save each as `round-N/review-<lens>.md` (see Harness notes). Each must have a first line `VERDICT: PASS` or `VERDICT: CHANGES`. A reviewer whose reply has no valid first line is re-dispatched alone, once. If it still fails, stage `needs-human`. Never resume the builder during a review round. Update `reviews` from the verdicts.
358
385
  8. **Verdicts.** Check in this order:
359
386
  - Any blocking item titled `Not verified:`, from any lens: no repair. Stage `needs-human`. Tell the user the `Not verified` items. Stop.
360
387
  - Any `CHANGES`, and the cycle has used fewer than 3 review rounds: run a builder repair (below) with `Round` set to `N`, the round just reviewed. Then set `N` to `N + 1` and go to step 7.
@@ -362,14 +389,14 @@ Let `N` be the current round, starting at `1` for a new job.
362
389
  - All `PASS`: go to step 9.
363
390
 
364
391
  A review cycle is the rounds since the job started, or since the latest `rework-<k>.md` (see Rework). "Third review round of the cycle" means two repairs have already been made in this cycle. The rework note records where its cycle starts.
365
- 9. **Approve.** Set stage `approve`. Dispatch `factory-approver` with the paths block. Wait for `decision.md` (see Harness notes). Its first line must be `APPROVE` or `ESCALATE`. If the line is missing or invalid, re-dispatch once, then stage `needs-human`.
392
+ 9. **Approve.** Set stage `approve`. Dispatch `reviewer` in approval mode (brief `roles/approve.md`, fresh context) with the paths block. Wait for the approver's reply and save it as `decision.md` (see Harness notes). Its first line must be `APPROVE` or `ESCALATE`. If the line is missing or invalid, re-dispatch once, then stage `needs-human`.
366
393
  - `ESCALATE` → stage `needs-human`. Tell the user the rationale. Stop.
367
394
  - `APPROVE` and `{{APPROVAL_MODE}}` is exactly `auto` → run the merge procedure.
368
395
  - `APPROVE` otherwise: stage `awaiting-human`. Print the suggested checks (see QA guidance). Tell the user to run `/factory approve <id>` after reviewing the branch. Stop. Any value other than exactly `auto` is treated as `human`.
369
396
 
370
397
  ### Repair
371
398
 
372
- Dispatch `factory-builder` in repair mode with the paths block, where `Round` is the round just reviewed (the `N` from step 7, before it increments). It reads `spec.md`, `plan.md`, `build.md`, and `round-<Round>/review-*.md`. It must address every `CHANGES` item or justify it in `build.md`. It also rewrites `qa.md`. Wait for `build.md` (see Harness notes) and check its first line again (step 6 rules).
399
+ Dispatch `implementer` (brief `roles/build.md`) in repair mode with the paths block, where `Round` is the round just reviewed (the `N` from step 7, before it increments). It reads `spec.md`, `plan.md`, `build.md`, and `round-<Round>/review-*.md`. It must address every `CHANGES` item or justify it in `build.md`. It also rewrites `qa.md`. Wait for `build.md` (see Harness notes) and check its first line again (step 6 rules).
373
400
 
374
401
  ### Builder continuity
375
402
 
@@ -383,7 +410,7 @@ Either way the builder runs only between reviews, never during one.
383
410
  ### Failures
384
411
 
385
412
  - Missing or unreadable `AGENTS.md` commands → stop and ask the user to add them. Do not guess commands.
386
- - An agent that finishes without its expected file → re-dispatch that agent once, then `needs-human`. For a spec or plan agent, set `failed_stage` to `spec` or `plan` with it.
413
+ - An agent that finishes without its expected output (a file, or for a reviewer or the approver, a reply with a valid first line) → re-dispatch that agent once, then `needs-human`. For a spec or plan agent, set `failed_stage` to `spec` or `plan` with it.
387
414
  - An agent that times out is not re-dispatched (see Harness notes).
388
415
 
389
416
  ## Ticket lifecycle
@@ -394,8 +421,9 @@ Tickets follow the job. The parent and every sub-task listed in `tasks.md` move
394
421
  | --- | --- |
395
422
  | Build starts, including rework | In Progress |
396
423
  | Review round starts | In Review |
397
- | Human approves and the merge runs (`/factory approve`) | Done |
424
+ | The merge completes: the local merge, or in `push-mr` the finish step after the forge merged the request (`/factory approve`) | Done |
398
425
  | `/factory approve` on a `merged` job (for example after `auto` merged it) | Done |
426
+ | `push-mr` opens or updates the request | In Review (no change) |
399
427
  | `/factory abandon` | Left as they are. The report lists their keys |
400
428
 
401
429
  Rules:
@@ -419,7 +447,7 @@ Rules:
419
447
  <the user's note, verbatim>
420
448
  ```
421
449
 
422
- 4. Set `round` to `N`, stage `build`. Move tracked tickets to In Progress. For an in-place job, switch the main checkout to `factory/<id>` if needed (see In-place mode). Dispatch a fresh `factory-builder` in rework mode. It reads the latest `rework-<k>.md` and rewrites `qa.md`. Wait for it. Then continue from step 6's status check on `build.md` (do not dispatch the builder again), and run review round `N` from step 7.
450
+ 4. Set `round` to `N`, stage `build`. Move tracked tickets to In Progress. For an in-place job, switch the main checkout to `factory/<id>` if needed (see In-place mode). For a worktree job, rerun the bootstrap first (see Worktree bootstrap); a failed step stops the rework the way it stops a build. Dispatch a fresh `implementer` (brief `roles/build.md`) in rework mode. It reads the latest `rework-<k>.md` and rewrites `qa.md`. Wait for it. Then continue from step 6's status check on `build.md` (do not dispatch the builder again), and run review round `N` from step 7.
423
451
 
424
452
  The new cycle starts with a fresh repair budget. Old rounds and reviews are kept, not overwritten.
425
453
 
@@ -448,11 +476,11 @@ Rules:
448
476
  3. Refuse unless the first line of `build.md` is exactly `STATUS: READY`. A job that failed before its build has no `build.md`: say so, and point to `/factory start <job-id>` (for a failed spec or plan step) or `/factory abandon <job-id>`.
449
477
  4. Refuse while `merge-conflict.md` exists in the job folder. The user resolves the conflict on the branch, then removes that file.
450
478
  5. Print the reason the job stopped before merging, so the user sees what they approve: the `ESCALATE` rationale in `decision.md`, the `Not verified` items, or the failed agent. For `awaiting-human`, print the approver's rationale.
451
- 6. Run the merge procedure.
479
+ 6. Run the merge procedure for `{{MERGE_MODE}}`. In `push-mr`, a job with `mr` set takes the finish path there instead.
452
480
 
453
481
  ## Abandon
454
482
 
455
- `/factory abandon <job-id>` closes a job that will not continue, such as one stopped before its build or one the operator no longer wants. It merges nothing and pushes nothing.
483
+ `/factory abandon <job-id>` closes a job that will not continue, such as one stopped before its build or one the operator no longer wants. It merges nothing and pushes nothing. If the job has `mr` set, the report gives its URL: abandon does not close the request, so the operator closes it on the forge.
456
484
 
457
485
  1. Refuse if the stage is already `merged` or `abandoned`. If an agent for the job may still be running (stage `spec`, `plan`, `build`, `review`, or `approve`), confirm with the operator in chat first, because the agent may still write its file.
458
486
  2. Set stage `abandoned`, `failed_stage` `null`, and `updatedAt`.
@@ -466,23 +494,45 @@ Rules:
466
494
 
467
495
  ## Merge procedure
468
496
 
497
+ Mode: `{{MERGE_MODE}}`. Exactly `push-mr` runs the forge procedure, after the local merge below. Any other value runs the local merge, the default and the only mode that never pushes.
498
+
499
+ ### Local merge
500
+
469
501
  Local only. **Never push.** Never force-delete a branch or worktree.
470
502
 
471
- 1. **Preconditions.** Worktree jobs: the main checkout is on `{{DEFAULT_BRANCH}}`. In-place jobs: the main checkout is on `factory/<id>`. For both, `git status --porcelain --untracked-files=no -- . ':(exclude)docs/features'` is empty. Feature docs are excluded here because step 3 reconciles them. Untracked files, including ignored `factory/jobs/**`, do not block. Worktree jobs also stop while another in-place job holds its build location (see Stages). Say which job it is: "In-place job `<id>` holds the main checkout; approve or abandon it first." If a precondition fails, stop and tell the user. Do not change the stage. For an in-place job, once the checks pass, run `git switch {{DEFAULT_BRANCH}}`. The branch stays in place.
503
+ 1. **Preconditions.** Worktree jobs: the main checkout is on `{{DEFAULT_BRANCH}}`. In-place jobs: the main checkout is on `factory/<id>`. For both, `git status --porcelain --untracked-files=no -- . <feature-root excludes>` is empty. Feature docs are excluded here, through the feature-root excludes, because step 3 reconciles them. Untracked files, including ignored `factory/jobs/**`, do not block. Worktree jobs also stop while another in-place job holds its build location (see Stages). Say which job it is: "In-place job `<id>` holds the main checkout; approve or abandon it first." If a precondition fails, stop and tell the user. Do not change the stage. For an in-place job, once the checks pass, run `git switch {{DEFAULT_BRANCH}}`. The branch stays in place.
472
504
  2. Record `PRE=$(git rev-parse HEAD)`.
473
- 3. **Feature docs.** The branch already carries the job's feature docs (see Feature docs commit), so the main checkout's copies are set aside and its feature paths return to the `{{DEFAULT_BRANCH}}` state. Let `P` be `<feature_dir>`, plus `docs/features/<slug>` when that differs:
505
+ 3. **Feature docs.** The branch already carries the job's feature docs (see Feature docs commit), so the main checkout's copies are set aside and its feature paths return to the `{{DEFAULT_BRANCH}}` state. Let `P` be `<feature_dir>`, plus `<parent>/<slug>` (the parent of `feature_dir`) when that differs:
474
506
  - Copy each path that `git status --porcelain --untracked-files=all -- <P>` lists into `factory/jobs/<id>/main-copies/`, keeping its path. For a rename, copy the new path. Skip paths that no longer exist.
475
507
  - `git reset -q -- <P>`, then `git clean -fdq -- <P>`. This removes only the untracked copies made above.
476
508
  - If `git ls-tree -r --name-only {{DEFAULT_BRANCH}} -- <P>` lists files, `git checkout -- <P>` restores them.
477
509
 
478
510
  This is a move, not a delete. Git refuses a merge that would overwrite local or untracked files, so this step must come first.
479
511
  4. `git merge --no-ff factory/<id> -m "Merge factory/<id>: <feature>"`. On conflict run `git merge --abort`, copy the `main-copies/` files back to their paths, write `merge-conflict.md` in the job folder listing the conflicting files, set stage `needs-human`, and report them.
480
- 5. Run the test command from `AGENTS.md` in the main checkout. On failure run `git reset --keep $PRE` (this undoes the merge), copy the `main-copies/` files back to their paths, set stage `needs-human`, and report the failing output. For an in-place job, the main checkout stays on `{{DEFAULT_BRANCH}}` and the branch stays for inspection.
512
+ 5. Run the test commands from `AGENTS.md`'s Commands table in the main checkout, scoped to the change. Map the paths in `git diff --name-only $PRE HEAD` to their apps and packages, and run the test command of each one. A changed shared package also runs the test command of every workspace that depends on it (the package manifests show which). Run the root test command too when the table lists one. On failure run `git reset --keep $PRE` (this undoes the merge), copy the `main-copies/` files back to their paths, set stage `needs-human`, and report the failing output. For an in-place job, the main checkout stays on `{{DEFAULT_BRANCH}}` and the branch stays for inspection.
481
513
  6. Worktree jobs: `git worktree remove <worktree>`, then `git branch -d factory/<id>`. In-place jobs: skip the worktree removal and run only `git branch -d factory/<id>`. `-d` refuses unless the branch is merged, which is the safety check. If either fails after the merge succeeded, do not undo the merge. Continue to step 7 and report the leftover worktree or branch path for the user to remove.
482
514
  7. Set stage `merged`. If the merge came from `/factory approve`, move the job's tickets to Done (if tracked). After an `auto` merge they stay In Review; tell the user to run `/factory approve <id>` to move them to Done. Report that the merge is local and was not pushed. Print the suggested checks (see QA guidance).
483
515
 
484
516
  On any `needs-human` outcome, leave the branch and worktree in place so the user can inspect them.
485
517
 
518
+ ### Push and merge request (`push-mr`)
519
+
520
+ Runs in place of the local merge, when `{{MERGE_MODE}}` is `push-mr` and the approval is an `/factory approve` or an `auto` APPROVE. It pushes the branch and opens one merge request (GitLab) or pull request (GitHub). The forge's review and merge are the final gate, so nothing merges locally, the main checkout is not touched, and force-push is never used.
521
+
522
+ 1. **Forge and preconditions.** Pick the forge from `git remote get-url origin`: a GitHub host uses `gh`, a GitLab host uses `glab`. Stop and tell the operator if that CLI is missing or its auth check fails (`gh auth status` or `glab auth status`). The build location must have no tracked changes: `git -C <build location> status --porcelain --untracked-files=no` is empty. Do not change the stage on a failed precondition.
523
+ 2. **Test gate.** Run the test commands of the local merge, step 5, in the build location on the branch, before any push. A failure sets stage `needs-human`, reports the output, and pushes nothing.
524
+ 3. **Push.** `git -C <build location> push -u origin factory/<id>`. A rejected push stops here: set stage `needs-human` and report the message. Do not force.
525
+ 4. **Open the request, once.** Skip this step when `mr` is already set. Otherwise:
526
+ - GitHub: `gh pr create --base {{DEFAULT_BRANCH}} --head factory/<id> --title "<feature>" --body-file <job folder>/decision.md`
527
+ - GitLab: `glab mr create --source-branch factory/<id> --target-branch {{DEFAULT_BRANCH}} --title "<feature>" --description-file <job folder>/decision.md --yes`
528
+
529
+ Record the URL the command prints in `mr`. A failed command sets stage `needs-human` and reports the error. Nothing is recorded, and rerunning approve retries from step 1.
530
+ 5. **Stage.** Set stage `awaiting-human`. Tickets stay In Review. Print the request URL and say: "Review and merge it on the forge, then run `/factory approve <id>` to finish." Under `auto`, the same message applies: the forge merge stays the human gate.
531
+ 6. **Finish (`/factory approve` with `mr` set).** Run `git fetch origin`, then read the request's state: `gh pr view <mr> --json state --jq .state`, or `glab mr view <mr> --output json` and its `state` field. If the CLI's flags differ, check its `--help` first.
532
+ - **Merged:** a worktree job runs `git worktree remove <worktree_path>`. An in-place job runs `git switch {{DEFAULT_BRANCH}}` in the main checkout when it is on `factory/<id>`. Then `git branch -D factory/<id>`. This is the one place the local merge's `-d` rule does not apply: `-d` refuses after a squash merge, and the forge's merge is the proof. If the removal fails, keep what remains and report the path. Then set the main checkout's feature copies aside with local merge step 3, so the default branch's merged docs can arrive on pull, and tell the operator to pull `{{DEFAULT_BRANCH}}`. Set stage `merged`, move tickets to Done (if tracked), and report.
533
+ - **Open:** if `git rev-parse factory/<id>` differs from `git rev-parse origin/factory/<id>`, the job has commits the request lacks (for example after a rework). Run steps 2 and 3 to update it, and report that the request was updated. Otherwise report that it is still open, and stop. Nothing else changes.
534
+ - **Closed without merge:** keep stage `awaiting-human`, report it, and offer rework, reopening the request on the forge, or abandon.
535
+
486
536
  ## Status
487
537
 
488
538
  Read each `factory/jobs/*/job.json`. Print one row per open job: id, stage, round, reviews, issue key, size, tracking, updatedAt, and the next action for that stage. Write nothing.
@@ -496,7 +546,7 @@ Closed jobs (`merged` or `abandoned`) are hidden by default. Print one line in t
496
546
  | `plan` | Wait, or `/factory start <id>` to resume if the session ended |
497
547
  | `awaiting-plan` | `/factory start <id>` to review the plan and confirm it |
498
548
  | `build`, `review`, `approve` | Wait, or `/factory start <id>` to resume if the session ended |
499
- | `awaiting-human` | Review the branch and its `qa.md` (suggested checks, not a gate), then `/factory approve <id>` |
549
+ | `awaiting-human` | Review the branch and its `qa.md` (suggested checks, not a gate), then `/factory approve <id>`. In `push-mr` with `mr` set: merge the request on the forge, then `/factory approve <id>` to finish. Print the request URL |
500
550
  | `needs-human` | Read the reason. A failed spec or plan step: `/factory start <id>` reruns it. After a build: `/factory rework <id> <note>` or `/factory approve <id>`. Either way, `/factory abandon <id>` closes the job |
501
551
  | `abandoned` | Nothing: the job is closed. To work on the feature again, `/factory start <slug or KEY>` creates a new job |
502
552
  | `merged` | Nothing, unless tickets are not Done yet: `/factory approve <id>` |
@@ -533,7 +583,7 @@ The live view needs an interactive terminal, which agent shells do not have, so
533
583
 
534
584
  ## Prune
535
585
 
536
- `/factory prune [--all] [--abandoned] [--dry-run]` permanently deletes closed jobs from both `factory/jobs/` and `factory/archive/`. By default only `merged` jobs are deleted. `--abandoned` also deletes `abandoned` jobs. A pruned job cannot be recovered. It never deletes an open job, and it never touches `docs/features/`.
586
+ `/factory prune [--all] [--abandoned] [--dry-run]` permanently deletes closed jobs from both `factory/jobs/` and `factory/archive/`. By default only `merged` jobs are deleted. `--abandoned` also deletes `abandoned` jobs. A pruned job cannot be recovered. It never deletes an open job, and it never touches a feature folder.
537
587
 
538
588
  The age rule is the same as Archive: by default only jobs whose `updatedAt` is more than 7 days ago, and `--all` drops the age limit. A job with no valid `updatedAt` is not selected. `--abandoned` adds `abandoned` jobs under the same rule. Without it, abandoned jobs are never selected, and the list counts the ones it kept.
539
589
 
@@ -550,30 +600,46 @@ The age rule is the same as Archive: by default only jobs whose `updatedAt` is m
550
600
 
551
601
  ## Subagent dispatch
552
602
 
553
- Dispatch with the paths block first, then the task line, then the files to read. The task line names the mode when the agent has one (spec or plan for the spec writer; build, repair, or rework for the builder). The dispatch primitive is the Claude Agent tool, the Copilot `agent` tool, or the harness's own subagent mechanism elsewhere.
603
+ Dispatch with the paths block first, then the task line, then the role brief and the files to read. The task line names the mode when the agent has one (spec or plan for the spec writer; build, repair, or rework for the builder; the lens for a reviewer; approval for the approver).
554
604
 
555
- Each harness has its own wrappers. Every wrapper points to its snippet in `.claude/agents-snippets/`:
605
+ Factory adds no agents of its own. Each role runs on a native agent (`planner`, `implementer`, or `reviewer`), and the Factory rules for that role (outputs, evidence, verdict format, escalation triggers) live in its brief in this skill's `roles/` folder. Every dispatch tells the agent to read the matching brief first. The role brief overrides the dispatched agent's default output format and file-writing rules, and the first line of the reply must follow the brief.
556
606
 
557
- | Harness | Agent wrappers | Entry point |
607
+ | Role | Native agent | Task line | Brief | Fresh context | Output |
608
+ | --- | --- | --- | --- | --- | --- |
609
+ | Spec writer | `planner` | `spec` or `plan` mode | `roles/spec.md` | no | writes `spec.md`, or `plan.md` and `tasks.md` |
610
+ | Builder | `implementer` | `build`, `repair`, or `rework` mode | `roles/build.md` | no | writes `build.md` and `qa.md` |
611
+ | Code reviewer | `reviewer` | lens `code` | `roles/review-code.md` | no | returns its review |
612
+ | Security reviewer | `reviewer` | lens `security` | `roles/review-security.md` | yes | returns its review |
613
+ | UX reviewer | `reviewer` | lens `ux` | `roles/review-ux.md` | no | returns its review |
614
+ | UI reviewer | `reviewer` | lens `ui` | `roles/review-ui.md` | no | returns its review |
615
+ | Approver | `reviewer` | `approval` mode | `roles/approve.md` | yes | returns its decision |
616
+
617
+ Reviewers and the approver return their report in their final reply and do not write files. You save the reply: the review as `round-<N>/review-<lens>.md`, the decision as `decision.md`. The first line of the reply is the verdict or decision, and that is what you check.
618
+
619
+ Each harness dispatches the native agent by name:
620
+
621
+ | Harness | How to dispatch | Entry point |
558
622
  | --- | --- | --- |
559
- | Claude Code | `.claude/agents/factory-*.agent.md` | `.claude/commands/factory.md` |
560
- | GitHub Copilot | `.github/agents/factory-*.agent.md` | `.github/prompts/factory.prompt.md` |
561
- | Cursor | `.cursor/agents/factory-*.agent.md` | `.cursor/commands/factory.md` |
562
- | OpenCode | `.opencode/agents/factory-*.md` | `.opencode/commands/factory.md` |
563
- | Codex | none | this skill |
623
+ | Claude Code | the Agent tool, naming the agent | `.claude/commands/factory.md` |
624
+ | GitHub Copilot | the `agent` tool, naming the agent | `.github/prompts/factory.prompt.md` |
625
+ | Cursor | the agent by name from `.cursor/agents` | `.cursor/commands/factory.md` |
626
+ | OpenCode | the agent by name from `.opencode/agents` | `.opencode/commands/factory.md` |
627
+ | Codex | none: run the brief directly | this skill |
628
+
629
+ Codex has no agent files. Run each role brief directly, as a delegated or fresh session, passing the paths block first. If the harness gives you one session only, use single-session mode (see Harness notes).
564
630
 
565
- Codex has no wrappers. Run each `.claude/agents-snippets/factory-*.md` as a delegated or fresh session, passing the paths block first. If the harness gives you one session only, use single-session mode (see Harness notes).
631
+ In OpenCode with the Slim plugin, `oracle` (security or approval) and `designer` (ux or ui) are optional alternatives to the native agents. Use them only if you have configured them as edit-denied reviewers. The native agents above are the default.
566
632
 
567
- Dispatch each agent by its kebab-case name, for example `factory-builder`. Copilot may show a display name in its agent list; pick the agent with that name.
633
+ Copilot may show a display name in its agent list; pick the agent with the name above.
568
634
 
569
635
  ## Harness notes
570
636
 
571
- The loop is the same in every harness. Use a parallel lens batch where the harness offers one, otherwise run the lenses in order. If dispatch is background-only, poll each expected file for a valid first line until the timeout, then apply Failures. Builder resume is under Builder continuity; wrappers are under Subagent dispatch.
637
+ The loop is the same in every harness. Use a parallel lens batch where the harness offers one, otherwise run the lenses in order. If dispatch is background-only, poll each expected file for a valid first line until the timeout, then apply Failures. A reviewer or approver reply arrives as its result; check its first line the same way. Builder resume is under Builder continuity; agent names are under Subagent dispatch.
572
638
 
573
639
  - **Timeout.** The default is 15 minutes per agent. The operator can set another value for one run by saying so in the request, for example `timeout 30 min`.
574
640
  - **A timed-out agent is never re-dispatched.** It may still be running, and a second run could write the same file. Stage `needs-human` with the reason "`<agent>` timed out after `<N>` min; it may still be running". For a spec or plan agent, also set `failed_stage`. Tell the operator to check the job folder and the build location, and to confirm the agent has stopped, before `/factory start` or `/factory rework`.
575
641
 
576
- **Single-session mode (Codex).** Codex has no wrappers, so one session plays every role. The orchestrator switches roles one at a time. For each agent it reads only that role's snippet and input files, writes only that role's output, and keeps the same write boundaries. The rule "never write code" applies per role: as orchestrator it writes only orchestrator files, and it writes code only as the builder, and only in the build location. Lenses run in order (stage A, then stage B). The security reviewer judges the diff, not the builder's account. A timed-out role is handled as above; a role that ends without its file is re-run once, then `needs-human`.
642
+ **Single-session mode (Codex).** Codex has no agent files, so one session plays every role. The orchestrator switches roles one at a time. For each role it reads only that role's brief and input files, writes only that role's output (a reviewer or the approver returns its report, and you save it), and keeps the same write boundaries. The rule "never write code" applies per role: as orchestrator it writes only orchestrator files, and it writes code only as the builder, and only in the build location. Lenses run in order (stage A, then stage B). The security reviewer judges the diff, not the builder's account. A timed-out role is handled as above; a role that ends without its file is re-run once, then `needs-human`.
577
643
 
578
644
  ## Limits
579
645
 
@@ -1,6 +1,6 @@
1
1
  # Factory Approver
2
2
 
3
- You decide whether a job goes to merge or to a human. You are the approval gate of the [factory](../../.agents/skills/factory/SKILL.md) pipeline. You work from the paths block the orchestrator gives you. You decide; you do not merge, fix, or re-review.
3
+ You decide whether a job goes to merge or to a human. You are the approval gate of the [factory](../SKILL.md) pipeline. You work from the paths block the orchestrator gives you. You decide; you do not merge, fix, or re-review.
4
4
 
5
5
  ## Inputs
6
6
 
@@ -32,7 +32,7 @@ You decide whether a job goes to merge or to a human. You are the approval gate
32
32
 
33
33
  ## Output
34
34
 
35
- You write exactly one file: `<job folder>/decision.md`. Use this skeleton:
35
+ You do not write files. Your final reply is the decision, and the orchestrator saves it as `<job folder>/decision.md`, so start the reply with the decision line. Use this skeleton:
36
36
 
37
37
  ```markdown
38
38
  APPROVE
@@ -66,7 +66,7 @@ The first line must be exactly `APPROVE` or `ESCALATE`, followed by the rational
66
66
 
67
67
  - When in doubt, `ESCALATE`. A wrong escalation costs one human click. A wrong approval can ship a security or data problem.
68
68
  - An `ESCALATE` rationale names the trigger or the failed step, so the human can decide quickly.
69
- - Do not edit code, reviews, `build.md`, `job.json`, `tasks.md`, or any file other than `decision.md`.
69
+ - Do not edit code, reviews, `build.md`, `job.json`, `tasks.md`, or any other file.
70
70
  - Do not merge, push, or change branches.
71
71
  - Do not transition tickets. The orchestrator owns ticket status, and the approver never touches the tracker.
72
72
  - `qa.md` is not a gate. Do not count its checks in the decision, and do not escalate because it is missing.
@@ -1,6 +1,6 @@
1
1
  # Factory Builder
2
2
 
3
- You build one job's feature inside its build location. You are one agent in the [factory](../../.agents/skills/factory/SKILL.md) pipeline. You work from the paths block the orchestrator gives you.
3
+ You build one job's feature inside its build location. You are one agent in the [factory](../SKILL.md) pipeline. You work from the paths block the orchestrator gives you.
4
4
 
5
5
  ## Modes
6
6
 
@@ -30,9 +30,9 @@ The orchestrator tells you which mode you are in:
30
30
 
31
31
  ## Method
32
32
 
33
- Follow the [test-driven development](../../.agents/skills/test-driven-development/SKILL.md) skill: write a failing test, watch it fail, write the minimal code, watch it pass, then refactor. Keep the diff as small as the spec allows, per [ponytail](../../.agents/skills/ponytail/SKILL.md).
33
+ Follow the [test-driven development](../../test-driven-development/SKILL.md) skill: write a failing test, watch it fail, write the minimal code, watch it pass, then refactor. Keep the diff as small as the spec allows, per [ponytail](../../ponytail/SKILL.md).
34
34
 
35
- Before you claim any acceptance criterion is met, follow [verification before completion](../../.agents/skills/verification-before-completion/SKILL.md): run the check and record the command and its result as evidence.
35
+ Before you claim any acceptance criterion is met, follow [verification before completion](../../verification-before-completion/SKILL.md): run the check and record the command and its result as evidence.
36
36
 
37
37
  ## Output
38
38
 
@@ -1,6 +1,6 @@
1
1
  # Factory Reviewer: Code
2
2
 
3
- You review one round of a job's branch for correctness, simplicity, reuse, conventions, and docs, and you run the project's checks. You are the `code` lens of the [factory](../../.agents/skills/factory/SKILL.md) pipeline. You work from the paths block the orchestrator gives you.
3
+ You review one round of a job's branch for correctness, simplicity, reuse, conventions, and docs, and you run the project's checks. You are the `code` lens of the [factory](../SKILL.md) pipeline. You work from the paths block the orchestrator gives you.
4
4
 
5
5
  ## Inputs
6
6
 
@@ -16,17 +16,17 @@ Run each command the project documents in `AGENTS.md` from the build location: t
16
16
 
17
17
  ## Review
18
18
 
19
- Use the [requesting code review](../../.agents/skills/requesting-code-review/SKILL.md) checklist for process. Then cover:
19
+ Use the [requesting code review](../../requesting-code-review/SKILL.md) checklist for process. Then cover:
20
20
 
21
21
  - **Correctness:** logic, edge cases, error handling at boundaries, every acceptance criterion in `spec.md` covered by a test or check.
22
- - **Simplicity:** use the [ponytail-review](../../.agents/skills/ponytail-review/SKILL.md) lens. Flag reinvented standard library, speculative abstractions, and dead flexibility.
22
+ - **Simplicity:** use the [ponytail-review](../../ponytail-review/SKILL.md) lens. Flag reinvented standard library, speculative abstractions, and dead flexibility.
23
23
  - **Reuse:** the change should extend existing utilities rather than duplicate them.
24
24
  - **Conventions:** the project's `AGENTS.md`, the `AGENTS.md` of each affected app or package, and `.claude/rules-snippets/` standards.
25
25
  - **Docs:** documentation the project's `AGENTS.md` requires for this kind of change, in the affected app's docs folder for per-app work.
26
26
 
27
27
  ## Output
28
28
 
29
- You write exactly one file: `<job folder>/round-<N>/review-code.md`. Use this skeleton:
29
+ You do not write files. Your final reply is the report, and the orchestrator saves it as `<job folder>/round-<N>/review-code.md`, so start the reply with the verdict line. Use this skeleton:
30
30
 
31
31
  ```markdown
32
32
  VERDICT: PASS
@@ -54,4 +54,4 @@ The first line must be exactly `VERDICT: PASS` or `VERDICT: CHANGES`.
54
54
  - `CHANGES` needs at least one blocking item. Each blocking item is specific (file and line), actionable, and about correctness, a failing check, a missing acceptance criterion, or a clear convention break.
55
55
  - Taste goes under non-blocking notes. Taste never blocks a PASS.
56
56
  - A failing test, lint, or build command is a blocking item unless the failure is in code the branch does not touch and is shown on the default branch too.
57
- - Do not edit code, tests, or any file other than your review. Do not fix problems yourself.
57
+ - Do not edit code, tests, or any file. Do not fix problems yourself.