This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow-steward.git


The following commit(s) were added to refs/heads/main by this push:
     new 1a89b79  feat(pr-management-triage): add docs/spellcheck to 
static_check + optimistic-lock approve-workflow (#116)
1a89b79 is described below

commit 1a89b799752cba65f4e412a067b8ea50ac12007e
Author: Jarek Potiuk <[email protected]>
AuthorDate: Mon May 11 12:30:18 2026 +0200

    feat(pr-management-triage): add docs/spellcheck to static_check + 
optimistic-lock approve-workflow (#116)
    
    Two unrelated-but-small classifier-accuracy improvements, both
    prompted by misclassifications hit during a triage sweep on
    apache/airflow:
    
    1. classify-and-act.md: append `spellcheck`, `spelling`,
       `build documentation`, `build docs`, `build-docs` to the
       `static_check` substring list. A docs-build / spellcheck
       failure is symmetric with the other static checks — the
       contributor introduced text the checker doesn't accept and
       the fix is a code change. Without these patterns, row 13
       (`rerun`) fires on a single docs-build failure and the bot
       sends a useless rerun request that fails identically.
    
    2. actions.md: apply the Golden Rule 1b optimistic-lock pattern
       to `approve-workflow`. Re-list pending runs at action time;
       exit cleanly with a one-line note if empty (already approved
       between fetch and act). Matches what `mark-ready` and
       `mark-ready-with-ping` already do.
---
 .claude/skills/pr-management-triage/actions.md     | 39 ++++++++++++++++++----
 .../pr-management-triage/classify-and-act.md       | 12 ++++++-
 2 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/.claude/skills/pr-management-triage/actions.md 
b/.claude/skills/pr-management-triage/actions.md
index fa94b23..0dedf26 100644
--- a/.claude/skills/pr-management-triage/actions.md
+++ b/.claude/skills/pr-management-triage/actions.md
@@ -442,20 +442,45 @@ responsibility is clearly on the author.
 Two steps. **Inspect the diff first** — see
 [`workflow-approval.md`](workflow-approval.md) for the safety
 protocol. Only after the maintainer confirms the diff looks
-non-malicious, approve:
+non-malicious, **re-list the pending runs at action time** (the
+per-page `action_required` index built during fetch may be stale
+— another maintainer may have approved between fetch and now —
+and the optimistic-lock pattern below catches the no-op race
+without burning a useless mutation):
 
 ```bash
-# List pending workflow runs for this PR.
+# Re-list pending workflow runs for this PR at action time.
 # Runs awaiting approval are returned as `status: "completed"` with
 # `conclusion: "action_required"` — `?status=action_required` matches
 # none of them. Post-filter on `conclusion` to enumerate the real set.
-gh api "repos/<owner>/<repo>/actions/runs?head_sha=<head_sha>&per_page=20" \
-  --jq '.workflow_runs[] | select(.conclusion == "action_required") | .id' |
-  while read run_id; do
-    gh api -X POST "repos/<owner>/<repo>/actions/runs/${run_id}/approve"
-  done
+ids=$(gh api 
"repos/<owner>/<repo>/actions/runs?head_sha=<head_sha>&per_page=20" \
+        --jq '.workflow_runs[] | select(.conclusion == "action_required") | 
.id')
+
+if [ -z "$ids" ]; then
+  # Race: pending runs were approved between fetch and now (another
+  # maintainer, or auto-approval). Skip silently — the desired state
+  # ("CI is allowed to run for this contributor") is already true.
+  # Surface a one-line note to the maintainer so the no-op is visible.
+  echo "approve-workflow: no pending runs found at <head_sha> — already 
approved by someone else" >&2
+  exit 0
+fi
+
+while read -r run_id; do
+  [ -z "$run_id" ] && continue
+  gh api -X POST "repos/<owner>/<repo>/actions/runs/${run_id}/approve"
+done <<< "$ids"
 ```
 
+The optimistic-lock pattern is the same one
+[`mark-ready`](#mark-ready--add-ready-for-maintainer-review-label)
+uses (Golden rule 1b in [`SKILL.md`](SKILL.md)) — read the
+authoritative state immediately before mutating, exit cleanly
+if the desired state is already in place. Without it, a sweep
+that classified at T0 and acts at T0 + minutes (after the
+maintainer reviewed the diff) silently surfaces "exit=0, out=
+empty" with no guidance on whether the approval landed or
+nothing was there to approve in the first place.
+
 No comment is posted for `approve-workflow`. Approval is
 invisible to the contributor except for CI now running, which
 is what they wanted.
diff --git a/.claude/skills/pr-management-triage/classify-and-act.md 
b/.claude/skills/pr-management-triage/classify-and-act.md
index d42aae2..c425271 100644
--- a/.claude/skills/pr-management-triage/classify-and-act.md
+++ b/.claude/skills/pr-management-triage/classify-and-act.md
@@ -241,10 +241,20 @@ after that timestamp.
 Failed check name (case-insensitive substring match either
 direction) hits one of: `static check`, `pre-commit`, `lint`,
 `mypy`, `ruff`, `black`, `flake8`, `pylint`, `isort`, `bandit`,
-`codespell`, `yamllint`, `shellcheck`.
+`codespell`, `yamllint`, `shellcheck`, `spellcheck`,
+`spelling`, `build documentation`, `build docs`, `build-docs`.
 Additional patterns may be configured in
 `<project-config>/pr-management-triage-ci-check-map.md`.
 
+The doc-build / spellcheck patterns are included in the
+framework defaults because the failure mode is symmetric with
+the other static checks: the contributor introduced text the
+checker doesn't accept (a misspelled word, a broken docs
+include, a missing sphinx reference) and the fix is a code
+change, not a CI rerun. Without these patterns row 13 (`rerun`)
+fires on a single docs failure and the bot sends a useless
+rerun request that fails identically.
+
 ### `recent_main_failures`
 
 Cached set of failing check names from the most recent 10

Reply via email to