ci(bonk): fix concurrency cancellation, missing PR templates, long timeouts#769
Merged
ci(bonk): fix concurrency cancellation, missing PR templates, long timeouts#769
Conversation
…meouts
Three independent fixes to the four bonk-family workflows (/bonk, /ultrabonk,
/review, /ultrareview):
1. **Concurrency was cancelling unrelated runs.** All four workflows shared
the workflow-level group `bonk-<number>`. GitHub evaluates workflow-level
concurrency at queue time, before any `if:` filter, so every issue_comment
event in the repo enqueued all four workflows under the same group, and
simultaneous arrivals would evict in-flight runs. Moved concurrency to job
level (where it's evaluated only after `if:` passes) and made the group
per-workflow (`${{ github.workflow }}-<number>`). Spamming /bonk on the
same target now serializes; different actions on the same target can run
in parallel; non-matching events never enter the group at all.
Repro from #649: an /ultrabonk issue comment cancelled an in-flight /bonk
PR run because both were enqueued under `bonk-649` simultaneously and
GitHub's "at most one running and one pending" rule cancelled the rest.
2. **Auto-PR bodies were missing the template.** When /bonk or /ultrabonk
runs against an issue, opencode opens a PR via the Octokit API
(pulls.create), which doesn't auto-load the PR template the way the
GitHub web UI does. The model's free-form response was used as the PR
body verbatim, so pr-compliance.yml would close every auto-PR. Added a
custom prompt that tells the model to read .github/PULL_REQUEST_TEMPLATE.md
and structure its response as the PR body when code changes are pushed.
Conditional on "if your work results in code changes" so /bonk on an
existing PR (no new PR created) still flows through cleanly.
3. **Workflow timeouts dropped from 45 to 30 minutes.** Bounds the wall-clock
blast radius when a model session stalls (one stalled run last week burned
45 min of credit before the workflow timeout fired). 30 minutes is plenty
for a normal investigation; if the model genuinely needs longer, re-trigger.
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
docs | 69afee1 | Apr 25 2026, 09:46 AM |
|
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/blocks
@emdash-cms/cloudflare
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
18 tasks
ascorbic
added a commit
that referenced
this pull request
Apr 25, 2026
…#770) opencode has two permission defaults that ask for approval rather than allowing or denying outright: - external_directory (any tool touching paths outside the project cwd) - doom_loop (same tool call repeating 3x with identical input) CI runs have no TTY, so the prompts deadlock until the workflow timeout fires. PR #769 dropped that timeout from 45 to 30 min, but the underlying hang is still there. The triggering case last week was a bash redirect (`git show ... > /tmp/foo`) which counts as touching an external directory. Set both explicitly in OPENCODE_CONFIG_CONTENT for all four bonk-family workflows. external_directory is deny-by-default with /tmp/** and ~/** allowed (the only legitimate external paths a CI agent needs: scratch files and home-dir caches). doom_loop is deny so a stuck loop aborts the run instead of waiting forever. read defaults stay as opencode ships them (allow with .env files denied) since that baseline is sensible.
0aveRyan
pushed a commit
to 0aveRyan/emdash
that referenced
this pull request
Apr 27, 2026
…meouts (emdash-cms#769) Three independent fixes to the four bonk-family workflows (/bonk, /ultrabonk, /review, /ultrareview): 1. **Concurrency was cancelling unrelated runs.** All four workflows shared the workflow-level group `bonk-<number>`. GitHub evaluates workflow-level concurrency at queue time, before any `if:` filter, so every issue_comment event in the repo enqueued all four workflows under the same group, and simultaneous arrivals would evict in-flight runs. Moved concurrency to job level (where it's evaluated only after `if:` passes) and made the group per-workflow (`${{ github.workflow }}-<number>`). Spamming /bonk on the same target now serializes; different actions on the same target can run in parallel; non-matching events never enter the group at all. Repro from emdash-cms#649: an /ultrabonk issue comment cancelled an in-flight /bonk PR run because both were enqueued under `bonk-649` simultaneously and GitHub's "at most one running and one pending" rule cancelled the rest. 2. **Auto-PR bodies were missing the template.** When /bonk or /ultrabonk runs against an issue, opencode opens a PR via the Octokit API (pulls.create), which doesn't auto-load the PR template the way the GitHub web UI does. The model's free-form response was used as the PR body verbatim, so pr-compliance.yml would close every auto-PR. Added a custom prompt that tells the model to read .github/PULL_REQUEST_TEMPLATE.md and structure its response as the PR body when code changes are pushed. Conditional on "if your work results in code changes" so /bonk on an existing PR (no new PR created) still flows through cleanly. 3. **Workflow timeouts dropped from 45 to 30 minutes.** Bounds the wall-clock blast radius when a model session stalls (one stalled run last week burned 45 min of credit before the workflow timeout fired). 30 minutes is plenty for a normal investigation; if the model genuinely needs longer, re-trigger.
0aveRyan
pushed a commit
to 0aveRyan/emdash
that referenced
this pull request
Apr 27, 2026
…emdash-cms#770) opencode has two permission defaults that ask for approval rather than allowing or denying outright: - external_directory (any tool touching paths outside the project cwd) - doom_loop (same tool call repeating 3x with identical input) CI runs have no TTY, so the prompts deadlock until the workflow timeout fires. PR emdash-cms#769 dropped that timeout from 45 to 30 min, but the underlying hang is still there. The triggering case last week was a bash redirect (`git show ... > /tmp/foo`) which counts as touching an external directory. Set both explicitly in OPENCODE_CONFIG_CONTENT for all four bonk-family workflows. external_directory is deny-by-default with /tmp/** and ~/** allowed (the only legitimate external paths a CI agent needs: scratch files and home-dir caches). doom_loop is deny so a stuck loop aborts the run instead of waiting forever. read defaults stay as opencode ships them (allow with .env files denied) since that baseline is sensible.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Three independent fixes across the four bonk-family workflows (
/bonk,/ultrabonk,/review,/ultrareview).1. Concurrency was cancelling unrelated runs
All four workflows shared the workflow-level group
bonk-<number>. GitHub evaluates workflow-levelconcurrency:at queue time, before anyif:filter, so everyissue_commentevent in the repo enqueued all four workflows under the same group. With three or more arriving simultaneously (e.g./ultrabonkon issue 649 + bonk + review + ultrareview all firing on the same comment), GitHub's "at most one running and one pending" rule cancels the rest -- which is what cancelled an in-flight/bonkPR run last week.Moved
concurrency:to job level (where it's evaluated only afterif:passes, so non-matching events never enter the group) and made the group key per-workflow (${{ github.workflow }}-<number>). Behavior:/bonkon the same target serializes (queue, don't cancel)./bonkand/reviewon the same target run in parallel.2. Auto-PR bodies were missing the template
When
/bonkor/ultrabonkruns against an issue, opencode opens a PR via the Octokit API (pulls.create), which -- unlike the GitHub web UI -- doesn't auto-load.github/PULL_REQUEST_TEMPLATE.md. The model's free-form response was used as the PR body verbatim, so thepr-compliancecheck would close every auto-PR (e.g. #768).Added a custom prompt to
/bonkand/ultrabonkthat tells the model to read.github/PULL_REQUEST_TEMPLATE.mdand structure its response as the PR body when code changes are pushed. Conditional on "if your work results in code changes" so/bonkon an existing PR (no new PR created, just commits to the branch) flows through unchanged. Doesn't apply to/reviewand/ultrareviewsince they never auto-open PRs.3. Workflow timeouts dropped from 45 to 30 minutes
Bounds the wall-clock blast radius when a model session stalls. One stalled run earlier this week burned 45 minutes of credit before the workflow timeout fired with no useful output. 30 minutes is plenty for a normal investigation; if the model genuinely needs longer, re-trigger.
Type of change
Checklist
pnpm typecheckpasses (no TS files touched)pnpm lintpasses (verifiedpnpm --silent lint:json | jq '.diagnostics | length'returns0)pnpm testpasses (or targeted tests for my change) -- N/A, no production code changespnpm formathas been runpnpm locale:extracthas been run (if applicable) -- N/AAI-generated code disclosure
The YAML changes and the prompt content were drafted with Claude Opus during a debugging session that started by investigating why
/ultrabonkhad cancelled an in-flight/bonkrun. All edits reviewed and tested where possible.Screenshots / test output
pnpm --silent lint:json | jq '.diagnostics | length'→0pnpm format→ no changesconcurrency:evaluates at queue time, job-level evaluates afterif:.opencode/v1.4.6/packages/opencode/src/cli/cmd/github.ts-- thecreatePRcall usesoctoRest.rest.pulls.create({ ..., body })wherebody = ${response}\n\nCloses #${issueId}${footer}. No template loading anywhere.