The pattern (3 strikes)
Three team PRs have now merged (or nearly merged) without their Fixes #N line, breaking issue auto-close:
- protoAgent#2121 — first observed; issue needed manual closing; added "check the body" to the operator merge checklist
- protoAgent#2163 — dropped again; operator repaired the body pre-merge
- protoAgent#2166 — dropped even though the dispatch prompt carried "PR body carries
Fixes #2165" as an explicit numbered acceptance criterion
Strike 3 is the tell: this can't be fixed by prompting the coder harder. The PR body is generated boilerplate (## Summary\n<title> (bd-xxx)\nSee the diff for details.) — the coder's criterion compliance never reaches it.
Proposed fix — inject it mechanically at PR-open
The loop already knows the linkage: the feature description carries the source GitHub issue URL (the standard dispatch format leads with it). At the PR-opening step:
- Extract the first
https://github.com/<owner>/<repo>/issues/<n> from the feature's description (or, better, add an optional explicit source_issue field to board_create_feature and prefer it when set).
- If the issue's
<owner>/<repo> matches the PR's target repo, append \n\nFixes #<n> to the generated body. If it's a different repo (plugin PR referencing a protoAgent issue, etc.), append Refs <full-url> instead — cross-repo Fixes closes issues in the other repo only with write perms and is usually not what's wanted.
- If the coder's own body already contains a
Fixes/Closes #<n> for that issue, don't duplicate.
Keeps the coder out of the loop entirely for the one line that's pure metadata, and the operator merge-checklist item becomes a no-op instead of a recurring repair.
LOE ~2: one extraction helper + one body-assembly change + tests (same-repo, cross-repo, already-present, no-issue cases).
The pattern (3 strikes)
Three team PRs have now merged (or nearly merged) without their
Fixes #Nline, breaking issue auto-close:Fixes #2165" as an explicit numbered acceptance criterionStrike 3 is the tell: this can't be fixed by prompting the coder harder. The PR body is generated boilerplate (
## Summary\n<title> (bd-xxx)\nSee the diff for details.) — the coder's criterion compliance never reaches it.Proposed fix — inject it mechanically at PR-open
The loop already knows the linkage: the feature description carries the source GitHub issue URL (the standard dispatch format leads with it). At the PR-opening step:
https://github.com/<owner>/<repo>/issues/<n>from the feature's description (or, better, add an optional explicitsource_issuefield toboard_create_featureand prefer it when set).<owner>/<repo>matches the PR's target repo, append\n\nFixes #<n>to the generated body. If it's a different repo (plugin PR referencing a protoAgent issue, etc.), appendRefs <full-url>instead — cross-repoFixescloses issues in the other repo only with write perms and is usually not what's wanted.Fixes/Closes #<n>for that issue, don't duplicate.Keeps the coder out of the loop entirely for the one line that's pure metadata, and the operator merge-checklist item becomes a no-op instead of a recurring repair.
LOE ~2: one extraction helper + one body-assembly change + tests (same-repo, cross-repo, already-present, no-issue cases).