agentleFS
MartinKChenMartinKChen/harness-claude-code/skills/pattern-engineer-non-functional/SKILL.md

pattern-engineer-non-functional

Skill0 starsChanged 5 months agoMITView on GitHub

Engineer-facing non-functional guardrails for production code (ISO-25010 quality characteristics). A thin always-build floor — bounded reads, no N+1, hot-predicate indexes, upload caps, outbound timeouts, no event-loop-blocking sync calls — plus heavier spec-gated targets (latency / throughput / capacity / availability) built only when the slice declares a matching non-functional AC. Security is out of scope. Activate on a query, list, upload, outbound, or async surface.

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 3 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    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
  1. Distinctive:

    Do NOT activate for purely cosmetic changes, internal renames, comment edits, or conceptual questions that don't touch code.

    line 15
  2. Very specific:

    After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-engineer-non-functional.md in the consuming project …

    line 20
  3. Very specific:

    Timeout every outbound call: Every server-side fetch / HTTP client / DB statement carries an explicit timeout.

    line 30
  4. Very specific:

    When (and only when) the slice body's ## Acceptance criteria declares a non-functional clause, implement and prove it.

    line 39
  5. Distinctive:

    Call blocking/sync IO or CPU-bound work directly inside an async request handler.

    line 54
  6. Distinctive:

    Add a speculative cache, queue, read-replica, or load-shedding layer for a scale the slice never declared — that is the YAGNI trap this …

    line 55

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

pattern-engineer-non-functional

Non-functional guardrails for production-code authoring — the ISO-25010 / ISTQB quality characteristics (performance efficiency, reliability, scalability, resource utilization) that the functional happy path never exercises. Like the other engineer pattern skills, this is a quiet reference catalogue: the agent reads it to know which bounds to build in, not a checklist to walk through with the user. Reviewer feedback (pattern-reviewer-non-functional) is the user-facing channel; this skill exists so most findings never happen.

This skill is spec-gated by design. Most projects that install the plugin are early-stage and declare no non-functional acceptance criteria — and that is fine. You always build in the thin floor below (the bounds that are latent correctness bugs the moment real data arrives), but you do NOT speculatively add load tests, caching layers, or capacity engineering for a requirement the slice never stated. The heavier targets are pulled into scope only when the slice body declares a non-functional AC (a latency / throughput / capacity / availability clause). Build to the spec — no more, no less.

When to activate

  • Writing or editing production code that: issues a DB query, serves a list/collection endpoint, accepts a request body or file upload, makes an outbound HTTP/DB call, runs inside an async handler, processes a queue/worker message, renders a large collection in the UI, or implements a behavior whose slice declares a performance / capacity / availability acceptance criterion.
  • Do NOT activate for purely cosmetic changes, internal renames, comment edits, or conceptual questions that don't touch code.
  • Not the security catalogue — secrets, authz, input validation, SSRF, rate-limit-as-abuse-control live in pattern-engineer-security. (A rate limit declared as a capacity control belongs here; the same limit declared as an abuse control belongs there — they often coincide.)

Project memory overlay

After loading this skill, also check $MAIN_ROOT/.claude/memory/patterns/pattern-engineer-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. See memory-convention for the full contract (additivity, severity floor, conflict surfacing).

The thin floor — always build these in (no declared AC required)

These are not "performance polish"; they are bounds whose absence is a latent correctness/availability bug that surfaces the instant the table grows past your seed data or a dependency stalls. Build them in on every applicable surface, even on a day-one prototype. (Several overlap pattern-engineer-backend-standard — that is deliberate; this skill frames them as the resource/reliability floor and is the catalogue the non-functional review gates the advisory tier against.)

  • Bound every user-facing read. A list/collection query has a LIMIT (and a stable ORDER BY for pagination). Never SELECT * an unbounded table into memory and slice in Python/JS.
  • No N+1. A loop that issues one query per row is a single JOIN / IN (...) / selectinload. Fetch the set, not the elements.
  • Index the hot predicate. A column you filter or order by on a user-facing path gets an index in the same migration that introduces the access pattern — don't ship a sequential scan on a growing table.
  • Cap the inputs. Set a max request-body size and a max upload size at the edge. Bound array/string lengths in the boundary schema (this is also a validation concern — do it once, at the boundary).
  • Timeout every outbound call. Every server-side fetch / HTTP client / DB statement carries an explicit timeout. A dependency that hangs must fail your request, not pin a worker forever.
  • Never block the event loop. In an async handler, no synchronous CPU-bound or blocking-IO call (sync requests, time.sleep, a heavy sync hash, blocking file IO) — use the async client or offload to a thread/worker.
  • Bound the pools. Connection pools (DB, HTTP) have explicit max sizes; a request that can't get a connection fails fast rather than queueing unboundedly.
  • Don't accumulate unboundedly in memory. Stream / paginate / batch when processing a set whose size scales with usage; no per-request cache that grows without eviction.
  • Virtualize or paginate large UI lists. A rendered collection that can grow with data is paginated or windowed, not a single map over thousands of nodes.
  • Workers/consumers are idempotent on redelivery. At-least-once delivery will double-apply a non-idempotent handler — key the effect on the message/event ID.

Spec-gated targets — build these only when the slice declares the matching AC

When (and only when) the slice body's ## Acceptance criteria declares a non-functional clause, implement and prove it. Match the build to the clause; do not infer a target the issue never wrote.

Declared AC shapeWhat to build inHow it's proven (engineer authors the test)
Latency ("p95 < 200 ms", "responds within Xs")the efficient path that meets it (bounded query + index + no N+1); avoid per-request recomputationa test that measures the operation and asserts the budget, pinned in one place (no docstring/assertion drift)
Throughput / capacity ("N req/s", "handles M concurrent", "N rows")statelessness so it scales horizontally; back-pressure (429 + Retry-After) at the declared ceilinga load/concurrency test that drives the stated level and asserts it holds (no errors, no lost updates)
Availability / recovery ("degrades gracefully", "retries transient failures", "drains on shutdown")retry-with-backoff + jitter on transient faults; circuit-breaker/fallback where named; graceful SIGTERM that drains in-flight work; /healthz + /readyza test that injects the fault (dependency 5xx/timeout) and asserts the retry/fallback/drain behavior
Resource ceiling ("≤ X MB", "payload ≤ Y")the enforced bound at the boundary; reject past it with the declared statusa test asserting the bound rejects past the ceiling and accepts at it (off-by-one)
Frontend budget ("LCP < Xs", "bundle ≤ Y KB")code-split / lazy-load route boundaries; avoid shipping heavy deps eagerlythe budget assertion in the build/CI (bundle-size check) or a Lighthouse/web-vitals gate

Never do

  • Ship a user-facing list endpoint with no LIMIT / pagination because "there's not much data yet" — the bound is cheapest to add now.
  • Issue queries inside a row loop (N+1) where a set-based query is available.
  • Make a server-side outbound call (HTTP or DB) with no timeout.
  • Call blocking/sync IO or CPU-bound work directly inside an async request handler.
  • Add a speculative cache, queue, read-replica, or load-shedding layer for a scale the slice never declared — that is the YAGNI trap this skill explicitly warns against. Build the floor; defer the rest until an AC asks.
  • Re-target a number the issue didn't state (inventing "p95 < 100 ms" because it "feels right"). If there is no non-functional AC, there is no non-functional target beyond the floor.
  • Disable a declared timeout / pool bound / back-pressure to make a slow path "work" — fix the slow path.

The floor is binding even with 10 rows of test data — the bound is correctness, not capacity, and it is cheapest in the introducing change. pattern-reviewer-non-functional advises against this same floor; close the gap while authoring rather than in a fix cycle.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.