nitm-ai-dev-toolkit 5.3.0 → 5.3.1
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.
- package/CHANGELOG.md +4 -0
- package/package.json +1 -1
- package/src/monorepo/.agents/skills/factory/SKILL.md +38 -21
- package/src/monorepo/.agents/skills/factory/roles/approve.md +4 -2
- package/src/monorepo/.agents/skills/factory/roles/build.md +36 -8
- package/src/monorepo/.agents/skills/factory/roles/review-code.md +3 -1
- package/src/monorepo/.agents/skills/factory/roles/review-security.md +1 -1
- package/src/monorepo/.agents/skills/factory/roles/review-ui.md +1 -1
- package/src/monorepo/.agents/skills/factory/roles/review-ux.md +1 -1
- package/src/monorepo/.claude/prompt-snippets/implement-fixes.md +1 -1
- package/src/monorepo/.claude/prompt-snippets/implement.md +57 -6
- package/src/monorepo/factory/README.md +11 -5
- package/src/repo/.agents/skills/factory/SKILL.md +38 -21
- package/src/repo/.agents/skills/factory/roles/approve.md +4 -2
- package/src/repo/.agents/skills/factory/roles/build.md +36 -8
- package/src/repo/.agents/skills/factory/roles/review-code.md +3 -1
- package/src/repo/.agents/skills/factory/roles/review-security.md +1 -1
- package/src/repo/.agents/skills/factory/roles/review-ui.md +1 -1
- package/src/repo/.agents/skills/factory/roles/review-ux.md +1 -1
- package/src/repo/.claude/prompt-snippets/implement-fixes.md +1 -1
- package/src/repo/.claude/prompt-snippets/implement.md +57 -6
- package/src/repo/factory/README.md +11 -5
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Functional QA in the implement loop and Factory. Each acceptance criterion gets every feasible automated check (`local`, `covered`, or `na`), and a human check is added only where a person must judge it. Missing necessary tests and unavailable evidence stay pending or block acceptance rather than passing. A human check needs a `PASS` and an explicit `accept` for the tested tree. The Factory `qa.md` carries the functional QA record: `/factory approve` refuses failed, not-run, missing, or stale automated evidence, and a human check holds the merge even under `auto`. Human answers are kept in `build.md`. The manual checklist stays non-gating. Tests: `test/functional-qa-contract.test.js`.
|
|
13
|
+
|
|
10
14
|
## [5.3.0] - 2026-11-14
|
|
11
15
|
|
|
12
16
|
Retirement/relevance and wrapper-audit entries below were already shipped in 5.2.0.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitm-ai-dev-toolkit",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.1",
|
|
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"
|
|
@@ -5,7 +5,7 @@ description: Opt-in software factory for feature-sized work. Runs one job throug
|
|
|
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. 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.
|
|
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, It also appends the user's QA answer, verbatim, to `build.md` (see Functional QA).
|
|
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
|
|
|
@@ -51,7 +51,7 @@ A first argument of `start`, `approve`, `rework`, `abandon`, `status`, `watch`,
|
|
|
51
51
|
spec.md spec-writer, spec mode (from the feature spec template)
|
|
52
52
|
plan.md spec-writer, plan mode: approach, steps, and the **Size:** line
|
|
53
53
|
tasks.md spec-writer, plan mode, large work only
|
|
54
|
-
qa.md builder, on the branch:
|
|
54
|
+
qa.md builder, on the branch: functional QA record (plan, runs, results) and the human handoff (see Functional QA)
|
|
55
55
|
factory/
|
|
56
56
|
README.md setup and reference
|
|
57
57
|
.gitignore ignores jobs/ and archive/
|
|
@@ -62,7 +62,7 @@ factory/
|
|
|
62
62
|
intake.md you: the original request verbatim under `## Original request`, the questions and answers (when asked), and `## Baseline confirmed` (when needed)
|
|
63
63
|
spec-<k>.md you, from the operator's change request at the spec gate
|
|
64
64
|
plan-<k>.md you, from the operator's change request at the plan gate
|
|
65
|
-
build.md builder; cumulative round log
|
|
65
|
+
build.md builder; cumulative round log; you append the user's QA answer blocks (kept on rewrite)
|
|
66
66
|
round-<N>/review-<lens>.md one per configured lens
|
|
67
67
|
decision.md approver (or you, on escalation)
|
|
68
68
|
merge-conflict.md you, on a merge conflict (blocks approve)
|
|
@@ -194,10 +194,10 @@ Resume by stage:
|
|
|
194
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 |
|
|
195
195
|
| `review` | Rerun the review round `round` |
|
|
196
196
|
| `approve` | Rerun the approval (`reviewer` in approval mode, brief `roles/approve.md`) |
|
|
197
|
-
| `awaiting-human` | Print the approver's rationale, the
|
|
197
|
+
| `awaiting-human` | Print the approver's rationale, the QA record and any human handoff from `qa.md` (see QA guidance), and the `/factory approve` command |
|
|
198
198
|
| `needs-human`, `failed_stage` `spec` | Rerun the spec stage (see Spec), then show the spec gate |
|
|
199
199
|
| `needs-human`, `failed_stage` `plan` | Rerun the plan stage (see Plan), then show the plan gate |
|
|
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 |
|
|
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. If a human check is pending, print its exact handoff from `qa.md` first |
|
|
201
201
|
| `abandoned` | Closed. Say so and stop. To work on the feature again, run `/factory start <slug or KEY>`, which creates a new job |
|
|
202
202
|
| Archived (in `factory/archive/`, any stage) | Closed. Say so and stop (see Start step 1) |
|
|
203
203
|
|
|
@@ -383,7 +383,7 @@ PATHS
|
|
|
383
383
|
- Ports: builder <p>, ux <p+1>, ui <p+2>
|
|
384
384
|
```
|
|
385
385
|
|
|
386
|
-
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
|
|
386
|
+
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. The code lens checks its functional QA record. The other lenses read it for context only. The approver checks the record (see Functional QA).
|
|
387
387
|
|
|
388
388
|
## Loop
|
|
389
389
|
|
|
@@ -414,8 +414,8 @@ Let `N` be the current round, starting at `1` for a new job.
|
|
|
414
414
|
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.
|
|
415
415
|
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`.
|
|
416
416
|
- `ESCALATE` → stage `needs-human`. Tell the user the rationale. Stop.
|
|
417
|
-
- `APPROVE` and `{{APPROVAL_MODE}}` is exactly `auto` → run the merge procedure.
|
|
418
|
-
- `APPROVE` otherwise: stage `awaiting-human`. Print the
|
|
417
|
+
- `APPROVE` and `{{APPROVAL_MODE}}` is exactly `auto` → run the merge procedure, unless the job has a `human` criterion (see Functional QA). Such a job stops at `awaiting-human` even under `auto`, as below.
|
|
418
|
+
- `APPROVE` otherwise: stage `awaiting-human`. Print the QA guidance, with the human handoff when there is one (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`.
|
|
419
419
|
|
|
420
420
|
### Repair
|
|
421
421
|
|
|
@@ -474,21 +474,36 @@ Rules:
|
|
|
474
474
|
|
|
475
475
|
The new cycle starts with a fresh repair budget. Old rounds and reviews are kept, not overwritten.
|
|
476
476
|
|
|
477
|
-
## QA
|
|
477
|
+
## Functional QA
|
|
478
478
|
|
|
479
|
-
|
|
479
|
+
Functional QA means the changed behavior was run, not only built. The rules are the shared loop's [Functional QA](../../../.claude/prompt-snippets/implement.md#functional-qa): automated checks for every AC, a human check only where a person must judge, the plan before the build, recorded runs, safety, identity and freshness, and the handoff. This section adds the Factory mechanics. Gates use only the existing verdicts and stages.
|
|
480
480
|
|
|
481
|
-
-
|
|
482
|
-
-
|
|
483
|
-
-
|
|
481
|
+
- **Plan.** Before writing code, the builder writes the QA table into `qa.md` in the build location: one row per AC and check, with its kind (`local`, `covered`, `human`, or `na`), its exact command or fixture, and its expected result. A human check is an extra row on its AC, never a replacement for the automated rows. Observed and Result start as `-` and `planned`.
|
|
482
|
+
- **Run.** The order is fixed: the code commit, then the runs on that commit, then the evidence commit. After the final code commit, the builder runs each automated check and each cited `covered` test, fills in Observed and Result, records `Tested commit: <hash>` (the code commit), and commits `qa.md` with the work. A `human` row is never recorded as passed.
|
|
483
|
+
- **Review.** The code lens re-runs each automated command from the table and each cited `covered` test, and compares the results with the recorded ones (see the code brief). A failed row, a missing feasible automated check, or a label without its reason is a `VERDICT: CHANGES` item, repaired within the usual three review rounds. A check that could not run because a credential, data, or environment is missing is a blocking item titled `Not verified: functional QA <AC-n>: <reason>`. It sends the job to `needs-human`, and nothing is repaired for it.
|
|
484
|
+
- **Approve.** The approver checks the record (see its brief) and escalates on a failed, missing, or not-run automated check, or on stale evidence. Evidence is stale when the build location has uncommitted changes, or when a committed change since `Tested commit` touches a file that an automated check runs or covers. The only exempt change is a record-only edit to `qa.md`, one that changes the Observed, Result, or Tested commit cells and nothing else. Changes to files that no check runs or covers do not stale the record. A changed criterion, command, expected result, or evidence line does. The approver does not count human rows or the manual checklist.
|
|
485
|
+
- **Human checks.** For an AC with a human check, the handoff is the `## Manual checks` section of `qa.md`: numbered steps, each with its AC and expected result, plus the fields from implement.md's Functional QA (tested commit, setup and test accounts by name, seeded prerequisites, what was already tested, cleanup, and the response template). The orchestrator prints it at `awaiting-human`, even under `auto`, and the job waits there. Acceptance needs `PASS` and an explicit `accept` for the tested commit named in the handoff (Approve step 6). `not run` with `accept` stays pending. `reject` or `FAIL` means rework. The answer is saved verbatim in `build.md` as a `## Human QA answer` block. After any rework or any change to a checked file, the tested commit changes, and a new handoff is printed. Ask the user with the harness's native question tool when one exists, and only when no independent authorized work remains or a gate needs the answer; otherwise ask in chat at that point. Resume restores the exact pending handoff from `qa.md`, not a summary of it.
|
|
486
|
+
- **Unavailable user.** Nothing repeats or loops. The job stays at `awaiting-human`, the handoff stays in `qa.md`, the status table shows it, and other jobs continue. Absence is never signoff.
|
|
487
|
+
- **Where the evidence lives.** `qa.md` is on the job branch in the build location: the worktree path from the paths block, or the main checkout for an in-place job. The orchestrator reads it there before the merge, and from the main checkout's feature folder after it. Answers are in `build.md` in the job folder, which git ignores, so they survive worktree removal. The builder keeps those blocks when it rewrites `build.md`.
|
|
488
|
+
- **Missing record.** A missing `qa.md`, or a missing `## Functional QA` section, escalates when the job has any automated or human check. Otherwise it is only noted.
|
|
489
|
+
- **Optional checks.** They are listed under `## Not covered by automated tests`, each with its reason. They never block.
|
|
484
490
|
|
|
485
|
-
|
|
491
|
+
## QA guidance
|
|
492
|
+
|
|
493
|
+
The builder writes `qa.md`, committed with the work. It holds the functional QA record, the human handoff when there is one, and the operator's checklist. It rewrites it on repair and rework rounds. A small job can have a few lines.
|
|
494
|
+
|
|
495
|
+
When the job reaches `awaiting-human` or `needs-human`, and after an auto merge, print (from the build location before the merge, from the main checkout's feature folder after it):
|
|
496
|
+
|
|
497
|
+
- First, the mandatory items: every `## Not verified` item from the latest round's reviews, and every failed, not-run, or stale automated check from the record. These are blocking and never sit under the optional line.
|
|
498
|
+
- If a human check is pending: `Human QA required before /factory approve: answer the handoff below`, then the handoff.
|
|
499
|
+
- The `## Functional QA` table with its results.
|
|
500
|
+
- Under the line `Suggested checks before /factory approve — not a gate`, the `## Not covered by automated tests` items.
|
|
501
|
+
- If `qa.md` is missing: `No qa.md: no QA record or suggested checks.`
|
|
486
502
|
|
|
487
503
|
Rules:
|
|
488
504
|
|
|
489
|
-
-
|
|
490
|
-
- A missing `qa.md`
|
|
491
|
-
- When the job reaches `awaiting-human` or `needs-human`, and after an auto merge, print `qa.md` (from the build location before the merge, from the main checkout's feature folder after it). Then print the `## Not verified` items from the latest round's reviews. Put this line before them: `Suggested checks before /factory approve — not a gate`. If `qa.md` is missing, print `No qa.md: no suggested checks.` in its place.
|
|
505
|
+
- Only the checklist and the limitations are optional. They never change a verdict.
|
|
506
|
+
- A missing `qa.md`, or a missing `## Functional QA` section, escalates only when the job has an automated or human check. Otherwise it is noted.
|
|
492
507
|
|
|
493
508
|
## Approve
|
|
494
509
|
|
|
@@ -498,8 +513,10 @@ Rules:
|
|
|
498
513
|
2. Otherwise refuse unless stage is `awaiting-human` or `needs-human`. The user's explicit command is the approval. Do not re-run the approver.
|
|
499
514
|
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>`.
|
|
500
515
|
4. Refuse while `merge-conflict.md` exists in the job folder. The user resolves the conflict on the branch, then removes that file.
|
|
501
|
-
5.
|
|
502
|
-
6.
|
|
516
|
+
5. **Required QA evidence.** Refuse, in every mode and from `needs-human` too, while the functional QA record in `qa.md` shows a failed, not-run, or missing automated check or covered test, or stale evidence (see Functional QA, Approve). Name the row and what the user must supply. Do not waive this with the approve command: the fix is rework, or a builder repair followed by review. The existing overrides for other items are unchanged.
|
|
517
|
+
6. **Human QA.** Only when the job has a `human` check (see Functional QA). The command alone is not enough for it. If no answer is recorded for the tested commit, print the handoff from `qa.md` and ask in chat for the answer in the response template, then stop. When the answer comes, append it verbatim to `build.md` as a `## Human QA answer (<tested commit>)` block. Proceed only when every human check reads `PASS` with an explicit `accept` for that commit. A `FAIL` or `reject` does not merge: tell the user to run `/factory rework <job-id> <note>` naming the row. `defer`, `not run`, or no answer leaves the job at `awaiting-human`. A job with no `human` check skips this step.
|
|
518
|
+
7. 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.
|
|
519
|
+
8. Run the merge procedure for `{{MERGE_MODE}}`. In `push-mr`, a job with `mr` set takes the finish path there instead.
|
|
503
520
|
|
|
504
521
|
## Abandon
|
|
505
522
|
|
|
@@ -569,7 +586,7 @@ Closed jobs (`merged` or `abandoned`) are hidden by default. Print one line in t
|
|
|
569
586
|
| `plan` | Wait, or `/factory start <id>` to resume if the session ended |
|
|
570
587
|
| `awaiting-plan` | `/factory start <id>` to review the plan and confirm it |
|
|
571
588
|
| `build`, `review`, `approve` | Wait, or `/factory start <id>` to resume if the session ended |
|
|
572
|
-
| `awaiting-human` | Review the branch and
|
|
589
|
+
| `awaiting-human` | Review the branch and the QA record in `qa.md`. Answer any pending `human` check in its handoff, then `/factory approve <id>`. A `reject` means `/factory rework <id> <note>`. In `push-mr` with `mr` set: merge the request on the forge, then `/factory approve <id>` to finish. Print the request URL |
|
|
573
590
|
| `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 |
|
|
574
591
|
| `abandoned` | Nothing: the job is closed. To work on the feature again, `/factory start <slug or KEY>` creates a new job |
|
|
575
592
|
| `merged` | Nothing, unless tickets are not Done yet: `/factory approve <id>` |
|
|
@@ -668,7 +685,7 @@ The loop is the same in every harness. Use a parallel lens batch where the harne
|
|
|
668
685
|
|
|
669
686
|
## Limits
|
|
670
687
|
|
|
671
|
-
File-write boundaries are prompt conventions, not enforced isolation. Nothing physically stops an agent from writing outside its file. The real gates are the spec and plan gates, the reviewer verdicts, the approver's rules and dry-run merge check, and the merge procedure's preconditions and test run. Ticket updates are best-effort and never gate the pipeline. `qa.md`
|
|
688
|
+
File-write boundaries are prompt conventions, not enforced isolation. Nothing physically stops an agent from writing outside its file. The real gates are the spec and plan gates, the reviewer verdicts, the approver's rules and dry-run merge check, and the merge procedure's preconditions and test run. Ticket updates are best-effort and never gate the pipeline. The `## Functional QA` record in `qa.md` gates through the code lens and the approver. The manual checklist gates nothing. A pending `human` check gates the merge only through approval (see Functional QA).
|
|
672
689
|
|
|
673
690
|
## Related
|
|
674
691
|
|
|
@@ -4,7 +4,7 @@ You decide whether a job goes to merge or to a human. You are the approval gate
|
|
|
4
4
|
|
|
5
5
|
## Inputs
|
|
6
6
|
|
|
7
|
-
- The whole job history: `spec.md` and `plan.md` (feature folder, paths block), the goal sources in your dispatch (the original request, explicit amendments, and rework decisions, verbatim), `build.md`, `rework-*.md` if any, every `round-*/review-*.md`, and the job's `job.json`.
|
|
7
|
+
- The whole job history: `spec.md` and `plan.md` (feature folder, paths block), the QA record in `qa.md` (paths block's `qa.md` line, its `## Functional QA` section), the goal sources in your dispatch (the original request, explicit amendments, and rework decisions, verbatim), `build.md`, `rework-*.md` if any, every `round-*/review-*.md`, and the job's `job.json`.
|
|
8
8
|
- The final diff: `git -C <worktree> diff {{DEFAULT_BRANCH}}...factory/<id>`.
|
|
9
9
|
- The project's `AGENTS.md` for test commands.
|
|
10
10
|
|
|
@@ -13,6 +13,8 @@ You decide whether a job goes to merge or to a human. You are the approval gate
|
|
|
13
13
|
1. **Read the history.** Read everything listed above. Note any rework and what it asked for.
|
|
14
14
|
2. **Final-round reviews.** Confirm every review in the latest round has `VERDICT: PASS`. If any is `CHANGES` or missing, the decision is `ESCALATE`.
|
|
15
15
|
3. **Spot-check one acceptance criterion.** Pick at least one `AC-n` from `spec.md`. Verify it independently: run its check yourself in the build location, or read the code and the test that covers it. Do not trust the builder's evidence alone. Also check the branch diff against `plan.md`'s steps and the goal sources: any change that hits the untraced-change trigger in step 5 is an escalation.
|
|
16
|
+
|
|
17
|
+
Then check the `## Functional QA` record in `qa.md` against [SKILL Functional QA](../SKILL.md#functional-qa). Escalate when an automated check is `fail` or `not run`, when an automated row has no evidence from the tested commit, when a necessary automated check or covered test is missing, or when the record is stale. The record is stale when the build location has uncommitted changes (`git -C <worktree> status --porcelain` is not empty), or when a committed change since the tested commit touches a file that an automated check runs or covers (`git -C <worktree> diff --name-only <Tested commit> factory/<id>`). The only exempt change is a record-only edit to `qa.md`. Do not count human rows or the manual checklist.
|
|
16
18
|
4. **Dry-run merge.** Check for conflicts without changing anything:
|
|
17
19
|
```
|
|
18
20
|
git -C <main checkout> merge-tree --write-tree {{DEFAULT_BRANCH}} factory/<id>
|
|
@@ -70,4 +72,4 @@ The first line must be exactly `APPROVE` or `ESCALATE`, followed by the rational
|
|
|
70
72
|
- Do not edit code, reviews, `build.md`, `job.json`, `tasks.md`, or any other file.
|
|
71
73
|
- Do not merge, push, or change branches.
|
|
72
74
|
- Do not transition tickets. The orchestrator owns ticket status, and the approver never touches the tracker.
|
|
73
|
-
- `qa.md` is not a gate
|
|
75
|
+
- The manual checklist in `qa.md` is not a gate, and its absence does not escalate. The `## Functional QA` record is evidence you check in step 3. A `human` check is not yours to decide: the orchestrator holds the job for the user's answer, so do not escalate or approve on it.
|
|
@@ -34,6 +34,8 @@ Follow the [test-driven development](../../test-driven-development/SKILL.md) ski
|
|
|
34
34
|
|
|
35
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
|
+
Functional QA follows [Functional QA](../SKILL.md#functional-qa). Write the QA plan into `qa.md` before you write code, and run and record the checks after your final code commit. Do not claim a `human` row passed.
|
|
38
|
+
|
|
37
39
|
## Output
|
|
38
40
|
|
|
39
41
|
You write two files.
|
|
@@ -62,22 +64,44 @@ You write two files.
|
|
|
62
64
|
|
|
63
65
|
The first line must be exactly `STATUS: READY` or `STATUS: BLOCKED`.
|
|
64
66
|
|
|
65
|
-
2. `qa.md` in the feature folder of the build location (committed on the branch).
|
|
67
|
+
2. `qa.md` in the feature folder of the build location (committed on the branch). Write the QA plan before the code. After the final code commit, rewrite it whole, so it matches the code as it is now. Use this skeleton:
|
|
66
68
|
|
|
67
69
|
```markdown
|
|
68
70
|
# QA: <feature title>
|
|
69
71
|
|
|
72
|
+
## Functional QA
|
|
73
|
+
|
|
74
|
+
Tested commit: `<code commit hash, after the final code commit>`
|
|
75
|
+
|
|
76
|
+
| AC | Class | Command or fixture | Expected | Observed | Result |
|
|
77
|
+
| --- | --- | --- | --- | --- | --- |
|
|
78
|
+
| AC-1 | local | `<exact command>` | <expected result> | - | planned |
|
|
79
|
+
| AC-2 | covered | `<test file>` `<test name>` | <expected result> | - | planned |
|
|
80
|
+
| AC-3 | human | see Manual checks | <expected result> | - | planned |
|
|
81
|
+
|
|
70
82
|
## How to run
|
|
71
83
|
|
|
72
84
|
- Setup: `<command from AGENTS.md>`
|
|
73
85
|
- Dev server: `<command>` on port <builder port>, passed with `<flag or env var from AGENTS.md>`
|
|
74
86
|
- Seed data: <what the dev environment provides, or "none">
|
|
75
87
|
- Flags or config: <or "none">
|
|
88
|
+
- Test accounts: <names only; credentials stay in the project's local secret store>
|
|
89
|
+
- Cleanup: <how to stop what you started, and how to reset the fixture>
|
|
90
|
+
- Already tested by the agent: <the rows that passed, with their results>. Needs the user: <the human rows>.
|
|
91
|
+
|
|
92
|
+
## Manual checks (human)
|
|
76
93
|
|
|
77
|
-
|
|
94
|
+
Only for `human` rows. Each check is numbered, names its AC, and gives a result a person can see.
|
|
78
95
|
|
|
79
|
-
1. AC-
|
|
80
|
-
|
|
96
|
+
1. AC-3: <what to do>. Expected: <what a person can observe>.
|
|
97
|
+
|
|
98
|
+
Answer each case in this template, in the user's own words after it:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
QA-<n>: PASS | FAIL | not run
|
|
102
|
+
Actual or error evidence: <what you saw>
|
|
103
|
+
Acceptance: accept | reject | defer
|
|
104
|
+
```
|
|
81
105
|
|
|
82
106
|
## Not covered by automated tests
|
|
83
107
|
|
|
@@ -86,16 +110,20 @@ You write two files.
|
|
|
86
110
|
|
|
87
111
|
Rules for `qa.md`:
|
|
88
112
|
|
|
89
|
-
-
|
|
90
|
-
-
|
|
113
|
+
- Plan first: the table is written before any code. Each row names its AC, its class (`local`, `covered`, `human`, or `na`), and the exact command, test, or fixture. An `na` row states its reason in Expected.
|
|
114
|
+
- Record after the final code commit: Observed holds what you saw. Result is `pass`, `fail`, `not run: <reason>`, or `NA: <reason>`. A missing credential, seed data, or environment is `not run: <reason>`. A missing necessary test is written first where you can, or recorded as `not run: no test` with its reason.
|
|
115
|
+
- Never record a `human` row as passed. The user answers those.
|
|
116
|
+
- Keep every section of `build.md` you did not write this round, including the orchestrator's `## Human QA answer` blocks. Rewrite the round log around them, never over them.
|
|
117
|
+
- Safety: use local isolated fixtures and the project's local test accounts only. Do not touch production, external services, or real data, and do not cause external side effects. Start only the local processes a check needs. Stop the ones you started, and leave existing servers running. Never weaken authentication or add a bypass.
|
|
118
|
+
- Optional checks go under "Not covered by automated tests", each with its reason. They never block.
|
|
91
119
|
- Keep it short. A small job needs a few lines.
|
|
92
120
|
|
|
93
121
|
## Rules
|
|
94
122
|
|
|
95
123
|
- Address every `CHANGES` item in repair mode. Fix it, or justify in the log why it should stand. Silence is not an option.
|
|
96
|
-
- Use `STATUS: BLOCKED` only when the spec cannot be built as written (contradiction, missing decision, unavailable dependency). Say exactly what the human must decide. Do not block on things you can work around.
|
|
124
|
+
- Use `STATUS: BLOCKED` only when the spec cannot be built as written (contradiction, missing decision, unavailable dependency, or a necessary QA test that cannot be written). Say exactly what the human must decide. Do not block on things you can work around.
|
|
97
125
|
- Report an acceptance criterion as pass only with evidence. A criterion you did not check is `not verified`, and say so.
|
|
98
126
|
- Run test, lint, and build for the affected apps and packages, using the filtered form from `AGENTS.md`. If a shared package changed, also run its downstream consumers.
|
|
99
127
|
- Tick `tasks.md` in the build location as you finish each task: change `- [ ]` to `- [x]` on that line once its acceptance criteria pass and the work is committed. Leave the rest of the line, including any ticket key, unchanged. Do not tick a task you did not finish.
|
|
100
128
|
- Do not add dependencies, abstractions, or files the spec does not need.
|
|
101
|
-
- Do not merge, approve, or edit reviewer files.
|
|
129
|
+
- Do not merge, approve, or edit reviewer files. Never write a QA result you did not observe. The QA record gates through the code reviewer and the approver, so a result written to pass a check is a fault.
|
|
@@ -6,7 +6,7 @@ You review one round of a job's branch for correctness, simplicity, reuse, conve
|
|
|
6
6
|
|
|
7
7
|
- `spec.md` and `plan.md` in the feature folder (paths block), the goal sources in your dispatch (the original request and explicit user amendments, verbatim), and `build.md` in the job folder.
|
|
8
8
|
- The branch diff: `git -C <worktree> diff {{DEFAULT_BRANCH}}...factory/<id>`.
|
|
9
|
-
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's
|
|
9
|
+
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's functional QA record (`## Functional QA`) and manual checks. Check the record as the Functional QA review below says. The manual checks are context only and never change your verdict.
|
|
10
10
|
- Round `N > 1`: your own previous review, `round-<N-1>/review-code.md`. Check whether earlier blocking items were fixed, and say so.
|
|
11
11
|
- The project's `AGENTS.md` for test, lint, and build commands.
|
|
12
12
|
|
|
@@ -20,6 +20,7 @@ Use the [requesting code review](../../requesting-code-review/SKILL.md) checklis
|
|
|
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
22
|
- **Scope trace, both ways:** trace the branch diff to `spec.md`'s requirements and acceptance criteria, `plan.md`'s steps, and the goal sources in your dispatch. Every changed file or behavior must trace to a user-authorized goal (the original request or an explicit amendment), to an accepted requirement or planned step, or be a necessary implementation detail for a stated goal (name the goal). A requirement or planned step with no change is a gap. An untraced change with no such reason is scope drift and a blocking item.
|
|
23
|
+
- **Functional QA:** check the `## Functional QA` record against [SKILL Functional QA](../SKILL.md#functional-qa). Each AC lists every feasible automated check with its label: `local` for observable behavior, `covered` for a cited existing test, and `na` with a reason. A `human` check is added on top where a person must judge. It never replaces an automated check. Re-run each `local` command and each cited `covered` test in the table, and compare the result with the recorded one. Every automated row needs a `pass` from the tested commit. A missing feasible automated check, a result that does not reproduce, a `fail`, or a label without its reason is a blocking item with its fix. A check that could not run for a missing credential, data, or environment is a blocking item titled `Not verified: functional QA <AC-n>: <reason>`.
|
|
23
24
|
- **Simplicity:** use the [ponytail-review](../../ponytail-review/SKILL.md) lens. Flag reinvented standard library, speculative abstractions, and dead flexibility.
|
|
24
25
|
- **Reuse:** the change should extend existing utilities rather than duplicate them.
|
|
25
26
|
- **Conventions:** the project's `AGENTS.md`, the `AGENTS.md` of each affected app or package, and `.claude/rules-snippets/` standards.
|
|
@@ -55,4 +56,5 @@ The first line must be exactly `VERDICT: PASS` or `VERDICT: CHANGES`.
|
|
|
55
56
|
- `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.
|
|
56
57
|
- Taste goes under non-blocking notes. Taste never blocks a PASS.
|
|
57
58
|
- 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.
|
|
59
|
+
- An automated QA row (`local` or `covered`) that fails on re-run is a blocking item. A row that could not run for a missing credential, data, or environment is the `Not verified: functional QA` item above, not a repair.
|
|
58
60
|
- Do not edit code, tests, or any file. Do not fix problems yourself.
|
|
@@ -6,7 +6,7 @@ You audit one round of a job's branch for security problems. You are the `securi
|
|
|
6
6
|
|
|
7
7
|
- The branch diff: `git -C <worktree> diff {{DEFAULT_BRANCH}}...factory/<id>`.
|
|
8
8
|
- `spec.md` in the feature folder (paths block), for what the feature is meant to do.
|
|
9
|
-
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's
|
|
9
|
+
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's functional QA record and manual checks. Use it for context only. The QA gate belongs to the code lens and the approver, so it never changes your verdict.
|
|
10
10
|
- Round `N > 1`: your own previous review, `round-<N-1>/review-security.md`.
|
|
11
11
|
|
|
12
12
|
## Method
|
|
@@ -15,7 +15,7 @@ You look at a job's feature running in the build location and review the visual
|
|
|
15
15
|
- `build.md` for what the builder says it changed.
|
|
16
16
|
- The project's `AGENTS.md` for the dev command, how to pass the port, and the design system or component library in use.
|
|
17
17
|
- Existing components the feature should match, including shared UI packages. Find them in the codebase, not from memory.
|
|
18
|
-
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's
|
|
18
|
+
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's functional QA record and manual checks. Use it for context only. The QA gate belongs to the code lens and the approver, so it never changes your verdict.
|
|
19
19
|
- Round `N > 1`: your own previous review, `round-<N-1>/review-ui.md`.
|
|
20
20
|
|
|
21
21
|
## Method
|
|
@@ -14,7 +14,7 @@ You look at a job's feature running in the build location and review the user ex
|
|
|
14
14
|
- `spec.md` in the feature folder (paths block), for the acceptance criteria and user flows.
|
|
15
15
|
- `build.md` for what the builder says it changed.
|
|
16
16
|
- The project's `AGENTS.md` for the dev command and how to pass the port.
|
|
17
|
-
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's
|
|
17
|
+
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's functional QA record and manual checks. Use it for context only. The QA gate belongs to the code lens and the approver, so it never changes your verdict.
|
|
18
18
|
- Round `N > 1`: your own previous review, `round-<N-1>/review-ux.md`.
|
|
19
19
|
|
|
20
20
|
## Method
|
|
@@ -49,7 +49,7 @@ Implement bug fixes and corrections with proper validation and documentation.
|
|
|
49
49
|
4. **Verify, Review and Decide** (repeat implement.md steps 3, 4 and 5 until an exit):
|
|
50
50
|
- Verify: rerun the reproducing test and confirm it passes now, run every check that covers an AC, and run the full test suite for regressions.
|
|
51
51
|
- Review: the independent read-only reviewer checks the fix, the reproducing test, and the untracked files.
|
|
52
|
-
- Decide: repair goes back to the same builder. Repeat until `ACCEPTED`, `BLOCKED`, or `NOT ACCEPTED: needs decision
|
|
52
|
+
- Decide: repair goes back to the same builder. Repeat until `ACCEPTED`, `BLOCKED`, or `NOT ACCEPTED: needs decision` (which includes a pending human QA check, reason `awaiting human QA`). There is no round limit. A review PASS alone never accepts.
|
|
53
53
|
|
|
54
54
|
5. **Commit and Push** (only after `ACCEPTED`, and only when there are accepted changes): stage only the fix's paths, never `git add -A` or a foreign change. Skip the commit when nothing is staged.
|
|
55
55
|
```bash
|
|
@@ -36,6 +36,7 @@ build → verify → review → decide ─┬─ accept (review PASS, every re
|
|
|
36
36
|
- Turn every requirement in the supplied task into an acceptance criterion, `AC-1`, `AC-2`, ... There is no fixed count: one criterion per requirement, however many there are. Do not add requirements the task does not state.
|
|
37
37
|
- Each AC names its check. Discover the real checks; do not assume them. Read the project's manifests (for example `package.json` scripts, `Makefile`, `pyproject.toml`, `Cargo.toml`, `go.mod`), its CI configuration (for example `.github/workflows`), its README, and `AGENTS.md`. Use the commands the project actually runs.
|
|
38
38
|
- A documentation criterion may be checked by direct inspection: open the file and confirm the content, and quote what you found as evidence.
|
|
39
|
+
- Each AC also gets its functional QA checks: every feasible automated check, plus a human check only where a person must judge it. Write the QA plan before the build: the exact command or fixture, and the expected result. See [Functional QA](#functional-qa).
|
|
39
40
|
- A required check that cannot be discovered, or cannot be run, is a gap. It is not a pass, and it is not a bypass. It blocks acceptance of the affected task and of any aggregate run that needs it. Ask the user for the command as one targeted question and keep that question in the progress report. Independent tasks whose checks do not depend on the gap continue (see the Blocked exit in step 5).
|
|
40
41
|
- Ask only when a requirement is unclear in a way that changes what gets built: two readings lead to different code, or a needed fact is missing. Ask one targeted question with its options. A task-scoped question blocks only that task and its dependents: independent tasks with clear requirements continue, and the question stays in the progress report (see [subagent-workflow.md](../rules-snippets/subagent-workflow.md), Autonomous Execution and Blockers). If the whole request is unclear, stop and ask before any build.
|
|
41
42
|
- Take a baseline snapshot once, before any build. It is a plain copy of the state the task starts from, kept in a temporary directory outside the repository:
|
|
@@ -52,6 +53,7 @@ build → verify → review → decide ─┬─ accept (review PASS, every re
|
|
|
52
53
|
- For a bug, first write a failing test that reproduces it, and watch it fail for the right reason. Then make the minimal change that passes it. For a feature, follow TDD: failing test, minimal code, then refactor. Keep the diff as small as the task allows.
|
|
53
54
|
- Leave all its changes uncommitted and unstaged, including new files, so the review sees them. Do not commit.
|
|
54
55
|
- Report each AC as `pass` with the command and result, or `not verified` with the reason. List every changed and new file.
|
|
56
|
+
- Report each automated QA check with its exact command, expected result, and observed result. Write a failing test for a necessary automated check that does not exist yet, and report it when it cannot be written.
|
|
55
57
|
- Report `BLOCKED` with the decision the human must make if the task cannot be built as written.
|
|
56
58
|
|
|
57
59
|
**Later rounds (repair):** dispatch the same builder again with only the open items: every blocking review item, every AC that is not `pass`, and every check that failed or did not run. It must fix each item, or say in its report why it should stand. It must not expand scope.
|
|
@@ -60,6 +62,8 @@ build → verify → review → decide ─┬─ accept (review PASS, every re
|
|
|
60
62
|
|
|
61
63
|
Every round, run every check that covers an AC, using the commands from step 1. Treat the builder's report as a lead, not as evidence. For each AC, record `pass` with the command and result from this round, or `not verified` or `fail` with the reason. Docs criteria are recorded with the quoted content.
|
|
62
64
|
|
|
65
|
+
Also run the automated QA checks for every AC on the current tree, including each `covered` test the AC cites. Record each result as described in [Functional QA](#functional-qa). Human checks go to the handoff; do not run them yourself.
|
|
66
|
+
|
|
63
67
|
Checks are scoped: each repair and each task runs the checks for its own ACs. After all writers are reconciled, run the project's full required regression checks once: the repo-defined full suite, lint, typecheck, and build, where they exist. Use only commands the project defines; do not invent them. A failed required check is a repair. A required check that does not exist or cannot run is BLOCKED (see step 5).
|
|
64
68
|
|
|
65
69
|
### 4. Review (reviewer, read-only)
|
|
@@ -77,24 +81,25 @@ The reviewer's rules:
|
|
|
77
81
|
- The first line of the reply is exactly `VERDICT: PASS` or `VERDICT: CHANGES`.
|
|
78
82
|
- `VERDICT: CHANGES` needs at least one blocking item, each with `file:line`, the problem, and the specific fix. Blocking means a correctness issue, a failing check, a requirement with no test or evidence, or a clear convention break. Taste goes in non-blocking notes.
|
|
79
83
|
- Check each requirement of the original task, not only the diff. A requirement with no coverage is a blocking item.
|
|
84
|
+
- QA evidence and labels: check the functional QA rows against [Functional QA](#functional-qa). An automated check with no `pass` from this round's tree, a necessary automated check that is missing, a `covered` check with no cited test, or an `na` with no reason is a blocking item. A human check a person must judge is not a reviewer blocking item.
|
|
80
85
|
- Scope drift, both ways: trace the diff against the original supplied task. A change that no requirement needs is a blocking item unless the reviewer confirms it is a necessary implementation detail for a stated goal and says why. Goals are the original supplied task plus the user amendments recorded in step 1: do not require or assume a spec or plan (supplied-task exception). Simplicity and SRP notes stay non-blocking unless they add scope the task does not ask for.
|
|
81
86
|
|
|
82
87
|
### 5. Decide (orchestrator)
|
|
83
88
|
|
|
84
89
|
Pick one outcome per round:
|
|
85
90
|
|
|
86
|
-
- **Repair (back to step 2):** the review is `VERDICT: CHANGES`, **or** any AC is `not verified` or `fail`, **or** a required check failed or did not run. Send the open items to the builder, then run steps 3, 4 and 5 again on the current tree.
|
|
87
|
-
- **Accept (exit):** all of these hold on this round's verify and review: the review is `VERDICT: PASS`; every requirement has an AC marked `pass` with evidence from this round; every required check ran and passed; an independent reviewer produced the verdict;
|
|
88
|
-
- **Blocked (exit for the affected work):** the builder reports `BLOCKED`, a required check cannot be discovered
|
|
89
|
-
- **Needs user decision (exit for the affected work):** the task is unclear in a way only the user can settle. Stop work on that task and its dependents, report `NOT ACCEPTED: needs decision` with the question, and continue independent authorized work. This is not acceptance.
|
|
91
|
+
- **Repair (back to step 2):** the review is `VERDICT: CHANGES`, **or** any AC is `not verified` or `fail`, **or** a required check failed or did not run, **or** an automated QA check failed, or a necessary automated test is missing and can be written. Send the open items to the builder, then run steps 3, 4 and 5 again on the current tree.
|
|
92
|
+
- **Accept (exit):** all of these hold on this round's verify and review: the review is `VERDICT: PASS`; every requirement has an AC marked `pass` with evidence from this round; every required check ran and passed; every automated QA check passed on this round's tree; an independent reviewer produced the verdict; the builder did not report `BLOCKED`; and every human check has a `PASS` result and an explicit `accept` from the user for the tree it tested. Then report `ACCEPTED` with the AC evidence. A review PASS alone never accepts, and a pending human check is never treated as accepted.
|
|
93
|
+
- **Blocked (exit for the affected work):** the builder reports `BLOCKED`, a required check cannot be discovered, a necessary QA test cannot be written, or no independent reviewer is available. Report `BLOCKED` with the blocker and what would unblock it. Never mark blocked work accepted. Work that depends on it stops; independent authorized work with its own checks and reviewer continues. Without an independent reviewer nothing is accepted, but discovery and builds that do not need acceptance may continue and be reported as awaiting review. Stop the run only when no authorized work remains or a mandatory approval, security, or permission gate applies.
|
|
94
|
+
- **Needs user decision (exit for the affected work):** the task is unclear in a way only the user can settle, a check needs a credential, data, or environment only the user can provide, or a human check waits for the user's answer. Stop work on that task and its dependents, report `NOT ACCEPTED: needs decision` with the question, and continue independent authorized work. For a pending human check, the reason is `awaiting human QA`, and the report carries the exact handoff from [Functional QA](#functional-qa). This is not acceptance.
|
|
90
95
|
|
|
91
|
-
No other exit exists. An unmet requirement
|
|
96
|
+
No other exit exists. An unmet requirement or a failing check loops back to repair. A `not verified` result loops back to repair only when the missing piece is code or test work the builder can do. A `not verified` result that waits on evidence only the user or the environment can supply, or on a pending human answer, is the needs-decision exit. There is no round limit to escape the loop.
|
|
92
97
|
|
|
93
98
|
**Evidence freshness.** Acceptance uses evidence from the tree it accepts. Any edit after a verify or review, whether by the builder, a repair, or the orchestrator, invalidates the evidence it affects: rerun the checks covering those ACs and re-review the changed diff. Reuse evidence that the edit cannot affect. If unsure whether an edit affects a check, treat it as affected. Do not rerun everything for an unrelated edit.
|
|
94
99
|
|
|
95
100
|
### Commit (only when the calling flow asks)
|
|
96
101
|
|
|
97
|
-
The loop never commits by itself. Accepting reports the result; it does not create a commit. The calling command decides whether accepted work is committed, and only when its own flow says so and the user has not asked otherwise. When it does commit:
|
|
102
|
+
The loop never commits by itself. Accepting reports the result; it does not create a commit. The calling command decides whether accepted work is committed, and only when its own flow says so and the user has not asked otherwise. Pending human QA does not change that policy. It blocks acceptance, completion, and merge of the affected work. It neither grants nor removes a commit or push that the calling flow or an explicit checkpoint authorizes. When it does commit:
|
|
98
103
|
|
|
99
104
|
- Stage only the paths this task changed, taken from the builder's list and checked against the baseline. Never `git add -A`, and never stage a preexisting or foreign change.
|
|
100
105
|
- Skip the commit when nothing is staged. Do not create empty commits, and do not create a separate commit for each repair round.
|
|
@@ -106,6 +111,52 @@ The loop never commits by itself. Accepting reports the result; it does not crea
|
|
|
106
111
|
- A self-review is never presented as an independent review.
|
|
107
112
|
- These gates are prompt instructions, not host enforcement. Resuming after a pause depends on the host; this prompt does not guarantee automatic resume.
|
|
108
113
|
|
|
114
|
+
## Functional QA
|
|
115
|
+
|
|
116
|
+
Acceptance needs evidence that the changed behavior works. A process that starts, a page that loads, or a passing build is not evidence.
|
|
117
|
+
|
|
118
|
+
**Checks per AC.** Every AC gets every feasible automated check. A human check never replaces one.
|
|
119
|
+
|
|
120
|
+
- `local`: the changed behavior is observable (UI, API, CLI, or library). Run it locally with the project's documented commands and fixtures. Cover the happy path, the error path that matters, and a regression check for what the change could break, in proportion to the risk.
|
|
121
|
+
- `covered`: existing automated E2E or functional tests already exercise this behavior at the needed depth. Cite the test file and name, and run it. Do not add a duplicate manual check.
|
|
122
|
+
- `na`: no observable behavior, such as a docs-only change. State the reason.
|
|
123
|
+
|
|
124
|
+
**Human validation.** Add a `human` check to an AC when a person must judge it: a new user-facing flow, or a judgement call that no safe automated check settles. It supplements the automated checks for that AC. Human validation is not required for every change, and an AC without it is not thereby unverified.
|
|
125
|
+
|
|
126
|
+
Optional extra checks are explicit limitations with a reason. They never block acceptance.
|
|
127
|
+
|
|
128
|
+
**Plan before build.** For each AC, record its automated checks and any human check: the exact command or fixture, and the expected result. Write the plan before the build and give it to the builder.
|
|
129
|
+
|
|
130
|
+
**Record every run.** Each check records its exact command, the expected result, the observed result, and one outcome: `pass`, `fail`, `not run: <reason>`, or `NA: <reason>`. Run the automated checks on the current tree. Report a `covered` test with its result.
|
|
131
|
+
|
|
132
|
+
**Missing tests, credentials, and environments.** A missing necessary automated test blocks acceptance of the affected AC. The builder writes it in the next repair. If it cannot be written, the task is `BLOCKED`. A missing credential, seed data, or safe environment is never a pass: ask one targeted question, record the check as `not run` with its reason, and defer it. Such a check is pending, not failed, so it does not send the task to repair. Independent ACs continue.
|
|
133
|
+
|
|
134
|
+
**Safety.** Use local isolated fixtures and legitimate local test accounts from the project's documented setup. Without the user's authorization, do not touch production systems, external services, or real user data, and do not run destructive commands or cause external side effects. Start only the local processes a check needs. Stop the ones the agent started when the check is done, and leave existing servers running. Never weaken authentication, disable a check, or add a bypass to make a result pass.
|
|
135
|
+
|
|
136
|
+
**Identity and freshness.** Evidence is tied to the tree it ran on: its commit and, for uncommitted work, a QA-time snapshot. The baseline (step 1) stays exactly as it was taken before the build, for the review's comparison of preexisting state. It is not the QA identity. At QA and handoff time, capture the current task-scoped diff and the contents of every new file, save them in the progress record, and reference that snapshot from the QA record. Resume compares the current scope with the QA-time snapshot before reusing any evidence. An edit to a file that a check runs or covers invalidates that check, including an uncommitted edit. Rerun the invalidated checks, and reuse evidence that the edit cannot affect. An affected human check gets a new handoff.
|
|
137
|
+
|
|
138
|
+
**Human handoff.** Ask through the harness's native question tool when one exists, and only when no independent authorized work remains or a gate needs the answer. Otherwise ask in chat at that point. If the user is away or has said they will check in later, persist the handoff in the progress record, or in the feature's existing `qa.md` when there is one, and continue independent authorized work. The absence of an answer is never signoff. Pending work is not accepted, completed, or merged. Commits and pushes follow the calling command's existing policy and any explicit checkpoint the user authorized; pending QA neither grants nor removes them.
|
|
139
|
+
|
|
140
|
+
The handoff lists, in order:
|
|
141
|
+
|
|
142
|
+
1. The tested tree: branch and commit (`git rev-parse --short HEAD`), the QA-time snapshot reference when there are uncommitted changes (see Identity and freshness), and the AC or flow under test.
|
|
143
|
+
2. Setup: the documented setup and start commands, the URL or port, and the test accounts, named but not written out. Credentials stay in the project's local secret store, never in the handoff.
|
|
144
|
+
3. Seeded prerequisites.
|
|
145
|
+
4. Numbered actions, each with its expected observable outcome.
|
|
146
|
+
5. What the agent already tested, with the results, and what needs the user.
|
|
147
|
+
6. Safe cleanup.
|
|
148
|
+
7. The response template, one block per case:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
QA-<n>: PASS | FAIL | not run
|
|
152
|
+
Actual or error evidence: <what you saw>
|
|
153
|
+
Acceptance: accept | reject | defer
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Acceptance of a human check.** It needs both a `PASS` result and an explicit `accept` for the tree the handoff named. `not run` with `accept` stays pending, because the person did not see a result. `FAIL` or `reject` sends the AC to repair, then to a new automated run and a new handoff. `defer` stays pending. The orchestrator never signs off for the user and never treats its own evidence as the user's answer.
|
|
157
|
+
|
|
158
|
+
Resume restores the exact pending handoff from the progress record, not a summary of it.
|
|
159
|
+
|
|
109
160
|
## Your Task
|
|
110
161
|
|
|
111
162
|
1. **Analyze**: identify the files to create or modify, the dependencies between tasks, and the `[P]` tasks.
|
|
@@ -92,8 +92,8 @@ Session ended at a gate? `/factory start <job-id | slug | KEY>` shows that gate
|
|
|
92
92
|
|
|
93
93
|
## Approval modes
|
|
94
94
|
|
|
95
|
-
- **`human`** (default). An approved job stops at `awaiting-human`. Read the branch and `qa.md`, then run `/factory approve <job-id>`.
|
|
96
|
-
- **`auto`**. An approved job merges automatically. The approver still escalates anything touching auth, payments, data security, deployment, migrations, email, production data, new dependencies, or unresolved product decisions. Its tickets stay In Review until you run `/factory approve <job-id>`, which then moves them to Done.
|
|
95
|
+
- **`human`** (default). An approved job stops at `awaiting-human`. Read the branch and the QA handoff in `qa.md`, answer any pending human check, then run `/factory approve <job-id>`.
|
|
96
|
+
- **`auto`**. An approved job merges automatically. The approver still escalates anything touching auth, payments, data security, deployment, migrations, email, production data, new dependencies, or unresolved product decisions. A job with a human QA check still stops at `awaiting-human`, because that check is required validation. Its tickets stay In Review until you run `/factory approve <job-id>`, which then moves them to Done.
|
|
97
97
|
|
|
98
98
|
Any value other than exactly `auto` is treated as `human`.
|
|
99
99
|
|
|
@@ -128,9 +128,15 @@ Set `MERGE_MODE`. The approval gates are the same in both modes.
|
|
|
128
128
|
|
|
129
129
|
`push-mr` suits forge-reviewed setups, where required reviews or CI gates sit on the forge after your approval. It never force-pushes and never merges locally. Under `auto`, approve opens the request without a pause, but the forge merge and the second `/factory approve` stay yours.
|
|
130
130
|
|
|
131
|
-
##
|
|
131
|
+
## Functional QA (`qa.md`)
|
|
132
132
|
|
|
133
|
-
The builder writes `qa.md` in the feature folder, on the job's branch
|
|
133
|
+
The builder writes the QA plan into `qa.md` in the feature folder, on the job's branch, before it writes code. After the final code commit it records each check: the command, the expected result, the observed result, and `pass`, `fail`, `not run` (with the reason), or `NA`. Acceptance criteria that need a person are marked `human`, and their handoff lists the numbered steps, the expected results, and the response template.
|
|
134
|
+
|
|
135
|
+
- **Automated checks** run for every criterion on the job's tree. A failed check goes back to the builder. A check that could not run because a credential, data, or environment is missing stops the job for you, as a `Not verified` item.
|
|
136
|
+
- **Human checks** are added only where a person must judge: a new flow, or a judgement no safe automated check settles. They supplement the automated checks. The job waits at `awaiting-human`, even in `auto`. Answer the handoff with `PASS` and `accept`. `/factory approve` saves your answer in `build.md` and merges only when every human check reads `PASS` with `accept`. A failure or rejection means `/factory rework <job-id> <note>`.
|
|
137
|
+
- **Optional checks** are listed as limitations. They never block.
|
|
138
|
+
|
|
139
|
+
The approver reads the functional QA record and escalates on a failed, missing, or stale check. The manual checklist never affects a verdict, and a missing `qa.md` is only noted when the job has no `local` or `human` criteria. When a job waits for you, the orchestrator prints the record and the reviewers' `Not verified` items under the line `Suggested checks before /factory approve — not a gate`.
|
|
134
140
|
|
|
135
141
|
## Tickets
|
|
136
142
|
|
|
@@ -153,7 +159,7 @@ The parent and every sub-task move together. The orchestrator uses the project's
|
|
|
153
159
|
4. **Plan.** `planner` in plan mode writes `plan.md` (with the size) and `tasks.md` for large work.
|
|
154
160
|
5. **Plan gate.** You confirm the plan, or request changes. Nothing is ticketed or built before you confirm.
|
|
155
161
|
6. **Tickets and build location.** If tracked, the parent and sub-tasks are created and their keys are written into `tasks.md`. The folder is renamed to carry the key. Then a builder gets its own git worktree on branch `factory/<id>` (bootstrapped first, see Build location), or the in-place branch. The job's feature docs are committed on that branch.
|
|
156
|
-
7. **Build.** The builder follows TDD, ticks `tasks.md` as it completes tasks, writes `build.md`, and writes `qa.md
|
|
162
|
+
7. **Build.** The builder follows TDD, ticks `tasks.md` as it completes tasks, writes `build.md`, and writes `qa.md` (its functional QA plan before the code, and its results after).
|
|
157
163
|
8. **Review.** Every configured lens reviews the branch, and each reviewer's report is saved as `round-N/review-<lens>.md` with `VERDICT: PASS` or `VERDICT: CHANGES`.
|
|
158
164
|
9. **Repair.** Any `CHANGES` sends the builder back to fix it. Two repairs at most, so three review rounds. Then the job escalates to you.
|
|
159
165
|
10. **Approve.** `reviewer` in approval mode (fresh context) returns `APPROVE` or `ESCALATE`, and the orchestrator writes it to `decision.md`.
|
|
@@ -5,7 +5,7 @@ description: Opt-in software factory for feature-sized work. Runs one job throug
|
|
|
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. 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.
|
|
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, It also appends the user's QA answer, verbatim, to `build.md` (see Functional QA).
|
|
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
|
|
|
@@ -51,7 +51,7 @@ A first argument of `start`, `approve`, `rework`, `abandon`, `status`, `watch`,
|
|
|
51
51
|
spec.md spec-writer, spec mode (from the feature spec template)
|
|
52
52
|
plan.md spec-writer, plan mode: approach, steps, and the **Size:** line
|
|
53
53
|
tasks.md spec-writer, plan mode, large work only
|
|
54
|
-
qa.md builder, on the branch:
|
|
54
|
+
qa.md builder, on the branch: functional QA record (plan, runs, results) and the human handoff (see Functional QA)
|
|
55
55
|
factory/
|
|
56
56
|
README.md setup and reference
|
|
57
57
|
.gitignore ignores jobs/ and archive/
|
|
@@ -62,7 +62,7 @@ factory/
|
|
|
62
62
|
intake.md you: the original request verbatim under `## Original request`, the questions and answers (when asked), and `## Baseline confirmed` (when needed)
|
|
63
63
|
spec-<k>.md you, from the operator's change request at the spec gate
|
|
64
64
|
plan-<k>.md you, from the operator's change request at the plan gate
|
|
65
|
-
build.md builder; cumulative round log
|
|
65
|
+
build.md builder; cumulative round log; you append the user's QA answer blocks (kept on rewrite)
|
|
66
66
|
round-<N>/review-<lens>.md one per configured lens
|
|
67
67
|
decision.md approver (or you, on escalation)
|
|
68
68
|
merge-conflict.md you, on a merge conflict (blocks approve)
|
|
@@ -194,10 +194,10 @@ Resume by stage:
|
|
|
194
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 |
|
|
195
195
|
| `review` | Rerun the review round `round` |
|
|
196
196
|
| `approve` | Rerun the approval (`reviewer` in approval mode, brief `roles/approve.md`) |
|
|
197
|
-
| `awaiting-human` | Print the approver's rationale, the
|
|
197
|
+
| `awaiting-human` | Print the approver's rationale, the QA record and any human handoff from `qa.md` (see QA guidance), and the `/factory approve` command |
|
|
198
198
|
| `needs-human`, `failed_stage` `spec` | Rerun the spec stage (see Spec), then show the spec gate |
|
|
199
199
|
| `needs-human`, `failed_stage` `plan` | Rerun the plan stage (see Plan), then show the plan gate |
|
|
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 |
|
|
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. If a human check is pending, print its exact handoff from `qa.md` first |
|
|
201
201
|
| `abandoned` | Closed. Say so and stop. To work on the feature again, run `/factory start <slug or KEY>`, which creates a new job |
|
|
202
202
|
| Archived (in `factory/archive/`, any stage) | Closed. Say so and stop (see Start step 1) |
|
|
203
203
|
|
|
@@ -383,7 +383,7 @@ PATHS
|
|
|
383
383
|
- Ports: builder <p>, ux <p+1>, ui <p+2>
|
|
384
384
|
```
|
|
385
385
|
|
|
386
|
-
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
|
|
386
|
+
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. The code lens checks its functional QA record. The other lenses read it for context only. The approver checks the record (see Functional QA).
|
|
387
387
|
|
|
388
388
|
## Loop
|
|
389
389
|
|
|
@@ -414,8 +414,8 @@ Let `N` be the current round, starting at `1` for a new job.
|
|
|
414
414
|
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.
|
|
415
415
|
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`.
|
|
416
416
|
- `ESCALATE` → stage `needs-human`. Tell the user the rationale. Stop.
|
|
417
|
-
- `APPROVE` and `{{APPROVAL_MODE}}` is exactly `auto` → run the merge procedure.
|
|
418
|
-
- `APPROVE` otherwise: stage `awaiting-human`. Print the
|
|
417
|
+
- `APPROVE` and `{{APPROVAL_MODE}}` is exactly `auto` → run the merge procedure, unless the job has a `human` criterion (see Functional QA). Such a job stops at `awaiting-human` even under `auto`, as below.
|
|
418
|
+
- `APPROVE` otherwise: stage `awaiting-human`. Print the QA guidance, with the human handoff when there is one (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`.
|
|
419
419
|
|
|
420
420
|
### Repair
|
|
421
421
|
|
|
@@ -474,21 +474,36 @@ Rules:
|
|
|
474
474
|
|
|
475
475
|
The new cycle starts with a fresh repair budget. Old rounds and reviews are kept, not overwritten.
|
|
476
476
|
|
|
477
|
-
## QA
|
|
477
|
+
## Functional QA
|
|
478
478
|
|
|
479
|
-
|
|
479
|
+
Functional QA means the changed behavior was run, not only built. The rules are the shared loop's [Functional QA](../../../.claude/prompt-snippets/implement.md#functional-qa): automated checks for every AC, a human check only where a person must judge, the plan before the build, recorded runs, safety, identity and freshness, and the handoff. This section adds the Factory mechanics. Gates use only the existing verdicts and stages.
|
|
480
480
|
|
|
481
|
-
-
|
|
482
|
-
-
|
|
483
|
-
-
|
|
481
|
+
- **Plan.** Before writing code, the builder writes the QA table into `qa.md` in the build location: one row per AC and check, with its kind (`local`, `covered`, `human`, or `na`), its exact command or fixture, and its expected result. A human check is an extra row on its AC, never a replacement for the automated rows. Observed and Result start as `-` and `planned`.
|
|
482
|
+
- **Run.** The order is fixed: the code commit, then the runs on that commit, then the evidence commit. After the final code commit, the builder runs each automated check and each cited `covered` test, fills in Observed and Result, records `Tested commit: <hash>` (the code commit), and commits `qa.md` with the work. A `human` row is never recorded as passed.
|
|
483
|
+
- **Review.** The code lens re-runs each automated command from the table and each cited `covered` test, and compares the results with the recorded ones (see the code brief). A failed row, a missing feasible automated check, or a label without its reason is a `VERDICT: CHANGES` item, repaired within the usual three review rounds. A check that could not run because a credential, data, or environment is missing is a blocking item titled `Not verified: functional QA <AC-n>: <reason>`. It sends the job to `needs-human`, and nothing is repaired for it.
|
|
484
|
+
- **Approve.** The approver checks the record (see its brief) and escalates on a failed, missing, or not-run automated check, or on stale evidence. Evidence is stale when the build location has uncommitted changes, or when a committed change since `Tested commit` touches a file that an automated check runs or covers. The only exempt change is a record-only edit to `qa.md`, one that changes the Observed, Result, or Tested commit cells and nothing else. Changes to files that no check runs or covers do not stale the record. A changed criterion, command, expected result, or evidence line does. The approver does not count human rows or the manual checklist.
|
|
485
|
+
- **Human checks.** For an AC with a human check, the handoff is the `## Manual checks` section of `qa.md`: numbered steps, each with its AC and expected result, plus the fields from implement.md's Functional QA (tested commit, setup and test accounts by name, seeded prerequisites, what was already tested, cleanup, and the response template). The orchestrator prints it at `awaiting-human`, even under `auto`, and the job waits there. Acceptance needs `PASS` and an explicit `accept` for the tested commit named in the handoff (Approve step 6). `not run` with `accept` stays pending. `reject` or `FAIL` means rework. The answer is saved verbatim in `build.md` as a `## Human QA answer` block. After any rework or any change to a checked file, the tested commit changes, and a new handoff is printed. Ask the user with the harness's native question tool when one exists, and only when no independent authorized work remains or a gate needs the answer; otherwise ask in chat at that point. Resume restores the exact pending handoff from `qa.md`, not a summary of it.
|
|
486
|
+
- **Unavailable user.** Nothing repeats or loops. The job stays at `awaiting-human`, the handoff stays in `qa.md`, the status table shows it, and other jobs continue. Absence is never signoff.
|
|
487
|
+
- **Where the evidence lives.** `qa.md` is on the job branch in the build location: the worktree path from the paths block, or the main checkout for an in-place job. The orchestrator reads it there before the merge, and from the main checkout's feature folder after it. Answers are in `build.md` in the job folder, which git ignores, so they survive worktree removal. The builder keeps those blocks when it rewrites `build.md`.
|
|
488
|
+
- **Missing record.** A missing `qa.md`, or a missing `## Functional QA` section, escalates when the job has any automated or human check. Otherwise it is only noted.
|
|
489
|
+
- **Optional checks.** They are listed under `## Not covered by automated tests`, each with its reason. They never block.
|
|
484
490
|
|
|
485
|
-
|
|
491
|
+
## QA guidance
|
|
492
|
+
|
|
493
|
+
The builder writes `qa.md`, committed with the work. It holds the functional QA record, the human handoff when there is one, and the operator's checklist. It rewrites it on repair and rework rounds. A small job can have a few lines.
|
|
494
|
+
|
|
495
|
+
When the job reaches `awaiting-human` or `needs-human`, and after an auto merge, print (from the build location before the merge, from the main checkout's feature folder after it):
|
|
496
|
+
|
|
497
|
+
- First, the mandatory items: every `## Not verified` item from the latest round's reviews, and every failed, not-run, or stale automated check from the record. These are blocking and never sit under the optional line.
|
|
498
|
+
- If a human check is pending: `Human QA required before /factory approve: answer the handoff below`, then the handoff.
|
|
499
|
+
- The `## Functional QA` table with its results.
|
|
500
|
+
- Under the line `Suggested checks before /factory approve — not a gate`, the `## Not covered by automated tests` items.
|
|
501
|
+
- If `qa.md` is missing: `No qa.md: no QA record or suggested checks.`
|
|
486
502
|
|
|
487
503
|
Rules:
|
|
488
504
|
|
|
489
|
-
-
|
|
490
|
-
- A missing `qa.md`
|
|
491
|
-
- When the job reaches `awaiting-human` or `needs-human`, and after an auto merge, print `qa.md` (from the build location before the merge, from the main checkout's feature folder after it). Then print the `## Not verified` items from the latest round's reviews. Put this line before them: `Suggested checks before /factory approve — not a gate`. If `qa.md` is missing, print `No qa.md: no suggested checks.` in its place.
|
|
505
|
+
- Only the checklist and the limitations are optional. They never change a verdict.
|
|
506
|
+
- A missing `qa.md`, or a missing `## Functional QA` section, escalates only when the job has an automated or human check. Otherwise it is noted.
|
|
492
507
|
|
|
493
508
|
## Approve
|
|
494
509
|
|
|
@@ -498,8 +513,10 @@ Rules:
|
|
|
498
513
|
2. Otherwise refuse unless stage is `awaiting-human` or `needs-human`. The user's explicit command is the approval. Do not re-run the approver.
|
|
499
514
|
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>`.
|
|
500
515
|
4. Refuse while `merge-conflict.md` exists in the job folder. The user resolves the conflict on the branch, then removes that file.
|
|
501
|
-
5.
|
|
502
|
-
6.
|
|
516
|
+
5. **Required QA evidence.** Refuse, in every mode and from `needs-human` too, while the functional QA record in `qa.md` shows a failed, not-run, or missing automated check or covered test, or stale evidence (see Functional QA, Approve). Name the row and what the user must supply. Do not waive this with the approve command: the fix is rework, or a builder repair followed by review. The existing overrides for other items are unchanged.
|
|
517
|
+
6. **Human QA.** Only when the job has a `human` check (see Functional QA). The command alone is not enough for it. If no answer is recorded for the tested commit, print the handoff from `qa.md` and ask in chat for the answer in the response template, then stop. When the answer comes, append it verbatim to `build.md` as a `## Human QA answer (<tested commit>)` block. Proceed only when every human check reads `PASS` with an explicit `accept` for that commit. A `FAIL` or `reject` does not merge: tell the user to run `/factory rework <job-id> <note>` naming the row. `defer`, `not run`, or no answer leaves the job at `awaiting-human`. A job with no `human` check skips this step.
|
|
518
|
+
7. 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.
|
|
519
|
+
8. Run the merge procedure for `{{MERGE_MODE}}`. In `push-mr`, a job with `mr` set takes the finish path there instead.
|
|
503
520
|
|
|
504
521
|
## Abandon
|
|
505
522
|
|
|
@@ -569,7 +586,7 @@ Closed jobs (`merged` or `abandoned`) are hidden by default. Print one line in t
|
|
|
569
586
|
| `plan` | Wait, or `/factory start <id>` to resume if the session ended |
|
|
570
587
|
| `awaiting-plan` | `/factory start <id>` to review the plan and confirm it |
|
|
571
588
|
| `build`, `review`, `approve` | Wait, or `/factory start <id>` to resume if the session ended |
|
|
572
|
-
| `awaiting-human` | Review the branch and
|
|
589
|
+
| `awaiting-human` | Review the branch and the QA record in `qa.md`. Answer any pending `human` check in its handoff, then `/factory approve <id>`. A `reject` means `/factory rework <id> <note>`. In `push-mr` with `mr` set: merge the request on the forge, then `/factory approve <id>` to finish. Print the request URL |
|
|
573
590
|
| `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 |
|
|
574
591
|
| `abandoned` | Nothing: the job is closed. To work on the feature again, `/factory start <slug or KEY>` creates a new job |
|
|
575
592
|
| `merged` | Nothing, unless tickets are not Done yet: `/factory approve <id>` |
|
|
@@ -668,7 +685,7 @@ The loop is the same in every harness. Use a parallel lens batch where the harne
|
|
|
668
685
|
|
|
669
686
|
## Limits
|
|
670
687
|
|
|
671
|
-
File-write boundaries are prompt conventions, not enforced isolation. Nothing physically stops an agent from writing outside its file. The real gates are the spec and plan gates, the reviewer verdicts, the approver's rules and dry-run merge check, and the merge procedure's preconditions and test run. Ticket updates are best-effort and never gate the pipeline. `qa.md`
|
|
688
|
+
File-write boundaries are prompt conventions, not enforced isolation. Nothing physically stops an agent from writing outside its file. The real gates are the spec and plan gates, the reviewer verdicts, the approver's rules and dry-run merge check, and the merge procedure's preconditions and test run. Ticket updates are best-effort and never gate the pipeline. The `## Functional QA` record in `qa.md` gates through the code lens and the approver. The manual checklist gates nothing. A pending `human` check gates the merge only through approval (see Functional QA).
|
|
672
689
|
|
|
673
690
|
## Related
|
|
674
691
|
|
|
@@ -4,7 +4,7 @@ You decide whether a job goes to merge or to a human. You are the approval gate
|
|
|
4
4
|
|
|
5
5
|
## Inputs
|
|
6
6
|
|
|
7
|
-
- The whole job history: `spec.md` and `plan.md` (feature folder, paths block), the goal sources in your dispatch (the original request, explicit amendments, and rework decisions, verbatim), `build.md`, `rework-*.md` if any, every `round-*/review-*.md`, and the job's `job.json`.
|
|
7
|
+
- The whole job history: `spec.md` and `plan.md` (feature folder, paths block), the QA record in `qa.md` (paths block's `qa.md` line, its `## Functional QA` section), the goal sources in your dispatch (the original request, explicit amendments, and rework decisions, verbatim), `build.md`, `rework-*.md` if any, every `round-*/review-*.md`, and the job's `job.json`.
|
|
8
8
|
- The final diff: `git -C <worktree> diff {{DEFAULT_BRANCH}}...factory/<id>`.
|
|
9
9
|
- The project's `AGENTS.md` for test commands.
|
|
10
10
|
|
|
@@ -13,6 +13,8 @@ You decide whether a job goes to merge or to a human. You are the approval gate
|
|
|
13
13
|
1. **Read the history.** Read everything listed above. Note any rework and what it asked for.
|
|
14
14
|
2. **Final-round reviews.** Confirm every review in the latest round has `VERDICT: PASS`. If any is `CHANGES` or missing, the decision is `ESCALATE`.
|
|
15
15
|
3. **Spot-check one acceptance criterion.** Pick at least one `AC-n` from `spec.md`. Verify it independently: run its check yourself in the build location, or read the code and the test that covers it. Do not trust the builder's evidence alone. Also check the branch diff against `plan.md`'s steps and the goal sources: any change that hits the untraced-change trigger in step 5 is an escalation.
|
|
16
|
+
|
|
17
|
+
Then check the `## Functional QA` record in `qa.md` against [SKILL Functional QA](../SKILL.md#functional-qa). Escalate when an automated check is `fail` or `not run`, when an automated row has no evidence from the tested commit, when a necessary automated check or covered test is missing, or when the record is stale. The record is stale when the build location has uncommitted changes (`git -C <worktree> status --porcelain` is not empty), or when a committed change since the tested commit touches a file that an automated check runs or covers (`git -C <worktree> diff --name-only <Tested commit> factory/<id>`). The only exempt change is a record-only edit to `qa.md`. Do not count human rows or the manual checklist.
|
|
16
18
|
4. **Dry-run merge.** Check for conflicts without changing anything:
|
|
17
19
|
```
|
|
18
20
|
git -C <main checkout> merge-tree --write-tree {{DEFAULT_BRANCH}} factory/<id>
|
|
@@ -70,4 +72,4 @@ The first line must be exactly `APPROVE` or `ESCALATE`, followed by the rational
|
|
|
70
72
|
- Do not edit code, reviews, `build.md`, `job.json`, `tasks.md`, or any other file.
|
|
71
73
|
- Do not merge, push, or change branches.
|
|
72
74
|
- Do not transition tickets. The orchestrator owns ticket status, and the approver never touches the tracker.
|
|
73
|
-
- `qa.md` is not a gate
|
|
75
|
+
- The manual checklist in `qa.md` is not a gate, and its absence does not escalate. The `## Functional QA` record is evidence you check in step 3. A `human` check is not yours to decide: the orchestrator holds the job for the user's answer, so do not escalate or approve on it.
|
|
@@ -34,6 +34,8 @@ Follow the [test-driven development](../../test-driven-development/SKILL.md) ski
|
|
|
34
34
|
|
|
35
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
|
+
Functional QA follows [Functional QA](../SKILL.md#functional-qa). Write the QA plan into `qa.md` before you write code, and run and record the checks after your final code commit. Do not claim a `human` row passed.
|
|
38
|
+
|
|
37
39
|
## Output
|
|
38
40
|
|
|
39
41
|
You write two files.
|
|
@@ -62,22 +64,44 @@ You write two files.
|
|
|
62
64
|
|
|
63
65
|
The first line must be exactly `STATUS: READY` or `STATUS: BLOCKED`.
|
|
64
66
|
|
|
65
|
-
2. `qa.md` in the feature folder of the build location (committed on the branch).
|
|
67
|
+
2. `qa.md` in the feature folder of the build location (committed on the branch). Write the QA plan before the code. After the final code commit, rewrite it whole, so it matches the code as it is now. Use this skeleton:
|
|
66
68
|
|
|
67
69
|
```markdown
|
|
68
70
|
# QA: <feature title>
|
|
69
71
|
|
|
72
|
+
## Functional QA
|
|
73
|
+
|
|
74
|
+
Tested commit: `<code commit hash, after the final code commit>`
|
|
75
|
+
|
|
76
|
+
| AC | Class | Command or fixture | Expected | Observed | Result |
|
|
77
|
+
| --- | --- | --- | --- | --- | --- |
|
|
78
|
+
| AC-1 | local | `<exact command>` | <expected result> | - | planned |
|
|
79
|
+
| AC-2 | covered | `<test file>` `<test name>` | <expected result> | - | planned |
|
|
80
|
+
| AC-3 | human | see Manual checks | <expected result> | - | planned |
|
|
81
|
+
|
|
70
82
|
## How to run
|
|
71
83
|
|
|
72
84
|
- Setup: `<command from AGENTS.md>`
|
|
73
85
|
- Dev server: `<command>` on port <builder port>, passed with `<flag or env var from AGENTS.md>`
|
|
74
86
|
- Seed data: <what the dev environment provides, or "none">
|
|
75
87
|
- Flags or config: <or "none">
|
|
88
|
+
- Test accounts: <names only; credentials stay in the project's local secret store>
|
|
89
|
+
- Cleanup: <how to stop what you started, and how to reset the fixture>
|
|
90
|
+
- Already tested by the agent: <the rows that passed, with their results>. Needs the user: <the human rows>.
|
|
91
|
+
|
|
92
|
+
## Manual checks (human)
|
|
76
93
|
|
|
77
|
-
|
|
94
|
+
Only for `human` rows. Each check is numbered, names its AC, and gives a result a person can see.
|
|
78
95
|
|
|
79
|
-
1. AC-
|
|
80
|
-
|
|
96
|
+
1. AC-3: <what to do>. Expected: <what a person can observe>.
|
|
97
|
+
|
|
98
|
+
Answer each case in this template, in the user's own words after it:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
QA-<n>: PASS | FAIL | not run
|
|
102
|
+
Actual or error evidence: <what you saw>
|
|
103
|
+
Acceptance: accept | reject | defer
|
|
104
|
+
```
|
|
81
105
|
|
|
82
106
|
## Not covered by automated tests
|
|
83
107
|
|
|
@@ -86,15 +110,19 @@ You write two files.
|
|
|
86
110
|
|
|
87
111
|
Rules for `qa.md`:
|
|
88
112
|
|
|
89
|
-
-
|
|
90
|
-
-
|
|
113
|
+
- Plan first: the table is written before any code. Each row names its AC, its class (`local`, `covered`, `human`, or `na`), and the exact command, test, or fixture. An `na` row states its reason in Expected.
|
|
114
|
+
- Record after the final code commit: Observed holds what you saw. Result is `pass`, `fail`, `not run: <reason>`, or `NA: <reason>`. A missing credential, seed data, or environment is `not run: <reason>`. A missing necessary test is written first where you can, or recorded as `not run: no test` with its reason.
|
|
115
|
+
- Never record a `human` row as passed. The user answers those.
|
|
116
|
+
- Keep every section of `build.md` you did not write this round, including the orchestrator's `## Human QA answer` blocks. Rewrite the round log around them, never over them.
|
|
117
|
+
- Safety: use local isolated fixtures and the project's local test accounts only. Do not touch production, external services, or real data, and do not cause external side effects. Start only the local processes a check needs. Stop the ones you started, and leave existing servers running. Never weaken authentication or add a bypass.
|
|
118
|
+
- Optional checks go under "Not covered by automated tests", each with its reason. They never block.
|
|
91
119
|
- Keep it short. A small job needs a few lines.
|
|
92
120
|
|
|
93
121
|
## Rules
|
|
94
122
|
|
|
95
123
|
- Address every `CHANGES` item in repair mode. Fix it, or justify in the log why it should stand. Silence is not an option.
|
|
96
|
-
- Use `STATUS: BLOCKED` only when the spec cannot be built as written (contradiction, missing decision, unavailable dependency). Say exactly what the human must decide. Do not block on things you can work around.
|
|
124
|
+
- Use `STATUS: BLOCKED` only when the spec cannot be built as written (contradiction, missing decision, unavailable dependency, or a necessary QA test that cannot be written). Say exactly what the human must decide. Do not block on things you can work around.
|
|
97
125
|
- Report an acceptance criterion as pass only with evidence. A criterion you did not check is `not verified`, and say so.
|
|
98
126
|
- Tick `tasks.md` in the build location as you finish each task: change `- [ ]` to `- [x]` on that line once its acceptance criteria pass and the work is committed. Leave the rest of the line, including any ticket key, unchanged. Do not tick a task you did not finish.
|
|
99
127
|
- Do not add dependencies, abstractions, or files the spec does not need.
|
|
100
|
-
- Do not merge, approve, or edit reviewer files.
|
|
128
|
+
- Do not merge, approve, or edit reviewer files. Never write a QA result you did not observe. The QA record gates through the code reviewer and the approver, so a result written to pass a check is a fault.
|
|
@@ -6,7 +6,7 @@ You review one round of a job's branch for correctness, simplicity, reuse, conve
|
|
|
6
6
|
|
|
7
7
|
- `spec.md` and `plan.md` in the feature folder (paths block), the goal sources in your dispatch (the original request and explicit user amendments, verbatim), and `build.md` in the job folder.
|
|
8
8
|
- The branch diff: `git -C <worktree> diff {{DEFAULT_BRANCH}}...factory/<id>`.
|
|
9
|
-
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's
|
|
9
|
+
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's functional QA record (`## Functional QA`) and manual checks. Check the record as the Functional QA review below says. The manual checks are context only and never change your verdict.
|
|
10
10
|
- Round `N > 1`: your own previous review, `round-<N-1>/review-code.md`. Check whether earlier blocking items were fixed, and say so.
|
|
11
11
|
- The project's `AGENTS.md` for test, lint, and build commands.
|
|
12
12
|
|
|
@@ -20,6 +20,7 @@ Use the [requesting code review](../../requesting-code-review/SKILL.md) checklis
|
|
|
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
22
|
- **Scope trace, both ways:** trace the branch diff to `spec.md`'s requirements and acceptance criteria, `plan.md`'s steps, and the goal sources in your dispatch. Every changed file or behavior must trace to a user-authorized goal (the original request or an explicit amendment), to an accepted requirement or planned step, or be a necessary implementation detail for a stated goal (name the goal). A requirement or planned step with no change is a gap. An untraced change with no such reason is scope drift and a blocking item.
|
|
23
|
+
- **Functional QA:** check the `## Functional QA` record against [SKILL Functional QA](../SKILL.md#functional-qa). Each AC lists every feasible automated check with its label: `local` for observable behavior, `covered` for a cited existing test, and `na` with a reason. A `human` check is added on top where a person must judge. It never replaces an automated check. Re-run each `local` command and each cited `covered` test in the table, and compare the result with the recorded one. Every automated row needs a `pass` from the tested commit. A missing feasible automated check, a result that does not reproduce, a `fail`, or a label without its reason is a blocking item with its fix. A check that could not run for a missing credential, data, or environment is a blocking item titled `Not verified: functional QA <AC-n>: <reason>`.
|
|
23
24
|
- **Simplicity:** use the [ponytail-review](../../ponytail-review/SKILL.md) lens. Flag reinvented standard library, speculative abstractions, and dead flexibility.
|
|
24
25
|
- **Reuse:** the change should extend existing utilities rather than duplicate them.
|
|
25
26
|
- **Conventions:** the project's `AGENTS.md` and `.claude/rules-snippets/` standards.
|
|
@@ -55,4 +56,5 @@ The first line must be exactly `VERDICT: PASS` or `VERDICT: CHANGES`.
|
|
|
55
56
|
- `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.
|
|
56
57
|
- Taste goes under non-blocking notes. Taste never blocks a PASS.
|
|
57
58
|
- 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.
|
|
59
|
+
- An automated QA row (`local` or `covered`) that fails on re-run is a blocking item. A row that could not run for a missing credential, data, or environment is the `Not verified: functional QA` item above, not a repair.
|
|
58
60
|
- Do not edit code, tests, or any file. Do not fix problems yourself.
|
|
@@ -6,7 +6,7 @@ You audit one round of a job's branch for security problems. You are the `securi
|
|
|
6
6
|
|
|
7
7
|
- The branch diff: `git -C <worktree> diff {{DEFAULT_BRANCH}}...factory/<id>`.
|
|
8
8
|
- `spec.md` in the feature folder (paths block), for what the feature is meant to do.
|
|
9
|
-
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's
|
|
9
|
+
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's functional QA record and manual checks. Use it for context only. The QA gate belongs to the code lens and the approver, so it never changes your verdict.
|
|
10
10
|
- Round `N > 1`: your own previous review, `round-<N-1>/review-security.md`.
|
|
11
11
|
|
|
12
12
|
## Method
|
|
@@ -15,7 +15,7 @@ You look at a job's feature running in the build location and review the visual
|
|
|
15
15
|
- `build.md` for what the builder says it changed.
|
|
16
16
|
- The project's `AGENTS.md` for the dev command, how to pass the port, and the design system or component library in use.
|
|
17
17
|
- Existing components the feature should match. Find them in the codebase, not from memory.
|
|
18
|
-
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's
|
|
18
|
+
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's functional QA record and manual checks. Use it for context only. The QA gate belongs to the code lens and the approver, so it never changes your verdict.
|
|
19
19
|
- Round `N > 1`: your own previous review, `round-<N-1>/review-ui.md`.
|
|
20
20
|
|
|
21
21
|
## Method
|
|
@@ -14,7 +14,7 @@ You look at a job's feature running in the build location and review the user ex
|
|
|
14
14
|
- `spec.md` in the feature folder (paths block), for the acceptance criteria and user flows.
|
|
15
15
|
- `build.md` for what the builder says it changed.
|
|
16
16
|
- The project's `AGENTS.md` for the dev command and how to pass the port.
|
|
17
|
-
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's
|
|
17
|
+
- `qa.md` at the paths block's `qa.md (absolute, build location)` line, if it exists: the builder's functional QA record and manual checks. Use it for context only. The QA gate belongs to the code lens and the approver, so it never changes your verdict.
|
|
18
18
|
- Round `N > 1`: your own previous review, `round-<N-1>/review-ux.md`.
|
|
19
19
|
|
|
20
20
|
## Method
|
|
@@ -51,7 +51,7 @@ Implement bug fixes and corrections with proper validation and documentation.
|
|
|
51
51
|
4. **Verify, Review and Decide** (repeat implement.md steps 3, 4 and 5 until an exit):
|
|
52
52
|
- Verify: rerun the reproducing test and confirm it passes now, run every check that covers an AC, and run the full test suite for regressions.
|
|
53
53
|
- Review: the independent read-only reviewer checks the fix, the reproducing test, and the untracked files.
|
|
54
|
-
- Decide: repair goes back to the same builder. Repeat until `ACCEPTED`, `BLOCKED`, or `NOT ACCEPTED: needs decision
|
|
54
|
+
- Decide: repair goes back to the same builder. Repeat until `ACCEPTED`, `BLOCKED`, or `NOT ACCEPTED: needs decision` (which includes a pending human QA check, reason `awaiting human QA`). There is no round limit. A review PASS alone never accepts.
|
|
55
55
|
|
|
56
56
|
5. **Commit and Push** (only after `ACCEPTED`, and only when there are accepted changes): stage only the fix's paths, never `git add -A` or a foreign change. Skip the commit when nothing is staged.
|
|
57
57
|
```bash
|
|
@@ -36,6 +36,7 @@ build → verify → review → decide ─┬─ accept (review PASS, every re
|
|
|
36
36
|
- Turn every requirement in the supplied task into an acceptance criterion, `AC-1`, `AC-2`, ... There is no fixed count: one criterion per requirement, however many there are. Do not add requirements the task does not state.
|
|
37
37
|
- Each AC names its check. Discover the real checks; do not assume them. Read the project's manifests (for example `package.json` scripts, `Makefile`, `pyproject.toml`, `Cargo.toml`, `go.mod`), its CI configuration (for example `.github/workflows`), its README, and `AGENTS.md`. Use the commands the project actually runs.
|
|
38
38
|
- A documentation criterion may be checked by direct inspection: open the file and confirm the content, and quote what you found as evidence.
|
|
39
|
+
- Each AC also gets its functional QA checks: every feasible automated check, plus a human check only where a person must judge it. Write the QA plan before the build: the exact command or fixture, and the expected result. See [Functional QA](#functional-qa).
|
|
39
40
|
- A required check that cannot be discovered, or cannot be run, is a gap. It is not a pass, and it is not a bypass. It blocks acceptance of the affected task and of any aggregate run that needs it. Ask the user for the command as one targeted question and keep that question in the progress report. Independent tasks whose checks do not depend on the gap continue (see the Blocked exit in step 5).
|
|
40
41
|
- Ask only when a requirement is unclear in a way that changes what gets built: two readings lead to different code, or a needed fact is missing. Ask one targeted question with its options. A task-scoped question blocks only that task and its dependents: independent tasks with clear requirements continue, and the question stays in the progress report (see [subagent-workflow.md](../rules-snippets/subagent-workflow.md), Autonomous Execution and Blockers). If the whole request is unclear, stop and ask before any build.
|
|
41
42
|
- Take a baseline snapshot once, before any build. It is a plain copy of the state the task starts from, kept in a temporary directory outside the repository:
|
|
@@ -52,6 +53,7 @@ build → verify → review → decide ─┬─ accept (review PASS, every re
|
|
|
52
53
|
- For a bug, first write a failing test that reproduces it, and watch it fail for the right reason. Then make the minimal change that passes it. For a feature, follow TDD: failing test, minimal code, then refactor. Keep the diff as small as the task allows.
|
|
53
54
|
- Leave all its changes uncommitted and unstaged, including new files, so the review sees them. Do not commit.
|
|
54
55
|
- Report each AC as `pass` with the command and result, or `not verified` with the reason. List every changed and new file.
|
|
56
|
+
- Report each automated QA check with its exact command, expected result, and observed result. Write a failing test for a necessary automated check that does not exist yet, and report it when it cannot be written.
|
|
55
57
|
- Report `BLOCKED` with the decision the human must make if the task cannot be built as written.
|
|
56
58
|
|
|
57
59
|
**Later rounds (repair):** dispatch the same builder again with only the open items: every blocking review item, every AC that is not `pass`, and every check that failed or did not run. It must fix each item, or say in its report why it should stand. It must not expand scope.
|
|
@@ -60,6 +62,8 @@ build → verify → review → decide ─┬─ accept (review PASS, every re
|
|
|
60
62
|
|
|
61
63
|
Every round, run every check that covers an AC, using the commands from step 1. Treat the builder's report as a lead, not as evidence. For each AC, record `pass` with the command and result from this round, or `not verified` or `fail` with the reason. Docs criteria are recorded with the quoted content.
|
|
62
64
|
|
|
65
|
+
Also run the automated QA checks for every AC on the current tree, including each `covered` test the AC cites. Record each result as described in [Functional QA](#functional-qa). Human checks go to the handoff; do not run them yourself.
|
|
66
|
+
|
|
63
67
|
Checks are scoped: each repair and each task runs the checks for its own ACs. After all writers are reconciled, run the project's full required regression checks once: the repo-defined full suite, lint, typecheck, and build, where they exist. Use only commands the project defines; do not invent them. A failed required check is a repair. A required check that does not exist or cannot run is BLOCKED (see step 5).
|
|
64
68
|
|
|
65
69
|
### 4. Review (reviewer, read-only)
|
|
@@ -77,24 +81,25 @@ The reviewer's rules:
|
|
|
77
81
|
- The first line of the reply is exactly `VERDICT: PASS` or `VERDICT: CHANGES`.
|
|
78
82
|
- `VERDICT: CHANGES` needs at least one blocking item, each with `file:line`, the problem, and the specific fix. Blocking means a correctness issue, a failing check, a requirement with no test or evidence, or a clear convention break. Taste goes in non-blocking notes.
|
|
79
83
|
- Check each requirement of the original task, not only the diff. A requirement with no coverage is a blocking item.
|
|
84
|
+
- QA evidence and labels: check the functional QA rows against [Functional QA](#functional-qa). An automated check with no `pass` from this round's tree, a necessary automated check that is missing, a `covered` check with no cited test, or an `na` with no reason is a blocking item. A human check a person must judge is not a reviewer blocking item.
|
|
80
85
|
- Scope drift, both ways: trace the diff against the original supplied task. A change that no requirement needs is a blocking item unless the reviewer confirms it is a necessary implementation detail for a stated goal and says why. Goals are the original supplied task plus the user amendments recorded in step 1: do not require or assume a spec or plan (supplied-task exception). Simplicity and SRP notes stay non-blocking unless they add scope the task does not ask for.
|
|
81
86
|
|
|
82
87
|
### 5. Decide (orchestrator)
|
|
83
88
|
|
|
84
89
|
Pick one outcome per round:
|
|
85
90
|
|
|
86
|
-
- **Repair (back to step 2):** the review is `VERDICT: CHANGES`, **or** any AC is `not verified` or `fail`, **or** a required check failed or did not run. Send the open items to the builder, then run steps 3, 4 and 5 again on the current tree.
|
|
87
|
-
- **Accept (exit):** all of these hold on this round's verify and review: the review is `VERDICT: PASS`; every requirement has an AC marked `pass` with evidence from this round; every required check ran and passed; an independent reviewer produced the verdict;
|
|
88
|
-
- **Blocked (exit for the affected work):** the builder reports `BLOCKED`, a required check cannot be discovered
|
|
89
|
-
- **Needs user decision (exit for the affected work):** the task is unclear in a way only the user can settle. Stop work on that task and its dependents, report `NOT ACCEPTED: needs decision` with the question, and continue independent authorized work. This is not acceptance.
|
|
91
|
+
- **Repair (back to step 2):** the review is `VERDICT: CHANGES`, **or** any AC is `not verified` or `fail`, **or** a required check failed or did not run, **or** an automated QA check failed, or a necessary automated test is missing and can be written. Send the open items to the builder, then run steps 3, 4 and 5 again on the current tree.
|
|
92
|
+
- **Accept (exit):** all of these hold on this round's verify and review: the review is `VERDICT: PASS`; every requirement has an AC marked `pass` with evidence from this round; every required check ran and passed; every automated QA check passed on this round's tree; an independent reviewer produced the verdict; the builder did not report `BLOCKED`; and every human check has a `PASS` result and an explicit `accept` from the user for the tree it tested. Then report `ACCEPTED` with the AC evidence. A review PASS alone never accepts, and a pending human check is never treated as accepted.
|
|
93
|
+
- **Blocked (exit for the affected work):** the builder reports `BLOCKED`, a required check cannot be discovered, a necessary QA test cannot be written, or no independent reviewer is available. Report `BLOCKED` with the blocker and what would unblock it. Never mark blocked work accepted. Work that depends on it stops; independent authorized work with its own checks and reviewer continues. Without an independent reviewer nothing is accepted, but discovery and builds that do not need acceptance may continue and be reported as awaiting review. Stop the run only when no authorized work remains or a mandatory approval, security, or permission gate applies.
|
|
94
|
+
- **Needs user decision (exit for the affected work):** the task is unclear in a way only the user can settle, a check needs a credential, data, or environment only the user can provide, or a human check waits for the user's answer. Stop work on that task and its dependents, report `NOT ACCEPTED: needs decision` with the question, and continue independent authorized work. For a pending human check, the reason is `awaiting human QA`, and the report carries the exact handoff from [Functional QA](#functional-qa). This is not acceptance.
|
|
90
95
|
|
|
91
|
-
No other exit exists. An unmet requirement
|
|
96
|
+
No other exit exists. An unmet requirement or a failing check loops back to repair. A `not verified` result loops back to repair only when the missing piece is code or test work the builder can do. A `not verified` result that waits on evidence only the user or the environment can supply, or on a pending human answer, is the needs-decision exit. There is no round limit to escape the loop.
|
|
92
97
|
|
|
93
98
|
**Evidence freshness.** Acceptance uses evidence from the tree it accepts. Any edit after a verify or review, whether by the builder, a repair, or the orchestrator, invalidates the evidence it affects: rerun the checks covering those ACs and re-review the changed diff. Reuse evidence that the edit cannot affect. If unsure whether an edit affects a check, treat it as affected. Do not rerun everything for an unrelated edit.
|
|
94
99
|
|
|
95
100
|
### Commit (only when the calling flow asks)
|
|
96
101
|
|
|
97
|
-
The loop never commits by itself. Accepting reports the result; it does not create a commit. The calling command decides whether accepted work is committed, and only when its own flow says so and the user has not asked otherwise. When it does commit:
|
|
102
|
+
The loop never commits by itself. Accepting reports the result; it does not create a commit. The calling command decides whether accepted work is committed, and only when its own flow says so and the user has not asked otherwise. Pending human QA does not change that policy. It blocks acceptance, completion, and merge of the affected work. It neither grants nor removes a commit or push that the calling flow or an explicit checkpoint authorizes. When it does commit:
|
|
98
103
|
|
|
99
104
|
- Stage only the paths this task changed, taken from the builder's list and checked against the baseline. Never `git add -A`, and never stage a preexisting or foreign change.
|
|
100
105
|
- Skip the commit when nothing is staged. Do not create empty commits, and do not create a separate commit for each repair round.
|
|
@@ -106,6 +111,52 @@ The loop never commits by itself. Accepting reports the result; it does not crea
|
|
|
106
111
|
- A self-review is never presented as an independent review.
|
|
107
112
|
- These gates are prompt instructions, not host enforcement. Resuming after a pause depends on the host; this prompt does not guarantee automatic resume.
|
|
108
113
|
|
|
114
|
+
## Functional QA
|
|
115
|
+
|
|
116
|
+
Acceptance needs evidence that the changed behavior works. A process that starts, a page that loads, or a passing build is not evidence.
|
|
117
|
+
|
|
118
|
+
**Checks per AC.** Every AC gets every feasible automated check. A human check never replaces one.
|
|
119
|
+
|
|
120
|
+
- `local`: the changed behavior is observable (UI, API, CLI, or library). Run it locally with the project's documented commands and fixtures. Cover the happy path, the error path that matters, and a regression check for what the change could break, in proportion to the risk.
|
|
121
|
+
- `covered`: existing automated E2E or functional tests already exercise this behavior at the needed depth. Cite the test file and name, and run it. Do not add a duplicate manual check.
|
|
122
|
+
- `na`: no observable behavior, such as a docs-only change. State the reason.
|
|
123
|
+
|
|
124
|
+
**Human validation.** Add a `human` check to an AC when a person must judge it: a new user-facing flow, or a judgement call that no safe automated check settles. It supplements the automated checks for that AC. Human validation is not required for every change, and an AC without it is not thereby unverified.
|
|
125
|
+
|
|
126
|
+
Optional extra checks are explicit limitations with a reason. They never block acceptance.
|
|
127
|
+
|
|
128
|
+
**Plan before build.** For each AC, record its automated checks and any human check: the exact command or fixture, and the expected result. Write the plan before the build and give it to the builder.
|
|
129
|
+
|
|
130
|
+
**Record every run.** Each check records its exact command, the expected result, the observed result, and one outcome: `pass`, `fail`, `not run: <reason>`, or `NA: <reason>`. Run the automated checks on the current tree. Report a `covered` test with its result.
|
|
131
|
+
|
|
132
|
+
**Missing tests, credentials, and environments.** A missing necessary automated test blocks acceptance of the affected AC. The builder writes it in the next repair. If it cannot be written, the task is `BLOCKED`. A missing credential, seed data, or safe environment is never a pass: ask one targeted question, record the check as `not run` with its reason, and defer it. Such a check is pending, not failed, so it does not send the task to repair. Independent ACs continue.
|
|
133
|
+
|
|
134
|
+
**Safety.** Use local isolated fixtures and legitimate local test accounts from the project's documented setup. Without the user's authorization, do not touch production systems, external services, or real user data, and do not run destructive commands or cause external side effects. Start only the local processes a check needs. Stop the ones the agent started when the check is done, and leave existing servers running. Never weaken authentication, disable a check, or add a bypass to make a result pass.
|
|
135
|
+
|
|
136
|
+
**Identity and freshness.** Evidence is tied to the tree it ran on: its commit and, for uncommitted work, a QA-time snapshot. The baseline (step 1) stays exactly as it was taken before the build, for the review's comparison of preexisting state. It is not the QA identity. At QA and handoff time, capture the current task-scoped diff and the contents of every new file, save them in the progress record, and reference that snapshot from the QA record. Resume compares the current scope with the QA-time snapshot before reusing any evidence. An edit to a file that a check runs or covers invalidates that check, including an uncommitted edit. Rerun the invalidated checks, and reuse evidence that the edit cannot affect. An affected human check gets a new handoff.
|
|
137
|
+
|
|
138
|
+
**Human handoff.** Ask through the harness's native question tool when one exists, and only when no independent authorized work remains or a gate needs the answer. Otherwise ask in chat at that point. If the user is away or has said they will check in later, persist the handoff in the progress record, or in the feature's existing `qa.md` when there is one, and continue independent authorized work. The absence of an answer is never signoff. Pending work is not accepted, completed, or merged. Commits and pushes follow the calling command's existing policy and any explicit checkpoint the user authorized; pending QA neither grants nor removes them.
|
|
139
|
+
|
|
140
|
+
The handoff lists, in order:
|
|
141
|
+
|
|
142
|
+
1. The tested tree: branch and commit (`git rev-parse --short HEAD`), the QA-time snapshot reference when there are uncommitted changes (see Identity and freshness), and the AC or flow under test.
|
|
143
|
+
2. Setup: the documented setup and start commands, the URL or port, and the test accounts, named but not written out. Credentials stay in the project's local secret store, never in the handoff.
|
|
144
|
+
3. Seeded prerequisites.
|
|
145
|
+
4. Numbered actions, each with its expected observable outcome.
|
|
146
|
+
5. What the agent already tested, with the results, and what needs the user.
|
|
147
|
+
6. Safe cleanup.
|
|
148
|
+
7. The response template, one block per case:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
QA-<n>: PASS | FAIL | not run
|
|
152
|
+
Actual or error evidence: <what you saw>
|
|
153
|
+
Acceptance: accept | reject | defer
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Acceptance of a human check.** It needs both a `PASS` result and an explicit `accept` for the tree the handoff named. `not run` with `accept` stays pending, because the person did not see a result. `FAIL` or `reject` sends the AC to repair, then to a new automated run and a new handoff. `defer` stays pending. The orchestrator never signs off for the user and never treats its own evidence as the user's answer.
|
|
157
|
+
|
|
158
|
+
Resume restores the exact pending handoff from the progress record, not a summary of it.
|
|
159
|
+
|
|
109
160
|
## Your Task
|
|
110
161
|
|
|
111
162
|
1. **Analyze**: identify the files to create or modify, the dependencies between tasks, and the `[P]` tasks.
|
|
@@ -86,8 +86,8 @@ Session ended at a gate? `/factory start <job-id | slug | KEY>` shows that gate
|
|
|
86
86
|
|
|
87
87
|
## Approval modes
|
|
88
88
|
|
|
89
|
-
- **`human`** (default). An approved job stops at `awaiting-human`. Read the branch and `qa.md`, then run `/factory approve <job-id>`.
|
|
90
|
-
- **`auto`**. An approved job merges automatically. The approver still escalates anything touching auth, payments, data security, deployment, migrations, email, production data, new dependencies, or unresolved product decisions. Its tickets stay In Review until you run `/factory approve <job-id>`, which then moves them to Done.
|
|
89
|
+
- **`human`** (default). An approved job stops at `awaiting-human`. Read the branch and the QA handoff in `qa.md`, answer any pending human check, then run `/factory approve <job-id>`.
|
|
90
|
+
- **`auto`**. An approved job merges automatically. The approver still escalates anything touching auth, payments, data security, deployment, migrations, email, production data, new dependencies, or unresolved product decisions. A job with a human QA check still stops at `awaiting-human`, because that check is required validation. Its tickets stay In Review until you run `/factory approve <job-id>`, which then moves them to Done.
|
|
91
91
|
|
|
92
92
|
Any value other than exactly `auto` is treated as `human`.
|
|
93
93
|
|
|
@@ -122,9 +122,15 @@ Set `MERGE_MODE`. The approval gates are the same in both modes.
|
|
|
122
122
|
|
|
123
123
|
`push-mr` suits forge-reviewed setups, where required reviews or CI gates sit on the forge after your approval. It never force-pushes and never merges locally. Under `auto`, approve opens the request without a pause, but the forge merge and the second `/factory approve` stay yours.
|
|
124
124
|
|
|
125
|
-
##
|
|
125
|
+
## Functional QA (`qa.md`)
|
|
126
126
|
|
|
127
|
-
The builder writes `qa.md` in the feature folder, on the job's branch
|
|
127
|
+
The builder writes the QA plan into `qa.md` in the feature folder, on the job's branch, before it writes code. After the final code commit it records each check: the command, the expected result, the observed result, and `pass`, `fail`, `not run` (with the reason), or `NA`. Acceptance criteria that need a person are marked `human`, and their handoff lists the numbered steps, the expected results, and the response template.
|
|
128
|
+
|
|
129
|
+
- **Automated checks** run for every criterion on the job's tree. A failed check goes back to the builder. A check that could not run because a credential, data, or environment is missing stops the job for you, as a `Not verified` item.
|
|
130
|
+
- **Human checks** are added only where a person must judge: a new flow, or a judgement no safe automated check settles. They supplement the automated checks. The job waits at `awaiting-human`, even in `auto`. Answer the handoff with `PASS` and `accept`. `/factory approve` saves your answer in `build.md` and merges only when every human check reads `PASS` with `accept`. A failure or rejection means `/factory rework <job-id> <note>`.
|
|
131
|
+
- **Optional checks** are listed as limitations. They never block.
|
|
132
|
+
|
|
133
|
+
The approver reads the functional QA record and escalates on a failed, missing, or stale check. The manual checklist never affects a verdict, and a missing `qa.md` is only noted when the job has no `local` or `human` criteria. When a job waits for you, the orchestrator prints the record and the reviewers' `Not verified` items under the line `Suggested checks before /factory approve — not a gate`.
|
|
128
134
|
|
|
129
135
|
## Tickets
|
|
130
136
|
|
|
@@ -147,7 +153,7 @@ The parent and every sub-task move together. The orchestrator uses the project's
|
|
|
147
153
|
4. **Plan.** `planner` in plan mode writes `plan.md` (with the size) and `tasks.md` for large work.
|
|
148
154
|
5. **Plan gate.** You confirm the plan, or request changes. Nothing is ticketed or built before you confirm.
|
|
149
155
|
6. **Tickets and build location.** If tracked, the parent and sub-tasks are created and their keys are written into `tasks.md`. The folder is renamed to carry the key. Then a builder gets its own git worktree on branch `factory/<id>` (bootstrapped first, see Build location), or the in-place branch. The job's feature docs are committed on that branch.
|
|
150
|
-
7. **Build.** The builder follows TDD, ticks `tasks.md` as it completes tasks, writes `build.md`, and writes `qa.md
|
|
156
|
+
7. **Build.** The builder follows TDD, ticks `tasks.md` as it completes tasks, writes `build.md`, and writes `qa.md` (its functional QA plan before the code, and its results after).
|
|
151
157
|
8. **Review.** Every configured lens reviews the branch, and each reviewer's report is saved as `round-N/review-<lens>.md` with `VERDICT: PASS` or `VERDICT: CHANGES`.
|
|
152
158
|
9. **Repair.** Any `CHANGES` sends the builder back to fix it. Two repairs at most, so three review rounds. Then the job escalates to you.
|
|
153
159
|
10. **Approve.** `reviewer` in approval mode (fresh context) returns `APPROVE` or `ESCALATE`, and the orchestrator writes it to `decision.md`.
|