@muggleai/works 4.11.4 → 4.12.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/dist/{chunk-E52757MK.js → chunk-2DVZ2LYO.js} +5 -0
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/scripts/ensure-electron-app.sh +29 -4
- package/dist/plugin/skills/_shared/github-cli-recipes/line-comments-for-review.md +8 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/loop-user-identity.md +9 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/pr-edit.md +8 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/pr-metadata.md +12 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/push-to-branch.md +10 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/reply-line-comment.md +10 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/submitted-reviews.md +15 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/top-level-comment.md +7 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/unresolved-threads.md +33 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/verify-working-tree.md +17 -0
- package/dist/plugin/skills/_shared/github-cli-recipes.md +20 -0
- package/dist/plugin/skills/_shared/pr-followup-helpers/allow-list.md +53 -0
- package/dist/plugin/skills/_shared/pr-followup-helpers/classify.md +48 -0
- package/dist/plugin/skills/_shared/pr-followup-helpers/reply-routing.md +40 -0
- package/dist/plugin/skills/_shared/pr-followup-helpers.md +8 -146
- package/dist/plugin/skills/_shared/telemetry-events/muggle-do-cycle.md +25 -0
- package/dist/plugin/skills/_shared/telemetry-events/muggle-do-escalation.md +19 -0
- package/dist/plugin/skills/_shared/telemetry-events/muggle-do-resolve-reminder.md +19 -0
- package/dist/plugin/skills/_shared/telemetry-events/pr-followup-bootstrap.md +20 -0
- package/dist/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +23 -0
- package/dist/plugin/skills/_shared/telemetry-events.md +15 -0
- package/dist/plugin/skills/do/address-reviews.md +137 -0
- package/dist/plugin/skills/do/build.md +5 -5
- package/dist/plugin/skills/do/open-prs/forward.md +80 -0
- package/dist/plugin/skills/do/open-prs/update.md +54 -0
- package/dist/plugin/skills/do/open-prs.md +6 -102
- package/dist/plugin/skills/do/per-comment-replies.md +61 -0
- package/dist/plugin/skills/do/resolve-reminder.md +70 -0
- package/dist/plugin/skills/muggle-do/SKILL.md +41 -45
- package/dist/plugin/skills/muggle-pr-followup/CLAUDE.md +25 -0
- package/dist/plugin/skills/muggle-pr-followup/SKILL.md +21 -43
- package/dist/plugin/skills/muggle-pr-followup/bootstrap.md +88 -0
- package/dist/plugin/skills/muggle-pr-followup/contract.md +44 -161
- package/dist/plugin/skills/muggle-pr-followup/output-templates/bootstrap.md +42 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates/escalation.md +32 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates/help.md +17 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates/inline-reply.md +17 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates/resolve-reminder.md +12 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates/watcher-log.md +21 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates.md +14 -0
- package/dist/plugin/skills/muggle-pr-followup/state-schemas.md +104 -0
- package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +3 -3
- package/dist/release-manifest.json +4 -4
- package/package.json +6 -6
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/scripts/ensure-electron-app.sh +29 -4
- package/plugin/skills/_shared/github-cli-recipes/line-comments-for-review.md +8 -0
- package/plugin/skills/_shared/github-cli-recipes/loop-user-identity.md +9 -0
- package/plugin/skills/_shared/github-cli-recipes/pr-edit.md +8 -0
- package/plugin/skills/_shared/github-cli-recipes/pr-metadata.md +12 -0
- package/plugin/skills/_shared/github-cli-recipes/push-to-branch.md +10 -0
- package/plugin/skills/_shared/github-cli-recipes/reply-line-comment.md +10 -0
- package/plugin/skills/_shared/github-cli-recipes/submitted-reviews.md +15 -0
- package/plugin/skills/_shared/github-cli-recipes/top-level-comment.md +7 -0
- package/plugin/skills/_shared/github-cli-recipes/unresolved-threads.md +33 -0
- package/plugin/skills/_shared/github-cli-recipes/verify-working-tree.md +17 -0
- package/plugin/skills/_shared/github-cli-recipes.md +20 -0
- package/plugin/skills/_shared/pr-followup-helpers/allow-list.md +53 -0
- package/plugin/skills/_shared/pr-followup-helpers/classify.md +48 -0
- package/plugin/skills/_shared/pr-followup-helpers/reply-routing.md +40 -0
- package/plugin/skills/_shared/pr-followup-helpers.md +8 -146
- package/plugin/skills/_shared/telemetry-events/muggle-do-cycle.md +25 -0
- package/plugin/skills/_shared/telemetry-events/muggle-do-escalation.md +19 -0
- package/plugin/skills/_shared/telemetry-events/muggle-do-resolve-reminder.md +19 -0
- package/plugin/skills/_shared/telemetry-events/pr-followup-bootstrap.md +20 -0
- package/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +23 -0
- package/plugin/skills/_shared/telemetry-events.md +15 -0
- package/plugin/skills/do/address-reviews.md +137 -0
- package/plugin/skills/do/build.md +5 -5
- package/plugin/skills/do/open-prs/forward.md +80 -0
- package/plugin/skills/do/open-prs/update.md +54 -0
- package/plugin/skills/do/open-prs.md +6 -102
- package/plugin/skills/do/per-comment-replies.md +61 -0
- package/plugin/skills/do/resolve-reminder.md +70 -0
- package/plugin/skills/muggle-do/SKILL.md +41 -45
- package/plugin/skills/muggle-pr-followup/CLAUDE.md +25 -0
- package/plugin/skills/muggle-pr-followup/SKILL.md +21 -43
- package/plugin/skills/muggle-pr-followup/bootstrap.md +88 -0
- package/plugin/skills/muggle-pr-followup/contract.md +44 -161
- package/plugin/skills/muggle-pr-followup/output-templates/bootstrap.md +42 -0
- package/plugin/skills/muggle-pr-followup/output-templates/escalation.md +32 -0
- package/plugin/skills/muggle-pr-followup/output-templates/help.md +17 -0
- package/plugin/skills/muggle-pr-followup/output-templates/inline-reply.md +17 -0
- package/plugin/skills/muggle-pr-followup/output-templates/resolve-reminder.md +12 -0
- package/plugin/skills/muggle-pr-followup/output-templates/watcher-log.md +21 -0
- package/plugin/skills/muggle-pr-followup/output-templates.md +14 -0
- package/plugin/skills/muggle-pr-followup/state-schemas.md +104 -0
- package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +3 -3
- package/scripts/postinstall.mjs +36 -5
|
@@ -1,104 +1,8 @@
|
|
|
1
|
-
# PR
|
|
1
|
+
# Create-or-Update PR (Stage 7)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Two modes, set by the `/muggle-do` invocation. Each consumer loads only its mode's file.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Inputs
|
|
12
|
-
|
|
13
|
-
- Per-repo: name, path, branch.
|
|
14
|
-
- Requirements: goal, acceptance criteria.
|
|
15
|
-
- **Optional** E2E acceptance report from stage 6 — only present when validation ran. Produced by [`e2e-acceptance.md`](e2e-acceptance.md); schema is canonical in [`muggle-pr-visual-walkthrough/SKILL.md`](../muggle-pr-visual-walkthrough/SKILL.md) (Zod-validated by the CLI).
|
|
16
|
-
|
|
17
|
-
## Per repo
|
|
18
|
-
|
|
19
|
-
0. **`autoCreatePR` gate** — apply per [`../muggle-preferences/preference-gates/autoCreatePR.md`](../muggle-preferences/preference-gates/autoCreatePR.md). On skip, record the reason in `result.md` and move on.
|
|
20
|
-
|
|
21
|
-
1. **Push:** `git push -u origin <branch>` in the repo directory.
|
|
22
|
-
|
|
23
|
-
2. **Title** (under 70 chars):
|
|
24
|
-
- E2E report exists and has failures → `[E2E FAILING] <goal>`
|
|
25
|
-
- No E2E report at all (validation was `unit-only` or `skip`) → `[UNVERIFIED] <goal>` or `[UNIT-ONLY] <goal>` to match the validation strategy
|
|
26
|
-
- Otherwise → `<goal>`
|
|
27
|
-
|
|
28
|
-
3. **Body** — assemble in order:
|
|
29
|
-
- `## Goal` — from requirements.
|
|
30
|
-
- `## Acceptance Criteria` — bulleted; omit section if empty.
|
|
31
|
-
- `## Changes` — summary of what changed in this repo.
|
|
32
|
-
- `## Validation` — one line: link to E2E report, or `unit-only`, or `skip — <reason>`.
|
|
33
|
-
- **If an E2E report exists,** invoke [`muggle-pr-visual-walkthrough`](../muggle-pr-visual-walkthrough/SKILL.md) Mode B to render the walkthrough block. Embed the returned `body` verbatim (it brings its own `## E2E Acceptance Results` heading). If no report, skip this block entirely.
|
|
34
|
-
|
|
35
|
-
4. **Create:** `gh pr create --title "..." --body "..." --head <branch>`. Capture the PR URL and number.
|
|
36
|
-
|
|
37
|
-
5. **Overflow comment:** if the walkthrough skill returned a non-null `comment`, post it once:
|
|
38
|
-
```bash
|
|
39
|
-
jq -r '.comment' /tmp/muggle-pr-section.json | gh pr comment <PR#> --body-file -
|
|
40
|
-
```
|
|
41
|
-
Never post when `comment` is `null`.
|
|
42
|
-
|
|
43
|
-
## Stage 8 handoff
|
|
44
|
-
|
|
45
|
-
After every repo is processed, build the manifest and dispatch **one follow-up loop per opened PR**. The dispatches are the LAST action this stage takes — once they fire, the original session is free.
|
|
46
|
-
|
|
47
|
-
Write `.muggle-do/sessions/<slug>/prs.json` with one entry per **opened** PR (skip repos where `autoCreatePR` short-circuited or PR creation failed):
|
|
48
|
-
|
|
49
|
-
```json
|
|
50
|
-
[{ "repo": "owner/repo", "number": 142, "url": "...", "head_sha": "...", "state": "open" }]
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Seed `.muggle-do/sessions/<slug>/last_seen.json` keyed by `"<owner>/<repo>#<n>"` with the empty-cursor shape (full shape in [`../muggle-pr-followup/contract.md`](../muggle-pr-followup/contract.md)). Stage 7 only seeds; each per-PR loop owns advancing its own cursor.
|
|
54
|
-
|
|
55
|
-
Also seed `.muggle-do/sessions/<slug>/cycle.json` — the muggle-do implementation cycle declaration the follow-up loop will invoke on each actionable review:
|
|
56
|
-
|
|
57
|
-
```json
|
|
58
|
-
{
|
|
59
|
-
"cycleName": "muggle-do dev cycle",
|
|
60
|
-
"steps": [
|
|
61
|
-
{ "stage": 3, "file": "../do/build.md" },
|
|
62
|
-
{ "stage": 4, "file": "../do/impact-analysis.md" },
|
|
63
|
-
{ "stage": 5, "file": "../do/unit-tests.md" },
|
|
64
|
-
{ "stage": 6, "file": "../do/e2e-acceptance.md" },
|
|
65
|
-
{ "name": "post-walkthrough", "skill": "muggle-pr-visual-walkthrough", "mode": "A" }
|
|
66
|
-
],
|
|
67
|
-
"pushHandler": "git push origin <branch>",
|
|
68
|
-
"useSubagent": false
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
For each entry in `prs.json`, dispatch its own loop as the final action:
|
|
73
|
-
```
|
|
74
|
-
/loop 1m /muggle:muggle-pr-followup <slug> <pr-number>
|
|
75
|
-
```
|
|
76
|
-
Resolve `<slug>` from the session directory's basename. One loop per PR — multi-repo sessions opening N PRs result in N independent loops, each tracking its own PR's review thread.
|
|
77
|
-
|
|
78
|
-
If `prs.json` is empty (all repos skipped, or all PR creations failed), **do not dispatch** — record the reason in `result.md` and exit.
|
|
79
|
-
|
|
80
|
-
## Self-check before exit
|
|
81
|
-
|
|
82
|
-
- [ ] Every non-skipped repo got `gh pr create` to succeed.
|
|
83
|
-
- [ ] When an E2E report existed, the walkthrough block was rendered via Mode B (not hand-written).
|
|
84
|
-
- [ ] Overflow `comment` was posted only when non-null.
|
|
85
|
-
- [ ] `prs.json` and `last_seen.json` reflect the PRs actually opened.
|
|
86
|
-
- [ ] If `prs.json` is non-empty, the `/loop` dispatch was the last action.
|
|
87
|
-
|
|
88
|
-
## Output
|
|
89
|
-
|
|
90
|
-
**PRs Created:** repo → URL
|
|
91
|
-
**Skipped:** repo → reason (when `autoCreatePR` short-circuited)
|
|
92
|
-
**Overflow comments posted:** repo → PR #
|
|
93
|
-
**Stage 8:** `Watching <N> PR(s) — one /loop 1m /muggle:muggle-pr-followup <slug> <pr#> per PR` | `No PRs to watch — stage 8 not dispatched`
|
|
94
|
-
**Errors:** repo → message
|
|
95
|
-
|
|
96
|
-
## Post-merge cleanup
|
|
97
|
-
|
|
98
|
-
Gated by `autoCleanup`. Fires in a follow-up turn after merge — never from this stage. See [`../_shared/post-merge-cleanup.md`](../_shared/post-merge-cleanup.md).
|
|
99
|
-
|
|
100
|
-
Append one short reminder tied to the gate value:
|
|
101
|
-
|
|
102
|
-
- `always` → `Once merged, I'll run the cleanup sequence automatically.`
|
|
103
|
-
- `never` → omit.
|
|
104
|
-
- `ask` / absent → `Once merged, I'll check with you about cleanup.`
|
|
5
|
+
| Mode | When | Procedure |
|
|
6
|
+
| :--- | :--- | :-------- |
|
|
7
|
+
| Forward | After stages 1–6 of a fresh feature (called by `/muggle-do`'s forward pipeline). Creates the PR, seeds state, dispatches the first watcher. | [`open-prs/forward.md`](open-prs/forward.md) |
|
|
8
|
+
| Update | The PR already exists; the address-reviews orchestrator called this stage to push + refresh title/description/walkthrough. | [`open-prs/update.md`](open-prs/update.md) |
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Per-Comment Inline Replies
|
|
2
|
+
|
|
3
|
+
A `/muggle-do` step invoked from [`address-reviews.md`](address-reviews.md) (Step 4f) after the push has succeeded. Posts one inline nested reply on each line comment from the actionable reviews, describing what was done for that comment and referencing the new SHA.
|
|
4
|
+
|
|
5
|
+
This is **not** a top-level "summary reply on the review." Each comment thread gets its own reply, in context, via GitHub's `/comments/{id}/replies` endpoint.
|
|
6
|
+
|
|
7
|
+
## Inputs
|
|
8
|
+
|
|
9
|
+
- `actionable_reviews` — the list of reviews classified actionable in `address-reviews.md` Step 2.
|
|
10
|
+
- `new_sha` — the SHA `open-prs/update.md` just pushed.
|
|
11
|
+
- The PR's owner, repo, number.
|
|
12
|
+
|
|
13
|
+
## Procedure
|
|
14
|
+
|
|
15
|
+
### Step 1 — Build the comment-to-change map
|
|
16
|
+
|
|
17
|
+
For each comment in each actionable review, the cycle's `build.md` produced (or should have produced) a one-line note describing what was changed for that specific comment. Two sources, in order:
|
|
18
|
+
|
|
19
|
+
1. If `build.md` returned a `comment_changes` map keyed by comment id → short description, use it directly.
|
|
20
|
+
2. If not (legacy `build.md` that doesn't return that shape yet), infer from the diff + the comment's body: which file/line did the comment refer to, and what changed at or near it. The inferred description is best-effort; better to be brief than wrong.
|
|
21
|
+
|
|
22
|
+
If a comment has no associated change in either source (e.g. the comment was a question, not a change request), use the comment's body to compose a one-sentence answer.
|
|
23
|
+
|
|
24
|
+
### Step 2 — Post one reply per comment
|
|
25
|
+
|
|
26
|
+
For each comment id with a description:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
gh api --method POST \
|
|
30
|
+
-H "Accept: application/vnd.github+json" \
|
|
31
|
+
repos/<owner>/<repo>/pulls/<n>/comments/<comment-id>/replies \
|
|
32
|
+
-f body="<reply-body>"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Reply body uses the template in [`../muggle-pr-followup/output-templates/inline-reply.md`](../muggle-pr-followup/output-templates/inline-reply.md):
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
Addressed in <short-sha>: <one-line summary of the change made for THIS comment>.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`<short-sha>` is the first 7 chars of `new_sha`. The body must contain the literal `<short-sha>` substring — the resolve-reminder stage greps for it to classify threads as addressed-by-loop.
|
|
42
|
+
|
|
43
|
+
### Step 3 — Handle review-body-only comments
|
|
44
|
+
|
|
45
|
+
If an actionable review has a non-empty `body` and **zero** line comments, GitHub has no `/replies` endpoint for the review body itself (the API has been inconsistent on this and the only reliable path is a top-level PR comment that references the review). Use the *top-level reference* form:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
Re: review #<review_id> — addressed in <short-sha>: <one-line summary>.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Posted per [`../_shared/github-cli-recipes/top-level-comment.md`](../_shared/github-cli-recipes/top-level-comment.md). Fires at most once per actionable review-with-no-line-comments. Does not fire if the review has line comments — Step 2 covers those.
|
|
52
|
+
|
|
53
|
+
## Failure modes
|
|
54
|
+
|
|
55
|
+
- `gh api` returns an error for an individual reply → log to `followup.log`, continue with the remaining comments. Do not abort the whole step over one failure; the push has already happened and other replies still need posting.
|
|
56
|
+
- All replies fail → surface the most-recent `gh` error to the user, but do not abort the overall `/muggle-do` invocation. The resolve-reminder stage still runs; the watcher still respawns. The next cycle on this PR will produce more replies and the missing ones can be picked up by the human reviewer.
|
|
57
|
+
|
|
58
|
+
## Invariants
|
|
59
|
+
|
|
60
|
+
- One reply per line comment. No per-review summary reply anywhere.
|
|
61
|
+
- Every reply body contains the new SHA's 7-char prefix — the resolve-reminder stage greps for it.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Resolve-Reminder Stage
|
|
2
|
+
|
|
3
|
+
A `/muggle-do` stage that runs in **address-reviews mode only**, after per-comment inline replies have been posted. Scans every unresolved comment thread on the PR, classifies them, and posts ONE top-level PR comment listing the threads the loop addressed in this push.
|
|
4
|
+
|
|
5
|
+
Runs zero or one times per `/muggle-do` invocation:
|
|
6
|
+
|
|
7
|
+
- Runs when at least one actionable review was processed (i.e. the cycle actually pushed).
|
|
8
|
+
- Does not run when the entire input batch was ambiguous (no push, nothing to remind about).
|
|
9
|
+
- Does not run in the forward pipeline (a fresh PR has no review threads to remind about).
|
|
10
|
+
|
|
11
|
+
## Turn preamble (inline within `/muggle-do` cycle)
|
|
12
|
+
|
|
13
|
+
This stage does not print a turn preamble — it runs inside `/muggle-do`'s address-reviews cycle, immediately after per-comment replies and before respawning the watcher.
|
|
14
|
+
|
|
15
|
+
## Inputs
|
|
16
|
+
|
|
17
|
+
- The current PR (URL, owner, repo, number) from the session's `prs.json`.
|
|
18
|
+
- `last_seen.pushed_shas[]` from `last_seen.json` — the list of every SHA `/muggle-do` has pushed for this PR.
|
|
19
|
+
- The loop user's GitHub login (cached in `state.md` under `Loop user:` — re-resolve per [`../_shared/github-cli-recipes/loop-user-identity.md`](../_shared/github-cli-recipes/loop-user-identity.md) if missing).
|
|
20
|
+
|
|
21
|
+
## Procedure
|
|
22
|
+
|
|
23
|
+
### Step 1 — Fetch unresolved comment threads
|
|
24
|
+
|
|
25
|
+
Per [`../_shared/github-cli-recipes/unresolved-threads.md`](../_shared/github-cli-recipes/unresolved-threads.md). Filter client-side to `isResolved == false`. Each thread carries its line comments with `author.login`, `body`, and `databaseId`.
|
|
26
|
+
|
|
27
|
+
If the API call fails, log the error to `followup.log` and skip the stage. Do not surface a user-facing error — the resolve reminder is a nice-to-have, not load-bearing. The reply summaries on the threads themselves still happen.
|
|
28
|
+
|
|
29
|
+
### Step 2 — Classify each thread
|
|
30
|
+
|
|
31
|
+
For each unresolved thread, walk its comments in chronological order. Classify by the **first match** that applies:
|
|
32
|
+
|
|
33
|
+
- **Addressed by the loop** — at least one comment authored by the loop user **and** that comment's body cites a SHA prefix in `last_seen.pushed_shas[]`. Bodies use the form *"Addressed in `<short-sha>`: ..."* per [`../muggle-pr-followup/output-templates/inline-reply.md`](../muggle-pr-followup/output-templates/inline-reply.md), so a substring match on any `pushed_shas[i][:7]` works.
|
|
34
|
+
- **Addressed by a human** — at least one comment authored by a non-loop-user identity created after the original comment's timestamp, and no addressed-by-loop signal.
|
|
35
|
+
- **Not addressed** — neither of the above.
|
|
36
|
+
|
|
37
|
+
The classification considers only the unresolved threads' comments. Do not cross-reference timeline events from outside the threads.
|
|
38
|
+
|
|
39
|
+
### Step 3 — Build the resolve-reminder list
|
|
40
|
+
|
|
41
|
+
Collect the thread `databaseId` of every thread classified as **addressed by the loop in this push** (i.e. citing a SHA in `pushed_shas[]` where that SHA was added by the current invocation; older SHAs were already covered by prior cycles' reminders).
|
|
42
|
+
|
|
43
|
+
Note: the watcher does not maintain a "addressed-this-cycle" set; this stage derives it by comparing thread comments to the most-recent appended SHA. The simplest deterministic rule: include a thread iff at least one of its bot replies cites the **most recent** `pushed_shas[-1]`. Earlier SHAs were already addressed in past reminders.
|
|
44
|
+
|
|
45
|
+
### Step 4 — Post the top-level reminder comment
|
|
46
|
+
|
|
47
|
+
If the resolve-reminder list is non-empty, post **one** top-level PR comment using the template in [`../muggle-pr-followup/output-templates/resolve-reminder.md`](../muggle-pr-followup/output-templates/resolve-reminder.md) per [`../_shared/github-cli-recipes/top-level-comment.md`](../_shared/github-cli-recipes/top-level-comment.md).
|
|
48
|
+
|
|
49
|
+
If the list is empty (the push didn't end up addressing any threads — e.g. the actionable work was on lines that had no comment threads), post **nothing**. Still emit telemetry so the stage's run is observable.
|
|
50
|
+
|
|
51
|
+
### Step 5 — Emit telemetry
|
|
52
|
+
|
|
53
|
+
Emit one event per [`../_shared/telemetry-events/muggle-do-resolve-reminder.md`](../_shared/telemetry-events/muggle-do-resolve-reminder.md). Include:
|
|
54
|
+
|
|
55
|
+
- `addressed_by_loop` — count of threads added to the reminder list in Step 3.
|
|
56
|
+
- `addressed_by_human` — count from Step 2's other category.
|
|
57
|
+
- `not_addressed` — count from Step 2's "not addressed" category.
|
|
58
|
+
- `comment_posted` — true iff Step 4 actually posted a comment.
|
|
59
|
+
|
|
60
|
+
## Failure modes
|
|
61
|
+
|
|
62
|
+
This stage is best-effort. Any failure is logged to `followup.log` and silently skipped — the reviewer still gets the per-comment inline replies (the canonical signal that work was done), and the cycle continues to respawn the watcher.
|
|
63
|
+
|
|
64
|
+
The one exception: do not silently swallow a `gh pr comment` failure if Step 4 ran. The comment is a user-visible artifact; if it fails, surface the underlying `gh` error to the user so they know the reminder didn't post.
|
|
65
|
+
|
|
66
|
+
## Invariants
|
|
67
|
+
|
|
68
|
+
- Telemetry fires once per invocation, even when no comment is posted.
|
|
69
|
+
- The reminder only covers threads addressed by the **most recent** push — older SHAs were covered by prior cycles' reminders.
|
|
70
|
+
- This stage suggests; it does not resolve threads on the reviewer's behalf.
|
|
@@ -1,72 +1,68 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-do
|
|
3
|
-
description: Unified Muggle AI workflow entry point. Use when user types muggle do or asks for autonomous implementation to PR.
|
|
3
|
+
description: Unified Muggle AI workflow entry point. Use when user types muggle do or asks for autonomous implementation to PR. Also handles the `address-reviews` directive (dispatched by the muggle-pr-followup watcher when new submitted reviews land on a PR).
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Muggle Test Do
|
|
8
8
|
|
|
9
|
-
> Telemetry first step: see [
|
|
9
|
+
> Telemetry first step: see [`../_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-do"`.
|
|
10
10
|
|
|
11
|
-
Runs an autonomous dev cycle from requirements to PR. **Fire and review:**
|
|
11
|
+
Runs an autonomous dev cycle from requirements to PR. **Fire and review:** user answers one pre-flight questionnaire, then walks away. The [muggle-pr-followup](../muggle-pr-followup/SKILL.md) watcher invokes `/muggle-do` again with the *address-reviews* directive when new reviews land.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Forward pipeline (fresh feature)
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
15
|
+
| # | Stage | File |
|
|
16
|
+
| :- | :---- | :--- |
|
|
17
|
+
| 1 | Pre-flight (only user-facing stage) | [`../do/pre-flight.md`](../do/pre-flight.md) |
|
|
18
|
+
| 2 | Requirements | [`../do/requirements.md`](../do/requirements.md) |
|
|
19
|
+
| 3 | Build | [`../do/build.md`](../do/build.md) |
|
|
20
|
+
| 4 | Impact analysis | [`../do/impact-analysis.md`](../do/impact-analysis.md) |
|
|
21
|
+
| 5 | Unit tests | [`../do/unit-tests.md`](../do/unit-tests.md) |
|
|
22
|
+
| 6 | E2E acceptance | [`../do/e2e-acceptance.md`](../do/e2e-acceptance.md) |
|
|
23
|
+
| 7 | Create or update PR | [`../do/open-prs.md`](../do/open-prs.md) |
|
|
24
|
+
| 8 | Hand off to watcher | [`../muggle-pr-followup/SKILL.md`](../muggle-pr-followup/SKILL.md) |
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
Stage 7 dispatches one watcher per opened PR as its last action.
|
|
20
27
|
|
|
21
|
-
|
|
22
|
-
| :- | :---- | :--- | :----------- |
|
|
23
|
-
| 1 | Pre-flight | [../do/pre-flight.md](../do/pre-flight.md) | **Yes — one consolidated turn** |
|
|
24
|
-
| 2 | Requirements | [../do/requirements.md](../do/requirements.md) | No |
|
|
25
|
-
| 3 | Build | [../do/build.md](../do/build.md) | No |
|
|
26
|
-
| 4 | Impact analysis | [../do/impact-analysis.md](../do/impact-analysis.md) | No |
|
|
27
|
-
| 5 | Unit tests | [../do/unit-tests.md](../do/unit-tests.md) | No |
|
|
28
|
-
| 6 | E2E acceptance | [../do/e2e-acceptance.md](../do/e2e-acceptance.md) | No |
|
|
29
|
-
| 7 | Open PR | [../do/open-prs.md](../do/open-prs.md) | No |
|
|
30
|
-
| 8 | PR follow-up | [../muggle-pr-followup/SKILL.md](../muggle-pr-followup/SKILL.md) (generic) — invoked with muggle-do's cycle declaration | **Yes — only on ambiguous reviews** |
|
|
28
|
+
## Address-reviews flow
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
When invoked with the directive (PR URL + slug + review ids), routes to [`../do/address-reviews.md`](../do/address-reviews.md). Shares stages 3–6 + walkthrough with the forward pipeline; skips pre-flight, requirements, and PR creation. See the orchestrator for the cycle's exact step order, classification rules, and respawn logic.
|
|
33
31
|
|
|
34
|
-
|
|
32
|
+
## Input routing
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
Inspect `$ARGUMENTS` in this order:
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
1. **Address-reviews** — input contains a `github.com/.../pull/<n>` URL **and** one or more integers ≥ 100000000 (review id shape) → [`../do/address-reviews.md`](../do/address-reviews.md). Programmatic; never ask.
|
|
37
|
+
2. **Empty / `help` / `menu` / `?`** → menu + session selector.
|
|
38
|
+
3. **Task automation** (perform an action on a website) → `muggle:muggle-do-task`.
|
|
39
|
+
4. **Otherwise** → forward pipeline at Stage 1.
|
|
41
40
|
|
|
42
|
-
|
|
41
|
+
When in doubt between #3 and #4, ask one question.
|
|
43
42
|
|
|
44
|
-
##
|
|
45
|
-
|
|
46
|
-
Treat `$ARGUMENTS` as the user command:
|
|
43
|
+
## Preferences
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- **Feature development** (build / fix / refactor code) → start or resume a dev-cycle session.
|
|
45
|
+
| Preference | Gate |
|
|
46
|
+
| :--------- | :--- |
|
|
47
|
+
| `autoE2ETest` | Stage 6 — run E2E every cycle (default `always`), or fold into pre-flight |
|
|
52
48
|
|
|
53
|
-
|
|
49
|
+
`autoUseWorktree`, `autoRebase`, `autoCreatePR`, `autoCleanup` fire from per-stage files.
|
|
54
50
|
|
|
55
51
|
## Session model
|
|
56
52
|
|
|
57
|
-
|
|
53
|
+
`.muggle-do/sessions/<slug>/`. Schemas: [`../muggle-pr-followup/state-schemas.md`](../muggle-pr-followup/state-schemas.md).
|
|
58
54
|
|
|
59
|
-
| File |
|
|
60
|
-
| :--- |
|
|
61
|
-
| `state.md` | Stage 1
|
|
62
|
-
| `iterations/<NNN>.md` | Every stage |
|
|
63
|
-
| `requirements.md` | Stage 2
|
|
64
|
-
| `prs.json`, `last_seen.json`, `followup.log` | Stage
|
|
65
|
-
| `result.md` | Stage 7 (seeded),
|
|
55
|
+
| File | Owner |
|
|
56
|
+
| :--- | :---- |
|
|
57
|
+
| `state.md` | Stage 1 or bootstrap |
|
|
58
|
+
| `iterations/<NNN>.md` | Every stage |
|
|
59
|
+
| `requirements.md` | Stage 2 (forward only) |
|
|
60
|
+
| `prs.json`, `last_seen.json`, `followup.log` | Stage 7 / watcher / `/muggle-do` |
|
|
61
|
+
| `result.md` | Stage 7 (seeded), terminal tick (finalized) |
|
|
66
62
|
|
|
67
63
|
## Guardrails
|
|
68
64
|
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
65
|
+
- Stage 1 is the only user-facing forward stage. Stages 2–7 don't ask mid-cycle; blocker → pre-flight bug.
|
|
66
|
+
- Same stage failing 3× → escalate.
|
|
67
|
+
- 3 cycle iterations reach E2E with failures → ship with `[E2E FAILING]`.
|
|
68
|
+
- Address-reviews escalation (ambiguous or design-adjustment) does not block the watcher; user resolves on GitHub.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# muggle-pr-followup — folder TOC
|
|
2
|
+
|
|
3
|
+
This folder holds the watcher loop for PR review follow-ups. The watcher is a **dumb pipe**: it polls for new submitted reviews and dispatches `/muggle-do` when there are any. Cycle execution, classification, replies, and escalation all live in `/muggle-do`'s address-reviews mode — see [stage-8 design](../../../../muggle-ai-brain/architecture/2026-05-08-muggle-do-pr-comment-loop-design.md) for the architectural rationale.
|
|
4
|
+
|
|
5
|
+
## Files in this folder
|
|
6
|
+
|
|
7
|
+
- [`SKILL.md`](SKILL.md) — public entry. Smart-inference routing between bootstrap mode (URL input) and tick mode (slug + PR number). Read first.
|
|
8
|
+
- [`bootstrap.md`](bootstrap.md) — the bootstrap procedure (one-shot non-interactive seed + watcher dispatch).
|
|
9
|
+
- [`contract.md`](contract.md) — the watcher per-tick procedure (poll → dispatch → exit).
|
|
10
|
+
- [`state-schemas.md`](state-schemas.md) — canonical JSON shapes of session state files.
|
|
11
|
+
- [`output-templates.md`](output-templates.md) — TOC of message templates; per-group files in `output-templates/`.
|
|
12
|
+
|
|
13
|
+
## Cross-folder dependencies
|
|
14
|
+
|
|
15
|
+
Shared with other skills, under `../_shared/`:
|
|
16
|
+
|
|
17
|
+
- [`pr-followup-helpers.md`](../_shared/pr-followup-helpers.md) — TOC of allow-list / reply-routing / classify; per-section files in `_shared/pr-followup-helpers/`. Called by `/muggle-do`, not by this folder.
|
|
18
|
+
- [`telemetry-emit.md`](../_shared/telemetry-emit.md) — how to emit a telemetry event.
|
|
19
|
+
- [`telemetry-events.md`](../_shared/telemetry-events.md) — TOC of canonical event shapes; per-event files in `_shared/telemetry-events/`.
|
|
20
|
+
- [`github-cli-recipes.md`](../_shared/github-cli-recipes.md) — TOC of reusable `gh` / `git` snippets; per-recipe files in `_shared/github-cli-recipes/`.
|
|
21
|
+
|
|
22
|
+
Caller-specific, under `../do/`:
|
|
23
|
+
|
|
24
|
+
- [`open-prs.md`](../do/open-prs.md) — TOC for the create-or-update PR stage; per-mode files in `do/open-prs/`.
|
|
25
|
+
- [`resolve-reminder.md`](../do/resolve-reminder.md) — `/muggle-do`'s post-replies stage that posts the resolve-reminder top-level comment.
|
|
@@ -1,59 +1,37 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-pr-followup
|
|
3
|
-
description:
|
|
3
|
+
description: Watcher loop for PR review follow-ups. Polls one PR for new submitted reviews and dispatches `/muggle-do` (address-reviews mode) when there are any. A dumb pipe — no classification, no cycle execution, no replies. Use `/loop 1m /muggle:muggle-pr-followup <slug> <pr-number>` for ongoing polling, or `/muggle:muggle-pr-followup <pr-url>` to bootstrap a fresh watcher on an existing PR.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
#
|
|
7
|
+
# muggle-pr-followup
|
|
8
8
|
|
|
9
|
-
> Telemetry first step: see [
|
|
9
|
+
> Telemetry first step: see [`../_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-pr-followup"`.
|
|
10
10
|
|
|
11
|
-
A
|
|
11
|
+
A watcher that babysits one open PR's review thread. Polls for new submitted reviews; when any land, hands them off to `/muggle-do` and exits. `/muggle-do` is the executor — it classifies the reviews, runs the work, pushes, replies per comment, and respawns the watcher.
|
|
12
12
|
|
|
13
|
-
**
|
|
13
|
+
**The watcher is a dumb pipe.** It does not classify reviews, iterate cycles, post replies, or escalate. All of that lives in `/muggle-do`. See [stage-8 design](../../../../muggle-ai-brain/architecture/2026-05-08-muggle-do-pr-comment-loop-design.md) for the rationale.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
**Per-PR isolation.** One watcher per PR. Multi-PR work runs N independent watchers.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
## Routing
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
- One argument → ambiguous; list PRs under that slug, exit.
|
|
21
|
-
- Two arguments → resolve and run one tick.
|
|
19
|
+
The skill recognizes two modes by inspecting `$ARGUMENTS` and falling back to on-disk state. It never runs procedure inline — it identifies the mode and routes to the appropriate procedure file.
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
| Input | On-disk check | Mode |
|
|
22
|
+
| :---- | :------------ | :--- |
|
|
23
|
+
| First arg matches `https?://github\.com/[^/]+/[^/]+/pull/\d+` | — | **bootstrap** → [`bootstrap.md`](bootstrap.md) |
|
|
24
|
+
| `<slug> <pr-number>` | session dir for `<slug>` exists | **tick** → [`contract.md`](contract.md) |
|
|
25
|
+
| `<slug> <pr-number>` | session dir missing | **error:** "no session at `<path>`; pass a PR URL to start one" |
|
|
26
|
+
| `<pr-number>` alone | exactly one existing session contains it | **tick** for that PR |
|
|
27
|
+
| `<pr-number>` alone | zero or multiple matches | **error:** ambiguous; list candidates and exit |
|
|
28
|
+
| empty / `help` / `?` | — | **help:** list active loops per [`output-templates/help.md`](output-templates/help.md) |
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
Bootstrap accepts two optional trailing flags:
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
- `--slug=<name>` — override the default `<repo>-pr<n>` slug
|
|
33
|
+
- `--resume` — opt in to reusing an existing session slot (default is refuse on conflict)
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
## Folder TOC
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
"cycleName": "muggle-do dev cycle",
|
|
34
|
-
"steps": [
|
|
35
|
-
{ "stage": 3, "file": "../do/build.md" },
|
|
36
|
-
{ "stage": 4, "file": "../do/impact-analysis.md" },
|
|
37
|
-
{ "stage": 5, "file": "../do/unit-tests.md" },
|
|
38
|
-
{ "stage": 6, "file": "../do/e2e-acceptance.md" },
|
|
39
|
-
{ "name": "post-walkthrough", "skill": "muggle-pr-visual-walkthrough", "mode": "A" }
|
|
40
|
-
],
|
|
41
|
-
"pushHandler": "git push origin <branch>"
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
The cycle's job: read the amended `requirements.md`, run each declared step, push to the existing branch. The cycle returns one of `pushed | escalated | failed`. The skill doesn't care what's inside the steps — it just iterates them, captures the outcome, and writes a reply summary referencing the new SHA.
|
|
46
|
-
|
|
47
|
-
Callers without a `cycle.json` are rejected with `no cycle declared — caller must seed cycle.json at dispatch time`.
|
|
48
|
-
|
|
49
|
-
## Subagent dispatch (optional)
|
|
50
|
-
|
|
51
|
-
A caller may declare `"useSubagent": true` in `cycle.json`. When set, the implementation cycle runs as a separate Claude subagent rather than inline in the loop's tick — gives stronger isolation per PR but adds overhead per cycle. Default is inline (which is itself isolated per-tick via `/loop`).
|
|
52
|
-
|
|
53
|
-
## Design adjustment escalation
|
|
54
|
-
|
|
55
|
-
When the implementation cycle reports back that the review requires not just code change but a **design adjustment** beyond what the current requirements support (e.g. the build stage discovers the requested change conflicts with a load-bearing assumption), the cycle returns `failed: design-adjustment`. The loop treats this like an ambiguous escalation but with a different terminal message that points at the design conflict and asks the user to decide.
|
|
56
|
-
|
|
57
|
-
## Why a separate skill (and not e.g. inside the caller's own skill folder)
|
|
58
|
-
|
|
59
|
-
`/loop` dispatches via slash command; slash commands resolve to top-level skills under `plugin/skills/`. A per-tick loop driven by `/loop` therefore has to live as a top-level skill. Putting the loop's content directly inside a caller-specific folder would make `/loop`-dispatch impossible (or fragile via shell-only entry points). Keeping the loop generic and caller-agnostic is what lets `/loop` dispatch into it cleanly.
|
|
37
|
+
See [`CLAUDE.md`](CLAUDE.md) for the one-line index of every file in this folder.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Bootstrap Procedure
|
|
2
|
+
|
|
3
|
+
The procedure for the **bootstrap mode** of `muggle-pr-followup` — invoked when a user dispatches the skill with a GitHub PR URL. Routing into this mode is documented in [`SKILL.md`](SKILL.md#routing).
|
|
4
|
+
|
|
5
|
+
Bootstrap is **non-interactive**: it runs straight through, prompts the user for nothing, and ends with the first watcher dispatched. The first review the watcher sees triggers `/muggle-do`, where working-tree validation surfaces (via the existing E2E stage / muggle-test).
|
|
6
|
+
|
|
7
|
+
## Turn preamble
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
**muggle-pr-followup bootstrap** — seeding state for <owner>/<repo>#<n>.
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
|
|
15
|
+
`$ARGUMENTS = <pr-url> [--slug=<name>] [--resume]`
|
|
16
|
+
|
|
17
|
+
- `<pr-url>` matches `https?://github\.com/[^/]+/[^/]+/pull/\d+` — required.
|
|
18
|
+
- `--slug=<name>` overrides the default `<repo>-pr<n>` slug.
|
|
19
|
+
- `--resume` opts into refreshing an existing slot instead of refusing on conflict.
|
|
20
|
+
|
|
21
|
+
## Procedure
|
|
22
|
+
|
|
23
|
+
### Step 1 — Parse the URL
|
|
24
|
+
|
|
25
|
+
Extract `<owner>`, `<repo>`, `<pr-number>`. On malformed input, exit with the malformed-URL abort from [`output-templates/bootstrap.md`](output-templates/bootstrap.md).
|
|
26
|
+
|
|
27
|
+
### Step 2 — Fetch PR metadata
|
|
28
|
+
|
|
29
|
+
Per [`../_shared/github-cli-recipes/pr-metadata.md`](../_shared/github-cli-recipes/pr-metadata.md).
|
|
30
|
+
|
|
31
|
+
If `state` is `MERGED` or `CLOSED`, exit with the terminal-PR abort. If the `gh` call fails (not found, auth missing), surface the underlying error verbatim and exit.
|
|
32
|
+
|
|
33
|
+
### Step 3 — Verify the working tree
|
|
34
|
+
|
|
35
|
+
Per [`../_shared/github-cli-recipes/verify-working-tree.md`](../_shared/github-cli-recipes/verify-working-tree.md). On any check failure, exit with the wrong-working-tree abort.
|
|
36
|
+
|
|
37
|
+
### Step 4 — Resolve the slug
|
|
38
|
+
|
|
39
|
+
Default: `<repo>-pr<n>` (e.g. `muggle-ai-works-pr154`). Override: `--slug=<name>`. Session dir is `.muggle-do/sessions/<slug>/` relative to the caller's working tree.
|
|
40
|
+
|
|
41
|
+
### Step 5 — Idempotency check
|
|
42
|
+
|
|
43
|
+
If `.muggle-do/sessions/<slug>/` exists:
|
|
44
|
+
|
|
45
|
+
- Without `--resume` → exit with the slot-conflict abort. Both remedies (delete + re-run, or pass `--resume`) are spelled out in the message.
|
|
46
|
+
- With `--resume` → refresh `prs.json[0].head_sha` to the current `headRefOid` from Step 2. Leave `last_seen.json`, `state.md`, and everything else untouched. Skip to Step 8 (no need to re-seed; no need to refetch the cursor).
|
|
47
|
+
|
|
48
|
+
### Step 6 — Resolve the initial cursor
|
|
49
|
+
|
|
50
|
+
Fetch reviews per [`../_shared/github-cli-recipes/submitted-reviews.md`](../_shared/github-cli-recipes/submitted-reviews.md) with cursor 0, then take `max(id)`. If none, the cursor is 0. The watcher only acts on `id > cursor`, so this pins forward-only.
|
|
51
|
+
|
|
52
|
+
### Step 7 — Seed state files
|
|
53
|
+
|
|
54
|
+
Identify the loop user once per [`../_shared/github-cli-recipes/loop-user-identity.md`](../_shared/github-cli-recipes/loop-user-identity.md); cache in `state.md`.
|
|
55
|
+
|
|
56
|
+
Write under `.muggle-do/sessions/<slug>/`:
|
|
57
|
+
|
|
58
|
+
**`prs.json`** — see [`state-schemas.md`](state-schemas.md#prsjson). One entry, `state` = `"open"`, `head_sha` from Step 2's `headRefOid`.
|
|
59
|
+
|
|
60
|
+
**`last_seen.json`** — see [`state-schemas.md`](state-schemas.md#last_seenjson). One key (`"<owner>/<repo>#<n>"`), `reviewId` from Step 6, `last_pushed_sha: null`, `idle_tick_count: 0`, `cycles_completed: 0`, `escalated_review_ids: []`, `pushed_shas: []`.
|
|
61
|
+
|
|
62
|
+
**`state.md`** — see [`state-schemas.md`](state-schemas.md#statemd). `Bootstrapped from URL: yes`. Cache the loop-user login.
|
|
63
|
+
|
|
64
|
+
Do **not** write `cycle.json` or `requirements.md` — those files are no longer part of the session slot.
|
|
65
|
+
|
|
66
|
+
Create `iterations/` subdir (empty) for future caller use.
|
|
67
|
+
|
|
68
|
+
### Step 8 — Dispatch the first watcher
|
|
69
|
+
|
|
70
|
+
The last action of this turn:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
/loop 1m /muggle:muggle-pr-followup <slug> <n>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Step 9 — Print the success summary
|
|
77
|
+
|
|
78
|
+
Use the success-summary template from [`output-templates/bootstrap.md`](output-templates/bootstrap.md). Print it **before** the `/loop` dispatch so it's visible.
|
|
79
|
+
|
|
80
|
+
### Step 10 — Emit telemetry
|
|
81
|
+
|
|
82
|
+
Emit one event per [`../_shared/telemetry-events/pr-followup-bootstrap.md`](../_shared/telemetry-events/pr-followup-bootstrap.md). `caller = "user"` for direct invocation. Fire-and-forget per [`../_shared/telemetry-emit.md`](../_shared/telemetry-emit.md).
|
|
83
|
+
|
|
84
|
+
## Invariants
|
|
85
|
+
|
|
86
|
+
- All state writes happen in Step 7 — earlier aborts leave nothing on disk.
|
|
87
|
+
- If Step 7 fails mid-write, surface the OS error and tell the user to `rm -rf <slot>` and re-run; do not dispatch the watcher.
|
|
88
|
+
- Bootstrap never retries.
|