Repository navigation
pr-merge cost hold: LOW-rated shapes S&C's probe still passes #9241
Copy link
Copy link
Open
Labels
priority: mediumReal value, no hard deadline; normal backlog flow.Real value, no hard deadline; normal backlog flow.status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.A maintainer confirmed the item is real and in scope; ready to be worked.work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.Refactors, migrations, contract changes; cross-cutting and hard to reverse.
Description
Refs: #9221
Problem
The cost hold in #9224 (cost-review-required) closes S&C's HOLD findings. Its probe
still passes a set of shapes that S&C rated LOW. A change of one of these shapes merges
unattended with no owner decision when the HIGH path floor is off, as it is by default in the
pr-merge lane.
In this repository, .github/** and docs/conventions/** are already on the HIGH floor, so the
workflow cases below already wait for a person here.
Shapes still passing the probe
These are the passing rows from S&C's probe re-run against #9224's head.
Timeouts
- A timeout raised on a workflow that calls a local reusable workflow, which itself runs a model.
- A
timeout-minutesremoved entirely, so the default of 360 applies. - A
timeout-minutesset to an expression. - One job raised while a higher value is removed and re-added elsewhere in the same patch.
- A timeout set in flow-mapping style.
Model legs
- A model leg behind a local reusable workflow or composite action
(uses: ./.github/workflows/...,./.github/actions/...). - A non-Claude model action that replaces
claude-code-action. ANTHROPIC_MODELenv values, andwith: model:orwith: max-turns:inputs on a model step.--modelor--max-turnsin.github/actions/**/action.ymlor.github/scripts/**, which
are outside.github/workflows/.
Triggers and guards
- New triggers on a model workflow:
workflow_run, apushwith no paths,on: [...]lists. concurrency.cancel-in-progressor a jobif:guard removed from a model job.strategy.matrixgrowth andmax-parallel.
Files and paths
- A workflow in a subdirectory (
.github/workflows/sub/x.yml). - Spend logic in code:
.github/actions/resolve-config/*.mjs. Pulumi.yml, ARM templates (azuredeploy.json) and*.tf.json.
Moves
- A secret reference moved within one file. This is net zero by design, but a move can hide a
new use.
Next step
Triage each shape: hold it, accept it with a reason, or leave it to the review lanes. Then add
probe rows for the held ones to the cost tests.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
priority: mediumReal value, no hard deadline; normal backlog flow.Real value, no hard deadline; normal backlog flow.status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.A maintainer confirmed the item is real and in scope; ready to be worked.work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.Refactors, migrations, contract changes; cross-cutting and hard to reverse.
Type
Fields
No fields configured for Task.
Activity
github-actions commentedon Oct 22, 2026
Proposed work class: work-class: structural
Basis: automated intake triage; the lanes App applied this class.
Size: Medium
Complexity: Medium
Uncertainty: Knowable
Flags: none
Blocked by: none
#9241 (comment)
This decision settles the open scope questions. PR #10583 merged with
Refs:, so the issue stays open. Changelog entries and probe tests for #9241 are already on main. What remains is a check that the probe matches the three acceptance items above: model settings don't hold, timeouts hold only on private repositories, and billable shapes still hold.Automated triage, applied by the lanes App.
kyle-sexton commentedon Oct 22, 2026
More LOW items from Security & Cost's re-probes of #9224 (heads
f5d53282andb37ffc18):_raised_timeoutscompares each added value against the highest removedvalue in the patch. So a raise from 30 to 200 passes when an unchanged 300 is removed and re-added
elsewhere in the same patch. Fix: compare per job or by key path.
.lstrip()beforeDECISION_LINE.cost_decisionstrips leading whitespace before matching**Decision recorded.** Cost:. As a result, a marker after leading whitespace or blank lines, oron what renders as line 2, still counts. Fix: match the raw first line.
_unsafe_pipeline_linescompares multisets, so a check thatadded and removed lines are equal (
gained == lost) passes when two keys swap their values.Fix: compare by key path.
_SECRET_REFmisses:${{ secrets }},contains(secrets, ...), anda reference split across a folded scalar.
runs-on: ${{ matrix.os }}or${{ inputs.runner }}passeswhen the matrix values or the input's default gain a larger-runner label. The runner check
reads only
runs-onvalues.kyle-sexton commentedon Oct 22, 2026
Two items from the earlier comment are fixed in #9224 at 2795674, after the review lanes raised them: a
Cost:marker on line 2 no longer counts (DECISION_LINEtakes spaces or tabs only), and pr-pipeline.yaml value swaps between keys now hold (each change run is compared in place). The rest stay open.kyle-sexton commentedon Oct 24, 2026
Released for re-triage under the owner's 2026-10-24 rule: an issue stops for a person only for an intent or vision question, a security call, a host or attended run, or spend outside prepaid credit. The hold label came off and intake triage runs again now; it re-applies a hold, with a numbered question, when one of those applies.
To hold this issue again, add
needs-human(orstatus: needs-decision) and say why in a comment.melodic-automation-lanes commentedon Oct 24, 2026
Refinement. A read-only run explored this repository, searched its issues and pull requests, and read the allowed docs to draft what follows. On an issue a listed human filed, it counts as the issue's spec once posted, while unedited; it is still model text, so check it.
Intended outcome: Extend the cost hold in babysit_risk.py so the shape groups the owner chooses to hold rate HIGH as cost-review-required, with probe rows added to test_babysit_risk_cost.py.
Dependencies
Related work
Open questions
RECOMMENDED: Hold timeouts (including per-job comparison) and model legs (reusable workflows, composite actions, non-Claude actions, ANTHROPIC_MODEL, model and max-turns inputs, script and action files); accept moves; leave triggers, guards and file paths for a later pass. Basis: judgment: timeouts and model legs are direct spend levers, while a moved secret reference is net zero.
RECOMMENDED: Yes, one issue per group, with the later-comment items riding with their group. Basis: judgment: the triage sized this Large and the shapes are independent changes to babysit_risk.py.
RECOMMENDED: Yes: timeout comparison with timeouts, secret reference shapes with moves, runner expressions with model legs or files. Basis: plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:834
RECOMMENDED: Yes, since this is a spend-policy call outside prepaid credit; the owner should accept or hold each broad shape. Basis: judgment: the owner's 2026-10-24 rule keeps spend decisions with a person.
Sources read
Automated refinement by the lanes App. Answer with a comment whose first line is
**Decision recorded.**.14 remaining items
github-actions commentedon Oct 28, 2026
The triage sweep dispatched intake triage for this issue (attempt 1 of 2).
kyle-sexton commentedon Oct 28, 2026
Decision recorded. This supersedes the "Model legs: hold" and "timeouts hold on every repository" lines in this issue's spec. My standing cost rule of 2026-10-27 (docs/conventions/loop-lane/README.md, "When work stops for the owner") governs:
Acceptance:
fix(source-control): drop the cost hold's non-billing model and publi…
melodic-automation-lanes commentedon Oct 29, 2026
The lanes App's pull request #10583 merged with
Refs:, so this issue stays open and nothing starts the lane on it again. work-unblock removedstatus: readyandagent-ready, so the hourly triage sweep sends it back to intake triage. Admission then parks it atstatus: confirmedfor a check of what that pull request left, until a**Decision recorded.**comment says what is left or someone closes it.melodic-automation-lanes commentedon Oct 29, 2026
Not admitted to the issue lane: merged pull request #10583 names it with
Refs:after its newest decision or refinement comment, so its work may already be done: close the issue if it is, or post a comment whose first line is**Decision recorded.**saying what is left, which sends it back through intake. Admission takes the issue once each of those is met, when intake triages it again (.github/actions/resolve-config/admission-rules.json).melodic-automation-lanes commentedon Oct 29, 2026
The latest triage verdict holds nothing: admission moved the issue to
status: confirmed; its comment says why.