| name | commit |
| description | Lint, run the pre-PR checks, commit, push, and author or update the branch's pull request in the required plain-text format. Use when committing, pushing, or creating/updating a PR. |
Skill: Commit & PR
Get the branch clean, commit it, run the advisory lint review over the committed
diff, then — when it is ready — open or update the pull request.
Before authoring a commit or PR title or body, read:
.agents/skills/writing-style/SKILL.md
.agents/skills/writing-style/pull-requests.md
.agents/skills/writing-style/ai-writing-donts.md
Order matters. Your own cleanups and the mechanical fixes come first, then the
commit, and only then the --review pass. Committing before the review gives
you a clean checkpoint to review against (the review reads the whole branch diff
versus the merge base) and a natural place to land any follow-up fixes as a new
commit. The review is read-only: it never edits, commits, or pushes for you.
Checklist
Work top to bottom. For a quick work-in-progress checkpoint, do 1, 2, 4, 5,
7 (clean up, lint, stage, commit, push) and stop. The changed-test cleanup in
step 1 is a PR-readiness gate, not required for disposable WIP checkpoints. Run
the whole list for PR-ready work.
- Clean up your own diff (self-review).
- Mechanical lint & format —
./infra/pre-commit.py --changed-files --fix.
- Tests & docs checks, when relevant.
- Stage the specific files for this work.
- Commit. ← natural checkpoint; the working tree is now clean.
- Lint-catalog review — run
./infra/pre-commit.py --review once; fix or answer every finding.
- Push (maybe).
- Open or update the PR.
- Monitor the PR with
wait_for.py until an exit condition.
1. Clean up your own diff
Read your own git diff before anything else. Drop dead code, debugging
leftovers, and stale comments; tighten names; make the change say only what it
means to. The review in step 6 is advisory and read-only — it will not clean up
for you.
If the diff touches tests and this commit is intended for a PR or review, read
root TESTING.md and the relevant module-specific AGENTS.md or testing docs
as part of this self-review. Review every changed test for slop: tautological
assertions, disposable smoke probes left as pytest tests, internal call-count
assertions, incidental string or command-fragment assertions, over-mocking,
weakened tolerances, sleeps, skipped tests, and local marker/fake/mock
violations.
Fix or delete low-value tests before a PR-ready commit. Scratch probes are fine
during development and WIP checkpointing, but they must not survive into a PR.
2. Lint and format
./infra/pre-commit.py --changed-files --fix
./infra/pre-commit.py is the required entry point — never uv run pre-commit,
never --no-verify. If --fix cannot resolve something, fix it by hand. Do not
skip or weaken checks.
3. Tests and docs checks (when relevant)
uv run --no-project infra/ci/run_tests.py to run affected safe unit tests.
Do not override the repository's default marker expression.
- If docs pages were added/deleted/renamed:
uv run python infra/check_docs_source_links.py.
- If the change is docs-heavy:
uv run mkdocs build --strict.
4. Stage changes
Review git status and git diff, then stage the specific files that are part
of this work.
- Stage specific files — avoid
git add -A / git add ..
- Never stage secrets (
.env, credentials, tokens).
- If unrelated changes are present, ask the user before including them.
5. Commit
- Subject: imperative sentence (at most 72 characters), optional
[scope] prefix
([iris], [zephyr], [docs], …).
- Body (optional, blank-line separated): what changed and why — the context a
future reader needs. Keep relevant evidence and caveats; do not inventory
files or tests.
- Do not use a conventional-commit prefix such as
feat: or fix:.
- No emoji, no markdown, no bullets in the subject. Do not credit yourself —
this includes any
Co-Authored-By, Generated with, provider, or session URL
trailer. Omit it even if a harness default suggests adding one.
Review the exact message before committing. After the commit, inspect it with
git show -s --format='%s%n%n%b' HEAD; do not push if a tool added attribution,
a session trailer, or other text that was not in the reviewed message.
Create the commit. If a pre-commit hook fails, fix the issue and make a new
commit — never amend (unless the user asks) and never force-push.
This is the checkpoint the rest of the flow builds on: the working tree is clean
and the branch diff is settled before the review reads it.
6. Lint-catalog review (before every PR)
./infra/pre-commit.py --review --agent-command='<your headless CLI>'
Run this after the commit and before opening a PR. It fans out read-only
agents over the branch diff against the merge base with main — committed and
uncommitted work alike — so the clean checkpoint from step 5 is exactly what gets
reviewed. Pass your own headless invocation (--agent-command='claude -p' for
Claude Code, 'codex exec' for Codex; defaults to claude -p).
The review is advisory and read-only: it reports findings on stdout and does
not edit, stage, commit, or push anything. Then fix or answer every finding,
reporting your actions to the user, and land any fixes as a new commit. Search
the infra/lint files for the rule behind each ml-... code. Treat findings as
guidelines — apply them when they make the code better; the goal is
high-quality code, not blind adherence.
Do not recursively rerun --review after small, targeted touch-ups made in
response to its findings. Validate behavioral edits with the normal mechanical
checks and relevant tests. For a formatter-only mechanical edit, rerun formatting
and lint checks only. Rerun the advisory review only when the follow-up materially
changes the branch's design or scope, or when the user asks for another pass.
Each run writes the raw per-arm prompts and outputs, the combined findings, and a
summary under /tmp/marin-linter/<branch>/<timestamp>-<uniq>/ (the path is printed at the end) —
read it when a lane is slow or a run looks wrong.
7. Push
If asked, or if the branch has an upstream, push to the remote tracking branch (git push -u origin HEAD if no upstream is
set). If the push is rejected (diverged history), stop and ask the user — do not
force-push.
8. Open or update the PR
Do this once the branch is ready for review. The PR description becomes the
squash-merge commit message. Follow
.agents/skills/writing-style/pull-requests.md exactly: an imperative title of
at most 72 characters and an information-dense body. Most bodies are a few plain
paragraphs. They state what changes and why; they do not reproduce the diff,
test plan, or implementation notes.
Example:
Title: [RL] Normalize DAPO loss over global tokens
Body:
Normalize DAPO loss over all response tokens instead of normalizing each
example separately. Per-example normalization over-weights short responses,
hurting math tasks where correct answers need longer derivations.
Fixes #1234
Issue linking. If the work came from a GitHub issue, add Fixes #NNNN
(auto-closes on merge) or Part of #NNNN (partial work). Do not invent an issue
just to satisfy this — omit the link when none exists.
Specifications (>500 LOC only). A genuinely large PR must link a spec in an
issue or design doc. Name the important design decisions in the PR body and link
the spec for module maps, code excerpts, and detailed rationale.
Inspect the payload. Draft the body in a uniquely named temporary file and
use --body-file. Re-open that file and apply the final compression pass before
publishing. After creating or editing the PR, fetch the
exact title,body with gh pr view --json and immediately correct text inserted
by a tool or stale template.
Create it. Unless the user says otherwise and permissions allow, push to a
branch on the main repository and open the PR from it (use a fork only when
direct push is unavailable or the user asks):
gh pr create --title "<title>" --body-file "<body-file>" --label agent-generated
- Always add the
agent-generated label.
- Never credit yourself in commits or PR descriptions.
- Include
Fixes #NNNN when addressing a pre-existing issue.
- If you have a specific github tool, you may use it.
9. Monitor the PR
Opening the PR starts the integration phase. Green CI is not an exit condition:
reviews and comments can arrive after checks pass. Monitor every PR until it
merges or closes, the user tells you to stop, or a 12-hour wait times out.
Before the first wait, read every current issue comment, inline review comment,
and submitted review once, then address anything actionable. This is a one-time
inspection, not a monitoring loop. The comment and review arms establish a
baseline when they start and wake only for later new or edited feedback.
Set one honest status immediately before waiting, for example:
weaver status ok "waiting for PR #<N> events"
Do not refresh that status while nothing changes. Invoke wait_for.py as a
foreground, genuinely blocking call:
uv run scripts/ci/wait_for.py --timeout 12h \
"github.ci <N>" "github.pr <N>" \
"github.pr_comment <N>" "github.review <N>"
github.pr covers terminal merged/closed state, merge conflicts,
ready-for-review transitions, and review-decision changes. It does not inspect
comment or review bodies, so it does not replace github.pr_comment or
github.review. Keep all three arms. Monitoring must not use a raw poll shell
expression, gh pr checks --watch, or repeated gh pr view calls.
The wait owns its exponential backoff. While it is running:
- remain silent until it returns an event, timeout, or error;
- do not poll GitHub manually;
- do not launch another
wait_for.py;
- do not narrate unchanged CI, review, or merge state;
- do not repeatedly poll a yielded process handle. Give it back to the runtime's
blocking wait/resume facility.
The command prints one JSON object and exits: 0 means an arm fired, 2 means
the overall timeout elapsed, and 1 means the wait failed. An event is not
always a successful verdict. Read result.conclusion for github.ci and
result.reasons for github.pr.
Act on the event, read any feedback that arrived concurrently, then re-arm:
github.ci — on failure, read the failing job log and fix the
regression. A failure in an untouched file is not automatically
pre-existing: confirm the same job fails on main independently before
treating it as unrelated. Once CI finishes, omit github.ci from the next
wait because its terminal result would fire immediately. Add it back after a
push starts a new run.
github.pr — merged and closed are terminal. Resolve conflicted
before re-arming; an unchanged conflict is intentionally reported again by a
fresh wait. ready_for_review and review_decision describe review-state
changes in the attached snapshots. When review_decision fires, inspect the
submitted review because the lifecycle payload does not include its body.
github.pr_comment / github.review — address every actionable human
and agent comment. Prefix agent-authored replies with 🤖 and resolve the
thread. The default significant-comment filter ignores the authenticated
user's comments, review-bot progress placeholders, clean verdicts, wrappers,
Loom's exact Working on this in loom: <session URL> acknowledgement, and
Loom access-control replies addressed to a bot.
- Timeout — report the last statuses in the timeout payload and hand off.
Do not replace the completed 12-hour block with manual polling.
Re-arm after every non-terminal event. Once CI finishes, omit github.ci so its
terminal result does not fire immediately; keep github.pr,
github.pr_comment, and github.review armed for later feedback. Read current
feedback once before each re-arm so simultaneous events are not absorbed into a
new baseline without being handled.
A question requiring user input pauses monitoring: raise attention, ask the
question, and resume after the answer. Otherwise the only exit conditions are a
merged or closed PR, an explicit request to stop, or a 12-hour timeout.
Rules
./infra/pre-commit.py is the only pre-commit entry point.
- Commit before the initial
--review; do not rerun it for minor findings-only touch-ups.
- Never amend a commit unless the user explicitly asks.
- If there are no changes to commit, say so and stop.
.agents/skills/fix-issue/SKILL.md — end-to-end issue-fix workflow.
AGENTS.md — coding guidelines.