steward · git:20261028.76d34ab · 2026-10-28 · sha256 731ecc30fcfb6dc3
steward git:20261028.76d34abA
Immutable. This exact content never changes and is served at /api/v1/blob/731ecc30fcfb6dc3.
---
name: steward
description: Drive an mxcli pull request Claude opened to green and merge it. Covers when to open it, the local gate to pass before every push (make ci-local), which CI failure is a known runner flake, how to resolve the conflicts this repo keeps hitting, how to read the AI PR Review comment, and the merge-on-green default. Read before acting on a CI, review or conflict event on such a PR.
---
<!-- skill-index: generated by scripts/skill-index.py; make check-skill-index -->
## Find it fast
`sed -n '<from>,<to>p' SKILL.md` one section rather than reading the file;
`./mxcli syntax <topic>` answers *how do I write this* for a fraction of either.
| lines | section |
|---|---|
| 27-54 | Merge on green is the default |
| 55-72 | Before every push: `make ci-local` |
| 73-87 | Reading a red CI job |
| 88-103 | Conflicts this repo keeps hitting |
| 104-121 | The AI PR Review comment |
<!-- /skill-index -->
# Steward: Driving a PR to Merged
This is a **contributor** skill (dev-only); it is not synced to user projects.
It holds this repository's conventions for the loop after a PR is opened. How
to make the change itself is `/mxcli-dev:fix-issue` and the CLAUDE.md working
rules; this file starts where they stop.
## Merge on green is the default
The user reviews a change **in the session, before the PR exists**. So:
- Open a PR only after the user has seen the change summarized in the session
and asked for it. Never open one to get a review.
- Once it is open, merge it without asking again as soon as all of these hold
on the **current head**:
- every job of `Build, Test & Lint` (`.github/workflows/push-test.yml`) is
green, `integration-passed` included. A push to the PR branch runs that
workflow twice on the same commit, for the push and the pull_request
event; a job that passed in one run and was cancelled before it got a
runner in the other counts as green;
- GitHub reports no merge conflict;
- no human review thread or changes-requested review is open;
- no Critical item from the AI PR Review comment is unanswered (see below).
- Merge with a **merge commit** (not squash, not rebase), passing the head SHA
you checked as `expectedHeadSha`, so a push that lands in between is not
merged unseen.
- After the merge, unsubscribe from the PR, cancel its pending check-in, and
restart the working branch from the new main:
`git fetch origin main && git checkout -B <branch> origin/main`, then push.
The next PR starts from there; never stack new work on merged history.
Ask instead of merging when a human reviewer has commented or requested
changes, or when the PR is someone else's. Never merge a red head, whatever
the reason it is red.
## Before every push: `make ci-local`
`make build test lint` is a subset of the gate CI applies. `make ci-local`
runs what the `build-and-test` job runs, in its order, minus `govulncheck`.
Run it before the first push and before every push that changes code, and
push only on a clean exit. It takes a while; run it in the background.
- **Formatting:** `make fmt` is the fixer. `fmt-check` uses the toolchain's
gofmt (`go env GOROOT`), because the gofmt on `PATH` can be an older Go than
the `toolchain` line in `go.mod`, and its verdict differs from CI's.
- **Integration suites** need mxbuild, so `ci-local` does not run them. When
the change touches a package with integration tests, run that suite:
`make test-integration-<executor|roundtrip|parity|upgrade|other>`.
- **When the job gains a step,** add it to `ci-local` in the same PR.
- **A failure in code the change does not touch:** run the same target on
`origin/main`. If it fails there too, it is main's: fix it in its own PR
(it can go first), and never skip or disable the test to get past it.
## Reading a red CI job
The workflow is the source of truth for what runs; these are the jobs whose
failures need reading differently.
- **`build-and-test`:** reproduce with `make ci-local`.
- **`integration (<suite>)`:** reproduce with `make test-integration-<suite>`.
- **`tunnel-seam-cross-platform (macos-latest | windows-latest)`:** the one
known runner flake. The hosted macOS queue sometimes cancels the job before
it gets a runner (the job shows runner id 0 and no step ran). That is a job
that died before any test body ran: re-run the failed jobs **once**. A test
failure in this job is real: it runs the tunnel seam's own tests on that
platform (ADR-0009).
- **`AI PR Review`** is always green: it posts a comment, it does not gate.
## Conflicts this repo keeps hitting
While the PR is open, merge `origin/main` into its head. Do not rebase or
force-push it.
| File | Resolution |
|---|---|
| `CHANGELOG.md` `[Unreleased]` | Keep **both** sides: every entry is one line, so a conflict is two fixes landing at once. Afterwards check for a stray blank line or a duplicated entry. |
| A `SKILL.md` section index | Keep either side, then `make skill-index`. |
| `cmd/mxcli/skills/` | Never resolve by hand: `make sync-skills` regenerates it from `.claude/skills/mendix/`. |
| `docs-site/src/language/versions.md` tables | `make gen-migration-reference`. |
| `mdl/conformance/allowlist.txt` | Take the higher count on each conflicting line, then `make conformance-shrink`, which lowers every count to what the gate finds and never raises one. |
| Bug findings | They do not conflict: each finding is its own new file. |
Run `make ci-local` on the merge result before pushing it.
## The AI PR Review comment
`ai-review.yml` posts **one PR comment** headed `## AI Code Review`, not review
threads. It has sections Critical Issues, Moderate Issues, Minor Issues, What
Looks Good and Recommendation. On a large PR the model sees only a selected
part of the diff, so a claim that something is missing may only mean that file
was outside the selection.
| Section | How to treat it |
|---|---|
| Critical | Blocking. Verify each item against the code: fix and push it, or answer it with the path you traced and why it does not hold. |
| Moderate | A claim to verify, not an order. Fix it when a real caller reaches the failure and the fix is in proportion to it; otherwise say why not. |
| Minor | Optional. Never start a push for one. Carry the plainly correct ones into a push that already touches those files. |
Answer it with **one** PR comment that gives the outcome for each Critical and
Moderate item. Sometimes nothing is posted at all: the workflow skips posting
when its API key is missing or the API call fails, and still reports success.
A missing comment is neither an approval nor a blocker.