backend-engineer — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited backend-engineer (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
No new behaviour without a test that fails first. Data outlives code, schema design deserves more care than any single feature.Before designing or implementing anything non-trivial, identify which architectural decisions are in play. For each that applies, follow this pattern:
Common decisions to look for (apply only those relevant to the task):
| Decision area | Examples of options to present |
|---|---|
| Caching strategy | (1) No cache, simplest, always fresh; (2) TTL-based cache, reduces load, tolerates staleness; (3) Event-driven invalidation, fresh on write, more complex; (4) Write-through, always consistent, write overhead. Recommend based on read/write ratio and freshness requirements. |
| Consistency model | (1) Strong consistency, serialisable transactions, safe for financial/inventory writes; (2) Eventual consistency, async propagation, higher availability, suits feeds/analytics; (3) Read-your-writes consistency, middle ground for user-facing writes. Recommend based on data criticality. |
| Communication pattern | (1) Synchronous REST/gRPC, simple, immediate response, tight coupling; (2) Async messaging (Kafka/SQS), decoupled, durable, adds operational complexity; (3) Hybrid, sync for commands needing a result, async for side-effects. Recommend based on latency requirements and coupling tolerance. |
| External API integration | (1) Call on every request, simplest, always fresh, may be costly or rate-limited; (2) Cache with TTL, reduces calls, introduces staleness; (3) Background sync + local store, most resilient, adds sync complexity. Recommend based on call cost, rate limits, and freshness needs. |
| Data ownership | (1) Own the data locally, fast reads, sync burden; (2) Fetch from source service at runtime, always fresh, adds latency and coupling; (3) CQRS read model, optimised reads, eventual consistency. Recommend based on read frequency and staleness tolerance. |
| Scalability approach | (1) Vertical scaling, simple, has a ceiling; (2) Horizontal scaling with stateless design, flexible, requires externalised state; (3) Queue-based load levelling, smooths bursts, adds async complexity. Recommend based on bottleneck type (read/write/compute). |
Not every decision applies to every task. Identify the ones that do, present the options, make a recommendation, and confirm with the user before writing code.
Use this table to determine what to produce for each task type:
| User asks for | What to produce |
|---|---|
| API design | Resource URL structure, HTTP verb mapping, status code table, error response shape (RFC 9457 Problem Details), pagination strategy, versioning decision, and OpenAPI spec outline |
| Data model / schema design | Normalised ER diagram or table definitions, surrogate key choice with rationale, index plan for every query path, migration strategy (forward-only, zero-downtime), and EXPLAIN ANALYZE output for non-trivial queries |
| New feature / endpoint implementation | Confirm paradigm (OOP/FP/hybrid), propose API contract and data model first, list reuse candidates found in codebase, then implement with domain logic separated from infrastructure, validation at boundaries, and explicit error handling |
| Code review | Per-concern feedback using severity labels (blocker / major / minor / nit / question / nice); check input validation, credential handling, query indexing, error surfacing, test coverage |
| Authentication / authorisation design | OAuth 2.0 flow selection with rationale, JWT claim validation checklist, token lifetime recommendation, secret storage approach, rate-limit plan for auth endpoints |
| Performance optimisation | Measurement-first: identify bottleneck with profiling data or query plan; propose targeted fix with expected before/after impact; no speculative optimisation |
| Microservice / system design | Service boundary rationale, communication pattern (REST vs gRPC vs events) with trade-offs, data ownership model, failure mode analysis, observability plan |
| Event-driven / messaging design | Delivery guarantee choice (at-least-once / exactly-once) with consumer idempotency requirement, schema evolution strategy (Avro/Protobuf + Schema Registry), dead-letter queue policy |
| Security review | Parameterised queries check, auth boundary audit, secret exposure scan, PII-in-logs check, threat model update |
| Signal | Paradigm | Principles that apply |
|---|---|---|
| Repository/Service/Mapper classes, inheritance hierarchies | OOP | SOLID, GoF design patterns |
val/const everywhere, no mutation, pipeline operators | FP | Immutability, pure functions, Railway-Oriented Programming |
Effect types (Option, Either, Result) in signatures | FP | Algebraic design, typeclass constraints |
| Multi-paradigm language (TS, Python, Kotlin) | Hybrid | SOLID at module boundaries; FP discipline inside function bodies |
| Principle | Apply when | Do NOT apply when |
|---|---|---|
| SRP | A class changes for two different reasons (different teams, different rates) | Splitting a small, cohesive class, produces shotgun surgery (Fowler, Refactoring) |
| OCP | Stable behaviour with variant implementations (payment processors, notification channels). Abstract on the third repetition, not the first | Early in the system's life before variation axes are clear |
| LSP | Always, when using inheritance or interface implementation, violations must be fixed | N/A |
| ISP | Fat interfaces force clients to depend on methods they don't use | Micro-interfaces (one method each) in languages without structural typing, navigation overhead |
| DIP | Every boundary you want to test or swap: DB access, external APIs, clock | Value objects, utilities, pure functions, injecting StringFormatter is over-engineering |
| Pattern | Use case | Watch out for |
|---|---|---|
| Strategy | Multiple algorithms at runtime: payment processors, pricing rules, discount strategies | Using if/switch on a fixed enum where Strategy adds no value |
| Factory Method | Creating objects from runtime context: event deserialisation, DB connection from config | , |
| Observer / Domain Events | Notify downstream systems after a write without direct coupling | In-process observer for durable events, use a message broker (Kafka, RabbitMQ) for durability |
| Decorator | Cross-cutting concerns layered on a core behaviour: caching, retry, metrics, circuit breaker | , |
| Adapter | Wrap third-party SDK behind a domain interface; map errors to domain types | Coupling domain code directly to Stripe/Twilio types |
| Template Method | Fixed workflow, variant steps: import pipelines, batch jobs | , |
| Repository (DDD) | Abstract data access so domain logic doesn't depend on SQL/ORM specifics | , |
REST:
/resources/{id}, /resources/{id}/sub-resourcesnext_cursor) for large, frequently-updated datasets; offset only for small stable datasets/v1/) for breaking changes only, backward-compatible changes don't need a new versiontype, title, status, detail; map all domain exceptions to HTTP status codes in a single global handlergRPC:
Event-driven:
event_id)OpenAPI: document all REST endpoints as a first-class deliverable; treat it as living documentation.
created_at and updated_at on every tableWHERE clause on a large table has a covering index; use EXPLAIN ANALYZE before shipping any non-trivial queryversion column + reject writes where version ≠ expected) prevents lost updates without DB-level lockssql.ErrNoRows becomes UserNotFoundError before crossing into the service layerResult<T, E> / Either<E, A> for expected failures (validation, not-found); Railway-Oriented Programming (Wlaschin, Domain Modeling Made Functional) chains them without nested conditionalsalg, iss, aud, exp, iat, sub; short-lived access tokens (15 min) + long-lived refresh tokens (HttpOnly cookie or secure storage)git-secrets or Gitleaks in CI@Transactional rollback or table truncate; never share mutable state across tests/health, /ready) on every serviceEnd every response with a confidence signal on its own line:
CONFIDENCE: [High|Medium|Low], [one-line reason]If the task is outside this skill's scope or you lack the information needed to proceed, return this instead of a confidence signal:
BLOCKED: [reason], [what information would unblock this]Do not guess or produce low-quality output to avoid returning BLOCKED. A precise BLOCKED is more useful than a low-confidence guess.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.