You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(pr-pipeline): carry an owner-lifted claude-review cost hold forward across base-only merges #9436
The claude-review lane's cost hold (claude-lane-hold ... criteria=cost) is re-applied on every new head of a PR, even after the owner has approved the spend change and removed needs-human. On #9352 the owner approved the cost change once; the hold came back at 13:55Z, 15:11Z (after each main merge), and each time ci-status failed until an agent removed the label again.
Fix
Carry an owner's cost approval forward to later heads when the cost-relevant diff (workflow funding lines, .github/lane-funding.json, routing in pr-pipeline.yaml) is unchanged since the approved head: for example, record the approved head in the hold marker on unlabel, and skip a new cost hold when the cost-relevant paths' diff against that head is empty (a base-only merge).
Verification
A test: a PR whose cost hold was lifted at head A, then merged with main (no change to cost-relevant paths) at head B, gets no new cost hold at B; a change to a cost-relevant path at B re-holds.
#9509: the owner recorded the cost decision (issuecomment-6376016538, 22:30:12Z) and removed needs-human. The next head, 07fb37d, changed only cancel-in-progress and its docs, and claude-review held it again for cost at 23:07:32Z. The model's own hold text says: "The commit under review only changes cancel-in-progress and its docs, and adds no further cost."
Cause: the hold step remembers nothing about lifts. In ci-workflows v0.65.0 (d02b8697), pr-review-cli.yml's "Apply the hold" step (.github/actions/apply-review-hold/hold.cjs) only adds the label and marker whenever the counted leg returns a hold. Its documented contract is "Add-only ... It never removes a label" (pr-review-cli.yml:2282-2285). Its inputs carry no prior hold marker, label removal or **Decision recorded.** Cost: comment. The model re-judges the whole PR diff on every head, so a schedule still in the diff holds again.
Constraint for the fix:#9493 binds a cost decision to the head it approves. Carry a lift forward only when the cost-relevant diff is unchanged since the lifted head, as this issue's Fix says. Do not suppress cost outright once any decision exists. The fix lands in ci-workflows (apply-review-hold), then a re-pin here.
Q17 (how a cost decision binds) is settled as option (b). That supersedes the head-binding constraint in #9436 (comment).
How it was settled: on 2026-10-24, in the Automation Lanes session (c736de2c), the owner was given the open questions, Q17 among them, and answered verbatim: "least amount of friction, highest throughput (safely, within constraints) - go with whatever that is", and "only necessary things that would prevent an actual risk/attacker". Under that direction the session picked (b), the lower-friction option, which binding cost approvals to every head does not weaken against an attacker. The owner did not name (b) itself; it was chosen under the direction quoted above.
The rule under (b):
A cost decision binds to a pull request and covers every head of it. A new head does not need a new decision.
The decision counts when it is posted by the owner on the pull request itself, or on the pull request's linked issue (its closing issue, else its one plain Refs: issue) with text that names the pull request as #N. A decision on an issue that does not name the pull request does not carry over to it; this closes the fix(pr-merge): bind a cost decision to the pull request head it approves #9493 path.
The author, App, edit and created-after-the-PR checks are unchanged.
Readers: #9569 (merge gate, babysit and ci-status lift) and ci-workflows v0.65.2/v0.65.3 apply-review-hold (the review-lane hold step, melodic-software/ci-workflows#875).
The owner decided Q17 (how far a cost decision reaches) on 2026-10-24 at ~06:10Z, in the Automation Lanes session. Option (c) was put to him as the recommendation, and he answered verbatim: "go w/ recommended".
This replaces the (b) record at #9436 (comment). The session picked (b) under his general direction, without his own choice.
The rule under (c):
A cost decision covers later heads of the same pull request only while the cost-relevant paths are unchanged. These are the paths whose change makes a review lane hold for cost: new model-run triggers, dispatch caps, the model and effort settings of lane jobs. A later head that changes any of them needs a new decision.
A head that differs from the decided one only by a base merge, or by changes outside those paths, keeps the decision. This is what ends the re-hold after a base-only merge.
These rules from (b) still apply: a decision counts when an unedited owner comment carries it, posted on the pull request itself or on its linked issue (the closing issue, else the one plain Refs: issue) with text that names the pull request as #N. The author, App, edit and time checks are unchanged.
The owner decided Q18 on 2026-10-24 at about 06:2xZ, in the Lane Funding session. Q18 asked which change keeps a cost decision on a later head, which is how the Q17 (c) rule recorded at #9436 (comment) gets applied. He was shown (d) as the recommendation, with (b) and (a) as alternatives, and answered verbatim: "go w/ recomendations". That answer reached this session as Lane Funding's relay; I did not see it first-hand.
Rule (d): a cost decision carries to a later head of the same pull request only when every change since the decided head is a merge of the base. Any other commit, including a change outside known cost files, needs a new decision. No list of cost files is involved, so no list can miss a file. Example: #9561's added spend lived entirely in scripts a workflow calls, where no path or line rule would have caught it.
Shared mechanics, the same in both readers:
The decided head is the sha= in the latest bot-authored claude-lane-hold ... criteria=cost marker created before the decision comment.
Base-merge-only test: the pull request's own net change (its three-dot diff against the base) is identical at the decided head and at the current head. This holds across merges and rebases of the base, and it catches a hand edit made while resolving a conflict.
Any read failure, or a missing marker, means no carry, so the hold stays.
Readers: #9569 (merge gate, babysit, ci-status lift) and ci-workflows v0.65.4 apply-review-hold (re-pinned by #9589).
Activity
github-actions commentedon Oct 23, 2026
Proposed work class: none
Thanks for the report. Automated triage handed this issue to a maintainer.
Unconfirmed model suggestion: work-class: scoped
Basis: automated intake triage; a maintainer confirms or changes it.
Automated triage. A maintainer reviews it.
kyle-sexton commentedon Oct 24, 2026
Second instance, and the cause.
#9509: the owner recorded the cost decision (issuecomment-6376016538, 22:30:12Z) and removed
needs-human. The next head, 07fb37d, changed onlycancel-in-progressand its docs, and claude-review held it again forcostat 23:07:32Z. The model's own hold text says: "The commit under review only changes cancel-in-progress and its docs, and adds no further cost."Cause: the hold step remembers nothing about lifts. In ci-workflows v0.65.0 (
d02b8697),pr-review-cli.yml's "Apply the hold" step (.github/actions/apply-review-hold/hold.cjs) only adds the label and marker whenever the counted leg returns a hold. Its documented contract is "Add-only ... It never removes a label" (pr-review-cli.yml:2282-2285). Its inputs carry no prior hold marker, label removal or**Decision recorded.** Cost:comment. The model re-judges the whole PR diff on every head, so a schedule still in the diff holds again.Constraint for the fix: #9493 binds a cost decision to the head it approves. Carry a lift forward only when the cost-relevant diff is unchanged since the lifted head, as this issue's Fix says. Do not suppress
costoutright once any decision exists. The fix lands in ci-workflows (apply-review-hold), then a re-pin here.kyle-sexton commentedon Oct 24, 2026
Q17 (how a cost decision binds) is settled as option (b). That supersedes the head-binding constraint in #9436 (comment).
How it was settled: on 2026-10-24, in the Automation Lanes session (c736de2c), the owner was given the open questions, Q17 among them, and answered verbatim: "least amount of friction, highest throughput (safely, within constraints) - go with whatever that is", and "only necessary things that would prevent an actual risk/attacker". Under that direction the session picked (b), the lower-friction option, which binding cost approvals to every head does not weaken against an attacker. The owner did not name (b) itself; it was chosen under the direction quoted above.
The rule under (b):
Refs:issue) with text that names the pull request as#N. A decision on an issue that does not name the pull request does not carry over to it; this closes the fix(pr-merge): bind a cost decision to the pull request head it approves #9493 path.Readers: #9569 (merge gate, babysit and ci-status lift) and ci-workflows v0.65.2/v0.65.3 apply-review-hold (the review-lane hold step, melodic-software/ci-workflows#875).
kyle-sexton commentedon Oct 24, 2026
The owner decided Q17 (how far a cost decision reaches) on 2026-10-24 at ~06:10Z, in the Automation Lanes session. Option (c) was put to him as the recommendation, and he answered verbatim: "go w/ recommended".
This replaces the (b) record at #9436 (comment). The session picked (b) under his general direction, without his own choice.
The rule under (c):
Refs:issue) with text that names the pull request as#N. The author, App, edit and time checks are unchanged.Readers to update: #9569 (merge gate, babysit, ci-status lift) and the ci-workflows apply-review-hold step that #9589 pins.
kyle-sexton commentedon Oct 24, 2026
The owner decided Q18 on 2026-10-24 at about 06:2xZ, in the Lane Funding session. Q18 asked which change keeps a cost decision on a later head, which is how the Q17 (c) rule recorded at #9436 (comment) gets applied. He was shown (d) as the recommendation, with (b) and (a) as alternatives, and answered verbatim: "go w/ recomendations". That answer reached this session as Lane Funding's relay; I did not see it first-hand.
Rule (d): a cost decision carries to a later head of the same pull request only when every change since the decided head is a merge of the base. Any other commit, including a change outside known cost files, needs a new decision. No list of cost files is involved, so no list can miss a file. Example: #9561's added spend lived entirely in scripts a workflow calls, where no path or line rule would have caught it.
Shared mechanics, the same in both readers:
sha=in the latest bot-authoredclaude-lane-hold ... criteria=costmarker created before the decision comment.Readers: #9569 (merge gate, babysit, ci-status lift) and ci-workflows v0.65.4 apply-review-hold (re-pinned by #9589).
fix(pr-merge): carry a cost decision only across base merges