Installs into .claude/skills of the current project.
Are you the author of In Review?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/matthewsinclair-in-review)
---
description: "Two-stage code review: spec compliance then rule-library compliance via critic-<lang>"
chains_to: ["in-verify"]
---
# Two-Stage Code Review
Review code in two distinct passes. Do not combine them -- each pass has a different focus.
## When to invoke
- After completing a work package or significant task
- Before marking a steel thread as done
- When the user asks for a code review
## Procedure
### Stage 1: Spec compliance
Does the implementation match the plan?
Checklist:
- [ ] All deliverables from the WP/ST `info.md` are implemented
- [ ] No extra features added beyond what was planned
- [ ] File paths match what was specified in the plan
- [ ] Edge cases identified in the design are handled
- [ ] No "TODO" or "FIXME" left unresolved from the plan
**For Elixir projects with test specifications**: delegate to the `diogenes` agent for test-spec validation. Provide the design doc and the implementation; ask diogenes to verify alignment between spec and tests.
### Stage 2: Rule-library compliance
Is the code consistent with the Intent rule library? This stage dispatches to the right `critic-<lang>` subagent based on the project's ecosystem.
#### Language dispatch
Read the project's declared languages from `intent/.config/config.json`:
```bash
jq -r '(.languages // []) | .[]' intent/.config/config.json
```
For each language listed, dispatch to its critic subagent. Code languages map directly: `elixir` -> `critic-elixir`, `rust` -> `critic-rust`, `swift` -> `critic-swift`, `lua` -> `critic-lua`, `shell` -> `critic-shell`. The prose disciplines both map to the one `critic-prose`: `author` (books + courseware) and `content` (web pages + posts) each dispatch to `critic-prose`, which reviews prose (`.md`/`.mdx`/`.html`), not code, and resolves which discipline pack to apply from the declared `languages` -- see Prose projects below.
A mixed project (multiple entries in `languages`) dispatches to each critic whose language matches the files being reviewed. If `languages` is empty, no language-specific critic runs; only the agnostic checklist below applies.
#### Generic rule checklist (applies to every language)
Confirm no concretised-by rule is violated at the agnostic level:
- [ ] `IN-AG-HIGHLANDER-001` -- no duplicated code paths. To check for prior art, ask the index first: `intent search --kind def <name>` answers whether a thing with that name already exists anywhere in the tree, and the answer carries the index's own freshness. When it says the index is not complete for the paths that matter, fall back to grep. Where the project keeps a registry, `intent modules find <name>` searches that as well.
- [ ] `IN-AG-THIN-COORD-001` -- coordinators parse -> call -> render
- [ ] `IN-AG-PFIC-001` -- Pure Function, Impure Coordination. **Read it before checking it: `intent claude rules show IN-AG-PFIC-001`.** This line used to say _pattern-match, pipe, tagged-tuple, compose idioms in play_, which is a different rule -- code can be fully idiomatic and still bury I/O three calls deep in a domain core, so the old check passed the violation and recorded the rule as examined.
- [ ] `IN-AG-NO-SILENT-001` -- no rescue-and-swallow, no discarded fallible results
#### Delegate to `critic-<lang>`
The critic reads the rule library, applies each rule's Detection heuristic, and emits a report grouped by severity (CRITICAL, WARNING, RECOMMENDATION, STYLE). The skill invokes the critic once for code and once for tests, then reports the union:
```
Task(subagent_type="critic-elixir", prompt="review lib/**/*.ex")
Task(subagent_type="critic-elixir", prompt="test-check test/**/*_test.exs")
Task(subagent_type="critic-rust", prompt="review src/**/*.rs")
Task(subagent_type="critic-rust", prompt="test-check tests/**/*.rs")
Task(subagent_type="critic-swift", prompt="review Sources/**/*.swift")
Task(subagent_type="critic-swift", prompt="test-check Tests/**/*.swift")
Task(subagent_type="critic-lua", prompt="review src/**/*.lua")
Task(subagent_type="critic-lua", prompt="test-check spec/**/*_spec.lua")
Task(subagent_type="critic-shell", prompt="review bin/* scripts/*")
Task(subagent_type="critic-prose", prompt="review docs/**/*.md")
Task(subagent_type="critic-prose", prompt="review content/**/*.md")
```
**Prose projects (`author` and/or `content` in `languages`)**: `critic-prose` reviews prose, not code, and resolves its discipline pack from the declared `languages`. Under `/in-review` run its mechanical `review` tier (house style, structure, the mechanical trope pass, plus the discipline's mechanics -- author front-matter/objectives, or content page-meta/alt-text/links) on the prose targets (`.md`/`.mdx`/`.html`). Its judgment tier -- `craft-check` (author: voice, continuity, citation; content: scannability, CTA, reading level) and the full `/in-detrope` diagnosis -- is on instruction, not part of the automatic pass. Per the per-language loop above, a prose-only project (`languages: [author]` or `[content]`) runs no code critic; a mixed project (eg `[elixir, content]`) runs `critic-elixir` on the code subtree and `critic-prose` on the prose subtree -- dispatch is scoped to the declared `languages`, so a critic whose language nobody declared never runs. A project declaring both `author` and `content` applies both discipline packs.
**Polyglot projects**: when `languages` has more than one entry, the user has explicitly declared a polyglot. Invoke each critic with a target glob narrowed to its own subtree. Array order is the explicit declaration; the first entry is the primary where a primary is needed.
**Project-local config**: critics honour `.intent_critic.yml` at the project root for `disabled:` and `severity_min:` overrides. The full contract and a worked sample config are served by the INSTALL, not by the project: read the rules the install carries with `intent claude rules list` / `intent claude rules show <id>`, and the sample config ships beside them in the install's own `rules/_schema/` directory. **A path into the Intent repository would be wrong here twice over** -- it does not exist in a project Intent was installed into, and this file IS the installed payload.
### Stage 3: After both stages
- Fix critical issues before proceeding
- Log non-critical issues with `intent issues add "<title>" --severity low --body "<detail>"` (or in the thread's attached `tasks.md`, if it carries one)
- Invoke `/in-verify` to confirm fixes
## Red Flags
| Rationalisation | Reality |
| ----------------------------------------- | ------------------------------------------------------ |
| "The code works, review is unnecessary." | Working code can still be wrong. Review catches drift. |
| "I wrote it, I know it's correct." | Author blindness is real. Review with fresh eyes. |
| "Review will slow us down." | Rework from missed issues is slower than review. |
| "Stage 1 is enough, skip quality review." | Correct-but-messy code becomes tomorrow's bug. |