pattern-reviewer-non-functional
Skill0 starsChanged 5 months agoMITView on GitHub
Reviewer lens for the non-functional dimension of a production-code review (performance, reliability, scalability, resource use). Grades each gap under a strict spec-gated rule: HIGH (blocks) ONLY when it maps to a declared non-functional AC on a touched surface; floor gaps with no NFR AC (unbounded read, N+1, missing timeout) are Defer/Nit, never HIGH — so a slice with no NFR ACs is never blocked, only advised. Security is out of scope. Activate on a backend/frontend production-code review.
In this repository74 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- create-bug-issueSkill
- create-enhancement-issueSkill
- create-feature-issuesSkill
- dream-summary-memorySkill
- memory-conventionSkill
- operation-gitSkill
- pattern-architect-api-endpointSkill
- pattern-architect-data-modelSkill
- pattern-architect-deep-moduleSkill
- pattern-e2e-coding-standardSkill
- pattern-engineer-apiSkill
- pattern-engineer-backend-standardSkill
- pattern-engineer-coding-standardSkill
- pattern-engineer-containerSkill
- pattern-engineer-databaseSkill
- pattern-engineer-fastapiSkill
- pattern-engineer-frontend-standardSkill
- pattern-engineer-goSkill
- pattern-engineer-javaSkill
- pattern-engineer-kotlinSkill
- pattern-engineer-nodeSkill
- pattern-engineer-non-functionalSkill
- pattern-engineer-observabilitySkill
- pattern-engineer-pythonSkill
- pattern-engineer-rustSkill
- pattern-engineer-securitySkill
- pattern-engineer-ssrSkill
- pattern-engineer-swiftSkill
- pattern-engineer-typescriptSkill
- pattern-engineer-viteSkill
- pattern-exploratory-testingSkill
- pattern-reviewer-apiSkill
- pattern-reviewer-backend-standardSkill
- pattern-reviewer-coding-standardSkill
- pattern-reviewer-containerSkill
- pattern-reviewer-contractSkill
- pattern-reviewer-databaseSkill
- pattern-reviewer-fastapiSkill
- pattern-reviewer-frontend-standardSkill
- pattern-reviewer-goSkill
- pattern-reviewer-javaSkill
- pattern-reviewer-kotlinSkill
- pattern-reviewer-nodeSkill
- pattern-reviewer-observabilitySkill
- pattern-reviewer-pythonSkill
- pattern-reviewer-rustSkill
- pattern-reviewer-securitySkill
- pattern-reviewer-ssrSkill
- pattern-reviewer-swiftSkill
- pattern-reviewer-test-coverageSkill
- pattern-reviewer-typescriptSkill
- pattern-reviewer-viteSkill
- pattern-test-coverageSkill
- principle-engineer-tddSkill
- scaffold-projectSkill
- workflow-architect-interviewSkill
- workflow-designer-sample-pagesSkill
- workflow-design-interviewSkill
- workflow-e2e-authorSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 2 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 16
Do NOT activate on the security gate (pattern-reviewer-security) or the pre-implementation test-coverage gate (there is no production code …
- Very specific: line 20
After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-reviewer-non-functional.md in the consuming project …
- Distinctive: line 51
Acknowledge a clean axis: If the diff holds the floor and meets every declared NFR AC, zero findings is the correct result — never …
- Distinctive: line 68
When the diff (or a pushback in the fix flow) leans on one of these, the finding stands — restate the reality in the impact sentence:
- Very specific: line 91
Every finding matches the fan-out's structured shape (title, severity, effort, file, impactStatement, effortStatement, fix, lang, bad, …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
pattern-reviewer-non-functional
The reviewer's lens for the non-functional pillar of the code gate — performance efficiency, reliability, scalability, and resource utilization (ISO 25010 / ISTQB non-functional quality characteristics). The substance — what bound should exist — lives in pattern-engineer-non-functional and is shared verbatim with the engineer who writes the code. This skill governs only the reviewer's verb: detect a gap against that catalogue, grade it under the spec-gated rule, cite it, and report it so the fix flow can act on it.
Load
pattern-engineer-non-functionalfirst. Walk its thin floor and its spec-gated targets against the scoped diff to find gaps; everything below is how you turn each gap into a posted finding — and, above all, how you grade it so this lens never blocks a slice that didn't ask for the work.
When to activate
- The dispatched caller is reviewing the production-code gate on a slice whose diff touches
type:backendortype:frontendsurfaces. Run on every such dispatch. - A user says "review performance", "are there N+1s / unbounded queries", "will this scale", "did we meet the latency / capacity requirement".
- Do NOT activate on the security gate (
pattern-reviewer-security) or the pre-implementationtest-coveragegate (there is no production code to audit yet). Test files are out of scope.
Project memory overlay
After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-reviewer-non-functional.md in the consuming project (resolve MAIN_ROOT="$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")"). If present, load it as an additive overlay to the rules below; if absent, skip silently.
Scope note: this overlay is for reviewer-reporting adjustments only (finding shapes that over-flag in this project, severity carve-outs, citation conventions). Non-functional substance (a class of bound the project keeps missing) belongs in the shared
pattern-engineer-non-functionaloverlay, because that one reaches the engineer's authoring side too. Seememory-conventionfor the precedence contract.
References
| Reference | When to read |
pattern-engineer-non-functional | Always — the catalogue of bounds (thin floor + spec-gated targets) you are detecting gaps against. |
templates/review-comment.md | Always read before composing the comment body (single-context reviewer fallback path). The fan-out maps your findings into its own schema; the template fixes the finding-row shape. |
The severity rule — this is the whole point of the skill
The consuming project is usually early-stage and declares no non-functional acceptance criteria. This lens must not punish that. Severity is therefore split hard:
- HIGH (blocks the gate) — and ONLY this case: the gap maps to a declared non-functional AC on a surface the diff touched. That means an
ACnid in the Scope Manifest whose clause is a latency / throughput / concurrency / capacity / availability / recovery / resource-ceiling requirement, and the diff either did not build the bound it requires or shipped no test that proves it. These are the holes that mean the slice did not build what was asked — block on them, and enumerate every one. - MEDIUM (Deferred) / LOW (Nit) — everything else, NEVER HIGH: every thin-floor gap that no declared NFR AC names — an unbounded list query, an N+1, a missing outbound timeout, a blocking sync call in an async path, a missing hot-predicate index, an unwindowed large UI list — is surfaced as advice, not a blocker. It is real and worth fixing, but it must never hold the gate open and must never expand the slice. Use MEDIUM when the risk is material (an unbounded query on a table that clearly grows), LOW when it is minor or speculative.
- Never synthesize a non-functional AC. If you cannot point at an
ACnid in the manifest whose clause is non-functional, you do not have a blocker — at most you have floor advice. Do not invent "this should be fast" / "this should scale" from prose, a heading, or your own sense of good engineering. The manifest is the closed authority. - Pre-existing gaps are not this slice's debt. A missing bound on a surface this slice did not change is at most a Nit, and only if trivially adjacent — prefer to stay silent on untouched code.
Net effect: a slice with no NFR ACs can never be blocked by this lens — it can only receive floor advice. A slice that does declare an NFR AC is held to it. That is exactly the spec-gated behavior the bound is for.
Iron rules for every finding
- The slice body is the spec. A blocking finding is judged against the manifest's
## Acceptance criteria(the non-functional clauses among them) on a touched surface. Advisory floor findings are judged againstpattern-engineer-non-functional's thin-floor list. - Cite the gap by location AND by what it maps to. A blocker cites
file:line+ theACnlabel whose non-functional clause is unmet ("AC4 — p95 < 200ms — no test measures the endpoint"). A floor finding citesfile:line+ the floor rule ("unbounded read —services/orders/list.py:31selects with no LIMIT"). "This might be slow" is not a finding. - Read surrounding code, not just the diff. Confirm the bound is actually absent — follow the call into the repository/service, check for a
LIMITapplied downstream, an existing index in a sibling migration, a timeout set on the shared client. A bound that already exists out of the hunk is not a gap. - Distinguish "missing bound" from "below a declared target". Without a declared AC, you can only flag a missing bound (advisory). You may only flag below-target (blocking) when the AC states the number — never assert a latency/throughput number the issue didn't write.
- Don't double-report security. A missing rate limit framed as abuse control is
pattern-reviewer-security's; flag it here only when an AC declares it as a capacity/back-pressure requirement. When both lenses see it, the dedup step collapses it. - Effort is your honest cost-to-fix-now. L = localized (add a
LIMIT, set a timeout); M = multi-file or needs a new test (add an index migration + test; add a perf test); H = design rework (introduce pagination across an API + clients; add a circuit breaker). - Never refer to a finding as
#N(N a number). GitHub auto-links#1,#2, … to issues. Use a non-numeric handle: the AC label (AC4), the floor-rule name (unbounded-read,n-plus-one,missing-timeout,event-loop-block), the quoted title, orF1/F2. - Acknowledge a clean axis. If the diff holds the floor and meets every declared NFR AC, zero findings is the correct result — never manufacture a finding to look thorough.
What a floor gap looks like in the diff
Concrete shapes to scan for while walking the floor — each maps to a floor rule and, absent a declared NFR AC, grades MEDIUM/LOW:
- A
for/mapbody that issues a query or an HTTP call (n-plus-one). - A list/collection handler whose query has no
LIMITand no pagination cursor (unbounded-read). - A
fetch(...)/httpx/requests/ DBexecutewith notimeout=/AbortSignal.timeout(...)(missing-timeout). requests.get(...),time.sleep(...), a sync file read, or heavy sync compute inside anasync defhandler (event-loop-block).- Loading an entire table/collection into a list before filtering or counting (
unbounded-read). - A new filter/sort column on a growing table with no accompanying index in the same migration (
missing-index). - A React component mapping over a prop array that scales with data, with no windowing/pagination (
unwindowed-list). - A worker/consumer that is not idempotent on redelivery (
non-idempotent-consumer).
Rationalizations don't dissolve a finding
When the diff (or a pushback in the fix flow) leans on one of these, the finding stands — restate the reality in the impact sentence:
| Rationalization | Reality |
| "It's fast enough with our test data" | Test data is 10 rows; production is 10 million. Retrofitting pagination touches every caller. |
| "We'll add the index later" | "Later" is a 3am page when the sequential scan tips over. The introducing migration is the free moment. |
| "The dependency never hangs" | Without a timeout, one stalled dependency takes every worker with it. |
| "We don't have scale requirements yet" | The floor (bounds, timeouts, no N+1) is correctness, not capacity — it applies without an AC. (It is still advisory, never HIGH, without one.) |
| "Async makes it non-blocking automatically" | One sync call in an async handler blocks the whole event loop. |
Grading a gap
Walk pattern-engineer-non-functional (floor + spec-gated targets) against the scoped diff. For each gap collect a record:
{title, severity, effort, location (file:line), maps-to ("ACn — <clause>" for a blocker, or "<floor-rule>" for advice),
impact (what breaks/degrades if this ships), fix (concrete corrective action)}Severity is HIGH only for a declared-NFR-AC gap on a touched surface; every floor gap with no NFR AC is MEDIUM (Deferred) or LOW (Nit). Consolidate repeats — if five handlers all miss a timeout, file one finding listing all five.
Constructing the finding
Every finding matches the fan-out's structured shape (title, severity, effort, file, impactStatement, effortStatement, fix, lang, bad, good, dimension="non-functional"). For the single-context reviewer fallback, the comment-row shape is in templates/review-comment.md. Worked examples:
### [HIGH] AC4 not met — endpoint has no test proving p95 < 200 ms
**File:** `services/search/api.py:48`
**Maps to:** AC4 (the slice declares "search SHALL return within 200 ms p95")
**Impact:** The declared latency budget is unproven and the query is unindexed — a regression past 200 ms ships silently.
**Fix:** Add the index on `documents(tenant_id, created_at)` the access pattern needs, and a test that drives a representative dataset and asserts the p95 budget.### [MEDIUM] unbounded-read — list endpoint selects with no LIMIT or pagination
**File:** `services/orders/list.py:31`
**Maps to:** thin floor (no NFR AC declares this — advisory)
**Impact:** Returns the full table; latency and memory grow linearly with order count and will degrade as the table grows.
**Fix:** Add a `LIMIT` + cursor pagination (mirror `services/invoices/list.py`). Advisory — does not block this slice.- Cross-references use the AC/floor-rule label, the quoted title, or
F1/F2. - BAD/GOOD snippets help when the fix shape is non-obvious (the atomic/streaming rewrite); the maps-to + fix sentence is enough for a plain missing-bound.
Hand the collected findings back to the dispatching axis-reviewer (fan-out) or reviewer (fallback) — it owns comment composition, the severity-count summary, the verdict line, and posting. This skill never sets the verdict.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

