Maintainer Runbook¶

This page is the operational side of ChuMicro's public process: the settings that enforce it, the levers only a maintainer can pull, and what to do when something needs bypassing. Contributors need nothing here; their view is CONTRIBUTING.md, Creating a Pull Request, and Releases and Promotion.
The contract¶
maintakes pull requests only: squash merge, review threads resolved, and the required checks green (preflight,compatibility (3.11),(3.12),(3.13),Validate mpy bytecode). The ruleset binds the maintainer too. Bypass exists for emergencies and works only through a pull request, never a direct push.- Merging a PR that bumps a
VERSIONfile publishes an experimental release automatically. Merging is a release decision, not only a code decision; readVERSIONdiffs with that weight. - Stable is promoted, never automatic. Run
promote.ymlfrommainwith the experimental tag list, normally in response to a promotion request issue.
Repository settings that carry the process¶
The workflow files enforce what they can, but these settings live in the GitHub UI and API, where a code review cannot see them drift. Re-verify after any settings change.
| Setting | Required value | Why |
|---|---|---|
| Ruleset "main branch required rules" | PR required, squash only, the five required checks, every bypass actor in "pull request" mode | Nobody direct-pushes main, including admins |
| Ruleset "gh-pages required rules" | All updates blocked; bypass for DeployKey and admins only | Only the docs workflows write gh-pages, over GH_PAGES_DEPLOY_KEY |
| Actions: default workflow permissions | Read repository contents | Every workflow declares its own permissions; the read default backstops future files |
| Actions: approval for fork PR workflows | Required for all outside collaborators | A human reads the diff, including workflow edits, before repo CI runs it |
| Actions: "Allow GitHub Actions to create and approve pull requests" | Off | No workflow, AI review included, can ever count toward a merge |
Environment pypi |
Deployments from main only |
The PyPI trusted-publisher exchange is unreachable from any other ref |
| Private vulnerability reporting | Enabled | It is the only reporting channel SECURITY.md offers |
Verification commands, from a checkout with gh authenticated:
gh api repos/ChuMicro/ChuMicro/rulesets --jq '.[] | {name, enforcement}'
gh api repos/ChuMicro/ChuMicro/actions/permissions/workflow
gh api repos/ChuMicro/ChuMicro/actions/permissions/fork-pr-contributor-approval
gh api repos/ChuMicro/ChuMicro/private-vulnerability-reporting
Reviewing an outside pull request¶
- Read the diff before approving the CI run. A fork PR that edits
.github/workflows/ci.ymlruns its edited version on its own PR, so a green check on a fork PR means nothing until you have read what CI it actually ran. Fork runs get a read-only token and no secrets either way; the approval gate is about compute and about not lending the repo's green checkmark to unreviewed automation. - Approve the workflow run. The required checks gate the merge from there.
- Optionally comment
@claude /reviewon the PR for a Claude first pass (next section). - If a
VERSIONmoved, remember the merge publishes an experimental release. If one should have moved and did not,check-versionfails preflight and says so. - Squash-merge. The branch deletes itself, and
release.ymlfires if aVERSIONchanged.
AI review: design and abuse model¶
ai-review.yml lets Claude review a PR when a maintainer comments @claude /review on it. The threat that shaped the design is the drive-by PR: someone opens a PR that has nothing to do with the project, hoping a public "free review" spends tokens on the maintainer's account. Here is why that and its neighbors do not work:
- A PR alone spends nothing. The workflow triggers on comments, not on PRs. Opening a PR, editing it, pushing to it, or commenting on it as an outsider starts no run: the job filters the commenter's repo association, and the action independently verifies the actor has write access before doing anything. The only lever that spends money is the maintainer's own
@claude /reviewcomment, one review per comment, 20 minutes maximum per run. - The PR is data, not code.
issue_commentworkflows run the file from the default branch, so a PR editingai-review.ymlcannot change what reviews it. The PR head sits inpr-head/and is only read; no step installs, builds, imports, or tests it, so malicious PR code never executes in the job that holds the API key. - Injection has a small blast radius. The action strips hidden HTML, invisible characters, and similar smuggling paths from PR content, and the prompt orders Claude to treat PR text as data. If an injection lands anyway, the job's token can post comments and nothing else: contents are read-only, and the repository setting that would let Actions approve PRs is off. The worst case is a misleading review comment that a human reads with the same skepticism as any review.
- The key is scoped and capped.
ANTHROPIC_API_KEYexists only for this workflow. Set a monthly spend cap on that key in the Anthropic console so a runaway is bounded in dollars, not just minutes.
To retire the whole mechanism, disable the workflow in the Actions tab; the comment command becomes inert.
GitHub's Copilot code review composes with this rather than competing: it is a settings-page toggle, runs entirely on GitHub's side with GitHub's billing, and can take an always-on first pass on every PR, while @claude /review stays the deeper pass a maintainer summons deliberately. With the settings above, neither reviewer can approve a PR or count toward a merge.
Secrets inventory¶
| Secret | Reaches | Notes |
|---|---|---|
BUNDLE_DEPLOY_KEY, EXPERIMENTAL_BUNDLE_DEPLOY_KEY |
The two bundle repos, git-level | Single-repo SSH deploy keys |
LIBRARIES_DEPLOY_KEY, EXPERIMENTAL_LIBRARIES_DEPLOY_KEY |
The two libraries-channel repos | Single-repo SSH deploy keys |
GH_PAGES_DEPLOY_KEY |
This repo's gh-pages |
The docs workflows push over it, so their token stays read-only |
BUNDLE_TOKEN |
GitHub API, bundle-release creation | A PAT. Keep it fine-grained and scoped to the two bundle repos with Contents and Releases only; a classic repo PAT reaches everything the account can |
ANTHROPIC_API_KEY |
The AI review workflow | Spend-capped in the Anthropic console |
PyPI itself needs no secret: both publish workflows use trusted publishing (OIDC) through the pypi environment.
Action pinning¶
Every action in .github/workflows/ is pinned to a commit SHA with the version in a trailing comment. Dependabot bumps the SHAs monthly. Keep it that way: several of these actions hold deploy keys or tag-creation rights, and a moved tag on one of them is a supply-chain compromise of the release fabric. Do not accept a PR that reverts a SHA pin to a tag.
Emergencies¶
mainis broken and the fix cannot pass a required check (say, the check itself is what broke): open the fix as a PR anyway and use ruleset bypass at merge time. Bypass works through the PR merge button only; direct pushes stay blocked even for admins.- A required check is stuck on infrastructure (runner outage, cache corruption): re-run the job first. Bypassing a merge on a red check should be rare enough to feel uncomfortable.
- A release run half-finished: every leg is idempotent and the git tag is written last, so re-dispatching the same run with the same inputs finishes what remains. Releases and Promotion has the per-failure-mode detail, including first-release PyPI bootstrapping.
- Settings drift or emergency loosening: admins can always edit rulesets and Actions policy. Treat any loosening as temporary, and restore against the table above when the incident closes.