diff --git a/plugins/tend-ci-runner/skills/nightly/SKILL.md b/plugins/tend-ci-runner/skills/nightly/SKILL.md index 101cf5f7..2368473b 100644 --- a/plugins/tend-ci-runner/skills/nightly/SKILL.md +++ b/plugins/tend-ci-runner/skills/nightly/SKILL.md @@ -320,7 +320,7 @@ The default action is a PR, not an issue. If there's a plausible fix, make it For each finding: -1. **Create a PR** — branch, fix, run full test suite, commit, push, create PR, poll CI. **Every bug fix must include a regression test that would have failed before the fix.** If a test is not feasible (e.g., pure documentation changes), note why in the PR description. When uncertain about the approach, explain the trade-offs in the description. +1. **Create a PR** — branch, fix, run full test suite, commit, push, create PR, then poll CI per **CI Monitoring** in `/tend-ci-runner:running-in-ci`. Your job ends when those checks are terminal: a review posted on the PR while you poll belongs to `tend-mention`. **Every bug fix must include a regression test that would have failed before the fix.** If a test is not feasible (e.g., pure documentation changes), note why in the PR description. When uncertain about the approach, explain the trade-offs in the description. 2. **Create an issue only when there's no obvious fix** — design questions, problems needing maintainer input, or findings requiring investigation beyond what the survey can provide. ## Optional steps diff --git a/plugins/tend-ci-runner/skills/running-in-ci/SKILL.md b/plugins/tend-ci-runner/skills/running-in-ci/SKILL.md index b3f01a83..73720985 100644 --- a/plugins/tend-ci-runner/skills/running-in-ci/SKILL.md +++ b/plugins/tend-ci-runner/skills/running-in-ci/SKILL.md @@ -192,6 +192,22 @@ STATE=$(gh pr view --json state --jq '.state') If the PR is merged, the work is superseded. Comment if a real gap remains; do not push to the now-orphan branch. After merge, `gh pr view --json headRefOid` returns the SHA at merge time and never advances — polling it for a new push is a guaranteed deadlock. +### Re-check the head SHA before the expensive verify, not just before the push + +A PR another tend session opened keeps that session alive polling its checks, and closing a red gate is exactly the follow-up it stays alive for — so a sibling commit can land on the branch while you edit it. Find that out at `git push` and the suite you just ran was scoped against a stale head, so the whole verify cycle is paid again after the rebase. Record the head before editing and re-check it immediately before each expensive step — full test suite, coverage or snapshot regeneration, a long build: + +```bash +HEAD_OID=$(gh pr view --json headRefOid --jq '.headRefOid') +# ...edits... +read -r NOW_OID NOW_STATE < <(gh pr view --json headRefOid,state --jq '"\(.headRefOid) \(.state)"') +[ "$NOW_OID" = "$HEAD_OID" ] && [ "$NOW_STATE" = "OPEN" ] \ + || echo "sibling pushed or PR closed — fetch and re-scope before verifying" +``` + +`state` rides along on the same call because a merged or closed PR freezes `headRefOid` at its merge-time value (see above) — the OID comparison alone passes and the expensive step runs on work that is already superseded. On a non-`OPEN` state, stop per the subsection above rather than re-scoping. + +If it moved, `git fetch` and read the new commits before verifying: drop whatever the sibling already landed, rebase what's left, and verify once against the new head. Expect the overlap rather than treating it as a surprise — a reviewer and a coverage gate reading the same new code ask for the same missing test. The runs API can't substitute for this check: a `schedule` or `repository_dispatch` run reports `head_branch: main`, not the branch it is editing, so a live sibling is invisible there. + ## Merging Upstream into PR Branches When asked to merge the default branch into a PR branch: @@ -299,6 +315,12 @@ gh api "repos/{owner}/{repo}/actions/runs?branch=main&status=completed&per_page= If you cannot verify, say "I haven't confirmed whether these failures are pre-existing." +### A review that lands while you poll is not yours to action + +`tend-review` fires on any PR you open, so its review often arrives while you are still polling that PR's checks. Don't act on it. `tend-mention` is dispatched on `pull_request_review` for every PR the bot authored, and that dispatch runs whether or not you also respond — so a session that starts editing is racing a run already making the same edits and running the same suite. The loser only finds out at `git push`, discards its commit, and the whole fix-and-verify cycle is paid twice for one review. + +Poll your checks to terminal, do the follow-up you were gated on, and exit; name the outstanding review in your summary. This covers a review that arrives *while* you work — a session dispatched to answer a specific review owns that review and actions it normally. + ### Polling `gh run rerun --failed` After `gh run rerun --failed`, poll the rerun jobs directly. The parent run's `.status` stays `in_progress` until every sibling job finishes, including unrelated long-running ones, and the `pending()` recipe above also doesn't help — sibling check-runs on the head SHA still appear pending. Polling specific job IDs is the only fix.