Repository navigation
feat(source-control): resolve lane-answered outdated threads on owner PRs in the worker tier - #10841
kyle-sexton wants to merge 7 commits into
Conversation
… PRs in the worker tier The worker tier's --autonomous resolve refused every PR authored by a self login, so on owner-login PRs no thread was ever resolved. --own-pr-lane-logins (from babysit_lane_logins) lifts that refusal narrowly: it admits an outdated, bot-opened thread that a lane login other than the opener has replied to, with no comment by a self login. The severity line (CRITICAL, security, P0/P1) and the person-thread line still hold. Without the flag the refusal is unchanged. Refs: #10763 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…efusal fires fetch_pull_request_author read `login` from the top of the `gh pr view --json author` payload, where it is nested under `author`. It always returned an empty login, so --autonomous treated every PR as someone else's and the own-PR refusal never fired. It now reads the nested login and raises when it is missing, which the resolver reports as a refusal. Refs: #10763 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ns docs Refs: #10763 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
claude-security-review reviewed No security findings. critical-findings: 0 Scope read. I read the full diff and PR context. The code changes are Trust-control check (own-PR thread resolve, merge-hold inputs). I found no widening against the base:
Noted, not a finding. manifest userConfig Spend: nothing is added. The change uses no new model runs or paid resources. No hold. |
|
claude-review reviewed No blocking or advisory findings on this head (ca6b5f7). I read the whole diff (
I did not run the tests. The 3403-test and live-PR results in the PR description are the author's claims and I haven't verified them. Trusted-path files (
No Manifest checks (
Closing issues: none. The PR only references #10763, so there are no acceptance criteria to check. The PR body's own "Remaining" section says criterion 1 is unmet on current data. That is a rollout and configuration matter, not a code defect. Paved paths: I did not resolve the standards index, because this run has no shell and I judged no paved-path row relevant to this change. Minor, not counted:
|
… lane logins With babysit_lane_logins unset, the worker's own-PR resolve takes its lane login from merge.agent-identity in docs/conventions/pr-pipeline.yaml, read at the PR's base commit and the default branch head and used only when both declare the same one. It is never read from the PR head. A person merges that file, so a repository value that widens what the worker resolves stays operator-reviewed (ADR 0039). The setting wins when set; with neither, the own-PR refusal holds. Refs: #10763 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… answer laneAnswered held for any reply from a lane login, but address-feedback also posts INCORRECT, UNCERTAIN and VALID (defer) replies that leave the thread open. The latest lane reply must now open with the fixed disposition header renderReply writes, so a left-open thread stays with a person. Refs: #10763 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs: #10763
Summary
The worker tier's thread resolver refused every PR authored by your own login (
skippedOwnPr), so on owner-login PRs the worker resolved nothing, and the owner resolved lane-answered threads by hand.--own-pr-lane-logins(filled frombabysit_lane_logins) lifts that refusal for one kind of thread only: an outdated, bot-opened thread that a lane login other than the opener has already replied to.Fix
babysit_resolve_thread.py:project_threadcomputeslaneAnswered. Every comment is a bot's (a self-login comment counts against it, because on your own PR the self login is the person), and some reply after the opener comes from a lane login other than the opener's. Logins are compared casefolded with[bot]removed. A truncated page fails closed.classifytakesown_prand returnsskipped-own-pr-not-lane-answeredfor any other thread on an own PR. This check comes after the existing human-thread,isOutdatedand severity checks, so a CRITICAL or security thread still reportsskipped-severity-markedand a person-opened thread still reportsskipped-human-thread.mainkeeps theskippedOwnPrrefusal when the flag is absent or empty, refuses the flag outside--autonomous(exit 2), and leaves--independent-resolverrefusing own PRs. The summary gainsownPrandskippedOwnPrNotLaneAnswered, and audit records gainown_pr.babysit_gh.fetch_pull_request_authorreadloginfrom the top of thegh pr view --json authorpayload, but the login is nested underauthor. It always returned"", so the own-PR refusal from fix(source-control): refuse autonomous resolve on own PRs #2451 never fired. On owner PRs,--autonomouscould already resolve an outdated bot thread the owner had replied to, because a self reply is neutral forbotOnly. It now reads the nested login and raises when it is missing, and the resolver reports that as a refusal. As a result, without--own-pr-lane-loginsthe worker now resolves nothing on owner PRs.--autonomous:CRITICAL, anysecurityand P0/P1 markers setseverityFlagged. That is unchanged. A lane reply is scanned raw, so a lane reply that contains the word "security" also blocks the resolve. That is stricter than the rule needs, and it errs in the safe direction.babysit_lane_loginsdescription, asafety.mdbullet, the worker command lines inorchestration.mdandsafety.md, guard-contract rows (one refusal, three predicates, regenerated), and a provider-file pointer for who may resolve a conversation on a person-opened PR (no GitHub behavior is restated).Verification
bash plugins/source-control/skills/babysit-prs/scripts/engine.test.sh: 3403 tests OK (5 skipped), ruff clean, wrapper checks pass.OwnPrLaneAnsweredExceptiontests intest_babysit_resolve_thread.pyrun through the realproject_thread. They cover: an answered lane thread is resolved; an unanswered thread is not; a reply from a bot that is not a lane does not count; a lane replying to its own finding does not count; a CRITICAL security-lane thread isskipped-severity-marked; a person-started thread and an owner-started thread areskipped-human-thread; an owner reply inside a bot thread blocks the resolve; a current thread is skipped; without the flag, or with it empty,skippedOwnPris unchanged; the flag outside--autonomousexits 2.FetchPullRequestAuthorTestsintest_babysit_gh.py: the nested login is read, and a missing login raises. The first test fails on the old code, which returned"".resolve.own-pr-lane-logins-requires-autonomous,classify.own-pr-requires-a-lane-answer,classify.own-pr-keeps-the-severity-line,classify.own-pr-lane-answered-is-eligible.reference/guard-contract.mdwas regenerated.check-skill.sh plugins/source-control/skills: babysit-prs PASS (SKILL.md at 499 lines). markdownlint is clean.skippedOwnPr: true. Before the author fix, the same run reportedownPr: falseand twowould-resolvethreads, each of which had a reply from the owner.--own-pr-lane-logins melodic-automation-lanes: both outdated threads areskipped-own-pr-not-lane-answered, because the only reply on each is fromkyle-sexton, not a lane.github-actionsopener projectlaneAnswered: true. Live GraphQL logins (melodic-automation-lanes, typenameBot) match the configured value.--resolvewas run against a live thread, because no owner-login PR has a qualifying thread today (see Remaining).Remaining
kyle-sexton, none from the lanes App. Agent sessions answer under the owner login, and the API cannot tell those replies apart from the person's, so the rule ("never a thread a person wrote") correctly keeps them. The lanes App would have to post the answer for this path to fire. That needs a decision on the route (refinement question 1).babysit_lane_loginsis unset in user settings, so until it names the lanes App the worker omits the flag and still resolves nothing on owner PRs. No worker-tier babysit loop runs for this repository either: there is no crontab, no matching systemd user timer, and no babysit entry in the fleet operations doc.create --pushed), and whether PRs a person opens by hand stay in scope.Related
🤖 Generated with Claude Code