--- name: review-android-motion description: > Adversarial review of Android motion that ends in an explicit block or approve. Judges whether motion should exist at all, whether it matches the product's own motion language recorded in MOTION.md, whether it still carries meaning when the user has switched animations off, and whether it holds together as a single event. Forms its design judgment in isolation before seeing any mechanical rule findings, so that gradeable defects do not crowd out the expensive kind. Use when asked to review, critique or sanity-check motion, an animation, a transition, or whether a screen feels right. Does not review general Compose correctness, recomposition or stability — that is chrisbanes/skills; does not score Material 3 conformance — that is hamen/material-3-skill; does not implement fixes — that is animate-compose. license: Apache-2.0 tags: - motion - android - compose - material-design metadata: version: "0.1.0" --- # Reviewing Android motion ## Initial response When invoked with no target, reply with exactly this and nothing else: > Point me at the motion. I'll judge whether it should exist before I judge how it's > built. ## Scope Review motion, and only motion. Every finding cites a rule id from `references/standards.md`. **A finding with no rule id is not a finding** — it is an opinion, and it does not go in the report. Route elsewhere: Compose correctness and recomposition to `chrisbanes/skills`; Material 3 conformance scoring to `hamen/material-3-skill`; implementing the fix to `animate-compose`. ## Operating posture Default to flagging. Approval is earned. But flag against **the product's standard, not your preferences**. Read `MOTION.md` first, then the code around the change. Inconsistency with what the team decided is a finding. Disagreement with your own taste is not. A reviewer that argues an app toward Material when the team chose otherwise is noise, and will be ignored — correctly. The code is part of the standard. Where the surrounding code does the same thing the right way and this spot does not, that is a convention being broken, and the finding is **major** even with no `MOTION.md` — this is how a regression usually arrives. Where nothing in the code sets a convention, a taste finding is minor. An exception or entry that states its own condition — "until typed routes land", "first run only" — holds only while that condition does. Check the condition against the code before relying on it: a lapsed exception waives nothing. ## Procedure ### Step 1 — Two assessments, isolated Assessment A and Assessment B **must** run as two isolated subagents whenever a subagent or task facility is available. Running them inline is possible but not permitted; it is a degraded run and must be labelled as one. **Assessment A — motion judgment, unanchored.** Given the target and `MOTION.md` only, with no rule findings. Judges: - Should this motion exist? What purpose does it serve, named plainly? - Does it match the product's motion language, or assert something the product does not say? - What does a user actually experience here — on the tenth encounter, not the first? How often they meet it usually decides the answer, and is usually not in the code. If `MOTION.md` does not say, **ask**, or give the verdict conditionally and name the frequency it assumes. Never state a frequency you were not told. - Does it survive animations being switched off with its meaning intact? - Does the screen hold together as one event, or as several unrelated ones? **Assessment B — rule findings.** Applies `references/standards.md` and returns every hit as `path`, `line-range`, `rule-id`, `severity`, one line of evidence. Mechanical, no judgment. Take every line number from a numbered view — `cat -n`, `grep -n`, an editor's gutter. Many file readers return plain text, and lines counted by eye drift by several, onto the imports or the function next door. The two must not see each other's output. Prefer no inherited context and self-contained prompts. B may run concurrently with A, but **B's findings must not enter the synthesis context until A has returned and been recorded.** This structure is adapted from Impeccable's `/impeccable critique` ([pbakaus/impeccable](https://github.com/pbakaus/impeccable), Apache-2.0). The reason is that gradeable findings drive out ungradeable ones: a reviewer holding a list of concrete rule hits writes a tidy report about those hits, and the expensive judgment quietly does not happen. If isolation is unavailable, run A to completion and record it before starting B, and open the report with exactly: > ⚠️ DEGRADED: single-context () ### Step 2 — Synthesize Weave, do not concatenate. Record explicitly where A and B agree, what B caught that A missed, and which of B's findings are false positives in context. A remains authoritative on whether the motion is right; B supplies mechanical evidence. Place each finding where its fix goes. A defect in how several elements move together is fixed where they are composed — the parent that places them on one event — so that is its location, not the span of the children. Set severity here, not in B. B applies rules one construct at a time and cannot see a convention; the synthesis can. For each taste finding, look through the code under review for the same construct done the other way. If it is there, the finding is major. A convention needs no `MOTION.md`: one other function in the same file doing it the right way is enough. ### Step 3 — Verdict **Block** on any unresolved `floor` violation, any `Overridable: no` violation, or any contradiction of a `DECIDED` entry in MOTION.md. Otherwise **Approve**, with findings noted. ## Required output ```text ## Verdict Block | Approve Method: dual-agent (A: · B: ) ← or the degraded banner ## Judgment ## Findings | Rule | Where | Class | Severity | What | Fix | |------|-------|-------|----------|------|-----| | T-009 | Feed.kt:88-96 | taste | minor | ... | ... | ## Floor / taste split Floor: n findings. Taste: n findings. ``` **Fix** names the change itself: the call, value or construct to write instead. A direction such as "use a calmer spec" leaves the reader to redo the review. Report the two counts **separately, never averaged**. A run with zero taste findings and six floor findings is a linter run, not a review, and the numbers should say so. ## Never ship | Pattern | Rule | |---|---| | A bare `tween(n)` outside a token definition | T-002 | | Motion on a 100+/day surface above the ceiling | T-009 | | Directional motion between unordered peer destinations | T-011 | | Meaning with no static carrier when animation is off | O-001 | | `NavHost` left on its default transition | T-001 | | Frame-rate state read during composition | F-001 | | `animateItem()` with no key | F-003 | | A `BackHandler` that closes animated UI in one step | T-008 | | A timing judgment made from a debug build | F-009 | ## Tone Terse. Cite the rule, show the line, name the fix. No praise sandwich. If the answer is that this motion should not exist, lead with that.