SKILL.md
Kamae Code Review
Adversarial review against the kamae principles. The knowledge base lives in ../kamae/; this skill links rather than duplicates.
Step 0: Load applicable rules
Before any other step, glob and Read rules in priority order:
.claude/rules/*.md(project-level overrides at the working-tree root)~/.claude/rules/*.md(user-global preferences)../../rules/defaults/*.mdrelative to thisSKILL.md(plugin defaults)
For each file:
- Read the YAML frontmatter. Skip the rule unless
applies-toiskamae-reviewor*. - Group by
name. For eachname, keep only the highest-tier instance (1 > 2 > 3); within a tier the lexicographically last filename wins. - A
check-togglerule withenabled: falseremoves the named check from the walk in step 3 below. - A
conventionrule sets project-specific expectations the review respects (e.g., a designated location for Branded Types).
If no rules are found, proceed with all checks active. See [../../rules/README.md](../../rules/README.md) for the rule format.
Review Procedure
- Load principle knowledge. Before reading any code under review, read:
- [../kamae/SKILL.md](../kamae/SKILL.md) — principle index - The validation library guide matching the project's package.json under [../kamae/validation-libraries/](../kamae/validation-libraries/) (zod.md / valibot.md / arktype.md) - The Result library guide matching the project's package.json under [../kamae/result-libraries/](../kamae/result-libraries/) (neverthrow.md / byethrow.md / fp-ts.md / option-t.md) - Each topic file under ../kamae/ cited by the checklist sub-files you read.
- Read the files under review.
- Walk the checklist. Read each checklist sub-file in order; match findings to its items.
- [checklist/domain-modeling.md](./checklist/domain-modeling.md) — Discriminated Unions, Companion Objects, Branded Types, file structure, domain-owned ports, separate single-operation resolvers/stores (items 1.x) - [checklist/state-transitions.md](./checklist/state-transitions.md) — pure state transitions, exhaustiveness (items 2.x) - [checklist/error-handling.md](./checklist/error-handling.md) — Result types, error-boundary classification, DU error types (items 3.x) - [checklist/boundary.md](./checklist/boundary.md) — schema validation, no as assertions, schema-derived types (items 4.1, 4.2, 4.4) - [checklist/pii-protection.md](./checklist/pii-protection.md) — Sensitive<T> for PII (item 4.3) - [checklist/declarative-and-tests.md](./checklist/declarative-and-tests.md) — array operations, events, fixtures (items 5.x, 6.x)
- Report findings. For each violation:
1. Location (path:line). 2. Why it is a problem — cite the principle (link back to ../kamae/...) and the risk of violating it. 3. How to fix — code example showing the corrected version.
- Suggestions (non-violations with room for improvement) are communicated with the same format but framed as suggestions rather than findings.
Severity classes
Each checklist item is tagged High / Medium / Low.
- High — direct cause of runtime errors or compliance violations (
as, missing PII protection, missing schema validation, missing Branded Types on semantically distinct primitives). - Medium — invalid state representation, inconsistent error handling, missing exhaustiveness, catch-all type files, classes for domain models, domain contracts coupled to infrastructure types.
- Low — stylistic, readability, edge-case correctness (method notation,
interfacefor domain types, missingReadonly<>, non-kinddiscriminants, imperative array loops, fixtures withoutas const satisfies, matching schema/type duplication, misplaced ports without an outward dependency, unnecessarily broad dependency contracts). An existing schema/type mismatch is raised according to its incorrect acceptance, rejection, or data-exposure impact.
Example Finding
### Use of method notation
`src/domain/task/task-store.ts:15`
`save(task: Task): Promise<void>` uses method notation. Per
[`../kamae/SKILL.md` §1 "Use function property notation"](../kamae/SKILL.md),
parameters become bivariant under method notation, so a narrower implementation
such as `save(task: DoingTask): Promise<void>` will pass type checking at the
injection site.
Suggested fix:
\`\`\`typescript
type TaskStore = {
save: (task: Task) => Promise<void>;
};
\`\`\`