@muggleai/works 4.10.0 → 4.11.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/README.md +3 -3
- package/dist/{chunk-RK6XKSZK.js → chunk-Q7WNEMN4.js} +109 -43
- package/dist/{chunk-UVXOHXY2.js → chunk-ZKRHFTIC.js} +832 -89
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/README.md +4 -2
- package/dist/plugin/agents/acceptance-tester.md +24 -10
- package/dist/plugin/commands/m.md +7 -0
- package/dist/plugin/commands/mdo.md +7 -0
- package/dist/plugin/commands/mfeedback.md +7 -0
- package/dist/plugin/commands/mimport.md +7 -0
- package/dist/plugin/commands/mpr.md +7 -0
- package/dist/plugin/commands/mprefs.md +7 -0
- package/dist/plugin/commands/mregen.md +7 -0
- package/dist/plugin/commands/mrelease.md +7 -0
- package/dist/plugin/commands/mrepair.md +7 -0
- package/dist/plugin/commands/mstatus.md +7 -0
- package/dist/plugin/commands/mtest.md +7 -0
- package/dist/plugin/commands/mtestlocal.md +7 -0
- package/dist/plugin/commands/mtestprep.md +7 -0
- package/dist/plugin/commands/mupgrade.md +7 -0
- package/dist/plugin/scripts/ensure-electron-app.sh +35 -8
- package/dist/plugin/skills/_aliases.json +18 -0
- package/dist/plugin/skills/_shared/dev-server-readiness.md +231 -0
- package/dist/plugin/skills/_shared/failure-mode-handling.md +244 -0
- package/dist/plugin/skills/_shared/post-merge-cleanup.md +10 -0
- package/dist/plugin/skills/_shared/pr-followup-helpers.md +150 -0
- package/dist/plugin/skills/_shared/rebase-before-e2e.md +15 -0
- package/dist/plugin/skills/_shared/telemetry-emit.md +15 -0
- package/dist/plugin/skills/_shared/use-worktrees.md +53 -0
- package/dist/plugin/skills/do/build.md +51 -0
- package/dist/plugin/skills/do/e2e-acceptance.md +64 -19
- package/dist/plugin/skills/do/impact-analysis.md +47 -7
- package/dist/plugin/skills/do/open-prs.md +72 -74
- package/dist/plugin/skills/do/pre-flight.md +21 -14
- package/dist/plugin/skills/do/requirements.md +2 -2
- package/dist/plugin/skills/do/unit-tests.md +2 -2
- package/dist/plugin/skills/m/SKILL.md +8 -0
- package/dist/plugin/skills/mdo/SKILL.md +8 -0
- package/dist/plugin/skills/mfeedback/SKILL.md +8 -0
- package/dist/plugin/skills/mimport/SKILL.md +8 -0
- package/dist/plugin/skills/mpr/SKILL.md +8 -0
- package/dist/plugin/skills/mprefs/SKILL.md +8 -0
- package/dist/plugin/skills/mregen/SKILL.md +8 -0
- package/dist/plugin/skills/mrelease/SKILL.md +8 -0
- package/dist/plugin/skills/mrepair/SKILL.md +8 -0
- package/dist/plugin/skills/mstatus/SKILL.md +8 -0
- package/dist/plugin/skills/mtest/SKILL.md +8 -0
- package/dist/plugin/skills/mtestlocal/SKILL.md +8 -0
- package/dist/plugin/skills/mtestprep/SKILL.md +8 -0
- package/dist/plugin/skills/muggle/SKILL.md +9 -6
- package/dist/plugin/skills/muggle-do/SKILL.md +36 -61
- package/dist/plugin/skills/muggle-do-task/SKILL.md +134 -0
- package/dist/plugin/skills/muggle-feedback/SKILL.md +39 -0
- package/dist/plugin/skills/muggle-feedback/ops/delete.md +49 -0
- package/dist/plugin/skills/muggle-feedback/ops/list.md +65 -0
- package/dist/plugin/skills/muggle-feedback/ops/submit.md +130 -0
- package/dist/plugin/skills/muggle-pr-followup/SKILL.md +59 -0
- package/dist/plugin/skills/muggle-pr-followup/contract.md +191 -0
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +68 -43
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
- package/dist/plugin/skills/muggle-preferences/SKILL.md +16 -108
- package/dist/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
- package/dist/plugin/skills/muggle-preferences/ops/configure.md +49 -0
- package/dist/plugin/skills/muggle-preferences/ops/list.md +9 -0
- package/dist/plugin/skills/muggle-preferences/ops/reset.md +6 -0
- package/dist/plugin/skills/muggle-preferences/ops/set.md +10 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/README.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +3 -3
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +2 -2
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +1 -2
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +4 -4
- package/dist/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +8 -25
- package/dist/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +4 -4
- package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +4 -4
- package/dist/plugin/skills/muggle-repair/SKILL.md +4 -2
- package/dist/plugin/skills/muggle-status/SKILL.md +8 -5
- package/dist/plugin/skills/muggle-test/SKILL.md +110 -86
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +83 -62
- package/dist/plugin/skills/muggle-test-import/SKILL.md +28 -23
- package/dist/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
- package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +34 -18
- package/dist/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
- package/dist/plugin/skills/muggle-upgrade/SKILL.md +4 -2
- package/dist/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
- package/dist/plugin/skills/mupgrade/SKILL.md +8 -0
- package/dist/release-manifest.json +4 -4
- package/dist/{src-GD3YFCCW.js → src-2G7ENRGI.js} +1 -1
- package/package.json +9 -7
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/README.md +4 -2
- package/plugin/agents/acceptance-tester.md +24 -10
- package/plugin/commands/m.md +7 -0
- package/plugin/commands/mdo.md +7 -0
- package/plugin/commands/mfeedback.md +7 -0
- package/plugin/commands/mimport.md +7 -0
- package/plugin/commands/mpr.md +7 -0
- package/plugin/commands/mprefs.md +7 -0
- package/plugin/commands/mregen.md +7 -0
- package/plugin/commands/mrelease.md +7 -0
- package/plugin/commands/mrepair.md +7 -0
- package/plugin/commands/mstatus.md +7 -0
- package/plugin/commands/mtest.md +7 -0
- package/plugin/commands/mtestlocal.md +7 -0
- package/plugin/commands/mtestprep.md +7 -0
- package/plugin/commands/mupgrade.md +7 -0
- package/plugin/scripts/ensure-electron-app.sh +35 -8
- package/plugin/skills/_aliases.json +18 -0
- package/plugin/skills/_shared/dev-server-readiness.md +231 -0
- package/plugin/skills/_shared/failure-mode-handling.md +244 -0
- package/plugin/skills/_shared/post-merge-cleanup.md +10 -0
- package/plugin/skills/_shared/pr-followup-helpers.md +150 -0
- package/plugin/skills/_shared/rebase-before-e2e.md +15 -0
- package/plugin/skills/_shared/telemetry-emit.md +15 -0
- package/plugin/skills/_shared/use-worktrees.md +53 -0
- package/plugin/skills/do/build.md +51 -0
- package/plugin/skills/do/e2e-acceptance.md +64 -19
- package/plugin/skills/do/impact-analysis.md +47 -7
- package/plugin/skills/do/open-prs.md +72 -74
- package/plugin/skills/do/pre-flight.md +21 -14
- package/plugin/skills/do/requirements.md +2 -2
- package/plugin/skills/do/unit-tests.md +2 -2
- package/plugin/skills/m/SKILL.md +8 -0
- package/plugin/skills/mdo/SKILL.md +8 -0
- package/plugin/skills/mfeedback/SKILL.md +8 -0
- package/plugin/skills/mimport/SKILL.md +8 -0
- package/plugin/skills/mpr/SKILL.md +8 -0
- package/plugin/skills/mprefs/SKILL.md +8 -0
- package/plugin/skills/mregen/SKILL.md +8 -0
- package/plugin/skills/mrelease/SKILL.md +8 -0
- package/plugin/skills/mrepair/SKILL.md +8 -0
- package/plugin/skills/mstatus/SKILL.md +8 -0
- package/plugin/skills/mtest/SKILL.md +8 -0
- package/plugin/skills/mtestlocal/SKILL.md +8 -0
- package/plugin/skills/mtestprep/SKILL.md +8 -0
- package/plugin/skills/muggle/SKILL.md +9 -6
- package/plugin/skills/muggle-do/SKILL.md +36 -61
- package/plugin/skills/muggle-do-task/SKILL.md +134 -0
- package/plugin/skills/muggle-feedback/SKILL.md +39 -0
- package/plugin/skills/muggle-feedback/ops/delete.md +49 -0
- package/plugin/skills/muggle-feedback/ops/list.md +65 -0
- package/plugin/skills/muggle-feedback/ops/submit.md +130 -0
- package/plugin/skills/muggle-pr-followup/SKILL.md +59 -0
- package/plugin/skills/muggle-pr-followup/contract.md +191 -0
- package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +68 -43
- package/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
- package/plugin/skills/muggle-preferences/SKILL.md +16 -108
- package/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
- package/plugin/skills/muggle-preferences/ops/configure.md +49 -0
- package/plugin/skills/muggle-preferences/ops/list.md +9 -0
- package/plugin/skills/muggle-preferences/ops/reset.md +6 -0
- package/plugin/skills/muggle-preferences/ops/set.md +10 -0
- package/plugin/skills/muggle-preferences/preference-gates/README.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +3 -3
- package/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +2 -2
- package/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +1 -2
- package/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +4 -4
- package/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +8 -25
- package/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +4 -4
- package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +4 -4
- package/plugin/skills/muggle-repair/SKILL.md +4 -2
- package/plugin/skills/muggle-status/SKILL.md +8 -5
- package/plugin/skills/muggle-test/SKILL.md +110 -86
- package/plugin/skills/muggle-test-feature-local/SKILL.md +83 -62
- package/plugin/skills/muggle-test-import/SKILL.md +28 -23
- package/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
- package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +34 -18
- package/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
- package/plugin/skills/muggle-upgrade/SKILL.md +4 -2
- package/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
- package/plugin/skills/mupgrade/SKILL.md +8 -0
- package/scripts/postinstall.mjs +11 -1
- package/dist/plugin/skills/do/validate-code.md +0 -38
- package/plugin/skills/do/validate-code.md +0 -38
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# Failure-Mode Handling — Shared Reference
|
|
2
|
+
|
|
3
|
+
> Source of truth for **(a)** the pre-execution replay-vs-regen choice and **(b)** the post-execution failure router used by `muggle-test`, `muggle-test-feature-local`, `muggle-do-task`, and `muggle-test-regenerate-missing`. Skills MUST link here rather than restate the rules.
|
|
4
|
+
|
|
5
|
+
## The contract
|
|
6
|
+
|
|
7
|
+
Every decision in this doc follows the same shape:
|
|
8
|
+
|
|
9
|
+
1. **Classify** — pick a bucket from a fixed taxonomy based on the available signals.
|
|
10
|
+
2. **Suggest** — present the bucket-specific suggestion to the user via `AskUserQuestion`.
|
|
11
|
+
3. **User decides** — the user always makes the final call. Never auto-act.
|
|
12
|
+
4. **Emit telemetry** — record `(aiClassification, aiSuggestion, userAction, signals)` via `muggle-local-telemetry-event-emit` so the rules can be refined later from real data.
|
|
13
|
+
|
|
14
|
+
The classification rules below are **starting heuristics**. Trust the AI's bucket only enough to phrase a default suggestion — let the user override freely.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## F. Run-level verdict taxonomy
|
|
19
|
+
|
|
20
|
+
The buckets in sections A–C operate **per script** (one classification per test-case execution). This section defines the **single verdict** an acceptance-tester subagent returns to its orchestrator — one verdict per PR / per dispatched run, summarizing every test case it touched.
|
|
21
|
+
|
|
22
|
+
### Verdicts
|
|
23
|
+
|
|
24
|
+
| Verdict | Meaning |
|
|
25
|
+
|---|---|
|
|
26
|
+
| **PASS** | All relevant test cases ran and passed. The PR's user-visible change is exercised and works. |
|
|
27
|
+
| **FAIL** | At least one test case demonstrated wrong behavior caused by the PR code. The PR is regressive. |
|
|
28
|
+
| **PARTIAL** | Some relevant tests passed; some were INCONCLUSIVE (not failed). Useful coverage, with gaps. |
|
|
29
|
+
| **INCONCLUSIVE** | All relevant tests were blocked by environment factors — script staleness, empty local DB, missing fixtures, tests out of date relative to current master UI. **Not a regression signal.** |
|
|
30
|
+
| **BLOCKED** | An infra blocker prevented any meaningful execution: Auth0 tenant rejecting test emails, dev server unreachable, MCP service down, port wouldn't bind. **Not a regression signal.** |
|
|
31
|
+
| **SKIPPED** | No code under test — placeholder branch, empty diff vs. master, deliberate no-op change. |
|
|
32
|
+
|
|
33
|
+
PASS and FAIL are the only verdicts that say something about the PR itself. PARTIAL means "some coverage, some gaps." INCONCLUSIVE, BLOCKED, and SKIPPED all mean **don't draw a regression conclusion from this run** — they signal an environment, script, or input problem, not a product defect.
|
|
34
|
+
|
|
35
|
+
### Mapping per-script buckets to run verdicts
|
|
36
|
+
|
|
37
|
+
When the subagent aggregates per-script results from sections B and C into one verdict:
|
|
38
|
+
|
|
39
|
+
| Per-script bucket | Section | Typical run verdict |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| `infra` (replay or regen) | B / C | **BLOCKED** |
|
|
42
|
+
| `stale-script` (replay) | B | **INCONCLUSIVE** |
|
|
43
|
+
| `product-defect` (replay) | B | **FAIL** |
|
|
44
|
+
| `product-uxux` (regen) | C | **FAIL** |
|
|
45
|
+
| `agent-course` (regen) | C | **INCONCLUSIVE** (agent couldn't complete, not a PR defect) |
|
|
46
|
+
| `transient` (regen) | C | retry once; if still transient → **INCONCLUSIVE** |
|
|
47
|
+
|
|
48
|
+
When a run mixes buckets across multiple test cases, take the most-significant verdict in this priority order: **FAIL > PARTIAL > BLOCKED > INCONCLUSIVE > SKIPPED > PASS**. If any one test case maps to FAIL, the run is FAIL. If some passed and some were INCONCLUSIVE, the run is PARTIAL.
|
|
49
|
+
|
|
50
|
+
### How orchestrators consume the verdict
|
|
51
|
+
|
|
52
|
+
Subagents return the verdict as part of a structured block, not free-form prose. The orchestrator parses this block to decide whether to post a "regression" PR comment, a "needs investigation" comment, or skip the PR. See `agents/acceptance-tester.md` for the exact block format the subagent must emit.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## A. Pre-execution: replay vs regen (used by `muggle-test`)
|
|
57
|
+
|
|
58
|
+
Run during change analysis, **per impacted test case**. Picks the initial execution mode before Step 7. Other skills with a single user-picked target (`muggle-test-feature-local`, `muggle-do-task`) skip this section — the user already chose.
|
|
59
|
+
|
|
60
|
+
### Inputs
|
|
61
|
+
|
|
62
|
+
- The change summary from `git diff` (file paths + diff content).
|
|
63
|
+
- The test case (title, description, instructions, last passing run timestamp).
|
|
64
|
+
- Existing test scripts for that test case from `muggle-remote-test-script-list`.
|
|
65
|
+
|
|
66
|
+
### Rules (fire in order; first match wins)
|
|
67
|
+
|
|
68
|
+
| # | Condition | Mode | Reason |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| 1 | No replayable/succeeded script exists for the test case | `regen` | Nothing to replay. |
|
|
71
|
+
| 2 | A changed file looks like UI/markup mapped to this test case (component, page, route, template, JSX/TSX/Vue/Svelte/HTML, CSS that changes layout or selectors) | `regen` | Selectors likely broken — replay would fail on staleness. |
|
|
72
|
+
| 3 | Last successful run was > **30 days** ago | `regen` | Drift accumulates; the saved script is stale even without a flagged change. |
|
|
73
|
+
| 4 | Otherwise — changes are logic-only / backend / styling-without-DOM-impact | `replay` | Selectors should still work; replay catches real regressions. |
|
|
74
|
+
|
|
75
|
+
### Mapping "changed file → test case"
|
|
76
|
+
|
|
77
|
+
Use the test case's `instructions` and `goal` text plus filenames in the diff. Match heuristically — a test case titled "Submit signup form" plus a diff in `app/auth/signup/page.tsx` is a clear match. When in doubt, prefer `regen` (rule 2 wins) — a needless regen wastes budget; a stale replay fails the test for the wrong reason.
|
|
78
|
+
|
|
79
|
+
### Telemetry
|
|
80
|
+
|
|
81
|
+
Emit **`pre-execution-classification`** for every test case in the batch, before execution starts:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"eventType": "pre-execution-classification",
|
|
86
|
+
"skillName": "muggle-test",
|
|
87
|
+
"aiClassification": "replay" | "regen",
|
|
88
|
+
"aiSuggestion": "<same as classification>",
|
|
89
|
+
"testCaseId": "<id>",
|
|
90
|
+
"projectId": "<id>",
|
|
91
|
+
"signals": ["rule-1-no-script" | "rule-2-ui-changed" | "rule-3-stale-30d" | "rule-4-default-replay"],
|
|
92
|
+
"metadata": { "lastPassedAgeDays": <n>, "changedFilesMatched": ["..."] }
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Skill MAY surface the per-test-case decision in the report (e.g., "regenerating 3, replaying 5") so the user can override before execution. If the user overrides, emit a follow-up event with `userAction` set to the overriding mode.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## B. Post-replay failure (used by all four skills with replays)
|
|
101
|
+
|
|
102
|
+
Triggered when `muggle-local-execute-replay` returns `status: "failed"` (or non-zero Electron exit) **and** the run is not an orchestration timeout already covered in `muggle-test-feature-local/SKILL.md` Step 6.
|
|
103
|
+
|
|
104
|
+
### Buckets
|
|
105
|
+
|
|
106
|
+
| Bucket | Meaning |
|
|
107
|
+
|---|---|
|
|
108
|
+
| **infra** | Something is wrong inside Muggle Test itself (e.g., click didn't register on a clearly-clickable element, Electron crash, browser engine quirk). Not the user's fault and not a stale script. |
|
|
109
|
+
| **stale-script** | The test script no longer matches the live UI (selectors moved, label paths changed, page renamed). The product still works; the script is out of date. |
|
|
110
|
+
| **product-defect** | The script and infra are fine; the user's app actually misbehaved (assertion failure on previously-passing step, unexpected error, wrong page after action). This is the failure mode acceptance testing exists to catch. |
|
|
111
|
+
|
|
112
|
+
### Initial signal heuristics
|
|
113
|
+
|
|
114
|
+
Derive signals from the run's per-step results, error messages, and step screenshots (`muggle-local-run-result-get`):
|
|
115
|
+
|
|
116
|
+
- **infra** signals: `electron-crash`, `chromium-error`, `click-no-effect-on-clickable-element`, `timeout-on-trivial-wait`, `internal-error-in-mcp-output`.
|
|
117
|
+
- **stale-script** signals: `element-not-found`, `selector-timeout`, `label-path-mismatch`, `nav-target-404`, `aria-label-changed`.
|
|
118
|
+
- **product-defect** signals: `assertion-failed-on-passing-step`, `unexpected-error-toast`, `wrong-page-after-action`, `network-500-from-app`, `form-validation-rejected-valid-input`.
|
|
119
|
+
|
|
120
|
+
If signals span multiple buckets, pick the most specific one and list all signals in telemetry — the user can override.
|
|
121
|
+
|
|
122
|
+
### Suggestions per bucket
|
|
123
|
+
|
|
124
|
+
Present via `AskUserQuestion`. The first option is the AI's recommendation (label it `(Recommended)`); always include the others so the user can redirect. **Always include "Skip — just report" so the user can opt out without committing to anything.**
|
|
125
|
+
|
|
126
|
+
| Bucket | Recommended suggestion | Other options |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| **infra** | Report bug to Muggle AI → invoke `muggle-feedback` skill with `category: "muggle-infra"` (and run id / signals). | Retry; muggle-feedback (different category); Skip. |
|
|
129
|
+
| **stale-script** | Regenerate the script → call `muggle-local-execute-test-generation` (or remote equivalent) for this test case, then re-replay. | Retry as-is; muggle-feedback; Skip. |
|
|
130
|
+
| **product-defect** | Surface as a real defect — show the failing step + screenshot + one-line summary; offer to share via email/SMS/file ticket (see "Sharing real defects" below). | muggle-feedback (if the script's *expectation* was wrong); Retry; Skip. |
|
|
131
|
+
|
|
132
|
+
### Sharing real defects
|
|
133
|
+
|
|
134
|
+
When the user picks "share / file ticket" on a `product-defect`:
|
|
135
|
+
|
|
136
|
+
1. Build a one-paragraph summary: test case title, failing step, expected-vs-actual, screenshot path, run id.
|
|
137
|
+
2. Ask `AskUserQuestion`: where to share?
|
|
138
|
+
- Email — open `mailto:` with the summary pre-filled.
|
|
139
|
+
- SMS — copy the summary to clipboard, instruct user to paste.
|
|
140
|
+
- File ticket — if `gh` is available and there's a repo, offer `gh issue create` with the summary as the body; otherwise copy summary and instruct user.
|
|
141
|
+
- Skip — just keep the report.
|
|
142
|
+
3. Record the choice in telemetry (`userAction: "share-email" | "share-sms" | "share-ticket" | "skip"`).
|
|
143
|
+
|
|
144
|
+
### Telemetry
|
|
145
|
+
|
|
146
|
+
Emit **two events per failure**: one when the AI classifies (before asking the user) and one when the user picks an action.
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"eventType": "replay-failure-classified",
|
|
151
|
+
"skillName": "<this skill>",
|
|
152
|
+
"aiClassification": "infra" | "stale-script" | "product-defect",
|
|
153
|
+
"aiSuggestion": "report-bug" | "regenerate" | "share-defect",
|
|
154
|
+
"runId": "<local run id>",
|
|
155
|
+
"testCaseId": "<id>",
|
|
156
|
+
"projectId": "<id>",
|
|
157
|
+
"signals": ["element-not-found", "selector-timeout"],
|
|
158
|
+
"metadata": { "failingStep": "<step name>", "errorExcerpt": "<first 200 chars>" }
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"eventType": "replay-failure-resolved",
|
|
165
|
+
"skillName": "<this skill>",
|
|
166
|
+
"aiClassification": "<same as above>",
|
|
167
|
+
"aiSuggestion": "<same as above>",
|
|
168
|
+
"userAction": "regenerate" | "report-bug" | "share-email" | "retry" | "muggle-feedback" | "skip",
|
|
169
|
+
"runId": "<local run id>",
|
|
170
|
+
"testCaseId": "<id>",
|
|
171
|
+
"projectId": "<id>"
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
The `(aiSuggestion, userAction)` pair is the metric we tune from — when they diverge, the classifier needs work.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## C. Post-regen failure (used by all four skills with generation)
|
|
180
|
+
|
|
181
|
+
Triggered when `muggle-local-execute-test-generation` (or the remote equivalent) returns `failed`, exit 26, `goal_not_achievable`, or any other non-passing terminal state.
|
|
182
|
+
|
|
183
|
+
### Buckets
|
|
184
|
+
|
|
185
|
+
| Bucket | Meaning |
|
|
186
|
+
|---|---|
|
|
187
|
+
| **transient** | Network blip, single LLM call failed, intermittent flake. Likely succeeds on retry without changing anything. |
|
|
188
|
+
| **infra** | A Muggle Test bug stopped generation from progressing (handler crash, schema validation in our code, deterministic LLM-pipeline failure). |
|
|
189
|
+
| **agent-course** | The generation agent went down a wrong path (chose the wrong button, misread the goal, looped on a blocking modal). The product is fine and the test case is fine — the agent's *course* needs steering. |
|
|
190
|
+
| **product-uxux** | The product itself blocks the test (broken page, missing element, server error). Agent can't proceed because the feature doesn't actually work. |
|
|
191
|
+
|
|
192
|
+
### Initial signal heuristics
|
|
193
|
+
|
|
194
|
+
From `muggle-local-run-result-get` (summary, structured summary, last steps, error):
|
|
195
|
+
|
|
196
|
+
- **transient**: `network-error`, `llm-rate-limit`, `single-tool-call-error`, run had partial progress then died.
|
|
197
|
+
- **infra**: `electron-mcp-handler-crash`, `internal-validation-error`, `pipeline-stuck`, identical failure repeated more than twice.
|
|
198
|
+
- **agent-course**: `goal_not_achievable` with summary mentioning the agent picked a different element, looped on a modal, kept trying the same wrong action; many steps but no real progress.
|
|
199
|
+
- **product-uxux**: server 5xx in step screenshots, "page not found" reached repeatedly, expected element provably absent (visible in screenshot), product clearly broken in the artifact log.
|
|
200
|
+
|
|
201
|
+
### Suggestions per bucket
|
|
202
|
+
|
|
203
|
+
Present via `AskUserQuestion`. **Always show the run summary first** so the user has context, then offer the bucket's recommended action plus alternatives.
|
|
204
|
+
|
|
205
|
+
| Bucket | Recommended suggestion | Other options |
|
|
206
|
+
|---|---|---|
|
|
207
|
+
| **transient** | Retry as-is. | muggle-feedback; Edit test case; Skip. |
|
|
208
|
+
| **infra** | Report bug to Muggle AI → `muggle-feedback` with `category: "muggle-infra"` (run id, signals, summary excerpt). | Retry; Skip. |
|
|
209
|
+
| **agent-course** | Steer the agent → invoke `muggle-feedback` skill so the user describes what should have happened; the workflow re-runs with the corrected course. | Retry; Edit test case; Skip. |
|
|
210
|
+
| **product-uxux** | Wait for fix — share the run summary + screenshot to the dev. Offer email / SMS / file ticket (see "Sharing real defects" in section B). | Retry once the fix lands; muggle-feedback; Skip. |
|
|
211
|
+
|
|
212
|
+
### Telemetry
|
|
213
|
+
|
|
214
|
+
Same two-event pattern as section B, with `eventType` values `regen-failure-classified` and `regen-failure-resolved`. `aiClassification` is one of the four bucket strings; `userAction` is the user's pick.
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"eventType": "regen-failure-classified",
|
|
219
|
+
"skillName": "<this skill>",
|
|
220
|
+
"aiClassification": "transient" | "infra" | "agent-course" | "product-uxux",
|
|
221
|
+
"aiSuggestion": "retry" | "report-bug" | "muggle-feedback" | "wait-and-share",
|
|
222
|
+
"runId": "<local run id>",
|
|
223
|
+
"testCaseId": "<id>",
|
|
224
|
+
"projectId": "<id>",
|
|
225
|
+
"signals": ["goal_not_achievable", "loop-on-modal"],
|
|
226
|
+
"metadata": { "summary": "<excerpt>", "stepsCompleted": <n> }
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## D. Emitting telemetry — implementation notes
|
|
233
|
+
|
|
234
|
+
- Tool: `muggle-local-telemetry-event-emit` (local-only, fire-and-forget).
|
|
235
|
+
- Sink: `~/.muggle-ai/telemetry/failure-events.jsonl` (one JSON record per line, append-only).
|
|
236
|
+
- Never block the skill on a telemetry call. If the tool errors, log and continue.
|
|
237
|
+
- Always emit the **classified** event before asking the user, and the **resolved** event immediately after the user picks. Don't merge them into one event after the fact — the *latency* between AI suggestion and user choice is also data.
|
|
238
|
+
- For the pre-execution classifier (section A), the event has no separate "resolved" pair unless the user actively overrides; if they do, emit a single follow-up `pre-execution-classification` event with `userAction` set.
|
|
239
|
+
|
|
240
|
+
## E. What this doc deliberately does not bake in
|
|
241
|
+
|
|
242
|
+
- **Quantitative thresholds** beyond rule A.3 (30-day drift). Bucket signal lists above are an initial best guess; once telemetry has data, the user will refine which signals reliably indicate which bucket.
|
|
243
|
+
- **Auto-retry**. There is no "if X then automatically rerun" path anywhere. The user decides every time — that's the whole point of the contract.
|
|
244
|
+
- **Cross-bucket fallbacks**. If the AI mis-classifies, the user picks a different option from the AskUserQuestion list; the AI does not retry classification.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Cleanup After the Change Is Merged
|
|
2
|
+
|
|
3
|
+
Gated by [`autoCleanup`](../muggle-preferences/preference-gates/autoCleanup.md). Follow the standard procedure in [`preference-gates/README.md`](../muggle-preferences/preference-gates/README.md). Fire only after the PR is **merged** — never while it's still open.
|
|
4
|
+
|
|
5
|
+
On `always`, the four steps below run as one pre-authorized sequence (no per-step prompts). Stop on the first failure; do not force.
|
|
6
|
+
|
|
7
|
+
1. `git worktree remove {worktreePath}` — only if a worktree was used.
|
|
8
|
+
2. `git branch -d {branch}` then `git push origin --delete {branch}`.
|
|
9
|
+
3. Clear `.muggle-ai/` session folders for this branch's runs and stale `/tmp/muggle-prepare-*.log` files. Cloud results stay.
|
|
10
|
+
4. Invoke `commit-commands:clean_gone` via the `Skill` tool.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# PR follow-up helpers
|
|
2
|
+
|
|
3
|
+
Generic operational guidance for running a PR-comment follow-up loop on GitHub: reviewer allow-list resolution, reply routing across the different comment endpoints, and a classification rule for reviewer comments with worked examples and a borderline test. Caller-agnostic — any loop that picks one comment per tick and decides what to do with it can drive off this doc.
|
|
4
|
+
|
|
5
|
+
The classification produces an **action shape** (in-place change, deep-cycle through the caller's implementation pipeline, reply only, escalate, etc.) — the caller maps each shape to its specific routing (which stage to dispatch, which terminal-message template to use, which reply endpoint to hit).
|
|
6
|
+
|
|
7
|
+
## Resolving the reviewer allow-list
|
|
8
|
+
|
|
9
|
+
Stage 8 only acts on comments authored by users in the **allow-list** = (requested reviewers ∪ CODEOWNERS) − bots − PR author. Re-resolve every tick (decision 9 in the design doc).
|
|
10
|
+
|
|
11
|
+
### Step 1: requested reviewers
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
gh pr view <number> --repo <owner>/<repo> --json reviewRequests,author
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`reviewRequests` is an array of `{ login? , slug? }`. User reviewers have `login`; team reviewers have `slug` (and `name`). Expand teams to member logins:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
gh api orgs/<org>/teams/<slug>/members --jq '.[].login'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Record `prAuthor = author.login` for the exclusion step.
|
|
24
|
+
|
|
25
|
+
### Step 2: CODEOWNERS
|
|
26
|
+
|
|
27
|
+
Look for the file in this order — first hit wins:
|
|
28
|
+
|
|
29
|
+
1. `.github/CODEOWNERS`
|
|
30
|
+
2. `CODEOWNERS`
|
|
31
|
+
3. `docs/CODEOWNERS`
|
|
32
|
+
|
|
33
|
+
Read from the PR's **head branch** (not master), because a PR that adds CODEOWNERS should be allowed to take effect once merged but is informational while open. In practice this means:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
gh api repos/<owner>/<repo>/contents/.github/CODEOWNERS?ref=<head_sha> --jq '.content' | base64 -d
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Parse line-by-line:
|
|
40
|
+
|
|
41
|
+
- Skip blank lines and lines starting with `#`.
|
|
42
|
+
- Each line is `<pattern> <owner1> <owner2> ...`.
|
|
43
|
+
- Owners are either `@user` or `@org/team`. Strip the leading `@`.
|
|
44
|
+
- For our purposes we don't need to match `<pattern>` against changed files — CODEOWNERS membership for the *repo* is enough. Collect the union of all owners across all lines.
|
|
45
|
+
|
|
46
|
+
Expand `@org/team` to member logins via the orgs/teams/members endpoint (same as Step 1).
|
|
47
|
+
|
|
48
|
+
If no CODEOWNERS file exists in any of the three locations, the CODEOWNERS contribution is empty. Don't fail.
|
|
49
|
+
|
|
50
|
+
### Step 3: filter
|
|
51
|
+
|
|
52
|
+
Allow-list = (requested reviewers ∪ CODEOWNERS) − `{prAuthor}` − bot logins.
|
|
53
|
+
|
|
54
|
+
Bot logins are any login matching:
|
|
55
|
+
|
|
56
|
+
- Ends with `[bot]` (e.g. `dependabot[bot]`)
|
|
57
|
+
- Exact match in the standard list: `dependabot`, `github-actions`, `renovate`, `mergify`
|
|
58
|
+
|
|
59
|
+
A comment author not in the allow-list is silently ignored — do not reply, do not address.
|
|
60
|
+
|
|
61
|
+
## Reply routing
|
|
62
|
+
|
|
63
|
+
GitHub's PR APIs are not uniform across comment types. Route by parent type.
|
|
64
|
+
|
|
65
|
+
### Line-level review comment
|
|
66
|
+
|
|
67
|
+
A comment attached to a specific file:line that belongs to a review thread. This is the **most common** path.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
gh api \
|
|
71
|
+
--method POST \
|
|
72
|
+
-H "Accept: application/vnd.github+json" \
|
|
73
|
+
/repos/<owner>/<repo>/pulls/<number>/comments/<comment_id>/replies \
|
|
74
|
+
-f body="Done in $(git rev-parse --short HEAD) — renamed \`fooBar\` to \`foo_bar\`."
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The reply lands in the same review thread. The reply itself becomes a new line-level comment with `in_reply_to_id = <comment_id>`.
|
|
78
|
+
|
|
79
|
+
### Review body (CHANGES_REQUESTED with no inline comments)
|
|
80
|
+
|
|
81
|
+
A reviewer left a summary review with `state: CHANGES_REQUESTED` and a body, but **no** inline comments. GitHub has no "reply to review body" endpoint — post a top-level PR comment that references the review:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
gh pr comment <number> --repo <owner>/<repo> --body "Re: review #<review_id> — done in $(git rev-parse --short HEAD)."
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Failing CI check
|
|
88
|
+
|
|
89
|
+
No reply. The fix commit IS the response. Include the failing check name in the commit subject so the connection is obvious in `git log`:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
fix(ci): typecheck — narrow type of foo
|
|
93
|
+
fix(ci): lint — remove unused import
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Never
|
|
97
|
+
|
|
98
|
+
- Never post a top-level comment in reply to a line-level comment. It loses thread context and pollutes the PR conversation tab.
|
|
99
|
+
- Never `gh pr review --comment` for replies — that endpoint is for *new* reviews, not replies.
|
|
100
|
+
- Never reply twice to the same comment. The cursor in `last_seen.json` is the only re-entry guard; advance it after every reply.
|
|
101
|
+
|
|
102
|
+
## Classify
|
|
103
|
+
|
|
104
|
+
Classify the **review as a unit**, not individual comments.
|
|
105
|
+
|
|
106
|
+
| Class | Signal | Action |
|
|
107
|
+
| :---- | :----- | :----- |
|
|
108
|
+
| **actionable** | Review names at least one concrete change or asks an answerable question. Soft phrasing counts when there's a concrete referent. | Treat as amended requirements; run the caller's implementation cycle; reply with one summary referencing the new SHA. |
|
|
109
|
+
| **ambiguous** | No actionable signal — pure vibes, contradictory, or depends on knowledge the loop can't access. | Escalate once with two interpretations; pause the PR. |
|
|
110
|
+
|
|
111
|
+
Default to **actionable**. CI catches wrong attempts; reviewers correct on the next round. Escalation is a round-trip with an absent user — reserve it.
|
|
112
|
+
|
|
113
|
+
Reply summary shape:
|
|
114
|
+
|
|
115
|
+
- **actionable**: `Addressed review <review_id> in <sha> — cycle ran clean (or: with <N> failures, see walkthrough).`
|
|
116
|
+
- **ambiguous**: no bot reply.
|
|
117
|
+
|
|
118
|
+
### Worked examples — Actionable reviews
|
|
119
|
+
|
|
120
|
+
| Review (summarized) | Why actionable |
|
|
121
|
+
| :------------------ | :------------- |
|
|
122
|
+
| 3 comments: "rename `fooBar` to `foo_bar`", "use `const` here", "fix this typo" | Three concrete edits |
|
|
123
|
+
| 1 comment: "could the procedure be simpler?" | Soft-phrased but the intent is clear — simplify; pick the best interpretation, run the cycle, reply with what was changed |
|
|
124
|
+
| Review body: "Mostly looks good. Two things: extract the validation into a helper, and add a null check before the lookup." Plus 0 line comments. | Two concrete directives in the body |
|
|
125
|
+
| 4 comments: "why this approach?", "is this called from X?", "does this need to handle empty array?", "what's the perf here?" | All questions but each is answerable; cycle dispatches an "answer + maybe-fix" pass and the reply summary captures each answer |
|
|
126
|
+
| 1 comment: "rewrite this module — the architecture doesn't match the spec" | Substantive rebuild, but the direction is clear: redo the module per the spec |
|
|
127
|
+
| 1 comment: "I'd lean toward the bar.ts pattern" | Concrete referent (bar.ts) — apply that pattern |
|
|
128
|
+
|
|
129
|
+
The single review goes through one full cycle regardless of comment count.
|
|
130
|
+
|
|
131
|
+
### Worked examples — Ambiguous reviews
|
|
132
|
+
|
|
133
|
+
| Review (summarized) | Why ambiguous |
|
|
134
|
+
| :------------------ | :------------ |
|
|
135
|
+
| 1 comment: "👀" / "hmm" / ":thinking:" | No signal at all |
|
|
136
|
+
| 1 comment: "this is wrong" with no target or direction | Asserts a problem but doesn't propose a fix |
|
|
137
|
+
| 2 comments: "use X" + "but actually don't use X" | Self-contradicting — can't reconcile without the reviewer |
|
|
138
|
+
| 1 comment: "we discussed this offline — please address" | References context the loop doesn't have |
|
|
139
|
+
| 1 comment: "won't this break the prod migration we did last week?" | Implicit change request gated on knowledge the loop can't access |
|
|
140
|
+
| Mixed: 2 concrete directives + 1 comment "but also, rethink the whole approach" | The "rethink the whole approach" subverts the other two; escalate to confirm scope |
|
|
141
|
+
|
|
142
|
+
Escalate per the caller's escalation procedure (write the review id to the cursor's escalated set, emit one terminal message with both interpretations, pause the PR until the user resolves).
|
|
143
|
+
|
|
144
|
+
### Borderline rule
|
|
145
|
+
|
|
146
|
+
If you can paraphrase the review's intent as **"do X"** with X being a concrete change (one or several) — it's actionable. Pick the best interpretation and dispatch the cycle.
|
|
147
|
+
|
|
148
|
+
If you can paraphrase it only as **"the reviewer is dissatisfied but I can't tell with what"** — it's ambiguous.
|
|
149
|
+
|
|
150
|
+
When the review mixes both ("3 concrete directives + 1 dissatisfaction"), the safer move is usually to action the concrete directives and ask about the dissatisfaction in the reply summary. Pure ambiguity means *nothing* in the review is actionable.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Rebase Onto the Default Branch Before Dev Server / E2E
|
|
2
|
+
|
|
3
|
+
Gated by [`autoRebase`](../muggle-preferences/preference-gates/autoRebase.md). Follow the standard procedure in [`preference-gates/README.md`](../muggle-preferences/preference-gates/README.md).
|
|
4
|
+
|
|
5
|
+
**Fire only when `behind > 0`:**
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git fetch origin
|
|
9
|
+
default=$(git symbolic-ref refs/remotes/origin/HEAD --short | sed 's|origin/||')
|
|
10
|
+
behind=$(git rev-list --count "HEAD..origin/${default}")
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Pass `{behind}` and `{default}` to the picker prompts. On `always`, run `git rebase origin/${default}`; stop and report on conflicts — never auto-resolve.
|
|
14
|
+
|
|
15
|
+
Stale branches produce false failures and false greens — that's why this gate exists.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Skill Telemetry — Shared Convention
|
|
2
|
+
|
|
3
|
+
At the start of every `muggle-*` skill, call `muggle-local-telemetry-skill-emit` once. Fire-and-forget — never await, never let a telemetry failure block the skill.
|
|
4
|
+
|
|
5
|
+
**Args:**
|
|
6
|
+
|
|
7
|
+
- `skillName`: this skill's name (e.g. `"muggle-test"`)
|
|
8
|
+
- `trigger`: one of
|
|
9
|
+
- `"user-slash"` — user typed `/<skill-name>` (the common case; default this)
|
|
10
|
+
- `"claude-proactive"` — Claude matched on the skill's description, not a slash command
|
|
11
|
+
- `"nested-skill"` — invoked from another skill via the `Skill` tool
|
|
12
|
+
|
|
13
|
+
## Failure-mode events
|
|
14
|
+
|
|
15
|
+
Skills that run replays or generations also emit structured failure-mode events through a separate tool — `muggle-local-telemetry-event-emit`. Don't reinvent the schema or sink in the skill; follow [`failure-mode-handling.md`](./failure-mode-handling.md), which defines the bucket taxonomies, the AI-classify → user-pick contract, and the exact event shape.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Worktrees for Dev Work
|
|
2
|
+
|
|
3
|
+
Use this for feature development, local validation, and PR iteration.
|
|
4
|
+
|
|
5
|
+
## Core guidance
|
|
6
|
+
|
|
7
|
+
- **One worktree per branch.** Never switch branches inside a long-lived checkout.
|
|
8
|
+
- **Isolate runtime resources.** Parallel worktrees need unique ports and isolated mutable test state.
|
|
9
|
+
- **Keep worktrees disposable.** Create for focused work, remove after merge.
|
|
10
|
+
|
|
11
|
+
## Start new change work
|
|
12
|
+
|
|
13
|
+
1. Update the base branch (usually `main`).
|
|
14
|
+
2. Create a new worktree and branch:
|
|
15
|
+
```bash
|
|
16
|
+
git worktree add <repo>-worktrees/<slug> -b <branch>
|
|
17
|
+
```
|
|
18
|
+
3. Install dependencies and run setup in that worktree.
|
|
19
|
+
4. Keep all edits and commits for the change in that same worktree.
|
|
20
|
+
|
|
21
|
+
## Test in the worktree
|
|
22
|
+
|
|
23
|
+
- Run lint, typecheck, and unit/integration tests from the worktree.
|
|
24
|
+
- Run your local E2E acceptance flow from that same worktree for user-facing validation.
|
|
25
|
+
- Run the dev server from the same worktree so code, env, and cache all match.
|
|
26
|
+
- In parallel runs, ensure each worktree has a unique port and isolated test data.
|
|
27
|
+
|
|
28
|
+
## E2E + worktree checklist
|
|
29
|
+
|
|
30
|
+
1. Confirm command cwd, checked-out branch, and server source are the same worktree.
|
|
31
|
+
2. Start the app from that worktree and verify readiness first (see [`dev-server-readiness.md`](dev-server-readiness.md)).
|
|
32
|
+
3. Run local E2E acceptance checks in that same session.
|
|
33
|
+
4. Isolate test data across parallel branches (separate users/accounts/orgs or resettable fixtures).
|
|
34
|
+
5. Re-run E2E acceptance checks after meaningful code changes during PR review.
|
|
35
|
+
|
|
36
|
+
## Common failure modes to avoid
|
|
37
|
+
|
|
38
|
+
- **Mixed checkouts:** Test command and server run from different directories.
|
|
39
|
+
- **Port collision:** Multiple branches share a dev-server port.
|
|
40
|
+
- **Shared mutable state:** Parallel runs mutate the same account or fixtures.
|
|
41
|
+
- **Stale server:** Old process still serves previous branch code.
|
|
42
|
+
|
|
43
|
+
## Pull request workflow
|
|
44
|
+
|
|
45
|
+
1. Commit on the branch tied to the worktree.
|
|
46
|
+
2. Push the branch and open the PR.
|
|
47
|
+
3. Keep review fixes in that same worktree.
|
|
48
|
+
4. Re-run relevant checks before each push, including E2E acceptance checks for user-facing changes.
|
|
49
|
+
|
|
50
|
+
## Tear down
|
|
51
|
+
|
|
52
|
+
After merge, remove the worktree.
|
|
53
|
+
See [`post-merge-cleanup.md`](post-merge-cleanup.md).
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Build Agent (Stage 3)
|
|
2
|
+
|
|
3
|
+
Implement the code change for this dev cycle. Read the frozen requirements from stage 2, produce the edits in each affected repo's worktree, and commit.
|
|
4
|
+
|
|
5
|
+
## Turn preamble
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
**Stage 3 — Build** — implementing the change per the frozen requirements.
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Inputs
|
|
12
|
+
|
|
13
|
+
- `requirements.md` from stage 2: goal, acceptance criteria, affected repos.
|
|
14
|
+
- `state.md` from pre-flight: worktree path per repo, target branch, anything else the build needs to know about the environment.
|
|
15
|
+
|
|
16
|
+
## Your job
|
|
17
|
+
|
|
18
|
+
For each affected repo:
|
|
19
|
+
|
|
20
|
+
1. **Re-read `requirements.md`.** Treat goal + AC as frozen. If something is unclear at this stage, that's a pre-flight bug — escalate, do not improvise.
|
|
21
|
+
2. **Apply the change** in the repo's worktree. Edit existing files first; create new files only when the requirements demand it. Match the surrounding code's style, naming, and file layout.
|
|
22
|
+
3. **Don't add what wasn't asked for.** No speculative abstractions, no extra logging, no "while I'm here" refactors. Three similar lines is better than a premature abstraction.
|
|
23
|
+
4. **Commit** with a conventional-commit subject:
|
|
24
|
+
- `feat(<scope>): <short>` for new behavior
|
|
25
|
+
- `fix(<scope>): <short>` for bug fixes
|
|
26
|
+
- `refactor(<scope>): <short>` for reshape
|
|
27
|
+
- `docs(...)`, `chore(...)`, `test(...)` as appropriate
|
|
28
|
+
|
|
29
|
+
The body explains *why* when the why is non-obvious. The diff already says *what*.
|
|
30
|
+
|
|
31
|
+
## Output
|
|
32
|
+
|
|
33
|
+
Per repo:
|
|
34
|
+
|
|
35
|
+
**Repo:** name
|
|
36
|
+
- Files edited / created: list
|
|
37
|
+
- Commit subject: `<conventional commit>`
|
|
38
|
+
- Notable choices: anything that needed a judgment call (briefly)
|
|
39
|
+
|
|
40
|
+
**Overall:** READY for impact analysis | BLOCKED — reason
|
|
41
|
+
|
|
42
|
+
If a requirement is fundamentally unimplementable as written, halt and escalate with the specific blocker — do not ship a half-finished implementation.
|
|
43
|
+
|
|
44
|
+
## Re-entry from stage 8
|
|
45
|
+
|
|
46
|
+
Stage 8 (PR follow-up) may dispatch back to this stage when a reviewer comment requires real implementation work rather than an in-place doc edit. When re-entered:
|
|
47
|
+
|
|
48
|
+
- The dispatch from stage 8 carries the comment(s) that triggered the re-build as additional context; treat them as amendments to the goal/AC for this iteration.
|
|
49
|
+
- Continue on the existing branch — do not re-create the worktree.
|
|
50
|
+
- Cycle forward through impact analysis → unit tests → E2E → open PR (which is a no-op since the PR already exists; just push).
|
|
51
|
+
- Stage 8 resumes polling after the push lands.
|