AGENTS.md · git:20261004.c10df8e · 2026-10-04 · sha256 00b4bf6dbb2dde24

AGENTS.md git:20261004.c10df8eA

Immutable. This exact content never changes and is served at /api/v1/blob/00b4bf6dbb2dde24.

# Wikipedia-AI-Skills — Agent Instructions

Loaded automatically by pi in every session in this repo. See
`CONTRIBUTING.md` for the full contributor guide; this file is the binding
short version.

## PR-first workflow (hard rule)

All changes to `main` go through a pull request. Branch protection enforces
this server-side (6 required CI checks, no reviews); follow it even when you
could bypass it.

1. Start from up-to-date `main`: `git checkout main && git pull --ff-only origin main`
2. Create a branch: `git checkout -b <scope>/<change>` (e.g. `feat/my-skill`, `fix/toolforge`, `docs/agents-md`)
3. Commit with conventional style: `feat|fix|docs|ci|chore(<scope>): <summary>`
4. Push the branch, then `gh pr create` — the template
   (`.github/PULL_REQUEST_TEMPLATE.md`) auto-applies; fill in summary,
   what/why, and how it was tested
5. `gh pr checks --watch` — all 6 checks must pass before merging
6. Merge with `gh pr merge --merge --delete-branch`

Direct pushes to `main` are admin-bypass only, reserved for emergencies
(e.g. CI outage blocking a hotfix). If you bypass, say so explicitly in the
commit/PR.

## Remote state — query it, never infer it from local refs (hard rule)

`git log origin/main..HEAD` proves exactly one thing: *not merged into main*. It
says nothing about whether a branch was pushed, whether a PR exists, or what its
checks and review state are.

Learned the hard way: asked whether a commit had been pushed, an agent ran
`git log origin/main..HEAD`, saw the commit absent from `main`, and reported it as
"exists only on a local branch — awaiting its own PR/push". The branch was pushed
and had an **open PR with green CI**. A stale local `origin/*` is the usual cause.

- **Fetch first** (`git fetch origin`), or ask `gh` — those queries hit the API and
  cannot be stale.
- **Branch pushed?** `git ls-remote --heads origin`.
- **PR exists / open / merged?** `gh pr list`, `gh pr view <n>`.
- **Checks / mergeable?** `gh pr checks <n>`,
  `gh pr view <n> --json mergeable,mergeStateStatus`.
- **State the method with the claim.** "No PR in `gh pr list`" is checkable; "it
  isn't pushed" is a guess dressed as a fact. If you have not queried the remote,
  say so instead of asserting.
- **Absence is not evidence.** A local branch can exist with no PR; an open PR can
  exist for a branch you never fetched; and because this repo deletes branches on
  merge (`--delete-branch`), a missing branch says nothing about whether its PR
  merged — use `gh pr view <n> --json state,mergedAt`.

## Skill contributions

For new or changed skills (`.claude/skills/<name>/`):

- **New skills:** pass the 7-question candidacy filter
  (`docs/design-philosophy.md` §2) and record the verdict in the PR
- **Register:** `README.md` (skill table + "What can I do" table),
  `ROADMAP.md` ("Published skills"), and run
  `python3 scripts/refresh-url-registry.py --new-only` for any new URLs —
  CI's Skill Registration Check enforces the first two
- **Tests:** add mock-based tests under `tests/` for new scripts/assets;
  run `python3 -m pytest tests/ -q`. The suite is green (3 skips are
  optional-dependency guards); tests marked `@pytest.mark.slow` make real API
  calls and skip on HTTP 429/network drops via `run_live()` from
  `tests/live_calls.py` — a skip there is CI throttling, not a failure
- **Freshness:** bump `last_verified` in the frontmatter of any changed
  SKILL.md
- **Verify before pushing skill changes** (all offline, all must pass):
  `python3 scripts/verify-links.py && python3 scripts/verify-freshness.py \
  && python3 scripts/verify-snippets.py && python3 scripts/verify-commands.py \
  && python3 scripts/verify-api.py && python3 scripts/verify-mul-labels.py \
  && python3 scripts/verify-script-guards.py`

## API etiquette (summary)

Every request to Wikimedia/Wikimedia-adjacent hosts needs a descriptive
User-Agent (`$WIKIMEDIA_USER_AGENT`), 429/403 handling, and ≥1s pacing
**when running outside Toolforge/WMCS** (rate limiting is not enforced on
bots in Toolforge/WMCS — see the Wikitech Robot policy) — see the global
AGENTS.md and the `wikimedia-api-access` skill for details.

## Local tooling

- Githooks (pre-push tooling-reference check): `./setup-hooks.sh`
- The 6 required CI checks: `check-skill-registration`,
  `check-conftest-auto-discovery`, `check-roadmap-mentions`, `verify`,
  `validate-tooling`, `tests` — they run on every PR unconditionally