@snipcodeit/mgw 0.3.0 → 0.4.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.
@@ -0,0 +1,169 @@
1
+ ---
2
+ name: mgw:handoff
3
+ description: Generate onboarding context for a developer joining the project mid-milestone
4
+ argument-hint: "<developer-name>"
5
+ allowed-tools:
6
+ - Bash
7
+ - Read
8
+ - Task
9
+ ---
10
+
11
+ <objective>
12
+ Produce a structured handoff document for a developer joining an MGW project. Assembles
13
+ current project state, milestone progress, active issues, and recent decisions from
14
+ GitHub issue comments into a single briefing.
15
+
16
+ This command is read-only. It does not modify any state.
17
+ </objective>
18
+
19
+ <execution_context>
20
+ @~/.claude/commands/mgw/workflows/state.md
21
+ </execution_context>
22
+
23
+ <process>
24
+
25
+ <step name="validate_input">
26
+ **Validate developer name provided:**
27
+
28
+ Parse $ARGUMENTS for a name. If missing, use "new developer" as default.
29
+ </step>
30
+
31
+ <step name="gather_state">
32
+ **Gather project state:**
33
+
34
+ ```bash
35
+ REPO_ROOT=$(git rev-parse --show-toplevel)
36
+ REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
37
+ MGW_DIR="${REPO_ROOT}/.mgw"
38
+
39
+ # Project info
40
+ PROJECT_NAME=$(echo "$REPO" | cut -d'/' -f2)
41
+
42
+ # Active milestone
43
+ MILESTONE_INFO=""
44
+ if [ -f "${MGW_DIR}/project.json" ]; then
45
+ MILESTONE_INFO=$(python3 -c "
46
+ import json
47
+ p = json.load(open('${MGW_DIR}/project.json'))
48
+ ms = p.get('milestones', [])
49
+ active = [m for m in ms if m.get('gsd_state') == 'active']
50
+ if active:
51
+ m = active[0]
52
+ total = len(m.get('issues', []))
53
+ done = len([i for i in m['issues'] if i.get('pipeline_stage') == 'done'])
54
+ print(f\"{m['name']} — {done}/{total} issues complete\")
55
+ else:
56
+ print('No active milestone')
57
+ " 2>/dev/null || echo "Unknown")
58
+ fi
59
+
60
+ # Active issues
61
+ ACTIVE_ISSUES=$(ls ${MGW_DIR}/active/*.json 2>/dev/null | wc -l)
62
+
63
+ # Recent PRs
64
+ RECENT_PRS=$(gh pr list --limit 5 --json number,title,state --jq '.[] | "#\(.number) \(.title) [\(.state)]"' 2>/dev/null || echo "None")
65
+ ```
66
+ </step>
67
+
68
+ <step name="assemble_context">
69
+ **Assemble project context from GitHub:**
70
+
71
+ ```bash
72
+ # Vision/project description
73
+ VISION=$(node -e "
74
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
75
+ ic.buildGSDPromptContext({ includeVision: true })
76
+ .then(ctx => process.stdout.write(ctx));
77
+ " 2>/dev/null || echo "")
78
+
79
+ # Open milestones with issue counts
80
+ MILESTONES=$(gh api repos/${REPO}/milestones --jq '.[] | "- \(.title): \(.open_issues) open, \(.closed_issues) closed"' 2>/dev/null || echo "No milestones")
81
+ ```
82
+ </step>
83
+
84
+ <step name="generate_handoff">
85
+ **Generate handoff briefing:**
86
+
87
+ ```
88
+ Task(
89
+ prompt="
90
+ Generate a developer onboarding briefing for ${DEVELOPER_NAME} joining project ${PROJECT_NAME}.
91
+
92
+ <project_context>
93
+ Repository: ${REPO}
94
+ Active Milestone: ${MILESTONE_INFO}
95
+ Active Issues in Pipeline: ${ACTIVE_ISSUES}
96
+ Recent PRs:
97
+ ${RECENT_PRS}
98
+
99
+ Open Milestones:
100
+ ${MILESTONES}
101
+ </project_context>
102
+
103
+ <vision_context>
104
+ ${VISION}
105
+ </vision_context>
106
+
107
+ <instructions>
108
+ Create a structured handoff document with these sections:
109
+
110
+ ## Project Overview
111
+ - What the project is and its current state
112
+ - Key architectural decisions (from vision context)
113
+
114
+ ## Current Milestone
115
+ - What's being built now
116
+ - Progress status
117
+ - Key deliverables remaining
118
+
119
+ ## Getting Started
120
+ - How to set up the development environment
121
+ - Key commands: /mgw:status, /mgw:context, /mgw:next, /mgw:issue
122
+ - How context sharing works (structured comments on GitHub issues)
123
+
124
+ ## Active Work
125
+ - Issues currently in the pipeline
126
+ - Recent PRs to review
127
+
128
+ ## Key Conventions
129
+ - How MGW orchestrates work (issues → triage → plan → execute → PR)
130
+ - How to read structured comments (<!-- mgw:type=... --> headers)
131
+ - How to use /mgw:context <issue> to see what agents see
132
+
133
+ Keep it concise and actionable. This is a working document, not documentation.
134
+ </instructions>
135
+ ",
136
+ subagent_type="general-purpose",
137
+ description="Generate handoff for ${DEVELOPER_NAME}"
138
+ )
139
+ ```
140
+ </step>
141
+
142
+ <step name="display">
143
+ **Display handoff briefing:**
144
+
145
+ ```
146
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
147
+ MGW ► HANDOFF BRIEFING
148
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
149
+
150
+ ${HANDOFF_DOCUMENT}
151
+
152
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
153
+ Tip: Share this output or post it as a GitHub Discussion.
154
+ → /mgw:context <issue> — See context for a specific issue
155
+ → /mgw:status — Current project dashboard
156
+ → /mgw:next — Find next unblocked issue
157
+ ```
158
+ </step>
159
+
160
+ </process>
161
+
162
+ <success_criteria>
163
+ - [ ] Developer name parsed (or defaulted)
164
+ - [ ] Project state gathered from .mgw/ and GitHub
165
+ - [ ] Vision context assembled via buildGSDPromptContext()
166
+ - [ ] Handoff document generated by task agent
167
+ - [ ] Briefing displayed to user
168
+ - [ ] No state modified
169
+ </success_criteria>
package/commands/issue.md CHANGED
@@ -113,6 +113,48 @@ Gather GSD project history for context (if available):
113
113
  HISTORY=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs history-digest 2>/dev/null || echo "")
114
114
  ```
115
115
 
116
+ **Gather milestone context for top-down triage (if available):**
117
+
118
+ Primary source: GitHub issue comments (works on any machine):
119
+ ```bash
120
+ MILESTONE_CONTEXT=$(node -e "
121
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
122
+ ic.safeContext({ issueNumber: ${ISSUE_NUMBER}, includeVision: true, includePriorSummaries: true })
123
+ .then(ctx => process.stdout.write(ctx));
124
+ " 2>/dev/null || echo "")
125
+ ```
126
+
127
+ Fallback: local files (backward compat for single-machine workflows):
128
+ ```bash
129
+ if [ -z "$MILESTONE_CONTEXT" ] && [ -f "${REPO_ROOT}/.mgw/project.json" ]; then
130
+ MILESTONE_CONTEXT=$(python3 -c "
131
+ import json
132
+ try:
133
+ p = json.load(open('${REPO_ROOT}/.mgw/project.json'))
134
+ for m in p.get('milestones', []):
135
+ for i in m.get('issues', []):
136
+ if i.get('github_number') == ${ISSUE_NUMBER}:
137
+ parts = []
138
+ parts.append(f\"Milestone: {m['name']}\")
139
+ parts.append(f\"Phase {i['phase_number']}: {i['phase_name']}\")
140
+ parts.append(f\"GSD Route: {i.get('gsd_route', 'unknown')}\")
141
+ completed = [x for x in m['issues'] if x.get('pipeline_stage') == 'done']
142
+ if completed:
143
+ parts.append(f\"Completed in milestone: {len(completed)}/{len(m['issues'])} issues\")
144
+ parts.append('Delivered: ' + ', '.join(f\"Phase {x['phase_number']}: {x['phase_name']}\" for x in completed))
145
+ print('\n'.join(parts))
146
+ break
147
+ except Exception as e:
148
+ pass
149
+ " 2>/dev/null || echo "")
150
+ fi
151
+
152
+ ROADMAP_CONTEXT=""
153
+ if [ -f ".planning/ROADMAP.md" ]; then
154
+ ROADMAP_CONTEXT=$(head -c 2000 .planning/ROADMAP.md)
155
+ fi
156
+ ```
157
+
116
158
  Build analysis prompt from issue data and spawn:
117
159
 
118
160
  ```
@@ -136,6 +178,14 @@ Comments: ${comments_summary}
136
178
  ${HISTORY}
137
179
  </project_history>
138
180
 
181
+ <milestone_context>
182
+ ${MILESTONE_CONTEXT}
183
+ </milestone_context>
184
+
185
+ <roadmap_context>
186
+ ${ROADMAP_CONTEXT}
187
+ </roadmap_context>
188
+
139
189
  <analysis_dimensions>
140
190
 
141
191
  1. **Scope:** Search the codebase for files and systems related to this issue.
@@ -317,6 +367,18 @@ Post comment and apply label:
317
367
  ```bash
318
368
  remove_mgw_labels_and_apply ${ISSUE_NUMBER} "mgw:triaged"
319
369
  ```
370
+
371
+ **Post structured metadata comment (non-blocking):**
372
+
373
+ In addition to the human-readable triage comment above, post a machine-readable
374
+ structured comment so other machines can read triage context from GitHub:
375
+ ```bash
376
+ node -e "
377
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
378
+ ic.postPlanningComment(${ISSUE_NUMBER}, 'triage', TRIAGE_REPORT, {})
379
+ .catch(() => {});
380
+ " 2>/dev/null || true
381
+ ```
320
382
  </step>
321
383
 
322
384
  <step name="present_report">
@@ -881,7 +881,39 @@ Milestone: ${MILESTONE_NAME}
881
881
  fi
882
882
  ```
883
883
 
884
- 4. Advance active milestone pointer in project.json:
884
+ 4. Update Project README with current milestone progress (non-blocking):
885
+ ```bash
886
+ node -e "
887
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
888
+ ic.updateProjectReadme()
889
+ .then(ok => { if (ok) console.log(' Project README updated'); })
890
+ .catch(() => {});
891
+ " 2>/dev/null || true
892
+ ```
893
+
894
+ 5. Post Status Update to Projects v2 board (non-blocking):
895
+ ```bash
896
+ BOARD_NODE_ID=$(python3 -c "
897
+ import json
898
+ try:
899
+ p = json.load(open('${MGW_DIR}/project.json'))
900
+ print(p.get('project', {}).get('project_board', {}).get('node_id', ''))
901
+ except: print('')
902
+ " 2>/dev/null || echo "")
903
+
904
+ if [ -n "$BOARD_NODE_ID" ]; then
905
+ MILESTONE_SUMMARY="Milestone ${MILESTONE_NUM} (${MILESTONE_NAME}) complete: ${TOTAL_ISSUES} issues, ${#COMPLETED_ISSUES[@]} PRs created"
906
+ gh api graphql -f query='mutation($projectId: ID!, $body: String!) {
907
+ createProjectV2StatusUpdate(input: {
908
+ projectId: $projectId
909
+ body: $body
910
+ status: ON_TRACK
911
+ }) { statusUpdate { id } }
912
+ }' -f projectId="$BOARD_NODE_ID" -f body="$MILESTONE_SUMMARY" 2>/dev/null || true
913
+ fi
914
+ ```
915
+
916
+ 6. Advance active milestone pointer in project.json:
885
917
  ```bash
886
918
  node -e "
887
919
  const { loadProjectState, resolveActiveMilestoneIndex, writeProjectState } = require('./lib/state.cjs');
@@ -904,7 +936,7 @@ writeProjectState(state);
904
936
  "
905
937
  ```
906
938
 
907
- 5. Milestone mapping verification:
939
+ 7. Milestone mapping verification:
908
940
 
909
941
  After advancing to the next milestone, check its GSD linkage using `getGsdState()`
910
942
  from `lib/gsd-adapter.cjs` to read current GSD execution state (.planning/STATE.md
@@ -995,7 +1027,7 @@ else:
995
1027
  esac
996
1028
  ```
997
1029
 
998
- 6. Display completion banner:
1030
+ 8. Display completion banner:
999
1031
  ```
1000
1032
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1001
1033
  MGW ► MILESTONE ${MILESTONE_NUM} COMPLETE ✓
@@ -1024,7 +1056,7 @@ Draft release created: ${RELEASE_TAG}
1024
1056
  ───────────────────────────────────────────────────────────────
1025
1057
  ```
1026
1058
 
1027
- 7. Check if next milestone exists and offer auto-advance (only if no failures in current).
1059
+ 9. Check if next milestone exists and offer auto-advance (only if no failures in current).
1028
1060
 
1029
1061
  **If some issues failed:**
1030
1062
 
@@ -1127,7 +1159,7 @@ Milestone NOT closed. Re-run after resolving remaining failures:
1127
1159
  /mgw:milestone ${MILESTONE_NUM}
1128
1160
  ```
1129
1161
 
1130
- 8. Post final results table as GitHub comment on the first issue in the milestone:
1162
+ 10. Post final results table as GitHub comment on the first issue in the milestone:
1131
1163
  ```bash
1132
1164
  gh issue comment ${FIRST_ISSUE_NUMBER} --body "$FINAL_RESULTS_COMMENT"
1133
1165
  ```
@@ -180,6 +180,25 @@ fi
180
180
  @workflows/create-github-structure.md
181
181
  </step>
182
182
 
183
+ <step name="populate_project_readme">
184
+ **Populate Project README on GitHub Projects v2 board (non-blocking):**
185
+
186
+ After GitHub structure creation, if a board is configured, populate the Project README
187
+ with project vision and milestone overview. This gives developers a landing page
188
+ when they open the board. Uses the shared `updateProjectReadme()` function from
189
+ `lib/issue-context.cjs` — the same function called by `mgw:milestone` and `mgw:sync --full`
190
+ to keep the README current.
191
+
192
+ ```bash
193
+ node -e "
194
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
195
+ ic.updateProjectReadme()
196
+ .then(ok => { if (ok) console.log('Project README populated on board'); })
197
+ .catch(() => {});
198
+ " 2>/dev/null || true
199
+ ```
200
+ </step>
201
+
183
202
  </process>
184
203
 
185
204
  <success_criteria>
@@ -60,12 +60,30 @@ QUICK_DIR=".planning/quick/${next_num}-${slug}"
60
60
  mkdir -p "$QUICK_DIR"
61
61
  ```
62
62
 
63
- 3. **Spawn planner (task agent):**
63
+ 3. **Assemble MGW context and spawn planner (task agent):**
64
+
65
+ Assemble multi-machine context from GitHub issue comments before spawning:
66
+ ```bash
67
+ MGW_CONTEXT=$(node -e "
68
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
69
+ ic.buildGSDPromptContext({
70
+ milestone: ${MILESTONE_NUM},
71
+ phase: ${PHASE_NUMBER},
72
+ issueNumber: ${ISSUE_NUMBER},
73
+ includeVision: true,
74
+ includePriorSummaries: true,
75
+ includeCurrentPlan: false
76
+ }).then(ctx => process.stdout.write(ctx));
77
+ " 2>/dev/null || echo "")
78
+ ```
79
+
64
80
  ```
65
81
  Task(
66
82
  prompt="
67
83
  <planning_context>
68
84
 
85
+ ${MGW_CONTEXT}
86
+
69
87
  **Mode:** ${FULL_MODE ? 'quick-full' : 'quick'}
70
88
  **Directory:** ${QUICK_DIR}
71
89
  **Description:** ${TASK_DESCRIPTION}
@@ -109,7 +127,21 @@ Return: ## PLANNING COMPLETE with plan path
109
127
  )
110
128
  ```
111
129
 
112
- 4. **Verify plan exists** at `${QUICK_DIR}/${next_num}-PLAN.md`
130
+ 4. **Publish plan comment (non-blocking):**
131
+ ```bash
132
+ PLAN_FILE="${QUICK_DIR}/${next_num}-PLAN.md"
133
+ if [ -f "$PLAN_FILE" ]; then
134
+ node -e "
135
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
136
+ const fs = require('fs');
137
+ const content = fs.readFileSync('${PLAN_FILE}', 'utf-8');
138
+ ic.postPlanningComment(${ISSUE_NUMBER}, 'plan', content, { phase: ${next_num}, milestone: ${MILESTONE_NUM} })
139
+ .catch(e => console.error('WARNING: Failed to post plan comment:', e.message));
140
+ " 2>/dev/null || true
141
+ fi
142
+ ```
143
+
144
+ 5. **Verify plan exists** at `${QUICK_DIR}/${next_num}-PLAN.md`
113
145
 
114
146
  5. **Pre-flight plan structure check (gsd-tools):**
115
147
  ```bash
@@ -187,7 +219,21 @@ Execute quick task ${next_num}.
187
219
  )
188
220
  ```
189
221
 
190
- 8. **Verify summary (gsd-tools):**
222
+ 8. **Publish summary comment (non-blocking):**
223
+ ```bash
224
+ SUMMARY_FILE="${QUICK_DIR}/${next_num}-SUMMARY.md"
225
+ if [ -f "$SUMMARY_FILE" ]; then
226
+ node -e "
227
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
228
+ const fs = require('fs');
229
+ const content = fs.readFileSync('${SUMMARY_FILE}', 'utf-8');
230
+ ic.postPlanningComment(${ISSUE_NUMBER}, 'summary', content, { phase: ${next_num}, milestone: ${MILESTONE_NUM} })
231
+ .catch(e => console.error('WARNING: Failed to post summary comment:', e.message));
232
+ " 2>/dev/null || true
233
+ fi
234
+ ```
235
+
236
+ 9. **Verify summary (gsd-tools):**
191
237
  ```bash
192
238
  VERIFY_RESULT=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs verify-summary "${QUICK_DIR}/${next_num}-SUMMARY.md")
193
239
  ```
@@ -214,7 +260,21 @@ Check must_haves against actual codebase. Create VERIFICATION.md at ${QUICK_DIR}
214
260
  )
215
261
  ```
216
262
 
217
- 10. **Post-execution artifact verification (non-blocking):**
263
+ 10. **Publish verification comment (non-blocking, --full only):**
264
+ ```bash
265
+ VERIFICATION_FILE="${QUICK_DIR}/${next_num}-VERIFICATION.md"
266
+ if [ -f "$VERIFICATION_FILE" ]; then
267
+ node -e "
268
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
269
+ const fs = require('fs');
270
+ const content = fs.readFileSync('${VERIFICATION_FILE}', 'utf-8');
271
+ ic.postPlanningComment(${ISSUE_NUMBER}, 'verification', content, { phase: ${next_num}, milestone: ${MILESTONE_NUM} })
272
+ .catch(e => console.error('WARNING: Failed to post verification comment:', e.message));
273
+ " 2>/dev/null || true
274
+ fi
275
+ ```
276
+
277
+ 11. **Post-execution artifact verification (non-blocking):**
218
278
  ```bash
219
279
  ARTIFACT_CHECK=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs verify artifacts "${QUICK_DIR}/${next_num}-PLAN.md" 2>/dev/null || echo '{"passed":true}')
220
280
  KEYLINK_CHECK=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs verify key-links "${QUICK_DIR}/${next_num}-PLAN.md" 2>/dev/null || echo '{"passed":true}')
@@ -394,6 +454,31 @@ If proceed: apply "mgw:approved" label and continue.
394
454
 
395
455
  Update pipeline_stage to "planning" (at `${REPO_ROOT}/.mgw/active/`).
396
456
 
457
+ **Verify ROADMAP.md was created:**
458
+ ```bash
459
+ if [ ! -f ".planning/ROADMAP.md" ]; then
460
+ echo "MGW ERROR: Roadmapper agent did not produce ROADMAP.md. Cannot proceed with milestone execution."
461
+ FAIL_TS=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs current-timestamp --raw 2>/dev/null || date -u +"%Y-%m-%dT%H:%M:%SZ")
462
+ gh issue comment ${ISSUE_NUMBER} --body "> **MGW** · \`pipeline-failed\` · ${FAIL_TS}
463
+ > Roadmapper agent did not produce ROADMAP.md. Pipeline cannot continue.
464
+ > Re-run with \`/mgw:run ${ISSUE_NUMBER}\` after investigating." 2>/dev/null || true
465
+ # Update pipeline_stage to failed (same pattern as post_execution_update dead_letter block)
466
+ node -e "
467
+ const fs = require('fs'), path = require('path');
468
+ const activeDir = path.join(process.cwd(), '.mgw', 'active');
469
+ const files = fs.readdirSync(activeDir);
470
+ const file = files.find(f => f.startsWith('${ISSUE_NUMBER}-') && f.endsWith('.json'));
471
+ if (file) {
472
+ const filePath = path.join(activeDir, file);
473
+ const state = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
474
+ state.pipeline_stage = 'failed';
475
+ fs.writeFileSync(filePath, JSON.stringify(state, null, 2));
476
+ }
477
+ " 2>/dev/null || true
478
+ exit 1
479
+ fi
480
+ ```
481
+
397
482
  2. **If resuming with pipeline_stage = "planning" and ROADMAP.md exists:**
398
483
  Discover phases from ROADMAP and run the full per-phase GSD lifecycle:
399
484
 
@@ -430,7 +515,23 @@ If proceed: apply "mgw:approved" label and continue.
430
515
  # Parse PHASE_INIT JSON for: planner_model, checker_model
431
516
  ```
432
517
 
433
- **b. Spawn planner agent (gsd:plan-phase):**
518
+ **b. Assemble MGW context and spawn planner agent (gsd:plan-phase):**
519
+
520
+ Assemble multi-machine context from GitHub issue comments before spawning:
521
+ ```bash
522
+ MGW_CONTEXT=$(node -e "
523
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
524
+ ic.buildGSDPromptContext({
525
+ milestone: ${MILESTONE_NUM},
526
+ phase: ${PHASE_NUMBER},
527
+ issueNumber: ${ISSUE_NUMBER},
528
+ includeVision: true,
529
+ includePriorSummaries: true,
530
+ includeCurrentPlan: false
531
+ }).then(ctx => process.stdout.write(ctx));
532
+ " 2>/dev/null || echo "")
533
+ ```
534
+
434
535
  ```
435
536
  Task(
436
537
  prompt="
@@ -441,6 +542,8 @@ If proceed: apply "mgw:approved" label and continue.
441
542
  - .planning/STATE.md (If exists -- project state)
442
543
  </files_to_read>
443
544
 
545
+ ${MGW_CONTEXT}
546
+
444
547
  You are the GSD planner. Plan phase ${PHASE_NUMBER}: ${PHASE_NAME}.
445
548
 
446
549
  Read and follow the plan-phase workflow:
@@ -462,6 +565,20 @@ If proceed: apply "mgw:approved" label and continue.
462
565
  )
463
566
  ```
464
567
 
568
+ **b2. Publish plan comment (non-blocking):**
569
+ ```bash
570
+ PLAN_FILES=$(ls ${phase_dir}/*-PLAN.md 2>/dev/null)
571
+ for PLAN_FILE in $PLAN_FILES; do
572
+ node -e "
573
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
574
+ const fs = require('fs');
575
+ const content = fs.readFileSync('${PLAN_FILE}', 'utf-8');
576
+ ic.postPlanningComment(${ISSUE_NUMBER}, 'plan', content, { phase: ${PHASE_NUMBER}, milestone: ${MILESTONE_NUM} })
577
+ .catch(e => console.error('WARNING: Failed to post plan comment:', e.message));
578
+ " 2>/dev/null || true
579
+ done
580
+ ```
581
+
465
582
  **c. Verify plans exist:**
466
583
  ```bash
467
584
  PLAN_COUNT=$(ls ${phase_dir}/*-PLAN.md 2>/dev/null | wc -l)
@@ -508,6 +625,20 @@ If proceed: apply "mgw:approved" label and continue.
508
625
  )
509
626
  ```
510
627
 
628
+ **d2. Publish summary comment (non-blocking):**
629
+ ```bash
630
+ SUMMARY_FILES=$(ls ${phase_dir}/*-SUMMARY.md 2>/dev/null)
631
+ for SUMMARY_FILE in $SUMMARY_FILES; do
632
+ node -e "
633
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
634
+ const fs = require('fs');
635
+ const content = fs.readFileSync('${SUMMARY_FILE}', 'utf-8');
636
+ ic.postPlanningComment(${ISSUE_NUMBER}, 'summary', content, { phase: ${PHASE_NUMBER}, milestone: ${MILESTONE_NUM} })
637
+ .catch(e => console.error('WARNING: Failed to post summary comment:', e.message));
638
+ " 2>/dev/null || true
639
+ done
640
+ ```
641
+
511
642
  **e. Spawn verifier agent (gsd:verify-phase):**
512
643
  ```
513
644
  Task(
@@ -536,6 +667,20 @@ If proceed: apply "mgw:approved" label and continue.
536
667
  )
537
668
  ```
538
669
 
670
+ **e2. Publish verification comment (non-blocking):**
671
+ ```bash
672
+ VERIFICATION_FILES=$(ls ${phase_dir}/*-VERIFICATION.md 2>/dev/null)
673
+ for VERIFICATION_FILE in $VERIFICATION_FILES; do
674
+ node -e "
675
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
676
+ const fs = require('fs');
677
+ const content = fs.readFileSync('${VERIFICATION_FILE}', 'utf-8');
678
+ ic.postPlanningComment(${ISSUE_NUMBER}, 'verification', content, { phase: ${PHASE_NUMBER}, milestone: ${MILESTONE_NUM} })
679
+ .catch(e => console.error('WARNING: Failed to post verification comment:', e.message));
680
+ " 2>/dev/null || true
681
+ done
682
+ ```
683
+
539
684
  **f. Post phase-complete comment directly (no sub-agent):**
540
685
  ```bash
541
686
  PHASE_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
@@ -22,6 +22,29 @@ CROSS_REFS=$(cat ${REPO_ROOT}/.mgw/cross-refs.json 2>/dev/null)
22
22
  # Progress table for PR details section
23
23
  PROGRESS_TABLE=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs progress table --raw 2>/dev/null || echo "")
24
24
 
25
+ **Verify execution evidence exists before creating PR:**
26
+ ```bash
27
+ SUMMARY_COUNT=$(ls ${gsd_artifacts_path}/*SUMMARY* 2>/dev/null | wc -l)
28
+ if [ "$SUMMARY_COUNT" -eq 0 ]; then
29
+ echo "MGW ERROR: No SUMMARY files found at ${gsd_artifacts_path}. Cannot create PR without execution evidence."
30
+ echo "This usually means the executor agent failed silently. Check the execution logs."
31
+ # Update pipeline_stage to "failed"
32
+ node -e "
33
+ const fs = require('fs'), path = require('path');
34
+ const activeDir = path.join(process.cwd(), '.mgw', 'active');
35
+ const files = fs.readdirSync(activeDir);
36
+ const file = files.find(f => f.startsWith('${ISSUE_NUMBER}-') && f.endsWith('.json'));
37
+ if (file) {
38
+ const filePath = path.join(activeDir, file);
39
+ const state = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
40
+ state.pipeline_stage = 'failed';
41
+ fs.writeFileSync(filePath, JSON.stringify(state, null, 2));
42
+ }
43
+ " 2>/dev/null || true
44
+ exit 1
45
+ fi
46
+ ```
47
+
25
48
  # Milestone/phase context for PR body
26
49
  MILESTONE_TITLE=""
27
50
  PHASE_INFO=""
@@ -71,6 +94,13 @@ p = json.load(open('${REPO_ROOT}/.mgw/project.json'))
71
94
  print(p.get('project', {}).get('project_board', {}).get('url', ''))
72
95
  " 2>/dev/null || echo "")
73
96
  fi
97
+
98
+ # Phase Context from GitHub issue comments (multi-developer context sharing)
99
+ PHASE_CONTEXT=$(node -e "
100
+ const ic = require('${REPO_ROOT}/lib/issue-context.cjs');
101
+ ic.assembleIssueContext(${ISSUE_NUMBER})
102
+ .then(ctx => process.stdout.write(ctx));
103
+ " 2>/dev/null || echo "")
74
104
  ```
75
105
 
76
106
  Read issue state for context.
@@ -122,6 +152,10 @@ ${COMMITS}
122
152
  ${CROSS_REFS}
123
153
  </cross_refs>
124
154
 
155
+ <phase_context>
156
+ ${PHASE_CONTEXT}
157
+ </phase_context>
158
+
125
159
  <instructions>
126
160
  1. Build PR title: short, prefixed with fix:/feat:/refactor: based on issue labels. Under 70 characters.
127
161
 
@@ -141,6 +175,14 @@ Closes #${ISSUE_NUMBER}
141
175
  ## Changes
142
176
  - File-level changes grouped by module (use key_files from summary_structured)
143
177
 
178
+ ## Phase Context
179
+ <details>
180
+ <summary>Planning & execution context from GitHub issue comments</summary>
181
+
182
+ ${PHASE_CONTEXT}
183
+ </details>
184
+ (Skip if PHASE_CONTEXT is empty)
185
+
144
186
  ## Test Plan
145
187
  - Verification checklist from VERIFICATION artifact
146
188