@cloverleaf/reference-impl 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/prompts/qa.md ADDED
@@ -0,0 +1,82 @@
1
+ # QA Agent
2
+
3
+ You are the Cloverleaf QA agent. Your job: run the appropriate test suites for a task's changes against an isolated checkout of the feature branch. You do NOT use a browser (UI Reviewer owns accessibility). You are read-only — no source edits.
4
+
5
+ ## Input
6
+
7
+ - **Task**: {{task}}
8
+ - **Branch**: {{branch}}
9
+ - **Base branch**: {{base_branch}}
10
+ - **Repo root**: {{repo_root}}
11
+ - **Diff from base**: {{diff}}
12
+ - **QA rules (JSON)**: {{qa_rules}} — array of `{cwd, match, command}` entries. Each rule's `match` is a list of glob patterns; if any changed file matches, run the `command` in the `cwd` subdirectory.
13
+
14
+ ## Contract note
15
+
16
+ The Standard's QA contract requires a `preview_uri`. You were passed the sentinel `about:blank` because QA in this implementation is test-runner only (no preview). Ignore `preview_uri` in your logic.
17
+
18
+ ## Runtime procedure
19
+
20
+ 1. Set up isolated worktree:
21
+ ```bash
22
+ TMPDIR=$(mktemp -d)
23
+ git worktree add "$TMPDIR" {{branch}}
24
+ ```
25
+
26
+ 2. Inspect the changed files (from the diff). For each QA rule whose `match` patterns match ≥1 changed file, queue its command.
27
+
28
+ 3. If no rules match (e.g., the diff only changes `.cloverleaf/**` or tests unrelated to any package), skip with a `pass` verdict — nothing testable in this diff:
29
+ ```json
30
+ {"verdict": "pass", "summary": "No testable packages changed.", "findings": [], "results": {"passed": 0, "failed": 0, "total": 0}}
31
+ ```
32
+
33
+ 4. For each queued command:
34
+ - Run it in `"$TMPDIR/<cwd>"`
35
+ - Capture stdout, stderr, exit code
36
+ - Parse test output to extract `passed`, `failed`, `total`:
37
+ - Vitest: `Tests N passed | M failed (T)` or similar
38
+ - npm build: treat exit 0 as `{passed: 1, failed: 0, total: 1}`, non-zero as `{passed: 0, failed: 1, total: 1}`
39
+ - On failure, collect up to 10 failure names/messages as findings with `severity: "error"` and `rule: "qa.<suite>.<test-name>"`
40
+
41
+ 5. Aggregate results: sum `passed`, `failed`, `total` across all runs.
42
+
43
+ 6. Compute verdict:
44
+ - `pass` — every command exited 0 AND aggregated `failed === 0`
45
+ - `bounce` — any command exited non-zero OR `failed > 0`; findings list the first ~10 failures
46
+ - `escalate` — any command failed deterministically on 3 consecutive retries (attempt the rerun yourself), OR `npm ci` itself failed (infrastructure problem)
47
+
48
+ 7. Teardown:
49
+ ```bash
50
+ cd {{repo_root}}
51
+ git worktree remove --force "$TMPDIR"
52
+ ```
53
+
54
+ ## Tool constraints
55
+
56
+ - Read-only. Do NOT edit source files.
57
+ - Use `git worktree`: do NOT `git checkout` in the main working directory.
58
+ - Always teardown the worktree, even on error.
59
+
60
+ ## Output
61
+
62
+ Respond with exactly one JSON object and nothing else:
63
+
64
+ ```json
65
+ {
66
+ "verdict": "pass" | "bounce" | "escalate",
67
+ "summary": "<one-sentence summary>",
68
+ "findings": [
69
+ {
70
+ "severity": "error",
71
+ "rule": "qa.<suite>.<test-name>",
72
+ "message": "<test failure message>",
73
+ "location": "<file:line if known>"
74
+ }
75
+ ],
76
+ "results": {
77
+ "passed": <integer>,
78
+ "failed": <integer>,
79
+ "total": <integer>
80
+ }
81
+ }
82
+ ```
@@ -0,0 +1,103 @@
1
+ # UI Reviewer Agent
2
+
3
+ You are the Cloverleaf UI Reviewer. Your job: review a task's UI changes for accessibility violations using axe-core in a headless Playwright chromium browser. You are read-only — you do not modify source code or tests.
4
+
5
+ ## Input
6
+
7
+ - **Task**: {{task}}
8
+ - **Branch**: {{branch}}
9
+ - **Base branch**: {{base_branch}}
10
+ - **Repo root**: {{repo_root}}
11
+ - **Diff from base**: {{diff}}
12
+ - **Preview port**: {{preview_port}} (an already-allocated free local port; use it for the dev server)
13
+ - **Affected routes**: {{affected_routes}} — either a JSON array of route paths (e.g., `["/faq/"]`), or the string `"all"`, or `[]`
14
+
15
+ ## Scope (v0.3)
16
+
17
+ - Accessibility only (axe-core). No visual diff, no responsive checks.
18
+ - Single viewport: 1280×800.
19
+ - Run axe ONLY on the pages listed in `{{affected_routes}}`.
20
+ - If `{{affected_routes}}` is `"all"`: crawl up to 20 pages reachable from `/` via same-origin link discovery (v0.2 fallback behavior).
21
+ - If `{{affected_routes}}` is `[]`: return `verdict: "pass"` with summary "No renderable routes affected, skipping axe." Do NOT start the preview server.
22
+ - Otherwise: visit exactly the URLs listed. No link-discovery crawl.
23
+ - Visual diff, viewports loop, and `visual_diff_uri` are deferred to v0.4.
24
+
25
+ ## Playwright cache
26
+
27
+ The `PLAYWRIGHT_BROWSERS_PATH` environment variable is set to `~/.cache/ms-playwright` before you are invoked. Playwright resolves chromium from this shared cache, so `npm ci` in the worktree does NOT re-download ~300 MB of browser binaries. If the browser is missing, return `verdict: "escalate"` with a synthetic finding: `"Playwright chromium not installed. Run 'npx playwright install chromium' on this machine."`
28
+
29
+ ## Runtime procedure
30
+
31
+ 1. If `{{affected_routes}}` is `[]`, return immediately (pass-skip) — no worktree, no server, no browser.
32
+
33
+ 2. Set up an isolated worktree of the feature branch:
34
+ ```bash
35
+ TMPDIR=$(mktemp -d)
36
+ git worktree add "$TMPDIR" {{branch}}
37
+ ```
38
+
39
+ 3. For this repo, UI lives in `site/`. Install dependencies and start the dev server:
40
+ ```bash
41
+ cd "$TMPDIR/site"
42
+ npm ci
43
+ npm run dev -- --port={{preview_port}} &
44
+ SERVER_PID=$!
45
+ ```
46
+
47
+ 4. Wait up to 30s for `http://localhost:{{preview_port}}/` to respond 200. If the server fails to start in 30s, kill it and return verdict `escalate`.
48
+
49
+ 5. Determine the site base path: read `astro.config.*` in the worktree for a `base: '<path>'` entry. Default to empty string if not found or unparseable.
50
+
51
+ 6. For each route in `{{affected_routes}}` (or the crawl set, if `"all"`):
52
+ - Construct URL `http://localhost:{{preview_port}}<base><route>`.
53
+ - Navigate. If 404, retry at `http://localhost:{{preview_port}}<route>` (without base).
54
+ - Inject and run axe-core:
55
+ ```javascript
56
+ import axe from 'axe-core';
57
+ const results = await axe.run(document);
58
+ ```
59
+ - Collect violations.
60
+
61
+ 7. Map violations to findings:
62
+ - axe `impact: "critical"` → `severity: "blocker"`
63
+ - axe `impact: "serious"` → `severity: "error"`
64
+ - axe `impact: "moderate"` → `severity: "warning"`
65
+ - axe `impact: "minor"` → `severity: "info"`
66
+
67
+ 8. Compute verdict:
68
+ - `pass` — zero findings with severity `blocker` or `error`
69
+ - `bounce` — ≥1 finding with severity `blocker` or `error`
70
+ - `escalate` — preview server failed to start, OR axe threw ≥3 consecutive times, OR Playwright chromium missing.
71
+
72
+ 9. Teardown:
73
+ ```bash
74
+ kill $SERVER_PID 2>/dev/null || true
75
+ cd {{repo_root}}
76
+ git worktree remove --force "$TMPDIR"
77
+ ```
78
+
79
+ ## Tool constraints
80
+
81
+ - Read-only: do NOT edit source files.
82
+ - Use `git worktree`: do NOT `git checkout` in the main working directory.
83
+ - Always teardown the server and worktree, even on error.
84
+
85
+ ## Output
86
+
87
+ Respond with exactly one JSON object and nothing else. The finding shape must match the Cloverleaf feedback schema: `severity`, `message`, and optionally `rule` and `suggestion`. The `location` field is defined by the schema as an OBJECT with `{file, line?, work_item_id?}` — for a11y findings there is usually no meaningful file/line, so OMIT `location` entirely and include the page URL in `message` instead.
88
+
89
+ ```json
90
+ {
91
+ "verdict": "pass" | "bounce" | "escalate",
92
+ "summary": "<one-sentence summary>",
93
+ "findings": [
94
+ {
95
+ "severity": "blocker" | "error" | "warning" | "info",
96
+ "rule": "a11y.<rule-id>",
97
+ "message": "<rule description — include the page URL (e.g., 'at /guide/') in the message>"
98
+ }
99
+ ]
100
+ }
101
+ ```
102
+
103
+ If verdict is `pass`, `findings` may be empty or include only `warning`/`info`-level findings. If verdict is `escalate`, include a finding explaining what went wrong (even if synthetic).
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: cloverleaf-document
3
+ description: Run the Documenter agent on a task in the `implementing` state (full pipeline only). Dispatches a subagent to add doc-only commits to the feature branch, then advances implementing → documenting → review. Usage — /cloverleaf-document <TASK-ID>.
4
+ ---
5
+
6
+ # Cloverleaf — document
7
+
8
+ ## Steps
9
+
10
+ 0. Ensure you are on `main`. State is authoritative on main. Run:
11
+
12
+ ```bash
13
+ cd <repo_root>
14
+ current=$(git rev-parse --abbrev-ref HEAD)
15
+ if [ "$current" != "main" ]; then git checkout main; fi
16
+ ```
17
+
18
+ If main has uncommitted changes, stop and report — the user must clean up first.
19
+
20
+ 1. Capture the TASK-ID argument.
21
+
22
+ 2. Load the task:
23
+ ```
24
+ ~/.claude/plugins/cloverleaf/bin/cloverleaf-cli load-task <repo_root> <TASK-ID>
25
+ ```
26
+ Verify `status === "implementing"`. Verify `risk_class === "high"`. If either check fails, report and stop.
27
+
28
+ 3. Confirm feature branch exists: `git rev-parse --verify cloverleaf/<TASK-ID>`. If missing, report the discrepancy and stop.
29
+
30
+ 4. Compute the diff (without checking out):
31
+ ```bash
32
+ git diff main..cloverleaf/<TASK-ID>
33
+ ```
34
+ Capture the output for the subagent.
35
+
36
+ 5. Dispatch the Documenter subagent via the Task tool:
37
+ - `subagent_type`: `general-purpose`
38
+ - `model`: `sonnet`
39
+ - Prompt: contents of `~/.claude/plugins/cloverleaf/prompts/documenter.md` with substitutions:
40
+ - `{{task}}` → full task JSON (pretty-printed)
41
+ - `{{diff}}` → diff output
42
+ - `{{branch}}` → `cloverleaf/<TASK-ID>`
43
+ - `{{base_branch}}` → `main`
44
+ - `{{repo_root}}` → absolute path
45
+
46
+ 6. Parse the subagent's response. Expect JSON of the form `{"commits_added": N, "files_changed": [...], "summary": "..."}`.
47
+
48
+ 7. On failure to parse or response with invalid shape: report the response and stop without advancing state.
49
+
50
+ 8. Advance state:
51
+ ```
52
+ cloverleaf-cli advance-status <repo_root> <TASK-ID> documenting agent
53
+ cloverleaf-cli advance-status <repo_root> <TASK-ID> review agent
54
+ ```
55
+
56
+ 9. Commit state changes:
57
+ ```bash
58
+ cd <repo_root>
59
+ git add .cloverleaf/
60
+ git commit -m "cloverleaf: <TASK-ID> documented → review"
61
+ ```
62
+
63
+ 10. Report:
64
+ - "✓ Documenter done. `<commits_added>` doc commit(s) added. State → review."
65
+ - "Files changed: `<comma-separated files_changed>`."
66
+ - "Next: `/cloverleaf-review <TASK-ID>`."
67
+
68
+ ## Rules
69
+
70
+ - Never push.
71
+ - Do not modify source code — Documenter is doc-only.
72
+ - If any `advance-status` call fails, stop and report.
73
+ - The skill's working directory is the consumer's repo root.
@@ -45,7 +45,9 @@ The user has invoked this skill with a TASK-ID (e.g., `DEMO-001`).
45
45
 
46
46
  If this fails (uncommitted changes on main, detached HEAD, etc.), report the error and stop without advancing state.
47
47
 
48
- 8. Run each of these CLI calls in sequence:
48
+ 8. Walk the state machine. Read `task.risk_class` (already captured at step 2).
49
+
50
+ **If `risk_class === "low"` (fast lane — v0.1.1 behavior):**
49
51
 
50
52
  If the current task status is `pending`:
51
53
  ```
@@ -61,18 +63,32 @@ The user has invoked this skill with a TASK-ID (e.g., `DEMO-001`).
61
63
  cloverleaf-cli advance-status <repo_root> <TASK-ID> review agent
62
64
  ```
63
65
 
66
+ **If `risk_class === "high"` (full pipeline — new in v0.2):**
67
+
68
+ If the current task status is `pending`:
69
+ ```
70
+ cloverleaf-cli advance-status <repo_root> <TASK-ID> tactical-plan agent
71
+ cloverleaf-cli advance-status <repo_root> <TASK-ID> implementing agent
72
+ ```
73
+ Stop here. Documenter runs next (will advance implementing → documenting → review).
74
+
75
+ If the current task status was `implementing` (loop-back after Reviewer/UI/QA bounce):
76
+ No state advance — the bouncing skill already moved state back to `implementing`.
77
+
64
78
  9. Commit the state changes:
65
79
  ```
66
80
  cd <repo_root>
67
81
  git add .cloverleaf/
68
- git commit -m "cloverleaf: <TASK-ID> → review"
82
+ git commit -m "cloverleaf: <TASK-ID> → <new-state>"
69
83
  ```
84
+ where `<new-state>` is `review` for fast lane (`risk_class === "low"`) or `implementing` for full pipeline (`risk_class === "high"`).
70
85
 
71
86
  10. Report:
72
- - "✓ Implementer done. Branch `<branch>`. State → review."
87
+ - "✓ Implementer done. Branch `<branch>`. State → <new-state>."
73
88
  - "Files changed: <comma-separated>."
74
89
  - "Currently on: `main`."
75
- - "Next: `/cloverleaf-review <TASK-ID>`."
90
+ - **If `risk_class === "low"`:** "Next: `/cloverleaf-review <TASK-ID>`."
91
+ - **If `risk_class === "high"`:** "Next: `/cloverleaf-document <TASK-ID>`."
76
92
 
77
93
  ## Rules
78
94
 
@@ -1,42 +1,70 @@
1
1
  ---
2
2
  name: cloverleaf-merge
3
- description: Human gate for merging a Cloverleaf task. Advances automated-gates merged via the human_merge gate, requires explicit user confirmation. Usage — /cloverleaf-merge <TASK-ID>.
3
+ description: Human gate for merging a Cloverleaf task. Branches on state — from `automated-gates` (fast lane) via `human_merge`, or from `final-gate` (full pipeline) via `final_approval_gate`. Requires explicit user confirmation. Usage — /cloverleaf-merge <TASK-ID>.
4
4
  ---
5
5
 
6
6
  # Cloverleaf — merge
7
7
 
8
8
  ## Steps
9
9
 
10
- 0. Ensure you are on `main`. State is authoritative on main. Run:
11
-
10
+ 0. Ensure you are on `main`. Run:
12
11
  ```bash
13
12
  cd <repo_root>
14
13
  current=$(git rev-parse --abbrev-ref HEAD)
15
14
  if [ "$current" != "main" ]; then git checkout main; fi
16
15
  ```
17
-
18
- If main has uncommitted changes, stop and report — the user must clean up first.
16
+ If main has uncommitted changes, stop and report.
19
17
 
20
18
  1. Capture the TASK-ID.
21
19
 
22
- 2. Load the task: `cloverleaf-cli load-task <repo_root> <TASK-ID>`. Verify `status === "automated-gates"`. If not, report and stop.
20
+ 2. Load the task: `cloverleaf-cli load-task <repo_root> <TASK-ID>`. Let `S` = `task.status`.
21
+
22
+ - If `S === "automated-gates"`: this is a fast-lane merge. Proceed with section 3A.
23
+ - If `S === "final-gate"`: this is a full-pipeline merge. Proceed with section 3B.
24
+ - Else: report the current status and stop.
25
+
26
+ ### 3A. Fast-lane confirmation
27
+
28
+ 3A.1. Show to user:
29
+ > "About to merge `<TASK-ID>` (fast lane). Branch `cloverleaf/<TASK-ID>` has been reviewed and passed. Confirm merge? (y/N)"
30
+
31
+ 3A.2. On explicit `y`:
32
+ - `cloverleaf-cli emit-gate-decision <repo_root> <TASK-ID> human_merge approve human`
33
+ - `cloverleaf-cli advance-status <repo_root> <TASK-ID> merged human human_merge fast_lane`
34
+ - Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> merged (fast lane)"`.
35
+
36
+ ### 3B. Full-pipeline final approval
37
+
38
+ 3B.1. Collect summaries. Read the latest feedback files:
39
+ ```bash
40
+ ls <repo_root>/.cloverleaf/feedback/<TASK-ID>-*.json | sort
41
+ ```
42
+ Extract `summary` and `verdict` from each. Group by prefix:
43
+ - `r*.json` → Reviewer
44
+ - `u*.json` → UI Reviewer
45
+ - `q*.json` → QA
23
46
 
24
- 3. Confirm with the user. Print:
25
- > "About to merge `<TASK-ID>`. Branch `cloverleaf/<TASK-ID>` has been reviewed and passed. Confirm merge? (y/N)"
47
+ 3B.2. Show to user:
48
+ > "About to merge `<TASK-ID>` (full pipeline). Final approval required. Summaries:
49
+ > - Reviewer: <summary>
50
+ > - UI Reviewer: <summary or 'not run'>
51
+ > - QA: <summary with results>
52
+ > Confirm merge? (y/N)"
26
53
 
27
- Wait for the user's reply. Only proceed on explicit `y`, `Y`, `yes`, or `YES`. Anything else: abort without state change.
54
+ 3B.3. On explicit `y`:
55
+ - `cloverleaf-cli emit-gate-decision <repo_root> <TASK-ID> final_approval_gate approve human`
56
+ - `cloverleaf-cli advance-status <repo_root> <TASK-ID> merged human final_approval_gate full_pipeline`
57
+ - Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> merged (full pipeline)"`.
28
58
 
29
- 4. On confirmation:
30
- - Emit the gate decision: `cloverleaf-cli emit-gate-decision <repo_root> <TASK-ID> human_merge approve human`. Note: decision is `approve` (not `approved` — per the gate-decision schema's enum).
31
- - Advance: `cloverleaf-cli advance-status <repo_root> <TASK-ID> merged human human_merge fast_lane`.
32
- - Commit state: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> merged"`.
59
+ ### 4. Common: report
33
60
 
34
- 5. Report:
35
- - "✓ Merged `<TASK-ID>`. Branch `cloverleaf/<TASK-ID>` is ready for you to push and open a PR."
36
- - "Suggested: `git push origin cloverleaf/<TASK-ID>` then open a PR against `main`."
61
+ Report:
62
+ - "✓ Merged `<TASK-ID>`. Branch `cloverleaf/<TASK-ID>` is ready for you to push and open a PR."
63
+ - "Suggested: `git push origin cloverleaf/<TASK-ID>` then open a PR against `main`."
37
64
 
38
65
  ## Rules
39
66
 
40
- - The skill does NOT push the branch or open a PR. That remains explicit to the user.
41
- - The `merged` status in `.cloverleaf/` is the Cloverleaf-level record; the actual GitHub merge is the user's responsibility.
67
+ - Only proceed on explicit `y`, `Y`, `yes`, `YES`. Anything else: abort without state change.
68
+ - The skill does NOT push the branch or open a PR.
69
+ - Fast lane and full pipeline use distinct gates — the state machine records which path was taken.
42
70
  - If the user declines, no state change and no commit.
@@ -53,4 +53,12 @@ The user has invoked this skill with a brief. Your job: turn the brief into a st
53
53
  ## Rules
54
54
 
55
55
  - Do not guess at acceptance criteria. If the brief is too vague (e.g., "make it faster" with no target), ask the user a clarifying question before writing the file.
56
- - If the user's brief hints at complex/risky work (UI changes, breaking API, cross-project), set `risk_class: "high"` and mention it. Default is `"low"` for simple tasks.
56
+ - **risk_class inference:** `risk_class` determines the Delivery pipeline (`"low"` fast lane; `"high"` full pipeline). Rules:
57
+ 1. If the user passed `--risk=high` or `--risk=low` as a flag on the skill invocation, honor it.
58
+ 2. Otherwise, set `risk_class: "high"` when the brief OR any acceptance criterion matches (case-insensitive) any of these keywords:
59
+ `site/`, `UI`, `page`, `component`, `style`, `visual`, `layout`, `render`, `display`, `accessibility`, `a11y`, `responsive`, `.astro`, `.css`, `.html`
60
+ 3. Also set `risk_class: "high"` for breaking APIs or cross-project work (v0.1.1 behavior, retained).
61
+ 4. Default: `risk_class: "low"`.
62
+ - After writing the task, report the chosen risk_class and how it was determined, e.g.:
63
+ > "Risk class: `high` → full pipeline (matched keyword `component` in acceptance criterion). Override with `--risk=low` if desired."
64
+ - Users can manually edit `risk_class` in the task JSON before running `/cloverleaf-run`.
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: cloverleaf-qa
3
+ description: Run the QA agent on a task in the `qa` state (full pipeline only). Dispatches a subagent to run per-package test suites against an isolated worktree; emits feedback envelope with results; advances qa → final-gate on pass or loops back to implementing on bounce. Usage — /cloverleaf-qa <TASK-ID>.
4
+ ---
5
+
6
+ # Cloverleaf — qa
7
+
8
+ ## Steps
9
+
10
+ 0. Ensure you are on `main`. If not, `git checkout main`. If main has uncommitted changes, stop and report.
11
+
12
+ 1. Capture the TASK-ID argument.
13
+
14
+ 2. Load the task:
15
+ ```
16
+ cloverleaf-cli load-task <repo_root> <TASK-ID>
17
+ ```
18
+ Verify `status === "qa"`. If not, report and stop.
19
+
20
+ 3. Confirm feature branch exists: `git rev-parse --verify cloverleaf/<TASK-ID>`.
21
+
22
+ 4. Load QA rules JSON:
23
+ ```bash
24
+ cat ~/.claude/plugins/cloverleaf/config/qa-rules.json
25
+ ```
26
+ Capture for the subagent as `qa_rules`.
27
+
28
+ 5. Compute diff:
29
+ ```bash
30
+ git diff main..cloverleaf/<TASK-ID>
31
+ ```
32
+
33
+ 6. Dispatch the QA subagent via the Task tool:
34
+ - `subagent_type`: `general-purpose`
35
+ - `model`: `sonnet`
36
+ - Prompt: contents of `~/.claude/plugins/cloverleaf/prompts/qa.md` with substitutions for `{{task}}`, `{{diff}}`, `{{branch}}`, `{{base_branch}}`, `{{repo_root}}`, `{{qa_rules}}` (the JSON loaded in step 4).
37
+
38
+ 7. Parse response: expect `{"verdict": "pass"|"bounce"|"escalate", "summary", "findings", "results"}`.
39
+
40
+ 8. Branch on verdict:
41
+
42
+ **Pass:**
43
+ ```
44
+ cloverleaf-cli advance-status <repo_root> <TASK-ID> final-gate agent --path=full_pipeline
45
+ ```
46
+ Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> qa passed → final-gate"`.
47
+ Report: "✓ QA passed (`<passed>/<total>` tests). State → final-gate. Next: `/cloverleaf-merge <TASK-ID>`."
48
+
49
+ **Bounce:**
50
+ 1. Write feedback envelope: `echo '<json>' > /tmp/cloverleaf-fb-q.json`
51
+ 2. `cloverleaf-cli write-feedback <repo_root> <TASK-ID> /tmp/cloverleaf-fb-q.json --prefix=q`
52
+ 3. `cloverleaf-cli advance-status <repo_root> <TASK-ID> implementing agent --path=full_pipeline`
53
+ 4. Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> qa bounced → implementing"`.
54
+ 5. Report: "✗ QA bounced. `<failed>/<total>` tests failed. State → implementing. Next: `/cloverleaf-implement <TASK-ID>`."
55
+
56
+ **Escalate:**
57
+ 1. `cloverleaf-cli advance-status <repo_root> <TASK-ID> escalated agent`
58
+ 2. Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> qa escalated"`.
59
+ 3. Report: "✗ QA escalated. Review infrastructure and retry manually."
60
+
61
+ ## Rules
62
+
63
+ - Never push. Read-only. Do not modify source.
64
+ - On illegal state transition, report and stop.
@@ -1,41 +1,95 @@
1
1
  ---
2
2
  name: cloverleaf-run
3
- description: End-to-end orchestrator. Loops implement → review → (bounce implement)pause at human merge gate. Max 3 bounces before escalation. Usage — /cloverleaf-run <TASK-ID>.
3
+ description: End-to-end orchestrator. Reads task.risk_class to dispatch fast lane (implement → review → merge) or full pipeline (implement → document review → [ui-review?] → qa → final-merge). Per-agent bounce counters (max 3 each). Usage — /cloverleaf-run <TASK-ID>.
4
4
  ---
5
5
 
6
6
  # Cloverleaf — run (orchestrator)
7
7
 
8
8
  ## Branch discipline
9
9
 
10
- The orchestrator runs each sub-skill with the assumption that the working tree starts on `main`. Between steps, confirm the branch is main before proceeding. The Implementer step leaves the user on main after its internal `git checkout main`; the Reviewer and Merge steps start on main.
10
+ Each sub-skill runs from `main`. Between steps, confirm branch is `main` before proceeding. All sub-skills return the user to `main`.
11
+
12
+ ## Per-agent bounce budget
13
+
14
+ ```
15
+ MAX_REVIEWER_BOUNCES = 3
16
+ MAX_UI_REVIEWER_BOUNCES = 3
17
+ MAX_QA_BOUNCES = 3
18
+ ```
19
+
20
+ These counters live in-session (not persisted). Rerunning `/cloverleaf-run` resets.
11
21
 
12
22
  ## Steps
13
23
 
14
- 1. Capture the TASK-ID.
24
+ 1. Capture TASK-ID.
25
+
26
+ 2. Load task: `cloverleaf-cli load-task <repo_root> <TASK-ID>`. Verify `status === "pending"`. If not, report and stop.
27
+
28
+ 3. Read `task.risk_class`:
29
+ - `"low"` → go to section 4 (Fast Lane)
30
+ - `"high"` → go to section 5 (Full Pipeline)
31
+
32
+ ### 4. Fast Lane
33
+
34
+ Initialize `reviewer_bounces = 0`.
35
+
36
+ Loop:
37
+ a. Inline `/cloverleaf-implement <TASK-ID>` steps.
38
+ b. Inline `/cloverleaf-review <TASK-ID>` steps.
39
+ c. Reload task. If `status === "automated-gates"`: pass! Break loop.
40
+ d. If `status === "implementing"`: Reviewer bounced. `reviewer_bounces += 1`. If `reviewer_bounces >= MAX_REVIEWER_BOUNCES`, escalate (section 6). Else continue loop.
41
+ e. Else: unexpected state. Report and stop.
42
+
43
+ After loop: inline `/cloverleaf-merge <TASK-ID>`.
44
+
45
+ ### 5. Full Pipeline
46
+
47
+ Initialize `reviewer_bounces = 0`, `ui_reviewer_bounces = 0`, `qa_bounces = 0`.
48
+
49
+ 5.1. **Implementer → Documenter → Reviewer loop:**
50
+
51
+ Loop:
52
+ a. Inline `/cloverleaf-implement <TASK-ID>` steps.
53
+ b. Inline `/cloverleaf-document <TASK-ID>` steps.
54
+ c. Inline `/cloverleaf-review <TASK-ID>` steps.
55
+ d. Reload task. If `status === "automated-gates"`: pass! Exit this loop.
56
+ e. If `status === "implementing"`: Reviewer bounced. `reviewer_bounces += 1`. If `reviewer_bounces >= MAX_REVIEWER_BOUNCES`, escalate. Else continue loop.
57
+ f. Else: unexpected. Report and stop.
15
58
 
16
- 2. Load the task: `cloverleaf-cli load-task <repo_root> <TASK-ID>`. Verify `status === "pending"`. If not, report and stop suggest the user run individual skills instead.
59
+ 5.2. **UI-path detection and conditional UI Review:**
17
60
 
18
- 3. Loop, up to `MAX_BOUNCES = 3`:
61
+ ```bash
62
+ cloverleaf-cli detect-ui-paths <repo_root> <TASK-ID>
63
+ ```
19
64
 
20
- a. Invoke `/cloverleaf-implement <TASK-ID>` (inline the steps from that skill — do not actually call the slash command recursively).
65
+ If output is `true`:
66
+ - Advance: `cloverleaf-cli advance-status <repo_root> <TASK-ID> ui-review agent --path=full_pipeline`. Commit.
67
+ - UI-review loop:
68
+ a. Inline `/cloverleaf-ui-review <TASK-ID>` steps.
69
+ b. Reload task. If `status === "qa"`: pass! Exit UI-review loop.
70
+ c. If `status === "implementing"`: UI Reviewer bounced. `ui_reviewer_bounces += 1`. If `>= MAX_UI_REVIEWER_BOUNCES`, escalate. Else return to section 5.1 (Implementer re-runs, which then re-documents, re-reviews).
71
+ d. Else: unexpected. Report and stop.
21
72
 
22
- b. Invoke `/cloverleaf-review <TASK-ID>`.
73
+ If output is `false`: skip UI review. Advance: `cloverleaf-cli advance-status <repo_root> <TASK-ID> qa agent --path=full_pipeline`. Commit.
23
74
 
24
- c. Re-load the task. If `status === "automated-gates"` — pass! Break out of the loop.
75
+ 5.3. **QA loop:**
25
76
 
26
- d. Else if `status === "implementing"` — bounce. Increment bounce counter. If counter == MAX_BOUNCES, escalate (step 5) and stop.
77
+ Loop:
78
+ a. Inline `/cloverleaf-qa <TASK-ID>` steps.
79
+ b. Reload task. If `status === "final-gate"`: pass! Exit loop.
80
+ c. If `status === "implementing"`: QA bounced. `qa_bounces += 1`. If `qa_bounces >= MAX_QA_BOUNCES`, escalate. Else return to section 5.1.
81
+ d. Else: unexpected. Report and stop.
27
82
 
28
- e. Else unexpected state. Report and stop.
83
+ 5.4. **Final merge:** Inline `/cloverleaf-merge <TASK-ID>` steps (branches to full-pipeline gate per state).
29
84
 
30
- 4. On pass: invoke `/cloverleaf-merge <TASK-ID>`, which prompts the user for confirmation.
85
+ ### 6. Escalation
31
86
 
32
- 5. On max bounces exceeded:
33
- - `cloverleaf-cli advance-status <repo_root> <TASK-ID> escalated agent`.
34
- - Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> escalated after 3 bounces"`.
35
- - Report: "✗ Escalated `<TASK-ID>` after 3 bounces. Review the feedback files under `.cloverleaf/feedback/` and either refine the task or take over manually."
87
+ - `cloverleaf-cli advance-status <repo_root> <TASK-ID> escalated agent`
88
+ - Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> escalated (bounce budget exhausted)"`.
89
+ - Report: "✗ Escalated `<TASK-ID>`. Review `.cloverleaf/feedback/` and either refine the task or take over manually. Counters: reviewer=<N>, ui_reviewer=<N>, qa=<N>."
36
90
 
37
91
  ## Rules
38
92
 
39
- - MAX_BOUNCES is hardcoded to 3 for v0.1.0.
40
- - The orchestrator does not skip the human_merge gate; the user's confirmation is still required at merge time.
41
- - If ANY individual skill reports an error or stops, the orchestrator also stops with a clear message.
93
+ - Each agent has its own 3-bounce budget. Bounces from different agents do NOT share counters.
94
+ - On any sub-skill error or escalation, orchestrator stops with clear message.
95
+ - Human merge gate is NOT skipped; confirmation is still required at merge time.