@yemi33/minions 0.1.1610 → 0.1.1612

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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.1610 (2026-04-28)
3
+ ## 0.1.1612 (2026-04-28)
4
4
 
5
5
  ### Features
6
6
  - hard-pin agent assignment when CC names a specific agent
@@ -9,6 +9,7 @@
9
9
  - replace runtime text tag with inline SVG logos
10
10
 
11
11
  ### Fixes
12
+ - suppress failure inbox notes
12
13
  - kill agents from engine tmp pid files
13
14
  - gate live completion banner on final process exit
14
15
  - wrap CC Model input so its label/hint survive runtime hydration
package/dashboard.js CHANGED
@@ -5201,6 +5201,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
5201
5201
  engine: { state: engine.state, pid: engine.pid },
5202
5202
  agents: agents.map(a => ({ id: a.id, name: a.name, status: a.status })),
5203
5203
  projects: PROJECTS.map(p => ({ name: p.name, reachable: fs.existsSync(p.localPath) })),
5204
+ minionsDir: MINIONS_DIR,
5204
5205
  uptime: process.uptime(),
5205
5206
  timestamp: new Date().toISOString()
5206
5207
  };
@@ -220,7 +220,7 @@ function completeDispatch(id, result = DISPATCH_RESULT.SUCCESS, reason = '', res
220
220
  ? `Non-retryable failure: ${effectiveReason}${classSuffix}`
221
221
  : (reason || `Failed after ${maxRetries} retries${classSuffix}`);
222
222
  lifecycle().updateWorkItemStatus(item.meta, WI_STATUS.FAILED, finalReason);
223
- // Alert: find items blocked by this failure and write inbox note
223
+ // Surface blocked dependents in logs without creating failure inbox noise.
224
224
  try {
225
225
  const config = getConfig();
226
226
  const failedId = item.meta.item.id;
@@ -229,16 +229,9 @@ function completeDispatch(id, result = DISPATCH_RESULT.SUCCESS, reason = '', res
229
229
  allItems.filter(w => w.status === WI_STATUS.PENDING && (w.depends_on || []).includes(failedId))
230
230
  .forEach(w => blockedItems.push(`- \`${w.id}\` — ${w.title}`));
231
231
 
232
- writeInboxAlert(`failed-${failedId}`,
233
- `# Work Item Failed \`${failedId}\`\n\n` +
234
- `**Item:** ${item.meta.item.title || failedId}\n` +
235
- `**Reason:** ${finalReason}\n\n` +
236
- (blockedItems.length > 0
237
- ? `**Blocked dependents (${blockedItems.length}):**\n${blockedItems.join('\n')}\n\n` +
238
- `These items cannot dispatch until \`${failedId}\` is fixed and reset to \`pending\`.\n`
239
- : `No downstream items are blocked.\n`)
240
- );
241
- } catch (e) { log('warn', 'write failure alert: ' + e.message); }
232
+ log('warn', `Work item ${failedId} failed: ${finalReason}` +
233
+ (blockedItems.length > 0 ? `; blocked dependents: ${blockedItems.map(line => line.replace(/^- `([^`]+)`.*/, '$1')).join(', ')}` : '; no downstream items blocked'));
234
+ } catch (e) { log('warn', 'summarize failure dependents: ' + e.message); }
242
235
  }
243
236
  }
244
237
 
@@ -69,19 +69,11 @@ function checkPlanCompletion(meta, config) {
69
69
  const doneItems = planItems.filter(w => DONE_STATUSES.has(w.status));
70
70
  const failedItems = planItems.filter(w => w.status === WI_STATUS.FAILED || w.status === WI_STATUS.CANCELLED);
71
71
 
72
- // Escalate failed/cancelled items to human — write inbox alert (deduped by slug)
73
72
  if (failedItems.length > 0) {
74
- const alertSlug = `plan-failure-escalation-${planFile.replace('.json', '')}`;
75
73
  const failDetails = failedItems.map(w =>
76
74
  `- \`${w.id}\`: ${w.title || 'Unknown'} — ${w.failReason || w.status}`
77
75
  ).join('\n');
78
- shared.writeToInbox('engine', alertSlug,
79
- `# Plan Items Failed: ${plan.plan_summary || planFile}\n\n` +
80
- `**${failedItems.length}** of ${planFeatureIds.size} item(s) failed or were cancelled:\n\n${failDetails}\n\n` +
81
- `The plan is completing with partial results (${doneItems.length} done, ${failedItems.length} failed).\n` +
82
- `Review failed items and re-dispatch manually if needed.\n`
83
- );
84
- log('warn', `Plan ${planFile}: ${failedItems.length} item(s) failed/cancelled — escalating to human: ${failedItems.map(w => w.id).join(', ')}`);
76
+ log('warn', `Plan ${planFile}: ${failedItems.length} item(s) failed/cancelled; completing with partial results (${doneItems.length} done, ${failedItems.length} failed):\n${failDetails}`);
85
77
  }
86
78
 
87
79
  // 1. Mark plan as completed
@@ -1127,8 +1119,7 @@ async function processPendingRebases(config) {
1127
1119
  if (entry.attempts < 3) {
1128
1120
  remaining.push(entry);
1129
1121
  } else {
1130
- shared.writeToInbox('engine', `rebase-fail-${pr.id}`,
1131
- `# Rebase Failed: ${pr.id}\n\nBranch \`${pr.branch}\` could not be rebased onto main after dependency ${entry.mergedItemId} merged.\n\nError: ${result.error}\n\nManual rebase may be needed.`);
1122
+ log('warn', `Rebase failed after retries for ${pr.id} on ${pr.branch}: ${result.error}`);
1132
1123
  }
1133
1124
  }
1134
1125
  }
@@ -1238,8 +1229,7 @@ async function handlePostMerge(pr, project, config, newStatus) {
1238
1229
  }
1239
1230
  const result = await rebaseBranchOntoMain(depPr, depProject, config);
1240
1231
  if (!result.success) {
1241
- shared.writeToInbox('engine', `rebase-fail-${depPr.id}`,
1242
- `# Rebase Failed: ${depPr.id}\n\nBranch \`${depPr.branch}\` could not be rebased onto main after dependency ${mergedItemId} merged.\n\nError: ${result.error}\n\nManual rebase may be needed.`);
1232
+ log('warn', `Rebase failed for ${depPr.id} on ${depPr.branch} after dependency ${mergedItemId} merged: ${result.error}`);
1243
1233
  }
1244
1234
  }
1245
1235
  }
@@ -1820,19 +1810,23 @@ async function runPostCompletionHooks(dispatchItem, agentId, code, stdout, confi
1820
1810
  };
1821
1811
  return runs;
1822
1812
  }, { defaultValue: {} });
1823
- // Write a completion note to inbox with back-references
1824
- const noteSlug = `sched-completion-${scheduleId}`;
1825
1813
  const status = effectiveSuccess ? 'succeeded' : 'failed';
1826
- const noteContent = `# Scheduled Task ${status}: ${meta.item.title || scheduleId}\n\n` +
1827
- `**Schedule:** \`${scheduleId}\`\n` +
1828
- `**Work Item:** \`${itemId}\`\n` +
1829
- `**Result:** ${status}\n` +
1830
- (resultSummary ? `\n## Summary\n${resultSummary}\n` : '');
1831
- shared.writeToInbox('engine', noteSlug, noteContent, null, {
1832
- sourceItem: itemId,
1833
- scheduleId,
1834
- });
1835
- log('info', `Scheduled task ${scheduleId} (${itemId}) → ${status}, back-reference written`);
1814
+ if (effectiveSuccess) {
1815
+ // Write a completion note to inbox with back-references only for successful scheduled runs.
1816
+ const noteSlug = `sched-completion-${scheduleId}`;
1817
+ const noteContent = `# Scheduled Task ${status}: ${meta.item.title || scheduleId}\n\n` +
1818
+ `**Schedule:** \`${scheduleId}\`\n` +
1819
+ `**Work Item:** \`${itemId}\`\n` +
1820
+ `**Result:** ${status}\n` +
1821
+ (resultSummary ? `\n## Summary\n${resultSummary}\n` : '');
1822
+ shared.writeToInbox('engine', noteSlug, noteContent, null, {
1823
+ sourceItem: itemId,
1824
+ scheduleId,
1825
+ });
1826
+ log('info', `Scheduled task ${scheduleId} (${itemId}) → ${status}, back-reference written`);
1827
+ } else {
1828
+ log('warn', `Scheduled task ${scheduleId} (${itemId}) → ${status}; inbox note suppressed`);
1829
+ }
1836
1830
  } catch (err) { log('warn', `Scheduled task back-reference: ${err.message}`); }
1837
1831
  }
1838
1832
 
package/engine.js CHANGED
@@ -1030,13 +1030,6 @@ async function spawnAgent(dispatchItem, config) {
1030
1030
  _trustCheckDone = true;
1031
1031
  updateAgentStatus(id, AGENT_STATUS.TRUST_BLOCKED, 'Agent appears to be waiting for trust approval');
1032
1032
  log('warn', `Trust gate detected for ${agentId} (${id}) — agent may be blocked on a permission prompt`);
1033
- writeInboxAlert(`trust-blocked-${id}`,
1034
- `# Trust Gate Blocked — \`${id}\`\n\n` +
1035
- `**Agent:** ${agentId}\n` +
1036
- `**Task:** ${dispatchItem.task || type}\n\n` +
1037
- `The agent appears to be blocked on a trust/permission prompt within 30s of spawn.\n` +
1038
- `Check the agent's live output and approve the trust gate manually.\n`
1039
- );
1040
1033
  }
1041
1034
  } else if (!_trustCheckDone) {
1042
1035
  _trustCheckDone = true; // past 30s window
@@ -1867,12 +1860,6 @@ function materializePlansAsWorkItems(config) {
1867
1860
  if (cycles.length > 0) {
1868
1861
  log('error', `Dependency cycle detected in plan ${file}: ${cycles.join(', ')} — skipping cyclic items`);
1869
1862
  cycles.forEach(c => cycleSet.add(c));
1870
- writeInboxAlert(`cycle-${path.basename(file, '.json')}`,
1871
- `# Dependency Cycle Detected — ${path.basename(file)}\n\n` +
1872
- `The following PRD items form a cycle and were **skipped** (will never be dispatched):\n\n` +
1873
- cycles.map(id => `- \`${id}\``).join('\n') + '\n\n' +
1874
- `Fix by removing or reordering the \`depends_on\` relationships in \`prd/${path.basename(file)}\`.\n`
1875
- );
1876
1863
  }
1877
1864
  }
1878
1865
 
@@ -2087,10 +2074,6 @@ async function discoverFromPrs(config, project) {
2087
2074
  const evalCycles = pr._reviewFixCycles || 0;
2088
2075
  const evalEscalated = evalCycles >= evalMax;
2089
2076
  if (evalEscalated && !pr._evalEscalated) {
2090
- writeInboxAlert(`eval-escalated-${pr.agent || 'unassigned'}-${prDisplayId}`,
2091
- `# Review Loop Escalation\n\n**PR ${pr.id}**: ${pr.title || ''} on branch \`${pr.branch || 'unknown'}\` has gone through **${evalCycles}** review→fix cycles without approval.\n\n` +
2092
- `Last review: ${pr.minionsReview?.note ? pr.minionsReview.note.slice(0, 200) : 'See PR thread'}\n\n` +
2093
- `Auto-dispatch of reviews and fixes has been suspended. Please review the PR manually.`);
2094
2077
  try {
2095
2078
  mutatePullRequests(projectPrPath(project), prs => {
2096
2079
  const target = shared.findPrRecord(prs, pr, project);
@@ -2258,12 +2241,6 @@ async function discoverFromPrs(config, project) {
2258
2241
  // Check if max retry cap reached — escalate to human instead of dispatching another fix
2259
2242
  if ((pr.buildFixAttempts || 0) >= maxBuildFix) {
2260
2243
  if (!pr.buildFixEscalated) {
2261
- writeInboxAlert(`build-fix-escalated-${pr.agent || 'unassigned'}-${prDisplayId}`,
2262
- `# Build Fix Escalation\n\n` +
2263
- `**PR ${pr.id}**: ${pr.title || ''} on branch \`${pr.branch || 'unknown'}\` has failed **${pr.buildFixAttempts}** consecutive auto-fix attempts.\n` +
2264
- `**Last failure:** ${pr.buildFailReason || 'Check CI pipeline for details'}\n\n` +
2265
- `Auto-fix dispatch has been suspended. Please investigate manually.\n`
2266
- );
2267
2244
  try {
2268
2245
  const prPath = projectPrPath(project);
2269
2246
  mutatePullRequests(prPath, prs => {
@@ -2305,19 +2282,8 @@ async function discoverFromPrs(config, project) {
2305
2282
  } catch (e) { log('warn', 'increment build fix attempts: ' + e.message); }
2306
2283
  }
2307
2284
 
2308
- // Notify the author agent about the build failure
2309
2285
  if (pr.agent && !pr._buildFailNotified) {
2310
- let alertBody = `# Build Failure Notification\n\n` +
2311
- `**Your PR ${pr.id}**: ${pr.title || ''} on branch \`${pr.branch || 'unknown'}\` has a failing build.\n` +
2312
- `**Reason:** ${pr.buildFailReason || 'Check CI pipeline for details'}\n\n`;
2313
- if (pr.buildErrorLog) {
2314
- // Include first 30 lines of error log in notification (full log in fix agent prompt)
2315
- const logPreview = pr.buildErrorLog.split('\n').slice(0, 30).join('\n');
2316
- alertBody += `**Error preview:**\n\`\`\`\n${logPreview}\n\`\`\`\n\n`;
2317
- }
2318
- alertBody += `A fix agent has been dispatched to address this. Review the fix when complete.\n`;
2319
- writeInboxAlert(`build-fail-${pr.agent}-${prDisplayId}`, alertBody);
2320
- // Mark notified to prevent duplicate alerts
2286
+ // Mark noted to prevent repeated processing; the fix dispatch and PR state carry the failure details.
2321
2287
  try {
2322
2288
  const prPath = projectPrPath(project);
2323
2289
  mutatePullRequests(prPath, prs => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1610",
3
+ "version": "0.1.1612",
4
4
  "description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
5
5
  "bin": {
6
6
  "minions": "bin/minions.js"
package/playbooks/ask.md CHANGED
@@ -28,7 +28,7 @@ The user has asked a question. Answer it thoroughly and clearly, writing your re
28
28
  - If the question is about "this" (ambiguous reference), check recent git history and agent activity for context
29
29
 
30
30
  ### 3. Write Your Answer
31
- Write your answer to `{{team_root}}/notes/inbox/{{agent_id}}-answer-{{task_id}}-{{date}}.md` with:
31
+ After you have successfully answered the question, write your answer to `{{team_root}}/notes/inbox/{{agent_id}}-answer-{{task_id}}-{{date}}.md` with:
32
32
 
33
33
  - **Question**: (restate briefly)
34
34
  - **Answer**: (clear, direct answer)
@@ -36,11 +36,13 @@ Write your answer to `{{team_root}}/notes/inbox/{{agent_id}}-answer-{{task_id}}-
36
36
 
37
37
  Keep it concise but complete. Write for a senior engineer who wants the real answer, not fluff.
38
38
 
39
+ If you cannot answer because the task is blocked, required context is missing, or research fails, do **not** write an inbox note. Report the blocker in your final response instead.
40
+
39
41
  ### 4. Status
40
42
 
41
43
  ## When to Stop
42
44
 
43
- Your task is complete once you have written your answer to the inbox file. Do NOT modify code, create PRs, or continue exploring beyond the question. Stop after writing.
45
+ Your task is complete once you have written the successful answer to the inbox file. Do NOT modify code, create PRs, or continue exploring beyond the question. Stop after writing.
44
46
 
45
47
  ## Rules
46
48
  - Do NOT modify any code unless the question explicitly asks you to.
@@ -73,7 +73,9 @@ If it is NOT a webapp (library, CLI tool, backend service without UI), skip this
73
73
 
74
74
  ## Output Format
75
75
 
76
- Write your findings to: `{{team_root}}/notes/inbox/{{agent_id}}-bt-{{pr_number}}-{{date}}.md`
76
+ Write your findings to `{{team_root}}/notes/inbox/{{agent_id}}-bt-{{pr_number}}-{{date}}.md` **only after a successful verification run**: the build passed, required tests passed, and any applicable local server is running or not applicable.
77
+
78
+ If the build fails, tests fail, dependency setup fails, or a required local server cannot start, do **not** write an inbox note. Follow the failure handling below and report the failure in your final response instead.
77
79
 
78
80
  Structure your report exactly like this:
79
81
 
@@ -85,16 +87,16 @@ Structure your report exactly like this:
85
87
  **Project:** {{project_name}}
86
88
 
87
89
  ### Build
88
- - Status: PASS / FAIL
90
+ - Status: PASS
89
91
  - Notes: (any warnings or issues)
90
92
 
91
93
  ### Tests
92
- - Status: PASS / FAIL / SKIPPED
93
- - Results: X passed, Y failed, Z skipped
94
- - Failed tests: (list if any)
94
+ - Status: PASS / SKIPPED
95
+ - Results: X passed, 0 failed, Z skipped
96
+ - Failed tests: none
95
97
 
96
98
  ### Local Server
97
- - Status: RUNNING / NOT_APPLICABLE / FAILED
99
+ - Status: RUNNING / NOT_APPLICABLE
98
100
  - URL: http://localhost:XXXX (if running)
99
101
  - Run Command: `cd <absolute-path> && <command>`
100
102
 
@@ -152,4 +154,4 @@ Leave the worktree in place at `{{project_path}}/../worktrees/bt-{{pr_number}}`
152
154
 
153
155
  ## When to Stop
154
156
 
155
- Your task is complete once you have: (1) built the project, (2) run tests, (3) started the app if applicable, and (4) written your findings to the inbox file. Stop after writing findings.
157
+ Your task is complete once you have: (1) built the project, (2) run tests, (3) started the app if applicable, and (4) written the success findings to the inbox file. If verification failed, stop after filing the failure work item when applicable and reporting the failure in your final response; do not write an inbox file.
@@ -31,7 +31,7 @@ Explore the codebase area specified in the task description. Your primary goal i
31
31
  - What conventions are followed?
32
32
 
33
33
  ### 4. Document Findings
34
- Write your findings to `{{team_root}}/notes/inbox/{{agent_id}}-explore-{{task_id}}-{{date}}.md` with these sections:
34
+ After the requested exploration succeeds, write your findings to `{{team_root}}/notes/inbox/{{agent_id}}-explore-{{task_id}}-{{date}}.md` with these sections:
35
35
  - **Area Explored**: what you looked at
36
36
  - **Architecture**: how it works
37
37
  - **Patterns**: conventions and patterns found
@@ -40,6 +40,8 @@ Write your findings to `{{team_root}}/notes/inbox/{{agent_id}}-explore-{{task_id
40
40
  - **Recommendations**: suggestions for the team
41
41
  - **Source References**: for EVERY finding, include the source — file paths, line numbers, PR URLs, API endpoints, config keys. Format: `(source: path/to/file.ts:42)` or `(source: PR-12345)`. This is critical — other agents and humans need to verify your findings.
42
42
 
43
+ If exploration is blocked or fails before you can produce sourced findings, do **not** write an inbox note. Report the blocker in your final response instead.
44
+
43
45
  ### 5. Create Deliverable (if the task asks for one)
44
46
  If the task asks you to write a design doc, architecture doc, or any durable artifact:
45
47
  1. Write the document in the current working directory (e.g., `docs/design-<topic>.md`)
@@ -64,7 +66,7 @@ Use subagents only for genuinely parallel, independent tasks. For reading files,
64
66
 
65
67
  ## When to Stop
66
68
 
67
- Your task is complete once you have written your findings to the inbox file. Do NOT continue reading additional files, exploring tangential areas, or producing extra analysis beyond what was asked. Write your findings and stop.
69
+ Your task is complete once you have written the successful findings to the inbox file. Do NOT continue reading additional files, exploring tangential areas, or producing extra analysis beyond what was asked. Write your findings and stop.
68
70
 
69
71
  ## Team Decisions
70
72
  {{notes_content}}
@@ -24,6 +24,7 @@ Your context window may be compacted or summarized mid-task by Claude's automati
24
24
  - Do NOT write to `agents/*/status.json` — the engine manages your status automatically.
25
25
  - Do NOT remove worktrees — the engine handles cleanup automatically.
26
26
  - Do NOT checkout branches in the main working tree — use worktrees or `git diff`/`git show`.
27
+ - Treat `notes/inbox/` writes as success artifacts only. If the task fails, is blocked, is cancelled, or ends partial, do **not** create an inbox note; report the failure in your final response, completion block, PR/work-item comment, or other task-specific failure channel instead.
27
28
  - Read `notes.md` for team rules and decisions before starting.
28
29
  - **Check team memory first, then look outside.** Before researching from scratch, check what the team already knows — in this order:
29
30
  1. `pinned.md` — critical context flagged by the human teammate (READ FIRST)
package/playbooks/test.md CHANGED
@@ -53,12 +53,14 @@ Example: `cd C:/Users/you/my-project && yarn dev`
53
53
 
54
54
  The agent process terminates after completion, so any dev server you start will die with it. The user needs this command to run it themselves.
55
55
 
56
- ## After Completion
56
+ ## After Successful Completion
57
57
 
58
- Write your findings to: `{{team_root}}/notes/inbox/{{agent_id}}-{{item_id}}-{{date}}.md`
58
+ Write your findings to `{{team_root}}/notes/inbox/{{agent_id}}-{{item_id}}-{{date}}.md` **only after a successful run**: all requested build/test/run steps completed, required checks passed, and any required PR was created.
59
+
60
+ If any requested build, test, run, or file-change step fails or is blocked, do **not** write an inbox note. Report the failure clearly in your final response, including the command, error summary, and any next action needed.
59
61
 
60
62
  Include:
61
- - Build status (pass/fail)
63
+ - Build status
62
64
  - Test results if applicable
63
65
  - Any errors or warnings
64
66
  - The run command (absolute paths, copy-pasteable from any terminal)
@@ -67,6 +69,6 @@ Include:
67
69
 
68
70
  ## When to Stop
69
71
 
70
- Your task is complete once you have run the tests, written findings to the inbox file, and (if the task involved file changes) created and submitted a PR. Stop after writing findings.
72
+ Your task is complete once you have run the tests, written the success findings to the inbox file, and (if the task involved file changes) created and submitted a PR. If the run failed or was blocked, stop after reporting the failure in your final response; do not write an inbox file.
71
73
 
72
74
  Do NOT remove worktrees — the engine handles cleanup automatically.
@@ -77,9 +77,13 @@ If the project has no runnable application, skip this step and note that in the
77
77
 
78
78
  ## Step 5: Write the Verification Report and Testing Guide
79
79
 
80
- Create the guide in TWO locations:
81
- 1. **Permanent location** (linked from dashboard): `{{team_root}}/prd/guides/verify-{{plan_slug}}.md`
82
- 2. **Inbox copy** (for team consolidation): `{{team_root}}/notes/inbox/verify-{{plan_slug}}.md`
80
+ Always create the permanent guide linked from the dashboard:
81
+ 1. **Permanent location**: `{{team_root}}/prd/guides/verify-{{plan_slug}}.md`
82
+
83
+ Create the inbox copy only after a successful verification run:
84
+ 2. **Inbox copy**: `{{team_root}}/notes/inbox/verify-{{plan_slug}}.md`
85
+
86
+ A successful verification run means every required project build/test passed or was legitimately not applicable, each runnable app was started and smoke-checked when required, and the required E2E PRs were created or updated. If verification is failed, blocked, or partial, do **not** create the inbox copy; record the details in the permanent guide and final response instead.
83
87
 
84
88
  **Be transparent.** The guide must clearly state what was built, what was tested, what passed, what failed, and what still needs human verification.
85
89
 
@@ -162,7 +166,7 @@ Use subagents only for genuinely parallel, independent build/test tasks on separ
162
166
 
163
167
  ## When to Stop
164
168
 
165
- Your task is complete once you have: (1) merged dependency branches, (2) built and tested, (3) written the verification report to both locations, and (4) created the E2E PR(s).
169
+ Your task is complete once you have: (1) merged dependency branches, (2) built and tested, (3) written the verification report to the permanent guide, (4) written the inbox copy only if verification succeeded, and (5) created the E2E PR(s).
166
170
 
167
171
  **IMPORTANT: Your final message MUST include the E2E PR URL(s) so the engine can track them.** Example final message:
168
172
 
@@ -45,9 +45,11 @@ Keep branch names lowercase, use hyphens, max 60 chars.
45
45
 
46
46
  Do NOT remove the worktree — the engine handles cleanup automatically.
47
47
 
48
- ## After Completion
48
+ ## After Successful Completion
49
49
 
50
- Write your findings to: `{{team_root}}/notes/inbox/{{agent_id}}-{{item_id}}-{{date}}.md`
50
+ Write your findings to `{{team_root}}/notes/inbox/{{agent_id}}-{{item_id}}-{{date}}.md` only after the work item succeeds: build/tests pass, the branch is pushed, and the PR is created.
51
+
52
+ If you stop because the task failed, is blocked, or is only partially complete, do **not** write an inbox note. Put the failure details in your final response and in any required PR/work-item comment instead.
51
53
 
52
54
  ## Handling Merge Conflicts
53
55
  If you encounter merge conflicts during push or PR creation: