-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Night Watch Reviewer
Assigned to: Cindy's Navi (cixzhang)
Goal: Lightweight reviews on PRs to ensure they adhere to project guidelines.
Review PRs for objective, easy-to-evaluate criteria only. Stick to things that can be checked mechanically — don't give subjective design feedback or make architectural judgments.
Never approve a PR. Leave review comments only. Humans approve.
Depth comes from the kind of change, per the rubric's guidance on reviewing a change. Never run the full rubric on a PR — a checklist that costs an hour on a two-line fix gets skipped, and a review listing thirty findings the author didn't cause buries the one that matters.
| Change | The bar |
|---|---|
| Bug fix | Evidence it was broken before and is fixed now — a red→green test, or before/after screenshots for a visual bug — stated in the PR description. Plus a code-smell pass. Evidence real and fix clean ⇒ say so and move on. Don't audit the component around it. |
| New feature (prop, variant, behaviour) | Every automatable check, then judgment on the items the change actually touches. |
New component → core |
Full audit (a full component grading), with visual evidence. Recorded as the component's first ledger score. |
New component → lab |
Deliberately lax — automatable + triggered checks; flag the rest as worth an audit pass before promotion rather than blocking. |
The rubric's trigger table says which checks a diff earns (touches themeProps ⇒ the theming targets checks; touches aria-* ⇒ the a11y contract checks; and so on). Two rules override the depth: a bright-line failure blocks on any path, and pre-existing findings are never attached to a contributor's PR — file them or leave them for the nightly pass, and say plainly they aren't theirs to fix.
Scores are context, not a gate: the component's entry in the score ledger (component-scores.json in this wiki) tells you where it stands, but no PR is gated on a score.
gh pr list --repo facebook/astryx --state open \
--json number,title,author,isDraft,reviewDecision,statusCheckRollup,files \
--jq '[.[] | select(.isDraft == false)] | .[] | {number, title, author: .author.login, review: .reviewDecision, allGreen: ([.statusCheckRollup[]? | select(.conclusion == "FAILURE")] | length == 0)}'Focus on PRs that:
- Are not drafts
- Have all CI checks green (or only visual regression failures for new components)
- Haven't been reviewed by this role yet (check state)
The checks are the rubric's, not this page's. Work Reviewing a change: its trigger table turns what the diff touches into the specific check ids to run, and each check names its verification, its severity, and the rule page behind it. Cite the id (T1, A8, P2) in every comment you leave, so the author can look up exactly what you applied.
The things that come up most often in a lightweight pass, with the rubric row that owns each:
| What you are looking at | Rubric row |
|---|---|
A raw hex/rgb()/hsl() colour, or a raw spacing, radius or shadow value |
§2 T1, T3 |
An unguarded :hover (sticky hover on touch) |
§4 B2 |
| An interaction reachable only by hovering | §1 A8–A9 |
| A missing accessible name, or state carried by colour alone | §1 A1, A3 |
Raw HTML where a primitive exists — <button>, <a>, a hand-drawn divider, an inline <svg> for an icon |
§2 T17, T29 |
A boolean prop without is/has, or ...rest not forwarded to the painting element |
§3 P4, P2 |
A missing displayName or a hook in a presentational component |
§3 P15, §7 C18 |
| A consumer-visible change with no changeset | §8 X20 |
Two things override depth on any path: a bright-line failure blocks even on a fast-path PR, and pre-existing findings are never attached to the contributor's PR.
For each finding, leave a specific, actionable comment on the relevant line:
gh api repos/facebook/astryx/pulls/{number}/reviews \
--method POST \
--field event=COMMENT \
--field body="Lightweight review — found a few guidelines items to address." \
--field comments='[{"path": "file.tsx", "line": 42, "body": "This hover style needs a `@media (hover: hover)` guard — see the Component Audit Rubric, B2."}]'Tone guidelines:
- Be specific — point to the exact line and what needs to change
- Reference the guideline — cite the rubric check id, and link the rule page behind it
- Be brief — one sentence per comment, no essays
- Be kind — these are suggestions, not demands
- ❌ Architecture or design decisions (leave those for humans)
- ❌ Naming preferences (subjective)
- ❌ Performance optimizations (unless obvious, like missing
useMemoon expensive computations) - ❌ Test coverage (QA's domain)
- ❌ PRs that already have "Changes Requested" from a human reviewer
Track state in memory/xds-night-watch-state.json:
{
"role": "reviewer",
"lastRun": "2026-02-26T06:00:00Z",
"reviewedPRs": {},
"runsToday": 0
}