Enforce strict three-layer architecture: thin HTTP routes, pure service logic with domain errors, isolated data access with dependency injection.
94
93%
Does it follow best practices?
Impact
97%
1.08xAverage score across 5 eval scenarios
Passed
No known issues
{
"context": "Tests whether the agent correctly separates error concerns: services throw typed domain errors (never HTTP errors), routes catch domain errors and map them to HTTP status codes, and error classes are framework-agnostic.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Domain error file",
"description": "A dedicated errors/domain.ts (or similarly named) file exists containing domain error class definitions, separate from route/service files",
"max_score": 8
},
{
"name": "Framework-agnostic errors",
"description": "Domain error classes do NOT extend or import any HTTP framework types (e.g., no express, fastify, http imports in the errors file)",
"max_score": 8
},
{
"name": "Service throws typed errors",
"description": "The service throws instances of typed domain error classes (e.g., ValidationError, BusinessRuleError, NotFoundError) — not generic Error with HTTP codes or status strings",
"max_score": 10
},
{
"name": "No HTTP in service",
"description": "The service file does NOT import or reference any HTTP framework module, req, res, response, request, ctx, or context objects",
"max_score": 10
},
{
"name": "No status codes in service",
"description": "The service does NOT set or return HTTP status codes (no references to 400, 404, 422, 500, or .status() calls)",
"max_score": 8
},
{
"name": "Route maps domain errors",
"description": "The route handler contains explicit catch blocks (or equivalent) that map domain error types to specific HTTP status codes (e.g., ValidationError → 400, NotFoundError → 404, BusinessRuleError → 422)",
"max_score": 10
},
{
"name": "Route re-throws unexpected",
"description": "The route handler re-throws (or passes to next()) errors that are NOT recognized domain errors, rather than swallowing them with a generic 500 response",
"max_score": 8
},
{
"name": "Route uses plain data",
"description": "The route handler passes plain data objects (not req, res, or ctx) to the service function",
"max_score": 8
},
{
"name": "No SQL in service",
"description": "The service file does NOT contain direct SQL queries or ORM query calls — it delegates to a repository/data access module",
"max_score": 10
},
{
"name": "Repo handles null",
"description": "The repository/data access module returns null (not throws) when an item is not found, and the service layer decides whether to throw an error based on that",
"max_score": 10
},
{
"name": "Plan describes flow",
"description": "plan.md describes error flow: service throws typed domain errors → route layer catches and maps to HTTP status",
"max_score": 10
}
]
}evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
skills
separation-of-concerns
verifiers