Skip to content

fix(budget): exempt the Dependabot merge pipeline, count marked agent comments, and set the cap from measured PR peaks (#2224) - #2229

Merged
don-petry merged 11 commits into
mainfrom
claude/issue-2224-budget-mechanical-and-agent-events
Oct 11, 2026
Merged

don-petry merged 11 commits into
mainfrom
claude/issue-2224-budget-mechanical-and-agent-events

Conversation

@don-petry

@don-petry don-petry commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The per-PR automation budget (#926) decided who is "automated" from the login alone. This PR corrects that in the two places where the login is misleading, and resets the cap from measurement so that only extreme cases are blocked.

  • Dependabot pipeline. On a PR authored by dependabot[bot], events by dependabot[bot] and the dependabot-automerge App are flagged mechanical. They neither count nor reset.
  • Agent comments under a human login. A comment or review whose body carries one of our automation markers is flagged agent_marked. It counts, and it never resets the budget.
  • Cap. MAX_PR_AUTOMATION_CYCLES goes from 10 to 50. The runaway detector's RUNAWAY_MAX_CYCLES goes from 10 to 25.

gather_pr_automation_events sets both flags and compute_pr_automation_cycles honours them, so every consumer inherits the rule with no change of its own.

Closes #2224

Problem

Both problems showed on petry-projects/broodminder-data#176, a green Dependabot PR that sat unmerged for 36 hours.

  1. Three branch updates by dependabot-rebase took the count to 10 (each one adds the App's merge commit and its re-approval). pr-review then posted the exhaustion comment, added needs-human-review and disabled auto-merge. dependabot-rebase only merges PRs with auto-merge on, so the PR stalled. A branch update is caused by a push to main, not by an agent answering an agent.
  2. One minute after that escalation, dev-lead's hold notice, posted as don-petry, was read as a human interaction and took the count to 0. The next pr-review run went past the budget gate. A machine action reset the budget, which Runaway PR #860: agents self-triggering — add per-PR churn breaker, human-gated cap resets, and self-trigger guards #926 says must never happen.

Fixing the second problem makes agent activity visible to the breaker for the first time, and the cap of 10 was never set against it. The first version of this PR only stopped marked comments resetting the budget and kept the cap at 10. Measured over each PR's life, that alone would have raised the share of PRs escalated at least once from 4.8% to 16.6%. The maintainer decided on 2026-10-10 that marked comments should count and that the cap should be raised from actual metrics.

Calibration

332 agent-authored PRs: every PR created in the org from 2026-09-10 to 2026-10-10, plus every PR still open. The metric is the peak of the running count over the PR's life.

Rule Median p95 p99 Highest merged Highest
main 5 9 14 14 23
This PR 10 25 35 35 93
Cap, under this PR's rule PRs that reach it at least once
10 50.9%
20 8.4%
30 2.4%
40 0.3%
50 0.3% (1 of 332)

The issue has the full tables and the two limits of the measurement.

Risk

Medium. This is the #860 runaway guard, and every agent consults it before writing.

  • The cap is five times higher. A loop made only of bot-login events (the feat: implement issue #846 — [Phase 2] Cache the LSP index and enforce the 30s cold-start SLA with auto-skip #860 shape) now runs to 50 events before it is stopped, not 10. Measured against feat: implement issue #846 — [Phase 2] Cache the LSP index and enforce the 30s cold-start SLA with auto-skip #860 that is minutes, not hours.
  • In exchange, loops that run under the owner login are counted at all. Before this PR a dev-lead loop that posted marked comments reset the budget on every pass.
  • The mechanical flag needs both a PR authored by dependabot[bot] and an event login in PR_BUDGET_MECHANICAL_LOGINS. Any other bot on a Dependabot PR still counts.
  • An unreadable PR author exempts nothing. Malformed events are passed through unflagged.
  • The daily runaway report (detection only, it never touches a PR) reads the same count. Its open >48h with agent churn reason will now also name PRs whose only recent activity is marked agent comments.
  • gather_pr_automation_events makes one more API call per check (the PR author), and merges its three lists on stdin so a long history is not placed on jq's command line.

Not changed, and stated in the code and in docs/agentic-interaction-model.md: a commit, an unmarked comment, or a review with no marker in its body (which includes review-thread replies) that an agent makes under the owner login still reads as a human interaction and resets the budget. The calibration is measured with those resets in place. If that gap is closed later, the counts rise and the cap must be measured again.

Test plan

  • bats tests/test_pr_automation_budget.bats tests/test_pr_runaway_regression.bats tests/test_pr_runaway_detect.bats: 102 pass, 1 fail. The failure is pr_age_hours computes whole hours against an injected now, which fails the same way on unmodified main on macOS (BSD date).
  • New and changed cases: the ten fix: catch GitHub API 429s silently swallowed in review-one-pr.sh #176 events (count 2 on a Dependabot PR, 10 on anyone else's, checked against the cap of that day); an agent loop on a Dependabot PR still exhausts; pipeline events do not move the reset point; empty author and empty login list exempt nothing; a marked comment counts and does not reset; an agent looping under a human login with no bot login involved exhausts the budget exactly at the cap; an unmarked comment by the same login still resets; every marker family recognised and a human's own body not; the marker set stays in step with _MAINTAINER_GATE_AGENT_MARKERS; six cases through gather_pr_automation_events with a stubbed gh; the default cap is 50.
  • Existing tests edited, all for the cap: threshold cases in tests/test_pr_automation_budget.bats follow MAX_PR_AUTOMATION_CYCLES instead of the literal 10; the two storms in tests/test_pr_runaway_regression.bats are scaled to the cap in force (they were 12 events against a cap of 10) and still exhaust and escalate once; three fixtures that built exactly ten bot events (test_persona_pr_pregate.bats, test_dev_lead_retry_pr_escalation.bats, test_dev_lead_resume.bats) build fifty; the detector's threshold cases in tests/test_pr_runaway_detect.bats move from 10/11 to 25/26.
  • shellcheck --severity=warning -x on both libraries: clean.
  • The 58 bats files that touch these libraries or their callers, run on macOS: 1,652 pass, 72 fail, and every one of the 72 also fails on unmodified main on this machine (GNU/BSD date differences and similar). tests/dev-lead/unit/test_fix_reviews.bats hit my local 300-second limit before finishing. CI on Linux is the authoritative run.
  • Replay of fix: catch GitHub API 429s silently swallowed in review-one-pr.sh #176 with this library: count 2 at the moment it was escalated.

Rollback

Revert this PR. No state is written and no marker or label format changes. Without a revert: set MAX_PR_AUTOMATION_CYCLES in the calling workflow to change the cap, or PR_BUDGET_MECHANICAL_LOGINS to an empty value to switch off the Dependabot exemption.

Monitoring

  • A run that flags events logs one line per kind: [budget] PR #N in <repo>: K Dependabot-pipeline event(s) left out of the automation budget (#2224) and … marker-carrying agent event(s) under a human login counted as automated (#2224).
  • Success: no <!-- pr-automation-budget exhausted --> comment on a Dependabot PR; dependabot-rebase no longer logs Skipping — auto-merge not enabled for a green one; budget escalations on agent PRs stay rare.
  • Regression signal: more than an occasional budget escalation per week after this reaches pr-review/v1-stable and dev-lead/v139-stable (the library ships on both channels), or the daily runaway report listing many PRs for automated cycles.

Interaction contract

  • N/A — this PR does not add or change an agentic role.

🤖 Generated with Claude Code

…rked agent comments re-arming the budget (#2224)

The per-PR automation budget (#926) decided who is automated from the login
alone. That was wrong in two directions.

On a PR authored by dependabot[bot], Dependabot's own commit and the
dependabot-automerge App's update-branch merge commits and re-approvals were
counted as agent activity. A Dependabot PR waiting behind a busy main reached
the cap after three or four branch updates, was labelled needs-human-review and
lost auto-merge (broodminder-data#176, held 36 hours). Those events are now
flagged `mechanical` and neither count nor reset. Both keys are required: any
other bot on a Dependabot PR, and the App on anyone else's PR, count as before.

dev-lead, the personas and auto-rebase post as the owner account, so each of
their comments read as a human interaction and reset the budget. On #176
dev-lead's hold notice took the count from 10 to 0 a minute after the
escalation. A comment or review whose body carries one of our automation
markers is now flagged `agent_marked` and never resets the budget. It does not
count either; only bot logins count.

gather_pr_automation_events sets the flags, so every consumer inherits the
rule. No event is dropped, because the stall and merge-ready scans read .when
from all of them. An unreadable PR author exempts nothing.

Commits, unmarked comments and review-thread replies made under a human login
still read as human. That limit is documented.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@don-petry
don-petry requested a review from a team as a code owner October 10, 2026 21:56
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 32 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: d04393d2-a6f6-45e2-a890-61c6c3adef86

📥 Commits

Reviewing files that changed from the base of the PR and between 3013fbd and dee7125.


📒 Files selected for processing (10)
  • docs/agentic-interaction-model.md
  • docs/postmortems/2026-06-pr-860-runaway.md
  • scripts/lib/pr-automation-budget.sh
  • scripts/lib/pr-runaway-detect.sh
  • tests/dev-lead/unit/test_dev_lead_resume.bats
  • tests/dev-lead/unit/test_dev_lead_retry_pr_escalation.bats
  • tests/test_persona_pr_pregate.bats
  • tests/test_pr_automation_budget.bats
  • tests/test_pr_runaway_detect.bats
  • tests/test_pr_runaway_regression.bats

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces corrections to the PR automation budget system (#2224). It ensures that Dependabot merge pipeline events on Dependabot-authored PRs do not count towards or reset the budget, and that agent comments or reviews carrying automation markers do not reset the budget even when posted under a human owner account. These changes are implemented in scripts/lib/pr-automation-budget.sh, documented in docs/agentic-interaction-model.md, and verified with new unit tests in tests/test_pr_automation_budget.bats. There are no review comments to assess, and I have no feedback to provide.

Comment thread docs/agentic-interaction-model.md Outdated
@codeant-ai

codeant-ai Bot commented Oct 10, 2026

Copy link
Copy Markdown

CodeAnt Nitpicks

1 code suggestion

1. Because test($re) matches anywhere in a body, a human quoting one of these markers is tagged as an agent and cannot reset the budget.

Incorrect condition logic · scripts/lib/pr-automation-budget.sh:92

@codeant-ai

codeant-ai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

CodeAnt PR Risk: High Risk

  • The PR should not merge yet: an agent's inline review-thread reply is collected as an empty-body owner review, resetting the budget and re-enabling automated writes.
  • The cap rises from 10 to 50; the 25-cycle runaway threshold only surfaces churn, so it does not close this reset path.

Assessed commit: dee7125c23c2

@don-petry

Copy link
Copy Markdown
Collaborator Author

QA Lead — test-risk advisory

Risk tier: MEDIUM. This changes the runaway guard that every agent checks before it writes, on both stable channels, and the mechanical flag can now lower a count. The tests are strong: written first, 21 new cases, a stubbed-gh gather path, a fail-closed author lookup and an untouched regression suite.

What I'd shore up (highest leverage first):

  • The commit login can be spoofed by name. For commits, login falls back to .commit.author.name when .author is null. That name is free text set by whoever pushes. A commit named dependabot[bot] with an email not linked to an account would be flagged mechanical and left out of the count. Before this PR it counted as a bot. Add a negative case: author: null, name dependabot[bot], on a Dependabot PR → still counts. Ideally only flag events whose login came from .author.login.
  • The author stub skips the real field path. The stub returns the login already extracted and ignores --jq '.user.login'. A typo in that path would fail closed and quietly turn the exemption off with no failing test. Have the stub return real /pulls/N JSON and apply the jq to it.
  • There's no clean local test baseline. The macOS run had 75 failures it also has on main, and test_fix_reviews.bats timed out. Treat the full Linux CI run as the gate, and confirm that file finished green.
  • Optional: pin that a body which merely mentions persona: outside an HTML comment is not flagged. That keeps the regex from widening later.

Escalate? No. The spoofing gap is narrow: it needs a Dependabot-authored PR, and an agent's comments and reviews still count. Fix it in this PR rather than block on it.

Advisory only — I comment, I do not change code. Ground: BMAD Test Architecture
(bmad-tea v1.19.0). Opt out on this item with the qa-lead:hands-off label.

@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-10-10T23:10:40Z.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (applied)

Changes committed and pushed. Requested items addressed:

  • docs/agentic-interaction-model.md:569 — applied

@don-petry
don-petry enabled auto-merge October 10, 2026 22:14
@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-10-10T23:30:23Z.

@donpetry-bot

Copy link
Copy Markdown
Contributor

No description provided.

@donpetry-bot

Copy link
Copy Markdown
Contributor

No description provided.

@donpetry-bot

Copy link
Copy Markdown
Contributor

No description provided.

@don-petry
don-petry disabled auto-merge October 10, 2026 22:52
don-petry and others added 2 commits October 10, 2026 17:54
… humans quote keywords

The agent_marked regex was too loose with [^>]*, allowing arbitrary text after
keywords. This caused humans quoting marker patterns to be incorrectly tagged as
agents, preventing them from resetting the automation budget. Fixed by requiring
proper delimiters (space, colon, or dash) after keywords without built-in
delimiters (pr-review-agent, pr-review-claim, dev-lead, dependency-advisory,
pr-automation-budget).

Updated test 57 to use proper delimiter patterns instead of artificial
'x y=z' suffixes, reflecting the more restrictive regex that prevents
false positives while still matching all valid marker formats.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@don-petry
don-petry enabled auto-merge October 10, 2026 23:07
@donpetry-bot

Copy link
Copy Markdown
Contributor

No description provided.

@don-petry

Copy link
Copy Markdown
Collaborator Author

No description provided.

@donpetry-bot

Copy link
Copy Markdown
Contributor

No description provided.

@don-petry
don-petry disabled auto-merge October 11, 2026 00:24
@don-petry

Copy link
Copy Markdown
Collaborator Author

Rate-limit notice: CodeRabbit's free OSS review capacity has been reached. No code findings are reported in this comment — it is a pure operational notice.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-bot-comment (no-changes)

Agent reasoning
Issues addressed: 0
Skipped (informational): 1
The CodeRabbit comment is a pure rate-limit notice ("Review limit reached") with no code findings. The entire comment consists only of the rate-limit block explaining that free OSS reviews are exhausted. No code sections (Security Architecture Review, actionable comments, nitpicks) are present.
Disposition: Posted `informational` disposition on the original comment (node `IC_kwDOR9SdIs8AAAABa741QQ`). The harness will resolve it.
No code changes required.
```

@don-petry
don-petry enabled auto-merge October 11, 2026 00:24
@don-petry
don-petry disabled auto-merge October 11, 2026 02:25
The agent_marked jq function was using test($re) which matches the regex
anywhere in the body. This caused false positives when a human quoted one of
our automation markers (e.g., in a code example), incorrectly flagging the
human's comment as agent-authored and preventing budget reset.

Fixed by stripping backtick-enclosed content before testing, so quoted
markers are not detected. This allows humans to quote markers when discussing
code without triggering the false positive.

Fixes the CodeAnt finding in #2229 (#2224 false-positive fix).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@don-petry don-petry changed the title fix(budget): stop counting the Dependabot merge pipeline, and stop marked agent comments re-arming the budget (#2224) fix(budget): exempt the Dependabot merge pipeline, count marked agent comments, and set the cap from measured PR peaks (#2224) Oct 11, 2026
@don-petry
don-petry force-pushed the claude/issue-2224-budget-mechanical-and-agent-events branch from 5f10f49 to df4600a Compare October 11, 2026 02:38
@don-petry
don-petry enabled auto-merge October 11, 2026 02:38
Comment thread scripts/lib/pr-automation-budget.sh Outdated
@don-petry

Copy link
Copy Markdown
Collaborator Author

No description provided.

@donpetry-bot

Copy link
Copy Markdown
Contributor

No description provided.

@don-petry
don-petry disabled auto-merge October 11, 2026 03:02
@don-petry

Copy link
Copy Markdown
Collaborator Author

No description provided.

don-petry and others added 2 commits October 10, 2026 22:09
…ed PR peaks (#2224)

Agent comments posted under the owner login now count toward the per-PR
automation budget as well as no longer resetting it. Before this, dev-lead,
persona and auto-rebase activity was invisible to the breaker.

The cap of 10 was never set against that activity, so MAX_PR_AUTOMATION_CYCLES
goes to 50, chosen from measurement to block only extreme cases. Sample: 332
agent-authored PRs (every one created in the org from 2026-09-10 to 2026-10-10,
plus those still open). Peak count between two human interactions: median 10,
p95 25, p99 35; highest on a PR that merged, 35; one PR (93) above 50. At a cap
of 10 with marked comments counted, 50.9% of the sample would have been
escalated at least once; at 50, 0.3%. #860 peaks at 1,487 under the same rule
and reaches 50 within ten minutes of its ack storm.

Stopping marked comments resetting the budget while keeping the cap at 10, as
the first commit on this branch did, would by itself have raised the share of
PRs escalated at least once from 4.8% to 16.6%.

The runaway detector's RUNAWAY_MAX_CYCLES goes from 10 to 25 (half the cap,
about p95) so the daily report still names a PR well before the breaker stops
it.

Tests that pinned the old cap now follow the default: the threshold cases, the
two #860 storm scenarios (scaled to the cap in force), three fixtures that
built exactly ten bot events, and the detector's threshold cases.

docs: review-thread replies do reset the budget. Each reply arrives as a review
with an empty body, and that review is collected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@don-petry
don-petry enabled auto-merge October 11, 2026 03:11
@don-petry

Copy link
Copy Markdown
Collaborator Author

No description provided.

…er match is not anchored (#2224)

Review feedback on #2229 questioned whether a review-thread reply can reset the
budget, since /pulls/{pr}/comments is never read. It can: the reply arrives on
/pulls/{pr}/reviews as a COMMENTED review with an empty body, which is collected
and carries no marker. A gather-level test now pins that known limit.

The marker regex stays unanchored. In the comments of the 54 open PRs, 495 of
2,300 marker-carrying agent comments have the marker somewhere other than the
start of the body, so anchoring would read a fifth of agent comments as human.
Quoted markers are handled by dropping backtick spans, as dev-lead's commit did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@don-petry

Copy link
Copy Markdown
Collaborator Author

No description provided.

@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-10-11T04:23:22Z.

@don-petry don-petry added the needs-human-review Flagged by automated PR review agent label Oct 11, 2026
@don-petry

Copy link
Copy Markdown
Collaborator Author

Test suite newly red — human attention needed

The fix-reviews pass left the test suite failing on test(s) that passed on the pre-pass head: resume: exhausted per-PR automation budget suppresses the resume, retry PR: exhausted automation budget (no label) → skips (no dispatch). A fix that breaks a passing test is wrong or incomplete, so dev-lead did not push this pass (#2013). Auto-merge has been disabled.

@don-petry
don-petry disabled auto-merge October 11, 2026 03:24
@don-petry

don-petry commented Oct 11, 2026 •

Copy link
Copy Markdown
Collaborator Author
Superseded — dev-lead is now withholding action under the `dev-lead:hands-off` label. Click to expand the prior `needs-human-review` hold notice.

dev-lead is withholding action on this item.

It is labeled needs-human-review (flagged for human review — this label is applied by automation as well as by people, so an item can become held without anyone noticing), so dev-lead will not pick it up while that label is present. This notice is posted once so the withhold is visible rather than looking like a stalled run.

To re-enable automated pickup: remove the needs-human-review label.

@don-petry don-petry added dev-lead:hands-off Exclude from dev-lead agent automation and removed needs-human-review Flagged by automated PR review agent labels Oct 11, 2026
@don-petry

Copy link
Copy Markdown
Collaborator Author

dev-lead is withholding action on this item.

It is labeled dev-lead:hands-off (deliberately kept off-limits to dev-lead (e.g. changes to the dev-lead automation itself)), so dev-lead will not pick it up while that label is present. This notice is posted once so the withhold is visible rather than looking like a stalled run.

To re-enable automated pickup: remove the dev-lead:hands-off label.

@sonarqubecloud

Copy link
Copy Markdown

@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-10-11T15:42:59Z.

@don-petry
don-petry enabled auto-merge October 11, 2026 14:52
@don-petry
don-petry merged commit df11bb3 into main Oct 11, 2026
69 checks passed
@don-petry
don-petry deleted the claude/issue-2224-budget-mechanical-and-agent-events branch October 11, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dev-lead:hands-off Exclude from dev-lead agent automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pr-automation-budget reads the login only: it escalates waiting Dependabot PRs, and agent activity posted as the owner is invisible to it

2 participants