Appearance
Production Backend Agent Rules (AGENTS-backend.md)
Copy this file directly into your target backend project root as
AGENTS.mdor append it to your existing project rules. Language-agnostic universal production baseline for backend services. Framework or language-specific rules should be appended directly inside the project-level AGENTS.md file.
1. Architecture & Design Principles
- [ ] Layered Separation & Dependency Inversion: Code MUST strictly adhere to clean layered architecture for runtime execution flow:
Transport Layer(Handlers/Controllers) ->Service Layer(Domain Logic) ->Data Layer(Repositories/Clients). Compile-time source dependencies MUST follow the Dependency Inversion Principle (DIP): domain modules define consumer-owned repository interfaces, and data modules implement them as adapters, wired exclusively at the application Composition Root. - [ ] Zero Transport Business Logic: Transport handlers MUST only extract authentication/tracing context from protocol headers, parse and validate input schemas, invoke domain services, and translate domain results or errors into protocol status codes and standardized error responses. Zero domain business logic or direct database queries inside transport handlers.
- [ ] Contract-First API Design & Lifecycle: APIs MUST be defined using machine-checkable contracts such as OpenAPI 3.1, Protocol Buffers, GraphQL schemas, or AsyncAPI. Breaking schema changes MUST require a major version bump or additive non-breaking evolution. Deprecated versions/endpoints MUST broadcast RFC 9745
Deprecationand RFC 8594Sunsetresponse headers (HTTP) or protocol-native annotations (e.g. GraphQL@deprecated, Protobufoption deprecated = true) during their decommissioning lifecycle. - [ ] Unified Error Payload: Error responses across all endpoints MUST conform to a flat top-level 5-key JSON envelope:
code(machine-readable string enum, e.g.INVALID_ARGUMENT,RESOURCE_NOT_FOUND),message(human-readable sanitized string, no raw stack traces),details(array of field validation objects or empty list),timestamp(RFC 3339 / ISO 8601 UTC string), andrequest_id(propagated trace/correlation ID).
2. Security & Authentication Baseline
- [ ] Authentication & Challenge Baseline: Authenticate API requests using short-lived OAuth 2.0 / OIDC JWTs, opaque tokens, or secure server-backed sessions transported via
Authorization: Bearerheaders or securehttpOnly,Secure,SameSitecookies (enforcing anti-CSRF header or Origin validation on cookie-authenticated state-changing requests). Token signatures MUST be validated against an explicit cryptographic algorithm allowlist (e.g.RS256,ES256; strictly forbiddingnoneor algorithm confusion attacks per RFC 8725),typheader verification (e.g.typ: "at+jwt"per RFC 9068), introspection status, standard claims (iss,aud,exp), and bounded clock skew ($\le 60\text{s}$). Verification of opaque tokens, session IDs, and signatures MUST use constant-time string comparisons. Unauthenticated or invalid requests MUST be rejected immediately with401 Unauthorizedcontaining an RFC 6750WWW-Authenticate: Bearerchallenge header. - [ ] OWASP BOLA/IDOR Prevention: Every query or mutation (read, write, update, delete) for protected user-owned or tenant-owned data MUST scope access by the authenticated user/tenant ID extracted from trusted server-side auth context (OWASP API1:2023). Cross-tenant resource lookups MUST return
404 Not Found(or generic403without existence metadata) to prevent resource enumeration. Public resources, admin operations, system jobs, and backfills MUST explicitly document their access scope. Never rely solely on client-provided route IDs. - [ ] Zero-Trust Boundary Input Validation: Validate all incoming request components (body payloads, query parameters, route parameters, and headers) against strict schemas (e.g. Zod
.strict(), Pydanticextra='forbid', Gojson.Decoder.DisallowUnknownFields()) at the transport boundary before passing data to domain services. Payloads containing unexpected or undeclared fields MUST be rejected immediately with400 Bad Request. - [ ] Secret Hygiene: Hardcoded secrets, API keys, or private certificates in code are strictly forbidden. Load secrets exclusively via environment variables or secret vaults.
- [ ] Distributed Rate Limiting: Apply distributed rate limiting keyed by authenticated identity (user/tenant ID or API key) on authenticated endpoints, composite identifiers (IP + account/email target) on sensitive auth endpoints (login, password reset, OTP), and client IP on public endpoints, returning standard
429 Too Many Requestsresponses withRetry-Afterheaders. - [ ] Broken Object Property Level Authorization (BOPLA / API3:2023): API schemas MUST enforce explicit property allowlists for both input payloads (preventing mass assignment to ORM models) and response serialization DTOs (preventing excessive data exposure of sensitive or internal object attributes such as password hashes, internal roles, and metadata). Read-only attributes MUST be excluded from write schemas.
3. Data Management & Persistence
- [ ] Zero-Downtime Migrations: Database schema changes MUST be versioned, immutable migration scripts following the Expand-Migrate-Contract pattern. New columns MUST be added as nullable or with constant defaults initially (avoiding volatile default expressions that force table rewrites). Index creation MUST use online/concurrent mechanisms (e.g. PostgreSQL
CREATE INDEX CONCURRENTLYexecuted outside transactional migration blocks, or MySQLALGORITHM=INPLACE), and migration sessions MUST configure explicit shortlock_timeoutlimits. - [ ] 100% Parameterized SQL: All database queries MUST use parameterized inputs or ORM parameter bindings. Raw string concatenation in SQL statements is strictly forbidden.
- [ ] Query Efficiency & N+1 Prevention: Relational queries MUST use explicit joins, eager loading, or DataLoader patterns to prevent N+1 query execution. Foreign key constraints MUST declare explicit
ON DELETEactions (RESTRICTby default;CASCADEstrictly for parent-owned dependent entities), and foreign keys/search attributes MUST be indexed. - [ ] Statement & Session Timeouts: Database connection pools MUST configure explicit statement execution caps, lock timeouts, and idle transaction timeouts (e.g. PostgreSQL
statement_timeout = 3s,lock_timeout,idle_in_transaction_session_timeout, or MySQLmax_execution_time) to prevent runaway queries and lingering locked sessions. - [ ] Short Transaction Boundaries: Database transactions MUST be managed at the Service layer and kept as short as possible. Performing external HTTP, gRPC, or async network I/O inside open DB transactions is strictly forbidden.
- [ ] Transaction Isolation Level: Relational database transactions MUST use at minimum
READ COMMITTEDisolation (using explicit optimistic versioning orSELECT FOR UPDATEpessimistic locking for read-modify-write flows).SERIALIZABLEisolation MUST be used only where strict consistency is required and MUST be paired with application-level retry handling for serialization failures (e.g. SQLSTATE40001). For non-relational stores, document equivalent consistency guarantees. Default engine isolation levels MUST be explicitly confirmed. - [ ] Audit Trail Metadata: Every mutable domain entity table MUST include mandatory audit attributes (
created_at,updated_atstored in UTC /TIMESTAMPTZ,created_by,updated_by, allowing null or system actor IDs for non-user actions). Append-only tables (e.g. outbox, event logs) and junction tables MAY omit update tracking fields. - [ ] Transactional Outbox & Event Idempotency: Asynchronous event publishing MUST use the Transactional Outbox pattern (with scheduled retention and cleanup for processed records) to avoid network I/O inside database transactions. Message consumers MUST enforce idempotency/deduplication using unique message keys.
4. Observability & Telemetry
- [ ] Structured JSON Logs: All application logging MUST be streamed to
stdout(orstderrfor errors) in structured JSON format with standard root fields (timestampin ISO 8601 UTC,level,service,message) and structured error fields (error.type,error.message,error.stack_trace). Explicit severity levels (DEBUG,INFO,WARN,ERROR,FATAL) MUST be used. Plain text print statements (console.log,fmt.Println,print()) are strictly forbidden in production. HTTP access logging middleware MUST exclude or downgrade routine/healthz/*probe requests toDEBUGlevel by default. - [ ] Distributed Trace Propagation: Extract incoming W3C
traceparent/tracestateheaders at transport ingress (HTTP/gRPC) and async message consumer ingress (or initialize new trace context) and propagate headers across all outgoing network and message queue calls. All structured log records MUST automatically includetrace_id,span_id, andrequest_idcorrelation attributes. - [ ] Automatic PII Redaction: Passwords, API tokens, authorization headers, cookies, credit card numbers, and PII MUST be automatically masked or redacted at the logger/middleware layer (via automated redaction paths or attribute replacers) before writing log records. Manual call-site masking is forbidden as the primary defense.
- [ ] Standardized Container Probes: Expose
GET /healthz/liveness(process responsiveness only, returning200 OK; strictly forbidden from querying databases or external networks) andGET /healthz/readiness(lightweight, non-locking backing dependency ping such asSELECT 1or RedisPING, returning200 OKwhen ready and actively serving, or503 Service Unavailableif backing dependencies fail or the application has initiated SIGTERM graceful teardown/draining, with sub-second timeouts calibrated strictly below Kubernetes probetimeoutSeconds). - [ ] OpenTelemetry-Compatible Instrumentation: Distributed tracing and metrics MUST use OpenTelemetry SDKs, OTel-compatible libraries, or vendor agents emitting standard OTLP telemetry aligned with OpenTelemetry semantic conventions and the Google SRE 4 Golden Signals (Latency histograms, Traffic counters, Error rates, and Saturation gauges). Business and service code MUST NOT depend directly on proprietary APM APIs; keep vendor routing at the instrumentation/exporter boundary.
5. Resilience & Lifecycle Control
- [ ] Mandatory Network Timeouts & Deadlines: Every HTTP client, database connection pool, gRPC client/stub, and cache call MUST specify explicit timeouts: connection/handshake timeouts, pool checkout timeouts, read/write socket timeouts, total end-to-end HTTP request timeouts, and RPC/context deadlines. Default or infinite timeouts are strictly banned.
- [ ] Smart Retries with Jitter & Retry Budgets: Retry transient network errors (TCP resets, connection drops) and transient HTTP responses (502, 503, 504, and 429) exclusively for idempotent requests or requests carrying a client-supplied idempotency key. Limit retries to a bounded maximum (e.g. max 3 attempts or token-bucket retry budget) using exponential backoff with randomized jitter. Parse
Retry-Afterheaders supporting bothdelay-secondsinteger andHTTP-dateformats (RFC 9110 §10.2.3). - [ ] Circuit Breakers: Non-critical downstream third-party integrations MUST be wrapped in stateful circuit breakers (e.g. tripping on >= 50% error rate or consecutive failure threshold over a rolling window). Breakers MUST fast-fail immediately in
Openstate to protect worker pools, probe recovery inHalf-Openstate, and provide explicit fallback handlers (cached stale data, degraded response, or graceful degradation). - [ ] Ordered Graceful Shutdown: Implement
SIGTERM/SIGINTsignal handlers that execute teardown in strict order: (1) stop accepting new ingress requests and fail readiness probes, (2) pause message queue consumers from pulling new jobs, (3) drain active in-flight requests within a bounded grace window (e.g. 30s), (4) close database pools, network clients, and storage handles, and (5) flush pending telemetry and structured log buffers before process exit. - [ ] Kubernetes Drain Coordination: In container-orchestrated environments, services MUST configure a
preStoplifecycle hook (e.g.sleep 10orsleep 15) to allow endpoint deregistration across ingress proxies and cloud load balancers to fully propagate beforeSIGTERMis delivered.terminationGracePeriodSecondsMUST be set greater than the sum ofpreStopdelay, app drain window, and a safety margin (e.g.15s preStop + 30s drain + 15s buffer = 60s terminationGracePeriodSeconds). Ensure container entrypoints useexecor init supervisors (tini) so PID 1 properly receives and handles OS signals.
6. Testing Strategy & QA
- [ ] Testing Pyramid & Mocking Boundaries: Target a balanced testing pyramid: high proportion (~70%) of fast, in-memory unit tests for domain business logic; focused (~20%) integration tests using Testcontainers for repositories/handlers; and lightweight (~10%) E2E smoke tests for critical paths. Mock ONLY external third-party network boundaries (e.g. WireMock, MSW, httpmock); DO NOT mock internal database engines, ORMs, caches, or message brokers in integration tests.
- [ ] Deterministic Test State: Tests MUST NOT share mutable state across runs. Use test data factories over static SQL dumps. Enforce database test isolation via per-test transaction rollbacks, worker-isolated schemas/databases, or deterministic post-test table truncation fixtures. Virtualize or freeze system clocks (e.g. clock injection,
freezegun,synctest, or test timers) for all time-sensitive domain logic. - [ ] Authorization & Authentication Test Matrix: Every protected API resource and mutation endpoint MUST have negative test coverage in CI asserting: (1) unauthenticated requests receive
401 UnauthorizedwithWWW-Authenticate, and (2) unauthorized/cross-tenant principals receive403 Forbidden(code:"PERMISSION_DENIED") or404 Not Found(code:"RESOURCE_NOT_FOUND") with the standard 5-key error envelope, zero resource leakage, and zero database state mutation (OWASP BOLA API1:2023). - [ ] Contract Validation in CI: Automatically validate API contract diffs in CI pipelines (e.g.
oasdiff,buf breaking,graphql-inspector,asyncapi diff). Detected breaking changes MUST block pull request merge unless accompanied by an explicit major version bump or deprecation policy. - [ ] Automated CI Quality & Security Gates: Enforce a minimum threshold of 80% line and branch coverage on core domain business logic (excluding auto-generated code and test fixtures). CI pipelines MUST execute static type checking, linters, and dependency vulnerability scans (e.g.
govulncheck,pip-audit,npm audit), blocking PR merges on static analysis errors or un-triaged high-severity vulnerabilities.
7. Code Quality, Maintainability & Documentation
- [ ] SOLID Alignment: Enforce all 5 SOLID principles: Single Responsibility (SRP), Open/Closed (OCP) via extension points/strategies, Liskov Substitution (LSP) for behavioral subtyping, Interface Segregation (ISP) via narrow consumer-owned interfaces, and Dependency Inversion (DIP) via injected abstractions. Maintain high cohesion and low coupling.
- [ ] Pragmatic DRY & YAGNI: Consolidate duplicated business rules in a single source of truth, but avoid hasty/speculative abstractions (AHA principle). Do NOT write unused generic parameters, dead code, or speculative plugin hooks.
- [ ] File Size & Complexity Bounds: Target 200–300 lines of code (LOC) per source file, enforce a 400 LOC soft cap, and treat 500 LOC as an absolute hard ceiling requiring sub-module decomposition. Exempt auto-generated artifacts (
*.pb.go, OpenAPI/GraphQL schemas), dependency lockfiles, and static test fixtures. - [ ] Guard Clauses & Function Complexity Bounds: Use early returns/exit guard clauses at the top of functions rather than deeply nested
if-elsebranches. Maintain low cognitive and cyclomatic complexity (target $\le 3$ nesting levels, cognitive complexity $\le 15$, and $\le 40$–$50$ LOC per function/method) to ensure linear, readable execution flow. - [ ] Self-Documenting Code & Intent Comments: Write descriptive, domain-aligned variable and function names. Comments MUST explain non-obvious business rationale (why), never repeating what readable code already expresses.
- [ ] Docstrings & Contract Sync: Keep inline API docstrings, module documentation, and external machine-checkable API contracts 100% in sync whenever signatures or data models change.