@snipcodeit/mgw 0.1.3 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,23 +1,35 @@
1
1
  ---
2
2
  name: mgw:review
3
- description: Review and classify new comments on a GitHub issue since last triage
4
- argument-hint: "<issue-number>"
3
+ description: Review GitHub comments on issues OR perform deep PR analysis
4
+ argument-hint: "<issue-number | pr-number | pr-url> [--pr]"
5
5
  allowed-tools:
6
6
  - Bash
7
7
  - Read
8
8
  - Write
9
9
  - Edit
10
+ - Glob
11
+ - Grep
10
12
  - Task
11
13
  - AskUserQuestion
12
14
  ---
13
15
 
14
16
  <objective>
15
- Standalone comment review for a triaged issue. Fetches new comments posted since
16
- triage, classifies them (material/informational/blocking), and updates the state
17
- file accordingly.
17
+ Two-mode review command:
18
18
 
19
- Use this when you want to check for stakeholder feedback before running the pipeline,
20
- or to review comments on a blocked issue before unblocking it.
19
+ **Mode 1: Issue Comment Review (default)**
20
+ Review and classify new comments on a GitHub issue since last triage. Fetches new comments,
21
+ classifies them (material/informational/blocking/resolution), and updates state.
22
+
23
+ Use this when checking for stakeholder feedback before running the pipeline, or reviewing
24
+ comments on a blocked issue.
25
+
26
+ **Mode 2: PR Deep Review (with --pr flag)**
27
+ Comprehensive PR review that mimics a senior engineer's code review process. Problem-solving
28
+ orchestration with high autonomy to analyze, question assumptions, and provide architectural
29
+ guidance across five dimensions.
30
+
31
+ This is intentionally different from execution orchestration — the reviewer has space to think
32
+ deeply rather than produce code.
21
33
  </objective>
22
34
 
23
35
  <execution_context>
@@ -28,82 +40,149 @@ or to review comments on a blocked issue before unblocking it.
28
40
  </execution_context>
29
41
 
30
42
  <context>
31
- Issue number: $ARGUMENTS
32
-
33
- State: .mgw/active/ (must exist — issue must be triaged first)
43
+ Reference: $ARGUMENTS (issue number, PR number, or PR URL)
44
+ Flags: --pr forces PR deep review mode
34
45
  </context>
35
46
 
36
47
  <process>
37
48
 
38
- <step name="validate_and_load">
39
- **Validate input and load state:**
49
+ <step name="detect_mode">
50
+ **Detect review mode:**
40
51
 
41
52
  ```bash
42
53
  REPO_ROOT=$(git rev-parse --show-toplevel)
43
- ```
44
54
 
45
- Parse $ARGUMENTS for issue number. If missing:
46
- ```
47
- AskUserQuestion(
48
- header: "Issue Number Required",
49
- question: "Which issue number do you want to review comments for?",
50
- followUp: "Enter the GitHub issue number (e.g., 42)"
51
- )
52
- ```
55
+ # Parse arguments
56
+ REFERENCE="$ARGUMENTS"
57
+ PR_MODE=false
53
58
 
54
- Load state file: `${REPO_ROOT}/.mgw/active/${ISSUE_NUMBER}-*.json`
59
+ # Check for --pr flag
60
+ if [[ "$REFERENCE" =~ --pr[[:space:]]|$ ]]; then
61
+ PR_MODE=true
62
+ REFERENCE=$(echo "$REFERENCE" | sed 's/--pr//g' | xargs)
63
+ fi
55
64
 
56
- If no state file exists:
65
+ # Determine if PR or issue based on format
66
+ if [[ "$REFERENCE" =~ ^https?://github\.com/[^/]+/[^/]+/pull/ ]]; then
67
+ # URL - determine if issue or PR
68
+ if [[ "$REFERENCE" =~ /pull/ ]]; then
69
+ PR_MODE=true
70
+ fi
71
+ PR_REF="$REFERENCE"
72
+ elif [[ "$REFERENCE" =~ ^https?://github\.com/[^/]+/[^/]+/issues/ ]]; then
73
+ PR_MODE=false
74
+ ISSUE_REF="$REFERENCE"
75
+ elif [[ "$REFERENCE" =~ ^[0-9]+$ ]]; then
76
+ # Number - check if it's a PR or issue by testing
77
+ # Default to issue comment review (safer default)
78
+ PR_MODE=false
79
+ NUMBER="$REFERENCE"
80
+ else
81
+ # Default: issue comment review
82
+ PR_MODE=false
83
+ NUMBER="$REFERENCE"
84
+ fi
85
+
86
+ # Export for later steps
87
+ export PR_MODE
57
88
  ```
58
- Issue #${ISSUE_NUMBER} hasn't been triaged yet.
59
- Run /mgw:issue ${ISSUE_NUMBER} first, then review comments.
89
+ </step>
90
+
91
+ <step name="route_to_mode">
92
+ **Route to appropriate review mode:**
93
+
94
+ If PR_MODE=true → Jump to "pr_review" section below
95
+ If PR_MODE=false → Continue to "issue_comments" section
96
+
97
+ </step>
98
+
99
+ # ═══════════════════════════════════════════════════════════════════════════════
100
+ # MODE 1: ISSUE COMMENT REVIEW (original functionality, optimized)
101
+ # ═══════════════════════════════════════════════════════════════════════════════
102
+
103
+ <step name="issue_validate">
104
+ **Validate issue and load state:**
105
+
106
+ ```bash
107
+ # Parse issue number
108
+ if [ -n "$NUMBER" ]; then
109
+ ISSUE_NUMBER="$NUMBER"
110
+ elif [ -n "$ISSUE_REF" ]; then
111
+ ISSUE_NUMBER=$(echo "$ISSUE_REF" | grep -oE '[0-9]+$' | head -1)
112
+ fi
113
+
114
+ if [ -z "$ISSUE_NUMBER" ]; then
115
+ AskUserQuestion(
116
+ header: "Issue Number Required",
117
+ question: "Which issue number do you want to review comments for?",
118
+ followUp: "Enter the GitHub issue number (e.g., 42)"
119
+ )
120
+ ISSUE_NUMBER="$ANSWER"
121
+ fi
122
+
123
+ # Verify issue exists
124
+ gh issue view "$ISSUE_NUMBER" >/dev/null 2>&1 || {
125
+ echo "Error: Issue #${ISSUE_NUMBER} not found."
126
+ exit 1
127
+ }
128
+
129
+ # Check if issue is triaged (state file exists)
130
+ if [ ! -f "${REPO_ROOT}/.mgw/active/${ISSUE_NUMBER}-*.json" ]; then
131
+ echo "Issue #${ISSUE_NUMBER} hasn't been triaged yet."
132
+ echo "Run /mgw:issue ${ISSUE_NUMBER} first, then review comments."
133
+ # Still allow review but warn
134
+ fi
60
135
  ```
61
136
  </step>
62
137
 
63
- <step name="fetch_comments">
64
- **Fetch current comment state from GitHub:**
138
+ <step name="issue_fetch_comments">
139
+ **Fetch current comment state:**
65
140
 
66
141
  ```bash
67
142
  CURRENT_COMMENTS=$(gh issue view $ISSUE_NUMBER --json comments --jq '.comments | length' 2>/dev/null || echo "0")
68
- STORED_COMMENTS="${triage.last_comment_count}"
143
+ STORED_COMMENTS=0
69
144
 
70
- if [ -z "$STORED_COMMENTS" ] || [ "$STORED_COMMENTS" = "null" ]; then
71
- STORED_COMMENTS=0
145
+ # Try to get stored count from state file
146
+ if [ -f "${REPO_ROOT}/.mgw/active/${ISSUE_NUMBER}-"*".json" ]; then
147
+ STATE_FILE=$(ls "${REPO_ROOT}/.mgw/active/${ISSUE_NUMBER}-"*".json" | head -1)
148
+ STORED_COMMENTS=$(jq -r '.triage.last_comment_count // 0' "$STATE_FILE" 2>/dev/null || echo "0")
72
149
  fi
73
150
 
74
151
  NEW_COUNT=$(($CURRENT_COMMENTS - $STORED_COMMENTS))
75
- ```
76
152
 
77
- If no new comments (`NEW_COUNT <= 0`):
78
- ```
79
- No new comments on #${ISSUE_NUMBER} since triage (${STORED_COMMENTS} comments at triage, ${CURRENT_COMMENTS} now).
80
- ```
81
- Stop.
153
+ if [ "$NEW_COUNT" -le 0 ]; then
154
+ echo "No new comments on #${ISSUE_NUMBER} since triage (${STORED_COMMENTS} stored, ${CURRENT_COMMENTS} now)."
155
+ echo "Done."
156
+ exit 0
157
+ fi
82
158
 
83
- If new comments exist, fetch them:
84
- ```bash
159
+ # Fetch new comments
85
160
  NEW_COMMENTS=$(gh issue view $ISSUE_NUMBER --json comments \
86
161
  --jq "[.comments[-${NEW_COUNT}:]] | .[] | {author: .author.login, body: .body, createdAt: .createdAt}" 2>/dev/null)
162
+
163
+ # Get issue context for classification
164
+ ISSUE_TITLE=$(gh issue view $ISSUE_NUMBER --json title -q '.title')
165
+ PIPELINE_STAGE=$(jq -r '.pipeline_stage // "new"' "$STATE_FILE" 2>/dev/null || echo "new")
166
+ GSD_ROUTE=$(jq -r '.gsd_route // "unknown"' "$STATE_FILE" 2>/dev/null || echo "unknown")
87
167
  ```
88
168
  </step>
89
169
 
90
- <step name="classify_comments">
91
- **Spawn classification agent:**
170
+ <step name="issue_classify">
171
+ **Spawn classification agent (lightweight):**
92
172
 
93
173
  ```
94
174
  Task(
95
175
  prompt="
96
- <files_to_read>
97
- - ./CLAUDE.md (Project instructions — if exists, follow all guidelines)
176
+ KR|<files_to_read>
177
+ ST|- ./CLAUDE.md (Project instructions — if exists)
98
178
  </files_to_read>
99
179
 
100
180
  Classify new comments on GitHub issue #${ISSUE_NUMBER}.
101
181
 
102
182
  <issue_context>
103
- Title: ${issue_title}
104
- Current pipeline stage: ${pipeline_stage}
105
- GSD Route: ${gsd_route}
106
- Triage scope: ${triage.scope}
183
+ Title: ${ISSUE_TITLE}
184
+ Current pipeline stage: ${PIPELINE_STAGE}
185
+ GSD Route: ${GSD_ROUTE}
107
186
  </issue_context>
108
187
 
109
188
  <new_comments>
@@ -111,150 +190,211 @@ ${NEW_COMMENTS}
111
190
  </new_comments>
112
191
 
113
192
  <classification_rules>
114
- Classify each comment (and the overall batch) into ONE of:
115
-
116
- - **material** — Comment changes scope, requirements, acceptance criteria, or design.
117
- Examples: 'Actually we also need to handle X', 'Changed the requirement to Y',
118
- 'Don't forget about edge case Z'.
193
+ - **material** Comment changes scope, requirements, acceptance criteria, or design
194
+ - **informational** — Status update, acknowledgment, question, +1
195
+ - **blocking** — Explicit instruction to stop or wait
196
+ - **resolution** Comment indicates a previously identified blocker has been resolved
119
197
 
120
- - **informational** Status update, acknowledgment, question that doesn't change scope, +1.
121
- Examples: 'Looks good', 'Thanks for picking this up', 'What's the ETA?', '+1'.
122
-
123
- - **blocking** — Explicit instruction to stop or wait. Must contain clear hold language.
124
- Examples: 'Don't work on this yet', 'Hold off', 'Blocked by external dependency',
125
- 'Wait for design review'.
126
-
127
- - **resolution** — Comment indicates a previously identified blocker or issue has been resolved.
128
- Examples: 'The dependency has been updated', 'Security review complete — approved',
129
- 'Added the missing acceptance criteria', 'Updated the issue with more detail',
130
- 'Fixed the blocking issue in #42'.
131
-
132
- If ANY comment in the batch is blocking, overall classification is blocking.
133
- If ANY comment is resolution (and none blocking), overall classification is resolution.
134
- If ANY comment is material (and none blocking/resolution), overall classification is material.
135
- Otherwise, informational.
198
+ Priority: blocking > resolution > material > informational
136
199
  </classification_rules>
137
200
 
138
201
  <output_format>
139
202
  Return ONLY valid JSON:
140
203
  {
141
204
  \"classification\": \"material|informational|blocking|resolution\",
142
- \"reasoning\": \"Brief explanation of why this classification was chosen\",
143
- \"per_comment\": [
144
- {
145
- \"author\": \"username\",
146
- \"snippet\": \"first 100 chars of comment\",
147
- \"classification\": \"material|informational|blocking|resolution\"
148
- }
149
- ],
150
- \"new_requirements\": [\"list of new requirements if material, empty array otherwise\"],
151
- \"blocking_reason\": \"reason if blocking, empty string otherwise\",
152
- \"resolved_blocker\": \"description of what was resolved, empty string otherwise\"
205
+ \"reasoning\": \"Brief explanation\",
206
+ \"per_comment\": [{\"author\": \"username\", \"snippet\": \"first 100 chars\", \"classification\": \"...\"}],
207
+ \"new_requirements\": [],
208
+ \"blocking_reason\": \"\",
209
+ \"resolved_blocker\": \"\"
153
210
  }
154
211
  </output_format>
155
- ",
212
+ ",
156
213
  subagent_type="general-purpose",
157
214
  description="Classify comments on #${ISSUE_NUMBER}"
158
215
  )
159
216
  ```
160
217
  </step>
161
218
 
162
- <step name="present_and_act">
219
+ <step name="issue_present_and_act">
163
220
  **Present classification and offer actions:**
164
221
 
165
- Display the classification result:
166
-
167
222
  ```
168
223
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
169
224
  MGW ► COMMENT REVIEW — #${ISSUE_NUMBER}
170
225
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
171
226
 
172
- New comments: ${NEW_COUNT} since triage
227
+ New comments: ${NEW_COUNT}
173
228
  Classification: ${classification}
174
229
  Reasoning: ${reasoning}
175
230
 
176
- ${per_comment_table}
177
-
178
- ${if material: 'New requirements detected:\n' + new_requirements}
179
- ${if blocking: 'Blocking reason: ' + blocking_reason}
231
+ Actions based on classification:
232
+ - informational: Update last_comment_count
233
+ - material: Update with new requirements
234
+ - blocking: Option to block pipeline
235
+ - resolution: Option to re-triage
180
236
  ```
181
237
 
182
- Offer actions based on classification:
238
+ </step>
183
239
 
184
- **If informational:**
185
- ```
186
- AskUserQuestion(
187
- header: "Informational Comments",
188
- question: "Mark comments as reviewed and update state?",
189
- options: [
190
- { label: "Yes", description: "Update last_comment_count, continue" },
191
- { label: "No", description: "Keep current state, don't update count" }
192
- ]
193
- )
240
+ # ═══════════════════════════════════════════════════════════════════════════════
241
+ # MODE 2: PR DEEP REVIEW (new functionality)
242
+ # ═══════════════════════════════════════════════════════════════════════════════
243
+
244
+ <step name="pr_review">
245
+ **PR Deep Review Mode:**
246
+
247
+ This section handles comprehensive PR analysis. Jump here if PR_MODE=true.
248
+
249
+ <step name="pr_validate">
250
+ **Validate and parse PR reference:**
251
+
252
+ ```bash
253
+ # Parse PR number from various formats
254
+ if [[ "$REFERENCE" =~ ^https?://github\.com/[^/]+/[^/]+/pull/([0-9]+) ]]; then
255
+ PR_NUMBER="${BASH_REMATCH[1]}"
256
+ elif [[ "$REFERENCE" =~ ^[0-9]+$ ]] && "$PR_MODE" = true; then
257
+ PR_NUMBER="$REFERENCE"
258
+ else
259
+ # Try current branch
260
+ CURRENT_BRANCH=$(git branch --show-current)
261
+ PR_NUMBER=$(gh pr view "$CURRENT_BRANCH" --json number -q '.number' 2>/dev/null || echo "")
262
+ fi
263
+
264
+ # Verify PR exists
265
+ gh pr view "$PR_NUMBER" >/dev/null 2>&1 || {
266
+ echo "Error: PR #${PR_NUMBER} not found."
267
+ exit 1
268
+ }
194
269
  ```
195
- If yes: update `triage.last_comment_count` to $CURRENT_COMMENTS in state file.
270
+ </step>
196
271
 
197
- **If material:**
272
+ <step name="pr_fetch_details">
273
+ **Fetch comprehensive PR details:**
274
+
275
+ ```bash
276
+ PR_DATA=$(gh pr view "$PR_NUMBER" --json number,title,body,state,url,baseRefName,headRefName,author,createdAt,changedFiles)
277
+ PR_TITLE=$(echo "$PR_DATA" | jq -r '.title')
278
+ PR_BODY=$(echo "$PR_DATA" | jq -r '.body // ""')
279
+ PR_STATE=$(echo "$PR_DATA" | jq -r '.state')
280
+ PR_URL=$(echo "$PR_DATA" | jq -r '.url')
281
+ PR_BASE=$(echo "$PR_DATA" | jq -r '.baseRefName')
282
+ PR_HEAD=$(echo "$PR_DATA" | jq -r '.headRefName')
283
+ PR_AUTHOR=$(echo "$PR_DATA" | jq -r '.author.login')
284
+ FILE_COUNT=$(echo "$PR_DATA" | jq -r '.changedFiles')
285
+
286
+ # Find linked issue
287
+ LINKED_ISSUE=$(echo "$PR_BODY" | grep -oE '(closes|fixes|addresses|resolves) #[[:digit:]]+' | grep -oE '[[:digit:]]+' | head -1)
288
+
289
+ if [ -n "$LINKED_ISSUE" ]; then
290
+ ISSUE_TITLE=$(gh issue view "$LINKED_ISSUE" --json title -q '.title' 2>/dev/null || echo "")
291
+ fi
198
292
  ```
199
- AskUserQuestion(
200
- header: "Material Comments Detected",
201
- question: "How should MGW handle the scope change?",
202
- options: [
203
- { label: "Acknowledge and continue", description: "Update state with new requirements, keep current route" },
204
- { label: "Re-triage", description: "Run /mgw:issue to re-analyze with new context" },
205
- { label: "Ignore", description: "Don't update state" }
206
- ]
207
- )
293
+ </step>
294
+
295
+ <step name="pr_prepare_context">
296
+ **Prepare review directory:**
297
+
298
+ ```bash
299
+ REVIEW_DIR="${REPO_ROOT}/.mgw/reviews"
300
+ mkdir -p "$REVIEW_DIR"
301
+
302
+ REVIEW_ID="pr-${PR_NUMBER}-$(date +%Y%m%d-%H%M%S)"
303
+ REVIEW_STATE_FILE="${REVIEW_DIR}/${REVIEW_ID}.json"
304
+
305
+ cat > "$REVIEW_STATE_FILE" << EOF
306
+ {
307
+ \"review_id\": \"${REVIEW_ID}\",
308
+ \"pr_number\": ${PR_NUMBER},
309
+ \"pr_title\": \"${PR_TITLE}\",
310
+ \"pr_url\": \"${PR_URL}\",
311
+ \"linked_issue\": ${LINKED_ISSUE:-null},
312
+ \"reviewer\": \"${PR_AUTHOR}\",
313
+ \"created_at\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\",
314
+ \"status\": \"in_progress\",
315
+ \"mode\": \"deep_pr_review\"
316
+ }
317
+ EOF
208
318
  ```
209
- If acknowledge: update `triage.last_comment_count` and store new_requirements in state.
210
- If re-triage: suggest running `/mgw:issue ${ISSUE_NUMBER}` to re-triage.
319
+ </step>
320
+
321
+ <step name="pr_spawn_reviewer">
322
+ **Spawn deep review agent:**
211
323
 
212
- **If blocking:**
213
324
  ```
214
- AskUserQuestion(
215
- header: "Blocking Comment Detected",
216
- question: "Block the pipeline for this issue?",
217
- options: [
218
- { label: "Block", description: "Set pipeline_stage to 'blocked'" },
219
- { label: "Override", description: "Ignore blocker, keep current stage" },
220
- { label: "Review", description: "I'll review the comments manually" }
221
- ]
325
+ Task(
326
+ prompt="
327
+ KR|<files_to_read>
328
+ ST|- ./CLAUDE.md (Project instructions — if exists)
329
+ </files_to_read>
330
+
331
+ You are a senior code reviewer. Perform deep PR analysis addressing five dimensions:
332
+
333
+ ## 1. TEST THIS PR
334
+ Run tests, build, verify functionality works.
335
+
336
+ ## 2. WHY DO WE NEED THIS?
337
+ Analyze rationale vs linked issue #${LINKED_ISSUE:-none}.
338
+
339
+ ## 3. STATED INTENT VS ACTUAL CHANGES
340
+ Compare PR claims vs actual code changes.
341
+
342
+ ## 4. IMPACT ANALYSIS
343
+ Side effects, dependencies, patterns, security, performance.
344
+
345
+ ## 5. ARCHITECTURAL REVIEW
346
+ Alternatives, design consistency, root cause vs symptom.
347
+
348
+ ## PR Context
349
+ - **PR:** #${PR_NUMBER} - ${PR_TITLE}
350
+ - **Author:** ${PR_AUTHOR}
351
+ - **Base:** ${PR_BASE} ← ${PR_HEAD}
352
+ - **Files:** ${FILE_COUNT}
353
+ - **Linked Issue:** ${LINKED_ISSUE:-none} ${ISSUE_TITLE:+- ${ISSUE_TITLE}}
354
+
355
+ ## Output
356
+
357
+ Write to ${REVIEW_STATE_FILE}:
358
+
359
+ node -e \"
360
+ const fs = require('fs');
361
+ const state = JSON.parse(fs.readFileSync('${REVIEW_STATE_FILE}', 'utf-8'));
362
+ state.analyses = {
363
+ test_results: { tests_passed: true/false, build_passed: true/false, summary: '...' },
364
+ rationale: { problem_identified: '...', problem_valid: true/false, priority: 'high/medium/low' },
365
+ intent_vs_implementation: { gaps: [], scope_creep: [] },
366
+ impact_analysis: { side_effects: [], dependencies: [], pattern_violations: [] },
367
+ architectural_review: { approach_correct: true/false, alternatives: [], recommendations: [] },
368
+ overall_verdict: { recommendation: 'approve/request_changes/needs_discussion', confidence: 'high/medium/low', summary: '...', blockers: [], concerns: [] }
369
+ };
370
+ state.status = 'completed';
371
+ state.completed_at = new Date().toISOString();
372
+ fs.writeFileSync('${REVIEW_STATE_FILE}', JSON.stringify(state, null, 2));
373
+ console.log('Review complete.');
374
+ \"
375
+ ",
376
+ subagent_type="general-purpose",
377
+ model="sonnet",
378
+ description="Deep review PR #${PR_NUMBER}"
222
379
  )
223
380
  ```
224
- If block: update `pipeline_stage = "blocked"` and `triage.last_comment_count` in state.
225
- If override: update `triage.last_comment_count` only, keep pipeline_stage.
381
+ </step>
226
382
 
227
- **If resolution:**
228
- ```
229
- AskUserQuestion(
230
- header: "Blocker Resolution Detected",
231
- question: "A previous blocker appears to be resolved. Re-triage this issue?",
232
- options: [
233
- { label: "Re-triage", description: "Run /mgw:issue to re-analyze with updated context" },
234
- { label: "Acknowledge", description: "Update comment count, keep current pipeline stage" },
235
- { label: "Ignore", description: "Don't update state" }
236
- ]
237
- )
383
+ <step name="pr_present">
384
+ **Present review results:**
385
+
386
+ ```bash
387
+ REVIEW_DATA=$(cat "$REVIEW_STATE_FILE")
388
+ # Parse and display results in structured format
238
389
  ```
239
- If re-triage:
240
- - Update `triage.last_comment_count`
241
- - Suggest: "Run `/mgw:issue ${ISSUE_NUMBER}` to re-triage with the resolved context."
242
- - If pipeline_stage is "blocked" or "needs-info" or "needs-security-review", note:
243
- "Re-triage will re-evaluate gates and may unblock the pipeline."
244
- If acknowledge:
245
- - Update `triage.last_comment_count`
246
- - Keep current pipeline_stage
247
390
  </step>
248
391
 
249
392
  </process>
250
393
 
251
394
  <success_criteria>
252
- - [ ] Issue state loaded from .mgw/active/
253
- - [ ] Current comment count fetched from GitHub
254
- - [ ] New comments identified (delta from stored count)
255
- - [ ] Classification agent spawned and returned structured result
256
- - [ ] Classification presented to user with per-comment breakdown
257
- - [ ] User chose action (acknowledge/re-triage/block/ignore)
258
- - [ ] State file updated according to user choice
259
- - [ ] Resolution classification type supported with re-triage prompt
395
+ - [ ] Mode detection works (issue comments vs PR deep review)
396
+ - [ ] Issue comment classification still functions
397
+ - [ ] PR deep review analyzes five dimensions
398
+ - [ ] State properly separated (.mgw/reviews/ for PR, .mgw/active/ for issues)
399
+ - [ ] Both modes preserve their respective contexts
260
400
  </success_criteria>