Review a Service
A review is worth having only if it finds what the author could not see. That means running the
checklists mechanically rather than reading for a general impression, verifying each finding
against a concrete failure, and being ruthless about what does not make the bar.
Padding a review with style opinions is not neutral — it buries the two findings that mattered.
Required Skills
Read and apply every principle that the code under review touches:
clean-architecture — layering, dependency direction, SOLID, pattern justification. (always)
test-strategy — test level, determinism, assertion quality, coverage of failure paths. (always
when tests are present or absent)
collaborative-judgment — deliberate trade-offs are reported as questions, not defects. (always)
service-boundaries — ownership, coupling, new modules or services. (conditional)
domain-modelling — domain types, aggregates, value objects. (conditional)
data-access — repositories, queries, transactions, migrations, caches. (conditional)
cqrs-and-consistency — read models, projections, ownership. (conditional)
infrastructure-adapters — clients, consumers, publishers, SDK wrappers. (conditional)
resilience-patterns — any call leaving the process, any message handler. (conditional)
idempotency-and-immutability — retryable operations, shared or mutable state. (conditional)
secure-service — handlers, clients, queries, credentials, personal data. (conditional)
api-contracts — endpoint, schema, or published event changes. (conditional)
api-protocols — GraphQL, gRPC, WebSocket or SSE surfaces. (conditional)
config-and-dependencies — settings, flags, dependency manifests. (conditional)
contract-testing — integrations between services. (conditional)
Workflow
Step 1 — Scope
Establish exactly what is under review, and say so before starting.
| Ask |
Scope |
| "review my changes" |
Uncommitted working tree plus staged changes |
| "review this branch" / a PR number |
The diff against the merge base |
| "review the orders service" |
The whole service — announce a sampling strategy, since a full audit of a large codebase in one pass is not credible |
| A file or directory |
That path |
For a diff, a finding must be in the changed code or activated by it. Pre-existing issues in a
file the diff happens to touch go in a separate "out of scope" list — never mixed into the findings.
Step 2 — Load the project's standards
- Read
.msskills/stack.md — idiom-appropriate expectations, and which libraries exist.
- Read
.msskills/config.yaml and follow each principle's Config Resolution. Project overrides
outrank this library's defaults. Reporting a deliberate house standard as a violation destroys
the review's credibility.
- Read the blueprint in
.msskills/designs/ if one covers this change. Deviation from an approved
design is itself a finding.
- Read
.msskills/decisions.md. A recorded decision is settled — do not re-litigate it as a
finding. If you believe it is now wrong, say so under judgment calls with what changed.
Step 3 — Run the checklists
For each file in scope, apply the Self-Validation Checklist and Active Anti-Pattern Scan of every
principle from Required Skills that governs that file. Work through them item by item — the value
of this workflow is that it is mechanical where a human reviewer is impressionistic.
Give disproportionate attention to the defects that are cheap to miss and expensive to ship:
- Missing ownership check — an ID from the request used to load a record with no scoping to the
caller (
secure-service, API1). Look for it on every single read and write path.
- Missing timeout on any outbound call (
resilience-patterns).
- Dual write — a database commit and a broker publish as separate steps (
resilience-patterns).
- Non-idempotent consumer under at-least-once delivery
(
idempotency-and-immutability).
- N+1 query on any path that handles a collection (
data-access).
- Breaking contract change — a field removed, renamed, narrowed, or made required
(
api-contracts).
- Destructive migration that makes the previous release un-rollbackable (
data-access).
- Secret in the repository (
secure-service).
- Untested failure path — error handling with no test (
test-strategy).
For a large scope, sample deliberately and say how: every trust boundary and every outbound call
first, then the domain, then the rest. State what you did not examine.
Step 4 — Verify each candidate
For every candidate finding, before it goes in the report:
Construct the failure. Name the input, state, or sequence that makes it go wrong, and the
observable consequence. If you cannot, it is a preference — drop it.
Look for the central mechanism. Timeouts, authorisation, validation, and error mapping are
often applied by a filter, a client factory, an interceptor, or a base class. A reviewer who has
not gone looking will report a wall of false positives.
Check it is not deliberate. A comment, a decision record, or a project override may explain
it. If it looks deliberate but undocumented, that is a judgment call, not a defect.
Assign severity by consequence, not by effort to fix:
| Severity |
Meaning |
| Critical |
Data loss, data exposure, unauthorised access, or breaks a deployed consumer |
| High |
Will cause an incident under load or failure |
| Medium |
Correctness or maintainability defect with bounded blast radius |
| Low |
Real but minor |
Anything below Low is not reported.
Independent pass. For a substantial change, also run the microservice-reviewer agent over the
same scope and merge its findings with yours, keeping the more specific version of any duplicate.
A second pass with no memory of the reasoning catches what a single reading rationalises.
Step 5 — Report
Lead with a two-line verdict: what the change does, and whether it is safe to ship. Then findings,
most severe first:
**High — Outbound call to the pricing service has no timeout**
`src/adapter/PricingClient.java:34` · violates `resilience-patterns`
The client is constructed without a request timeout, so a hung dependency holds the calling
thread indefinitely.
**Fails when:** pricing stops responding without closing connections. Checkout threads accumulate
until the pool is exhausted; every checkout then fails, including those not needing pricing.
**Fix:** set an explicit request timeout below checkout's own budget, and wrap the call in the
circuit breaker already configured for `inventory` in `ResilienceConfig`.
Close with:
- Judgment calls — real trade-offs the author may have decided deliberately, in the
collaborative-judgment format. Never as findings.
- Out of scope — pre-existing issues worth their own change, one line each.
- What was checked — the principles applied and, for a sampled review, what was not examined.
If nothing meets the bar, say so and list what you checked. A clean review is a real result.
Rules
- Report; do not fix. This workflow ends with findings. Applying them is a separate,
explicitly requested step.
- No praise section. The author wants the defects.
- No padding. Two real findings beat two real findings and eight style notes.
- Cite a file and a line for every finding.
- Never restate the principle — cite it and go straight to the specific violation.
- Say when you are unsure. A flagged uncertainty is useful; a confident claim that turns out to
be wrong costs the reader trust in the whole list.
1---2name: review-service3description: Audit service code against every microservices principle and report severity-ranked findings, each anchored to a file, a line, and the rule it breaks. Covers scoping a review to a diff, branch, pull request or whole service, running the applicable principle checklists and anti-pattern scans, verifying each candidate finding against a concrete failure scenario, and separating genuine defects from deliberate trade-offs. Use before merging, when reviewing a pull request or a diff, when auditing an existing service, or when the user says 'review', 'code review', 'audit this', or 'is this ready to ship'. Reports findings and does not change code — to apply fixes, follow up with implement-service or refactor-safely.4license: MIT5---67# Review a Service89A review is worth having only if it finds what the author could not see. That means running the10checklists mechanically rather than reading for a general impression, verifying each finding11against a concrete failure, and being ruthless about what does not make the bar.1213Padding a review with style opinions is not neutral — it buries the two findings that mattered.1415## Required Skills1617Read and apply every principle that the code under review touches:18191. `clean-architecture` — layering, dependency direction, SOLID, pattern justification. (always)202. `test-strategy` — test level, determinism, assertion quality, coverage of failure paths. (always21 when tests are present or absent)223. `collaborative-judgment` — deliberate trade-offs are reported as questions, not defects. (always)234. `service-boundaries` — ownership, coupling, new modules or services. (conditional)245. `domain-modelling` — domain types, aggregates, value objects. (conditional)256. `data-access` — repositories, queries, transactions, migrations, caches. (conditional)267. `cqrs-and-consistency` — read models, projections, ownership. (conditional)278. `infrastructure-adapters` — clients, consumers, publishers, SDK wrappers. (conditional)289. `resilience-patterns` — any call leaving the process, any message handler. (conditional)2910. `idempotency-and-immutability` — retryable operations, shared or mutable state. (conditional)3011. `secure-service` — handlers, clients, queries, credentials, personal data. (conditional)3112. `api-contracts` — endpoint, schema, or published event changes. (conditional)3213. `api-protocols` — GraphQL, gRPC, WebSocket or SSE surfaces. (conditional)3314. `config-and-dependencies` — settings, flags, dependency manifests. (conditional)3415. `contract-testing` — integrations between services. (conditional)3536## Workflow3738### Step 1 — Scope3940Establish exactly what is under review, and say so before starting.4142| Ask | Scope |43|---|---|44| "review my changes" | Uncommitted working tree plus staged changes |45| "review this branch" / a PR number | The diff against the merge base |46| "review the orders service" | The whole service — announce a sampling strategy, since a full audit of a large codebase in one pass is not credible |47| A file or directory | That path |4849For a diff, a finding must be **in the changed code or activated by it**. Pre-existing issues in a50file the diff happens to touch go in a separate "out of scope" list — never mixed into the findings.5152### Step 2 — Load the project's standards53541. Read `.msskills/stack.md` — idiom-appropriate expectations, and which libraries exist.552. Read `.msskills/config.yaml` and follow each principle's Config Resolution. **Project overrides56 outrank this library's defaults.** Reporting a deliberate house standard as a violation destroys57 the review's credibility.583. Read the blueprint in `.msskills/designs/` if one covers this change. Deviation from an approved59 design is itself a finding.604. Read `.msskills/decisions.md`. A recorded decision is settled — do not re-litigate it as a61 finding. If you believe it is now wrong, say so under judgment calls with what changed.6263### Step 3 — Run the checklists6465For each file in scope, apply the Self-Validation Checklist and Active Anti-Pattern Scan of every66principle from Required Skills that governs that file. Work through them item by item — the value67of this workflow is that it is mechanical where a human reviewer is impressionistic.6869Give disproportionate attention to the defects that are cheap to miss and expensive to ship:7071- **Missing ownership check** — an ID from the request used to load a record with no scoping to the72 caller (`secure-service`, API1). Look for it on every single read and write path.73- **Missing timeout** on any outbound call (`resilience-patterns`).74- **Dual write** — a database commit and a broker publish as separate steps (`resilience-patterns`).75- **Non-idempotent consumer** under at-least-once delivery76 (`idempotency-and-immutability`).77- **N+1 query** on any path that handles a collection (`data-access`).78- **Breaking contract change** — a field removed, renamed, narrowed, or made required79 (`api-contracts`).80- **Destructive migration** that makes the previous release un-rollbackable (`data-access`).81- **Secret in the repository** (`secure-service`).82- **Untested failure path** — error handling with no test (`test-strategy`).8384For a large scope, sample deliberately and say how: every trust boundary and every outbound call85first, then the domain, then the rest. State what you did not examine.8687### Step 4 — Verify each candidate8889For every candidate finding, before it goes in the report:90911. **Construct the failure.** Name the input, state, or sequence that makes it go wrong, and the92 observable consequence. If you cannot, it is a preference — drop it.932. **Look for the central mechanism.** Timeouts, authorisation, validation, and error mapping are94 often applied by a filter, a client factory, an interceptor, or a base class. A reviewer who has95 not gone looking will report a wall of false positives.963. **Check it is not deliberate.** A comment, a decision record, or a project override may explain97 it. If it looks deliberate but undocumented, that is a judgment call, not a defect.984. **Assign severity by consequence**, not by effort to fix:99100 | Severity | Meaning |101 |---|---|102 | **Critical** | Data loss, data exposure, unauthorised access, or breaks a deployed consumer |103 | **High** | Will cause an incident under load or failure |104 | **Medium** | Correctness or maintainability defect with bounded blast radius |105 | **Low** | Real but minor |106107Anything below Low is not reported.108109**Independent pass.** For a substantial change, also run the `microservice-reviewer` agent over the110same scope and merge its findings with yours, keeping the more specific version of any duplicate.111A second pass with no memory of the reasoning catches what a single reading rationalises.112113### Step 5 — Report114115Lead with a two-line verdict: what the change does, and whether it is safe to ship. Then findings,116most severe first:117118```markdown119**High — Outbound call to the pricing service has no timeout**120`src/adapter/PricingClient.java:34` · violates `resilience-patterns`121122The client is constructed without a request timeout, so a hung dependency holds the calling123thread indefinitely.124125**Fails when:** pricing stops responding without closing connections. Checkout threads accumulate126until the pool is exhausted; every checkout then fails, including those not needing pricing.127**Fix:** set an explicit request timeout below checkout's own budget, and wrap the call in the128circuit breaker already configured for `inventory` in `ResilienceConfig`.129```130131Close with:132133- **Judgment calls** — real trade-offs the author may have decided deliberately, in the134 `collaborative-judgment` format. Never as findings.135- **Out of scope** — pre-existing issues worth their own change, one line each.136- **What was checked** — the principles applied and, for a sampled review, what was not examined.137138If nothing meets the bar, say so and list what you checked. A clean review is a real result.139140## Rules141142- **Report; do not fix.** This workflow ends with findings. Applying them is a separate,143 explicitly requested step.144- **No praise section.** The author wants the defects.145- **No padding.** Two real findings beat two real findings and eight style notes.146- **Cite a file and a line** for every finding.147- **Never restate the principle** — cite it and go straight to the specific violation.148- **Say when you are unsure.** A flagged uncertainty is useful; a confident claim that turns out to149 be wrong costs the reader trust in the whole list.