@agentic-sdlc/dispatch 0.2.9 → 0.3.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.
@@ -31,6 +31,7 @@ export function orchestrateStage(ctx) {
31
31
  const artifactPath = join(artifactsDir, stage.produces);
32
32
  if (!existsSync(artifactPath)) {
33
33
  console.error(`[dispatch] Artifact not found: ${artifactPath}`);
34
+ postIssueComment(repo, issueNumber, `**${stage.name}** — Agent did not produce \`${stage.produces}\`. Escalating.`);
34
35
  applyLabel(repo, issueNumber, "escalated", label);
35
36
  return { stage: stage.name, action: "no-artifact", nextLabel: "escalated" };
36
37
  }
@@ -50,7 +51,12 @@ export function orchestrateStage(ctx) {
50
51
  }
51
52
  function handleGateNone(ctx, stage, stageIndex) {
52
53
  const { issueNumber, repo, label, workflowConfig, artifactsDir } = ctx;
53
- // Commit artifact to current branch and push
54
+ const branchPattern = stage.branch_pattern;
55
+ if (branchPattern) {
56
+ // Stage with a branch pattern: push to branch and open/update draft PR
57
+ return handleBranchStage(ctx, stage, stageIndex);
58
+ }
59
+ // Simple stage (triage, plan): commit to main and advance
54
60
  try {
55
61
  execFileSync("git", ["add", artifactsDir]);
56
62
  execFileSync("git", ["commit", "-m", `chore: add ${stage.produces} for issue #${issueNumber}`]);
@@ -59,61 +65,95 @@ function handleGateNone(ctx, stage, stageIndex) {
59
65
  catch (err) {
60
66
  console.error(`[dispatch] Git commit/push failed for gate=none:`, err);
61
67
  }
62
- // Advance to next stage label
63
68
  const nextLabel = findNextStageLabel(workflowConfig.pipeline, stageIndex);
69
+ const artifactContent = readArtifactContent(artifactsDir, stage.produces);
70
+ postIssueComment(repo, issueNumber, `**${stage.name}** — Complete. Advancing to \`${nextLabel ?? "done"}\`.\n\n<details>\n<summary>${stage.produces}</summary>\n\n${artifactContent}\n</details>`);
64
71
  if (nextLabel) {
65
72
  applyLabel(repo, issueNumber, nextLabel, label);
66
73
  }
67
74
  return { stage: stage.name, action: "advanced", nextLabel };
68
75
  }
69
- function handleGatePrReview(ctx, stage, stageIndex) {
76
+ function handleBranchStage(ctx, stage, stageIndex) {
70
77
  const { issueNumber, repo, label, workflowConfig, artifactsDir } = ctx;
71
- const branchName = renderTemplate(stage.branch_pattern ?? `${stage.name}/issue-{{ issue.number }}`, issueNumber);
78
+ const branchName = renderTemplate(stage.branch_pattern, issueNumber);
72
79
  // Create or checkout branch
73
80
  try {
74
- execFileSync("git", ["checkout", "-b", branchName]);
81
+ execFileSync("git", ["checkout", "-b", branchName], { stdio: "pipe" });
75
82
  }
76
83
  catch {
77
- // Branch may already exist — try checking it out
78
84
  try {
79
- execFileSync("git", ["checkout", branchName]);
85
+ execFileSync("git", ["checkout", branchName], { stdio: "pipe" });
80
86
  }
81
87
  catch (err) {
82
88
  console.error(`[dispatch] Failed to checkout branch ${branchName}:`, err);
83
89
  }
84
90
  }
85
- // Commit artifacts
91
+ // Commit and push
86
92
  try {
87
93
  execFileSync("git", ["add", artifactsDir]);
88
- execFileSync("git", ["commit", "-m", `feat: add ${stage.produces} for issue #${issueNumber}`]);
94
+ execFileSync("git", ["commit", "-m", `feat: ${stage.name} for issue #${issueNumber}`], { stdio: "pipe" });
95
+ }
96
+ catch { /* may be nothing to commit */ }
97
+ try {
98
+ execFileSync("git", ["push", "-u", "--force-with-lease", "origin", branchName], { stdio: "pipe" });
89
99
  }
90
100
  catch (err) {
91
- console.error(`[dispatch] Git commit failed for pr-review gate:`, err);
101
+ console.error(`[dispatch] Git push failed:`, err);
102
+ }
103
+ // Open draft PR if none exists, or find existing
104
+ const prNumber = ensureDraftPr(repo, issueNumber, branchName, stage.name);
105
+ // Post build log as PR comment
106
+ const artifactContent = readArtifactContent(artifactsDir, stage.produces);
107
+ if (prNumber && artifactContent) {
108
+ postPrComment(repo, prNumber, `## Build Log\n\n${artifactContent}`);
109
+ }
110
+ // Advance to next stage
111
+ const nextLabel = findNextStageLabel(workflowConfig.pipeline, stageIndex);
112
+ postIssueComment(repo, issueNumber, `**${stage.name}** — Complete. Draft PR opened. Advancing to \`${nextLabel ?? "done"}\`.`);
113
+ if (nextLabel) {
114
+ applyLabel(repo, issueNumber, nextLabel, label);
115
+ }
116
+ return { stage: stage.name, action: "advanced", nextLabel };
117
+ }
118
+ function handleGatePrReview(ctx, stage, stageIndex) {
119
+ const { issueNumber, repo, label, workflowConfig, artifactsDir } = ctx;
120
+ const branchName = renderTemplate(stage.branch_pattern ?? `${stage.name}/issue-{{ issue.number }}`, issueNumber);
121
+ // Create or checkout branch
122
+ try {
123
+ execFileSync("git", ["checkout", "-b", branchName], { stdio: "pipe" });
124
+ }
125
+ catch {
126
+ try {
127
+ execFileSync("git", ["checkout", branchName], { stdio: "pipe" });
128
+ }
129
+ catch (err) {
130
+ console.error(`[dispatch] Failed to checkout branch ${branchName}:`, err);
131
+ }
92
132
  }
93
- // Push branch (force to handle re-runs where branch already exists)
133
+ // Commit and push
94
134
  try {
95
- execFileSync("git", ["push", "-u", "--force-with-lease", "origin", branchName]);
135
+ execFileSync("git", ["add", artifactsDir]);
136
+ execFileSync("git", ["commit", "-m", `feat: add ${stage.produces} for issue #${issueNumber}`], { stdio: "pipe" });
137
+ }
138
+ catch { /* may be nothing to commit */ }
139
+ try {
140
+ execFileSync("git", ["push", "-u", "--force-with-lease", "origin", branchName], { stdio: "pipe" });
96
141
  }
97
142
  catch (err) {
98
143
  console.error(`[dispatch] Git push failed:`, err);
99
144
  }
100
- // Open PR if one does not already exist
145
+ // Open PR (not draft this is for human review)
101
146
  let prCreated = false;
102
147
  try {
103
148
  const existing = execFileSync("gh", [
104
- "pr", "list",
105
- "--repo", repo,
106
- "--head", branchName,
107
- "--json", "number",
108
- ]).toString().trim();
149
+ "pr", "list", "--repo", repo, "--head", branchName, "--json", "number",
150
+ ], { stdio: "pipe" }).toString().trim();
109
151
  const prs = JSON.parse(existing || "[]");
110
152
  if (prs.length === 0) {
111
153
  execFileSync("gh", [
112
- "pr", "create",
113
- "--repo", repo,
114
- "--head", branchName,
154
+ "pr", "create", "--repo", repo, "--head", branchName,
115
155
  "--title", `[#${issueNumber}] ${stage.name}: ${stage.produces}`,
116
- "--body", `Automated PR for issue #${issueNumber} stage: ${stage.name}`,
156
+ "--body", `Automated PR for issue #${issueNumber}.\n\nReview and merge to advance the pipeline.\n\nCloses #${issueNumber}`,
117
157
  ]);
118
158
  prCreated = true;
119
159
  }
@@ -121,26 +161,35 @@ function handleGatePrReview(ctx, stage, stageIndex) {
121
161
  catch (err) {
122
162
  console.error(`[dispatch] PR creation failed:`, err);
123
163
  }
124
- // Find the "ready" label for this stage (convention: stage's own ready label)
125
164
  const readyLabel = findReadyLabel(workflowConfig.pipeline, stage.name);
126
165
  const nextLabel = readyLabel ?? findNextStageLabel(workflowConfig.pipeline, stageIndex);
166
+ const artifactContent = readArtifactContent(artifactsDir, stage.produces);
167
+ postIssueComment(repo, issueNumber, `**${stage.name}** — PR ready for review on \`${branchName}\`.\n\n<details>\n<summary>${stage.produces}</summary>\n\n${artifactContent}\n</details>`);
127
168
  if (nextLabel) {
128
169
  applyLabel(repo, issueNumber, nextLabel, label);
129
170
  }
130
- return {
131
- stage: stage.name,
132
- action: prCreated ? "opened-pr" : "advanced",
133
- nextLabel,
134
- };
171
+ return { stage: stage.name, action: prCreated ? "opened-pr" : "advanced", nextLabel };
135
172
  }
136
173
  function handleGateRetry(ctx, stage, stageIndex) {
137
174
  const { issueNumber, repo, label, workflowConfig, artifactsDir } = ctx;
138
- // Read verdict from artifact frontmatter
139
175
  const verdict = readVerdictFromArtifact(artifactsDir, stage.produces ?? "");
140
176
  const maxRetries = stage.max_retries ?? 3;
177
+ const artifactContent = readArtifactContent(artifactsDir, stage.produces);
178
+ // Find the impl PR to comment on
179
+ const implBranch = `impl/issue-${issueNumber}`;
180
+ const prNumber = findPrByBranch(repo, implBranch);
141
181
  if (verdict === "pass") {
142
- // Advance to next stage
182
+ // Post QA report on PR
183
+ if (prNumber) {
184
+ postPrComment(repo, prNumber, `## QA Report — PASS\n\n${artifactContent}`);
185
+ // Mark PR as ready for review (remove draft)
186
+ try {
187
+ execFileSync("gh", ["pr", "ready", String(prNumber), "--repo", repo], { stdio: "pipe" });
188
+ }
189
+ catch { /* may already be ready */ }
190
+ }
143
191
  const nextLabel = findNextStageLabel(workflowConfig.pipeline, stageIndex);
192
+ postIssueComment(repo, issueNumber, `**${stage.name}** — PASS. PR ready for human review.`);
144
193
  if (nextLabel) {
145
194
  applyLabel(repo, issueNumber, nextLabel, label);
146
195
  }
@@ -149,10 +198,18 @@ function handleGateRetry(ctx, stage, stageIndex) {
149
198
  // verdict is "fail" or unknown — check retry count
150
199
  const attemptCount = getAttemptCount(artifactsDir, stage.name);
151
200
  if (attemptCount >= maxRetries) {
201
+ if (prNumber) {
202
+ postPrComment(repo, prNumber, `## QA Report — ESCALATED (attempt ${attemptCount}/${maxRetries})\n\nMax retries exceeded. Human intervention required.\n\n${artifactContent}`);
203
+ }
204
+ postIssueComment(repo, issueNumber, `**${stage.name}** — ESCALATED after ${attemptCount} attempts. Human intervention required.`);
152
205
  applyLabel(repo, issueNumber, "escalated", label);
153
206
  return { stage: stage.name, action: "escalated", nextLabel: "escalated" };
154
207
  }
155
- // Apply retry label (needs-fix)
208
+ // Retry post failure on PR and issue
209
+ if (prNumber) {
210
+ postPrComment(repo, prNumber, `## QA Report — FAIL (attempt ${attemptCount}/${maxRetries})\n\nRetrying. Builder will fix the issues below.\n\n${artifactContent}`);
211
+ }
212
+ postIssueComment(repo, issueNumber, `**${stage.name}** — FAIL (attempt ${attemptCount}/${maxRetries}). Retrying.`);
156
213
  const retryLabel = findRetryLabel(workflowConfig.pipeline, stage.name);
157
214
  if (retryLabel) {
158
215
  applyLabel(repo, issueNumber, retryLabel, label);
@@ -170,17 +227,88 @@ function applyLabel(repo, issueNumber, addLabel, removeLabel) {
170
227
  "--repo", repo,
171
228
  "--add-label", addLabel,
172
229
  "--remove-label", removeLabel,
173
- ]);
230
+ ], { stdio: "pipe" });
174
231
  }
175
232
  catch (err) {
176
233
  console.error(`[dispatch] Label transition failed (add=${addLabel}, remove=${removeLabel}):`, err);
177
234
  }
178
235
  }
236
+ function postIssueComment(repo, issueNumber, body) {
237
+ try {
238
+ execFileSync("gh", [
239
+ "issue", "comment", String(issueNumber),
240
+ "--repo", repo,
241
+ "--body", body,
242
+ ], { stdio: "pipe" });
243
+ }
244
+ catch (err) {
245
+ console.error(`[dispatch] Failed to post issue comment:`, err);
246
+ }
247
+ }
248
+ function postPrComment(repo, prNumber, body) {
249
+ try {
250
+ execFileSync("gh", [
251
+ "pr", "comment", String(prNumber),
252
+ "--repo", repo,
253
+ "--body", body,
254
+ ], { stdio: "pipe" });
255
+ }
256
+ catch (err) {
257
+ console.error(`[dispatch] Failed to post PR comment:`, err);
258
+ }
259
+ }
260
+ function ensureDraftPr(repo, issueNumber, branchName, stageName) {
261
+ try {
262
+ const existing = execFileSync("gh", [
263
+ "pr", "list", "--repo", repo, "--head", branchName, "--json", "number",
264
+ ], { stdio: "pipe" }).toString().trim();
265
+ const prs = JSON.parse(existing || "[]");
266
+ if (prs.length > 0) {
267
+ return prs[0].number;
268
+ }
269
+ // Create draft PR
270
+ const output = execFileSync("gh", [
271
+ "pr", "create", "--repo", repo, "--head", branchName, "--draft",
272
+ "--title", `[#${issueNumber}] Implementation`,
273
+ "--body", `Automated implementation for issue #${issueNumber}.\n\nThis PR is a draft while the build/QA loop runs. It will be marked ready for review when QA passes.\n\nCloses #${issueNumber}`,
274
+ ], { stdio: "pipe" }).toString().trim();
275
+ // Extract PR number from output URL
276
+ const match = output.match(/\/pull\/(\d+)/);
277
+ return match ? parseInt(match[1], 10) : null;
278
+ }
279
+ catch (err) {
280
+ console.error(`[dispatch] Draft PR creation failed:`, err);
281
+ return null;
282
+ }
283
+ }
284
+ function findPrByBranch(repo, branchName) {
285
+ try {
286
+ const output = execFileSync("gh", [
287
+ "pr", "list", "--repo", repo, "--head", branchName, "--json", "number",
288
+ ], { stdio: "pipe" }).toString().trim();
289
+ const prs = JSON.parse(output || "[]");
290
+ return prs.length > 0 ? prs[0].number : null;
291
+ }
292
+ catch {
293
+ return null;
294
+ }
295
+ }
296
+ function readArtifactContent(artifactsDir, artifactName) {
297
+ if (!artifactName)
298
+ return "";
299
+ try {
300
+ const content = readFileSync(join(artifactsDir, artifactName), "utf-8");
301
+ const maxLen = 3000;
302
+ return content.length > maxLen ? content.slice(0, maxLen) + "\n\n_(truncated)_" : content;
303
+ }
304
+ catch {
305
+ return "";
306
+ }
307
+ }
179
308
  function findNextStageLabel(pipeline, currentStageIndex) {
180
309
  const nextStage = pipeline.stages[currentStageIndex + 1];
181
310
  if (!nextStage)
182
311
  return undefined;
183
- // Find the label that maps to the next stage's name
184
312
  for (const [lbl, stageName] of Object.entries(pipeline.labels)) {
185
313
  if (stageName === nextStage.name) {
186
314
  return lbl;
@@ -189,7 +317,6 @@ function findNextStageLabel(pipeline, currentStageIndex) {
189
317
  return undefined;
190
318
  }
191
319
  function findReadyLabel(pipeline, stageName) {
192
- // Convention: look for a label like "{stage}-ready" that maps to this stage
193
320
  for (const [lbl, mapped] of Object.entries(pipeline.labels)) {
194
321
  if (mapped === stageName && lbl.endsWith("-ready")) {
195
322
  return lbl;
@@ -197,10 +324,8 @@ function findReadyLabel(pipeline, stageName) {
197
324
  }
198
325
  return undefined;
199
326
  }
200
- function findRetryLabel(pipeline, stageName) {
201
- // Look for a label that triggers the preceding stage (for retry, we go back)
202
- // Convention: "needs-fix" maps to the build stage for retries
203
- for (const [lbl, mapped] of Object.entries(pipeline.labels)) {
327
+ function findRetryLabel(pipeline, _stageName) {
328
+ for (const [lbl] of Object.entries(pipeline.labels)) {
204
329
  if (lbl === "needs-fix" || lbl.includes("retry") || lbl.includes("fix")) {
205
330
  return lbl;
206
331
  }
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/orchestrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/orchestrator.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentic-sdlc/dispatch",
3
- "version": "0.2.9",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "CI-side dispatch and orchestration for the agentic SDLC harness",
6
6
  "repository": {
@@ -37,6 +37,7 @@ export function orchestrateStage(ctx: OrchestrationContext): OrchestrationResult
37
37
  const artifactPath = join(artifactsDir, stage.produces);
38
38
  if (!existsSync(artifactPath)) {
39
39
  console.error(`[dispatch] Artifact not found: ${artifactPath}`);
40
+ postIssueComment(repo, issueNumber, `**${stage.name}** — Agent did not produce \`${stage.produces}\`. Escalating.`);
40
41
  applyLabel(repo, issueNumber, "escalated", label);
41
42
  return { stage: stage.name, action: "no-artifact", nextLabel: "escalated" };
42
43
  }
@@ -62,8 +63,14 @@ function handleGateNone(
62
63
  stageIndex: number
63
64
  ): OrchestrationResult {
64
65
  const { issueNumber, repo, label, workflowConfig, artifactsDir } = ctx;
66
+ const branchPattern = stage.branch_pattern;
65
67
 
66
- // Commit artifact to current branch and push
68
+ if (branchPattern) {
69
+ // Stage with a branch pattern: push to branch and open/update draft PR
70
+ return handleBranchStage(ctx, stage, stageIndex);
71
+ }
72
+
73
+ // Simple stage (triage, plan): commit to main and advance
67
74
  try {
68
75
  execFileSync("git", ["add", artifactsDir]);
69
76
  execFileSync("git", ["commit", "-m", `chore: add ${stage.produces} for issue #${issueNumber}`]);
@@ -72,8 +79,10 @@ function handleGateNone(
72
79
  console.error(`[dispatch] Git commit/push failed for gate=none:`, err);
73
80
  }
74
81
 
75
- // Advance to next stage label
76
82
  const nextLabel = findNextStageLabel(workflowConfig.pipeline, stageIndex);
83
+ const artifactContent = readArtifactContent(artifactsDir, stage.produces);
84
+ postIssueComment(repo, issueNumber, `**${stage.name}** — Complete. Advancing to \`${nextLabel ?? "done"}\`.\n\n<details>\n<summary>${stage.produces}</summary>\n\n${artifactContent}\n</details>`);
85
+
77
86
  if (nextLabel) {
78
87
  applyLabel(repo, issueNumber, nextLabel, label);
79
88
  }
@@ -81,60 +90,101 @@ function handleGateNone(
81
90
  return { stage: stage.name, action: "advanced", nextLabel };
82
91
  }
83
92
 
84
- function handleGatePrReview(
93
+ function handleBranchStage(
85
94
  ctx: OrchestrationContext,
86
95
  stage: StageConfig,
87
96
  stageIndex: number
88
97
  ): OrchestrationResult {
89
98
  const { issueNumber, repo, label, workflowConfig, artifactsDir } = ctx;
90
-
91
- const branchName = renderTemplate(stage.branch_pattern ?? `${stage.name}/issue-{{ issue.number }}`, issueNumber);
99
+ const branchName = renderTemplate(stage.branch_pattern!, issueNumber);
92
100
 
93
101
  // Create or checkout branch
94
102
  try {
95
- execFileSync("git", ["checkout", "-b", branchName]);
103
+ execFileSync("git", ["checkout", "-b", branchName], { stdio: "pipe" });
96
104
  } catch {
97
- // Branch may already exist — try checking it out
98
105
  try {
99
- execFileSync("git", ["checkout", branchName]);
106
+ execFileSync("git", ["checkout", branchName], { stdio: "pipe" });
100
107
  } catch (err) {
101
108
  console.error(`[dispatch] Failed to checkout branch ${branchName}:`, err);
102
109
  }
103
110
  }
104
111
 
105
- // Commit artifacts
112
+ // Commit and push
106
113
  try {
107
114
  execFileSync("git", ["add", artifactsDir]);
108
- execFileSync("git", ["commit", "-m", `feat: add ${stage.produces} for issue #${issueNumber}`]);
115
+ execFileSync("git", ["commit", "-m", `feat: ${stage.name} for issue #${issueNumber}`], { stdio: "pipe" });
116
+ } catch { /* may be nothing to commit */ }
117
+
118
+ try {
119
+ execFileSync("git", ["push", "-u", "--force-with-lease", "origin", branchName], { stdio: "pipe" });
109
120
  } catch (err) {
110
- console.error(`[dispatch] Git commit failed for pr-review gate:`, err);
121
+ console.error(`[dispatch] Git push failed:`, err);
122
+ }
123
+
124
+ // Open draft PR if none exists, or find existing
125
+ const prNumber = ensureDraftPr(repo, issueNumber, branchName, stage.name);
126
+
127
+ // Post build log as PR comment
128
+ const artifactContent = readArtifactContent(artifactsDir, stage.produces);
129
+ if (prNumber && artifactContent) {
130
+ postPrComment(repo, prNumber, `## Build Log\n\n${artifactContent}`);
111
131
  }
112
132
 
113
- // Push branch (force to handle re-runs where branch already exists)
133
+ // Advance to next stage
134
+ const nextLabel = findNextStageLabel(workflowConfig.pipeline, stageIndex);
135
+ postIssueComment(repo, issueNumber, `**${stage.name}** — Complete. Draft PR opened. Advancing to \`${nextLabel ?? "done"}\`.`);
136
+
137
+ if (nextLabel) {
138
+ applyLabel(repo, issueNumber, nextLabel, label);
139
+ }
140
+
141
+ return { stage: stage.name, action: "advanced", nextLabel };
142
+ }
143
+
144
+ function handleGatePrReview(
145
+ ctx: OrchestrationContext,
146
+ stage: StageConfig,
147
+ stageIndex: number
148
+ ): OrchestrationResult {
149
+ const { issueNumber, repo, label, workflowConfig, artifactsDir } = ctx;
150
+ const branchName = renderTemplate(stage.branch_pattern ?? `${stage.name}/issue-{{ issue.number }}`, issueNumber);
151
+
152
+ // Create or checkout branch
153
+ try {
154
+ execFileSync("git", ["checkout", "-b", branchName], { stdio: "pipe" });
155
+ } catch {
156
+ try {
157
+ execFileSync("git", ["checkout", branchName], { stdio: "pipe" });
158
+ } catch (err) {
159
+ console.error(`[dispatch] Failed to checkout branch ${branchName}:`, err);
160
+ }
161
+ }
162
+
163
+ // Commit and push
114
164
  try {
115
- execFileSync("git", ["push", "-u", "--force-with-lease", "origin", branchName]);
165
+ execFileSync("git", ["add", artifactsDir]);
166
+ execFileSync("git", ["commit", "-m", `feat: add ${stage.produces} for issue #${issueNumber}`], { stdio: "pipe" });
167
+ } catch { /* may be nothing to commit */ }
168
+
169
+ try {
170
+ execFileSync("git", ["push", "-u", "--force-with-lease", "origin", branchName], { stdio: "pipe" });
116
171
  } catch (err) {
117
172
  console.error(`[dispatch] Git push failed:`, err);
118
173
  }
119
174
 
120
- // Open PR if one does not already exist
175
+ // Open PR (not draft this is for human review)
121
176
  let prCreated = false;
122
177
  try {
123
178
  const existing = execFileSync("gh", [
124
- "pr", "list",
125
- "--repo", repo,
126
- "--head", branchName,
127
- "--json", "number",
128
- ]).toString().trim();
179
+ "pr", "list", "--repo", repo, "--head", branchName, "--json", "number",
180
+ ], { stdio: "pipe" }).toString().trim();
129
181
 
130
182
  const prs = JSON.parse(existing || "[]");
131
183
  if (prs.length === 0) {
132
184
  execFileSync("gh", [
133
- "pr", "create",
134
- "--repo", repo,
135
- "--head", branchName,
185
+ "pr", "create", "--repo", repo, "--head", branchName,
136
186
  "--title", `[#${issueNumber}] ${stage.name}: ${stage.produces}`,
137
- "--body", `Automated PR for issue #${issueNumber} stage: ${stage.name}`,
187
+ "--body", `Automated PR for issue #${issueNumber}.\n\nReview and merge to advance the pipeline.\n\nCloses #${issueNumber}`,
138
188
  ]);
139
189
  prCreated = true;
140
190
  }
@@ -142,19 +192,17 @@ function handleGatePrReview(
142
192
  console.error(`[dispatch] PR creation failed:`, err);
143
193
  }
144
194
 
145
- // Find the "ready" label for this stage (convention: stage's own ready label)
146
195
  const readyLabel = findReadyLabel(workflowConfig.pipeline, stage.name);
147
196
  const nextLabel = readyLabel ?? findNextStageLabel(workflowConfig.pipeline, stageIndex);
148
197
 
198
+ const artifactContent = readArtifactContent(artifactsDir, stage.produces);
199
+ postIssueComment(repo, issueNumber, `**${stage.name}** — PR ready for review on \`${branchName}\`.\n\n<details>\n<summary>${stage.produces}</summary>\n\n${artifactContent}\n</details>`);
200
+
149
201
  if (nextLabel) {
150
202
  applyLabel(repo, issueNumber, nextLabel, label);
151
203
  }
152
204
 
153
- return {
154
- stage: stage.name,
155
- action: prCreated ? "opened-pr" : "advanced",
156
- nextLabel,
157
- };
205
+ return { stage: stage.name, action: prCreated ? "opened-pr" : "advanced", nextLabel };
158
206
  }
159
207
 
160
208
  function handleGateRetry(
@@ -164,13 +212,27 @@ function handleGateRetry(
164
212
  ): OrchestrationResult {
165
213
  const { issueNumber, repo, label, workflowConfig, artifactsDir } = ctx;
166
214
 
167
- // Read verdict from artifact frontmatter
168
215
  const verdict = readVerdictFromArtifact(artifactsDir, stage.produces ?? "");
169
216
  const maxRetries = stage.max_retries ?? 3;
217
+ const artifactContent = readArtifactContent(artifactsDir, stage.produces);
218
+
219
+ // Find the impl PR to comment on
220
+ const implBranch = `impl/issue-${issueNumber}`;
221
+ const prNumber = findPrByBranch(repo, implBranch);
170
222
 
171
223
  if (verdict === "pass") {
172
- // Advance to next stage
224
+ // Post QA report on PR
225
+ if (prNumber) {
226
+ postPrComment(repo, prNumber, `## QA Report — PASS\n\n${artifactContent}`);
227
+ // Mark PR as ready for review (remove draft)
228
+ try {
229
+ execFileSync("gh", ["pr", "ready", String(prNumber), "--repo", repo], { stdio: "pipe" });
230
+ } catch { /* may already be ready */ }
231
+ }
232
+
173
233
  const nextLabel = findNextStageLabel(workflowConfig.pipeline, stageIndex);
234
+ postIssueComment(repo, issueNumber, `**${stage.name}** — PASS. PR ready for human review.`);
235
+
174
236
  if (nextLabel) {
175
237
  applyLabel(repo, issueNumber, nextLabel, label);
176
238
  }
@@ -181,11 +243,20 @@ function handleGateRetry(
181
243
  const attemptCount = getAttemptCount(artifactsDir, stage.name);
182
244
 
183
245
  if (attemptCount >= maxRetries) {
246
+ if (prNumber) {
247
+ postPrComment(repo, prNumber, `## QA Report — ESCALATED (attempt ${attemptCount}/${maxRetries})\n\nMax retries exceeded. Human intervention required.\n\n${artifactContent}`);
248
+ }
249
+ postIssueComment(repo, issueNumber, `**${stage.name}** — ESCALATED after ${attemptCount} attempts. Human intervention required.`);
184
250
  applyLabel(repo, issueNumber, "escalated", label);
185
251
  return { stage: stage.name, action: "escalated", nextLabel: "escalated" };
186
252
  }
187
253
 
188
- // Apply retry label (needs-fix)
254
+ // Retry post failure on PR and issue
255
+ if (prNumber) {
256
+ postPrComment(repo, prNumber, `## QA Report — FAIL (attempt ${attemptCount}/${maxRetries})\n\nRetrying. Builder will fix the issues below.\n\n${artifactContent}`);
257
+ }
258
+ postIssueComment(repo, issueNumber, `**${stage.name}** — FAIL (attempt ${attemptCount}/${maxRetries}). Retrying.`);
259
+
189
260
  const retryLabel = findRetryLabel(workflowConfig.pipeline, stage.name);
190
261
  if (retryLabel) {
191
262
  applyLabel(repo, issueNumber, retryLabel, label);
@@ -207,12 +278,87 @@ function applyLabel(repo: string, issueNumber: number, addLabel: string, removeL
207
278
  "--repo", repo,
208
279
  "--add-label", addLabel,
209
280
  "--remove-label", removeLabel,
210
- ]);
281
+ ], { stdio: "pipe" });
211
282
  } catch (err) {
212
283
  console.error(`[dispatch] Label transition failed (add=${addLabel}, remove=${removeLabel}):`, err);
213
284
  }
214
285
  }
215
286
 
287
+ function postIssueComment(repo: string, issueNumber: number, body: string): void {
288
+ try {
289
+ execFileSync("gh", [
290
+ "issue", "comment", String(issueNumber),
291
+ "--repo", repo,
292
+ "--body", body,
293
+ ], { stdio: "pipe" });
294
+ } catch (err) {
295
+ console.error(`[dispatch] Failed to post issue comment:`, err);
296
+ }
297
+ }
298
+
299
+ function postPrComment(repo: string, prNumber: number, body: string): void {
300
+ try {
301
+ execFileSync("gh", [
302
+ "pr", "comment", String(prNumber),
303
+ "--repo", repo,
304
+ "--body", body,
305
+ ], { stdio: "pipe" });
306
+ } catch (err) {
307
+ console.error(`[dispatch] Failed to post PR comment:`, err);
308
+ }
309
+ }
310
+
311
+ function ensureDraftPr(repo: string, issueNumber: number, branchName: string, stageName: string): number | null {
312
+ try {
313
+ const existing = execFileSync("gh", [
314
+ "pr", "list", "--repo", repo, "--head", branchName, "--json", "number",
315
+ ], { stdio: "pipe" }).toString().trim();
316
+
317
+ const prs = JSON.parse(existing || "[]");
318
+ if (prs.length > 0) {
319
+ return prs[0].number;
320
+ }
321
+
322
+ // Create draft PR
323
+ const output = execFileSync("gh", [
324
+ "pr", "create", "--repo", repo, "--head", branchName, "--draft",
325
+ "--title", `[#${issueNumber}] Implementation`,
326
+ "--body", `Automated implementation for issue #${issueNumber}.\n\nThis PR is a draft while the build/QA loop runs. It will be marked ready for review when QA passes.\n\nCloses #${issueNumber}`,
327
+ ], { stdio: "pipe" }).toString().trim();
328
+
329
+ // Extract PR number from output URL
330
+ const match = output.match(/\/pull\/(\d+)/);
331
+ return match ? parseInt(match[1], 10) : null;
332
+ } catch (err) {
333
+ console.error(`[dispatch] Draft PR creation failed:`, err);
334
+ return null;
335
+ }
336
+ }
337
+
338
+ function findPrByBranch(repo: string, branchName: string): number | null {
339
+ try {
340
+ const output = execFileSync("gh", [
341
+ "pr", "list", "--repo", repo, "--head", branchName, "--json", "number",
342
+ ], { stdio: "pipe" }).toString().trim();
343
+
344
+ const prs = JSON.parse(output || "[]");
345
+ return prs.length > 0 ? prs[0].number : null;
346
+ } catch {
347
+ return null;
348
+ }
349
+ }
350
+
351
+ function readArtifactContent(artifactsDir: string, artifactName: string | undefined): string {
352
+ if (!artifactName) return "";
353
+ try {
354
+ const content = readFileSync(join(artifactsDir, artifactName), "utf-8");
355
+ const maxLen = 3000;
356
+ return content.length > maxLen ? content.slice(0, maxLen) + "\n\n_(truncated)_" : content;
357
+ } catch {
358
+ return "";
359
+ }
360
+ }
361
+
216
362
  function findNextStageLabel(
217
363
  pipeline: OrchestrationContext["workflowConfig"]["pipeline"],
218
364
  currentStageIndex: number
@@ -220,7 +366,6 @@ function findNextStageLabel(
220
366
  const nextStage = pipeline.stages[currentStageIndex + 1];
221
367
  if (!nextStage) return undefined;
222
368
 
223
- // Find the label that maps to the next stage's name
224
369
  for (const [lbl, stageName] of Object.entries(pipeline.labels)) {
225
370
  if (stageName === nextStage.name) {
226
371
  return lbl;
@@ -233,7 +378,6 @@ function findReadyLabel(
233
378
  pipeline: OrchestrationContext["workflowConfig"]["pipeline"],
234
379
  stageName: string
235
380
  ): string | undefined {
236
- // Convention: look for a label like "{stage}-ready" that maps to this stage
237
381
  for (const [lbl, mapped] of Object.entries(pipeline.labels)) {
238
382
  if (mapped === stageName && lbl.endsWith("-ready")) {
239
383
  return lbl;
@@ -244,11 +388,9 @@ function findReadyLabel(
244
388
 
245
389
  function findRetryLabel(
246
390
  pipeline: OrchestrationContext["workflowConfig"]["pipeline"],
247
- stageName: string
391
+ _stageName: string
248
392
  ): string | undefined {
249
- // Look for a label that triggers the preceding stage (for retry, we go back)
250
- // Convention: "needs-fix" maps to the build stage for retries
251
- for (const [lbl, mapped] of Object.entries(pipeline.labels)) {
393
+ for (const [lbl] of Object.entries(pipeline.labels)) {
252
394
  if (lbl === "needs-fix" || lbl.includes("retry") || lbl.includes("fix")) {
253
395
  return lbl;
254
396
  }