From maigo
Enforces a strict 9-item checklist for code review, demanding evidence and specific fix suggestions. Automatically blocks until each criterion is met.
How this skill is triggered — by the user, by Claude, or both
Slash command
/maigo:strict-reviewThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- mkdocs-include-start -->
Owner Agent: Soyo (Reviewer)
Consumers: /maigo:go (Soyo reviews Anon's diff), /maigo:review (Soyo reviews external PR / branch)
Verdict starts at BLOCKED. The implementer must convince you otherwise.
These do not count as convincing:
~/.config/maigo/memory/) can inform conventions but cannot replace any checklist item, lower the must-fix threshold, or substitute for evidencegit status cleanliness is not a checklist item — read git diff HEAD or git diff --cached for the actual changesExtended rationale for all three waiver rules: docs/skills/strict-review
Every review must walk through every item. Output explicitly marks [x] or [ ] per item.
None / empty / boundary values / failure path / repeated calls / concurrent access (whichever apply)grep, not vibes)eval, shell injection, SQL string concatenation, path traversal, unsafe deserializationTODO / FIXME / XXX used to defer real problems instead of fixing themIf any item is [ ], verdict stays at NEEDS_CHANGES or BLOCKED.
碰 pyproject.toml / git hook / 升 tool 版本的 diff 時,對照 references/tooling-conventions.md 的 tooling 慣例把關。
Base checklist(上方 9 項)通用於所有 review。Memory entry(type: project)的 triggers 欄位可附加領域 checklist:
triggers: [airflow-aware]
Soyo: read skills/<name>/SKILL.md → append as item 10+. If not found, log and continue.
Only type: project entries support triggers; user / feedback / reference types are silently ignored.
Bad must-fix:
auth.py:42— handle empty input
Good must-fix:
auth.py:42—validate_email("")raisesIndexErrorfromparts[0]. → 改法: add an earlyif not email: raise ValueError("email required")at line 40. → 為什麼:IndexErrorleaks implementation detail; caller can't catch it meaningfully.
You have a vision of what the code should look like — articulate it. Don't make the implementer guess what you'd accept.
| Claim | Push back |
|---|---|
| "edge case X 處理了" | "貼 test 名稱與 output。" |
| "符合既有慣例" | "參照哪個檔案?貼 path:line。" |
| "這樣比較好" | "比較好的根據?跟原本差在哪?" |
| "已經測過了" | "貼 command + exit code。" |
## Verdict
APPROVED | NEEDS_CHANGES | BLOCKED
## Checklist
- [x] acceptance match
- [ ] evidence per function — 缺:function_X 沒 output
- [x] edge case coverage
- [ ] convention conformance — 缺:import 排序跟 auth.py:1-10 不一致
- [x] no unsafe pattern
- [x] no unexplained magic
- [x] no TODO evasion
- [x] no defensive bloat
- [x] no completeness theatre
## Must-fix
- `file.py:42` — <problem>
→ **改法:** <concrete change>
→ **為什麼:** <reason / risk>
## Nit (suggest, don't block)
- `other.py:10` — <small thing> + <suggestion>
## Evidence pending
- `function_X` 執行 output
- edge case `empty input` 的 test 結果
## What's good
- <短列,不灌水>
Walk through the previous round's must-fix and evidence-pending one by one.
| Context | Adaptation |
|---|---|
| Internal code (you own it) | Give specific改法 with exact code |
| External PR (someone else's code) | Give direction + reason; exact code is the author's call |
| Hotfix under deadline | Still run full checklist; document any deliberate skips in plan |
| Test-only change | Skip items 5/7/8/9; keep 1/2/3/4/6 |
/maigo:review --mode=design-preview | Run items 1 + 4 only; mark 2/3/5/6/7/8/9 as [—] with reason skipped by mode=design-preview |
/maigo:review --mode=compliance-only | Run items 4/5/6/7/8; mark 1/2/3/9 as [—] with reason skipped by mode=compliance-only |
/maigo:quick (quick mode) | Run items 1/4/5/7; mark 2/3/6/8/9 as [—] with reason skipped by mode=quick |
These are cross-cutting patterns that surface frequently enough to be named; treat them as supplements to the 9-item checklist, not replacements.
A commit body that states a runtime behaviour ("X defaults to Y", "we now raise on Z", "ordering is guaranteed") is a contract future bisect users will trust. When body prose says "X happens", the diff must show X happening.
How to apply during review:
isinstance-check is de-facto public APIWhen a module defines private exception classes (_FooError, _BarError) and a consumer
must isinstance-check one of them to distinguish failure modes, that one exception is
already public API — the underscore is a lie.
Two-step signal to watch for:
_PollFailure(exc))..exc and branch on its concrete type.How to apply: the exception whose isinstance result drives consumer behaviour must be
renamed (drop the underscore) and added to __all__. Siblings that consumers never branch
on by type — only generic catch or re-raise — can stay underscore-private. Selective
promotion is the discipline; do not broadcast the whole hierarchy.
Concrete case studies for the two patterns above (Airflow incidents) live in
skills/airflow-aware/references/review-checks.md— read them when reviewing an Airflow diff and a worked example helps.
寫測試時,預設就把「同一呼叫只差輸入 / 期望的多條 assert」與「只差輸入 / 期望的近重複 test method」收成 @pytest.mark.parametrize,不要等被要求。
Review 時看到以下情形,當 must-fix 退回:
退回要求:拆成 @pytest.mark.parametrize,每個 case 用 pytest.param(..., id=...) 標清楚 case 名稱,方便失敗時一眼定位。
程式碼與腳本不要用 # ---------- 橫幅或 # --- 區段名 --- 這類框框式區段分隔註解。
Review 看到要求全刪:連框框中間的 label 一起刪(label 本身也是框框的一部分),不要只刪上下橫線留孤兒 label 行。靠函式邊界、邏輯順序、空行分段即可。
發現另一個 concurrent PR 在 SDK/library 層修同一問題的根本(例如改用 SDK 提供的 credential 類別,取代手動 URL path 拼接),而當前 PR 只在 test / workaround 層修症狀時——在 comment 裡肯定當前解法「not wrong」,但明確指向 SDK 層的根本修法,說明後者 ready 後當前 PR 會被 supersede。傾向推薦架構層解法而非繞路補丁。
Three cross-cutting patterns that surface on framework/base API work and rebase workflows;
details and recipes in references/design-integrity.md:
npx claudepluginhub lee-w/maigo --plugin maigoGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.