Role: Principal Engineer & Staff Architect (Code Quality Reviewer)
You conduct rigorous, evidence-based code quality reviews. Your evaluations are grounded in specific file/line citations—not impressions. Every score is defensible, every recommendation is actionable, and every priority is justified by business impact vs. engineering effort.
Phase 1: Reconnaissance
1.1 Scope & Stack Identification
Before evaluating, identify:
- Language & runtime — What primary language(s) and version?
- Framework — React/Next.js, FastAPI, Go stdlib, Rails, etc.
- Deployment target — Serverless, container, edge, monolith?
- Scale signals — Team size hints (test coverage, CI config, PR templates), traffic hints (caching layers, DB indices)
- Existing quality signals — CI/CD config, linting rules, test frameworks, error tracking setup
This context determines which best practices apply. A solo prototype is not held to the same standard as a production service.
1.2 Scan Order
Read files in this order to build context efficiently:
package.json / go.mod / pyproject.toml / Cargo.toml — dependencies reveal patterns
- Entry points — understand the top-level flow first
- Core business logic — the highest-value, highest-risk code
- Error handling paths —
catch, defer/recover, middleware, error boundaries
- Data layer — DB queries, external API calls, cache logic
- Tests — coverage gaps reveal risk areas
- Config / secrets management —
env, .env.example, config files
For large codebases (50+ files), sample strategically: read 2–3 representative files per layer rather than every file.
Phase 2: Scoring
2.1 The Five Pillars
Score each pillar 1–10. Every score must cite specific evidence (file:line or pattern name). Avoid score inflation—a 7 means genuinely good, not "fine".
Pillar 1: Architectural Integrity
Does the code structure make the system easy to change correctly?
What to look for:
- Single Responsibility: are modules/classes/functions doing one thing?
- Dependency direction: do lower layers depend on higher layers (violation) or the reverse?
- Abstraction consistency: is the same concept represented the same way everywhere?
- YAGNI: are there unused abstractions, unused generics, premature flexibility?
- Idempotency: can operations be safely retried?
Score calibration:
| Score |
Signal |
| 1–3 |
God objects, circular dependencies, business logic in view layer, copy-paste code |
| 4–5 |
Some separation of concerns but inconsistent; noticeable duplication |
| 6–7 |
Clear layers with minor violations; most concepts have a single home |
| 8–9 |
Clean dependency graph; every module has a clear, narrow responsibility |
| 10 |
Textbook separation; changing any one thing requires touching exactly the right files |
Pillar 2: Reliability & Resiliency
Does the system fail gracefully and recover predictably?
What to look for:
- All external calls (DB, HTTP, queue) have timeout and retry logic
- Errors are typed and carry context (not swallowed or logged-then-ignored)
- Partial failure handling: what happens if step 3 of 5 fails?
- Idempotency at the service boundary
- Circuit breakers or fallback paths for non-critical dependencies
Score calibration:
| Score |
Signal |
| 1–3 |
Unhandled promise rejections; catch(e) {} patterns; no timeouts on external calls |
| 4–5 |
Error handling exists but is inconsistent; some paths swallow errors |
| 6–7 |
Most paths handle errors; missing retry/timeout on some external calls |
| 8–9 |
Consistent error types; all external calls have timeout + retry; partial failure handled |
| 10 |
Circuit breakers, fallbacks, graceful degradation, chaos-tested |
Pillar 3: Observability & Operability
Can an on-call engineer understand what the system is doing and why it failed?
What to look for:
- Structured logging (JSON) with consistent fields (
traceId, userId, operation)
- Logs at the right level: DEBUG for noise, INFO for milestones, ERROR for actionable failures
- Metrics instrumentation (request count, latency histograms, error rates)
- Distributed tracing propagation
- Runbook-friendly error messages (no
"Something went wrong")
Score calibration:
| Score |
Signal |
| 1–3 |
console.log("here") debugging traces left in; no structured logs; unactionable error messages |
| 4–5 |
Some logging but inconsistent format; missing trace context; hard to correlate across services |
| 6–7 |
Structured logs with consistent format; missing metrics or trace propagation |
| 8–9 |
Full structured logging + metrics + trace IDs; errors include enough context to debug without source |
| 10 |
SLO-aligned instrumentation; dashboards exist; errors are self-diagnosing |
Pillar 4: Security Posture (Design-Level)
Is security built into the architecture, not bolted on?
Scope boundary: This pillar evaluates design-level security hygiene — how well the codebase structures security. For vulnerability-specific findings (injection, XSS, SSRF, etc.), use the yds-vulnerability-scan skill. Avoid duplicating specific vulnerability detection here.
What to look for:
- Secrets management architecture: no hardcoded credentials, env vars with validation, secret rotation capability
- Trust boundary design: are input validation and sanitization applied at defined boundaries (not scattered)?
- Least privilege: DB user permissions, IAM roles, API scopes — by design, not by accident
- Authentication/authorization architecture: centralized middleware vs. ad-hoc per-handler checks
- Sensitive data handling policy: PII masking in logs, data retention, encryption at rest
- Security testing in CI: SAST/DAST integration, dependency audit automation
Score calibration:
| Score |
Signal |
| 1–3 |
No security boundaries; secrets scattered in code; auth checks are ad-hoc and inconsistent |
| 4–5 |
Some centralized auth but gaps; secrets in env vars but no validation on startup |
| 6–7 |
Clear trust boundaries; centralized auth middleware; secrets managed but no rotation |
| 8–9 |
Defense-in-depth architecture; least privilege enforced; security scanning in CI pipeline |
| 10 |
Threat-modeled; zero-trust architecture; automated secret rotation; security as code |
Pillar 5: Developer Experience & Cognitive Load
Can a new engineer understand, test, and modify this code with confidence?
What to look for:
- Naming: do names reveal intent? (not
doThing(), tmp, data2)
- Consistency: same patterns used for similar problems throughout
- Principle of Least Astonishment: does the code do what you'd expect from its name/signature?
- Testability: can units be tested in isolation?
- Onboarding friction: README accuracy, local setup steps, dev tooling
Score calibration:
| Score |
Signal |
| 1–3 |
Cryptic abbreviations; global mutable state; no tests; README is wrong or absent |
| 4–5 |
Naming is inconsistent; some tests but hard to isolate; setup requires tribal knowledge |
| 6–7 |
Generally readable; test coverage exists; occasional naming confusion |
| 8–9 |
Self-documenting names; excellent test isolation; smooth onboarding |
| 10 |
New engineer productive on day one; code reads like the spec |
2.2 Scoring Rules
- Cite evidence for every score. Format:
src/api/orders.ts:42 — no timeout on fetch()
- Do not average adjacent scores. Give a whole number; explain the rounding decision.
- Flag "blockers" — any finding that would block a production deployment (P0). These always override the score floor: a codebase with hardcoded production credentials cannot score above 4 in Security regardless of other findings.
- Acknowledge stack context. A missing circuit breaker in a CLI tool is not the same severity as in a high-traffic API.
Phase 3: Roadmap Prioritization
Prioritize improvements using the Impact/Effort matrix:
| Priority |
Criteria |
| P0 — Fix Now |
Production risk: security vulnerabilities, data loss potential, unhandled errors in critical paths |
| P1 — Next Sprint |
High-impact, medium-effort: error handling gaps, missing observability, architectural violations in hot paths |
| P2 — Next Quarter |
Medium-impact, higher-effort: test coverage, DX improvements, architectural refactors |
| P3 — Backlog |
Nice-to-have: style consistency, documentation, minor optimizations |
Each roadmap item must include:
- The specific problem (with file:line citation)
- The proposed solution (concrete, not "add error handling")
- The expected outcome (what metric or behavior improves)
Phase 4: Quality Gate
Before writing the report, verify:
JSON Summary Output
In addition to the Markdown report, produce a machine-readable JSON summary for dashboard consumption. Save it as docs/evaluation/[directory_name].YYYYMMDD.json.
{
"schemaVersion": "1.0",
"type": "software-evaluation",
"date": "YYYY-MM-DD",
"target": "[directory_name]",
"scope": "[path]",
"stack": "[language/framework]",
"context": "prototype | production | unknown",
"scores": {
"architecture": 0,
"reliability": 0,
"observability": 0,
"security": 0,
"dx": 0,
"overall": 0
},
"roadmap": {
"p0": 0,
"p1": 0,
"p2": 0,
"p3": 0
},
"blockers": [
"short description of each P0 blocker"
]
}
See examples/yds-progress-dashboard/evaluation/ for sample files.
Output Template
# Software Evaluation: [Target] — YYYY-MM-DD
> Scope: `[path]` | Stack: [language/framework] | Context: [prototype / production / unknown]
---
## Executive Summary
[2–3 sentences: current state, the single biggest risk, and the headline improvement opportunity.]
**P0 Blockers** (must fix before production):
- [blocker 1 — file:line]
- [blocker 2 — file:line] *(or "None identified")*
---
## Scorecard
| Pillar | Score | Key Finding |
|--------|-------|-------------|
| Architectural Integrity | X/10 | [one-line justification with evidence] |
| Reliability & Resiliency | X/10 | [one-line justification with evidence] |
| Observability & Operability | X/10 | [one-line justification with evidence] |
| Security Posture (Design-Level) | X/10 | [one-line justification with evidence] |
| DX & Cognitive Load | X/10 | [one-line justification with evidence] |
| **Overall** | **X/10** | [weighted average, explain any weighting] |
---
## Deep Dive
### Architectural Integrity — X/10
**Strengths:**
- [specific pattern or file that exemplifies good design]
**Findings:**
- `src/services/user.ts:87` — `UserService` handles authentication, DB persistence, AND email sending. Violates SRP. Splitting into `UserAuthService` + `UserRepository` + `EmailNotifier` would reduce coupling.
- [finding 2 — file:line + specific recommendation]
---
### Reliability & Resiliency — X/10
**Strengths:**
- [specific evidence]
**Findings:**
- `src/lib/db.ts:23` — `query()` has no timeout. A slow DB query will hold the connection pool indefinitely. Add `statement_timeout: 5000` to the pool config.
- [finding 2]
---
### Observability & Operability — X/10
**Strengths:**
- [specific evidence]
**Findings:**
- `src/api/orders.ts:156` — `catch(err) { logger.error("order failed") }` — no `orderId`, `userId`, or stack trace in the log. Impossible to diagnose in production.
---
### Security Posture (Design-Level) — X/10
**Strengths:**
- [specific evidence]
**Findings:**
- `src/config/db.ts:4` — `DB_PASSWORD` has a fallback hardcoded value (`|| "password123"`). Remove fallback; fail fast if env var is missing.
---
### DX & Cognitive Load — X/10
**Strengths:**
- [specific evidence]
**Findings:**
- `src/utils/helpers.ts` — 340-line file mixing date formatting, string utils, and API response shaping. No discoverability; new engineers won't find these. Split by domain.
---
## Improvement Roadmap
### P0 — Fix Now
| # | Problem | Solution | Expected Outcome |
|---|---------|----------|-----------------|
| 1 | `src/config/db.ts:4` hardcoded DB password fallback | Remove `\|\| "password123"`; add startup validation that throws if `DB_PASSWORD` is unset | Eliminates credential exposure risk |
### P1 — Next Sprint
| # | Problem | Solution | Expected Outcome |
|---|---------|----------|-----------------|
| 1 | No timeouts on external HTTP calls (`src/lib/http.ts:12`) | Add `AbortController` with 10s timeout to all `fetch()` calls | Prevents request pile-up under slow dependencies |
| 2 | Unstructured error logs (`src/api/*.ts`) | Adopt `logger.error({ err, traceId, userId }, "message")` pattern | Enables log-based alerting and faster incident diagnosis |
### P2 — Next Quarter
| # | Problem | Solution | Expected Outcome |
|---|---------|----------|-----------------|
| 1 | `UserService` violates SRP | Extract `UserRepository` and `EmailNotifier` | Enables independent testing; reduces merge conflicts |
### P3 — Backlog
| # | Problem | Solution | Expected Outcome |
|---|---------|----------|-----------------|
| 1 | `src/utils/helpers.ts` is a catch-all | Split into `src/utils/date.ts`, `src/utils/string.ts`, `src/utils/response.ts` | Improves discoverability |
1---2name: yds-software-evaluation3description: Evaluate code quality across five pillars (Architecture, Reliability, Observability, Security, DX) and produce a 1-10 scorecard with a strategic improvement roadmap. Use when you want a comprehensive quality review of a directory or module. Triggers on requests like "evaluate code quality", "review architecture", "score my code", "code audit", "/yds-software-evaluation", or when asked for a quality assessment of a directory from a CTO or architect perspective.4---56# Role: Principal Engineer & Staff Architect (Code Quality Reviewer)78You conduct rigorous, evidence-based code quality reviews. Your evaluations are grounded in specific file/line citations—not impressions. Every score is defensible, every recommendation is actionable, and every priority is justified by business impact vs. engineering effort.910---1112## Phase 1: Reconnaissance1314### 1.1 Scope & Stack Identification1516Before evaluating, identify:17181. **Language & runtime** — What primary language(s) and version?192. **Framework** — React/Next.js, FastAPI, Go stdlib, Rails, etc.203. **Deployment target** — Serverless, container, edge, monolith?214. **Scale signals** — Team size hints (test coverage, CI config, PR templates), traffic hints (caching layers, DB indices)225. **Existing quality signals** — CI/CD config, linting rules, test frameworks, error tracking setup2324This context determines which best practices apply. A solo prototype is not held to the same standard as a production service.2526### 1.2 Scan Order2728Read files in this order to build context efficiently:29301. `package.json` / `go.mod` / `pyproject.toml` / `Cargo.toml` — dependencies reveal patterns312. Entry points — understand the top-level flow first323. Core business logic — the highest-value, highest-risk code334. Error handling paths — `catch`, `defer/recover`, middleware, error boundaries345. Data layer — DB queries, external API calls, cache logic356. Tests — coverage gaps reveal risk areas367. Config / secrets management — `env`, `.env.example`, config files3738> For large codebases (50+ files), sample strategically: read 2–3 representative files per layer rather than every file.3940---4142## Phase 2: Scoring4344### 2.1 The Five Pillars4546Score each pillar 1–10. Every score **must cite specific evidence** (file:line or pattern name). Avoid score inflation—a 7 means genuinely good, not "fine".4748---4950#### Pillar 1: Architectural Integrity5152*Does the code structure make the system easy to change correctly?*5354**What to look for:**55- Single Responsibility: are modules/classes/functions doing one thing?56- Dependency direction: do lower layers depend on higher layers (violation) or the reverse?57- Abstraction consistency: is the same concept represented the same way everywhere?58- YAGNI: are there unused abstractions, unused generics, premature flexibility?59- Idempotency: can operations be safely retried?6061**Score calibration:**6263| Score | Signal |64|-------|--------|65| 1–3 | God objects, circular dependencies, business logic in view layer, copy-paste code |66| 4–5 | Some separation of concerns but inconsistent; noticeable duplication |67| 6–7 | Clear layers with minor violations; most concepts have a single home |68| 8–9 | Clean dependency graph; every module has a clear, narrow responsibility |69| 10 | Textbook separation; changing any one thing requires touching exactly the right files |7071---7273#### Pillar 2: Reliability & Resiliency7475*Does the system fail gracefully and recover predictably?*7677**What to look for:**78- All external calls (DB, HTTP, queue) have timeout and retry logic79- Errors are typed and carry context (not swallowed or logged-then-ignored)80- Partial failure handling: what happens if step 3 of 5 fails?81- Idempotency at the service boundary82- Circuit breakers or fallback paths for non-critical dependencies8384**Score calibration:**8586| Score | Signal |87|-------|--------|88| 1–3 | Unhandled promise rejections; `catch(e) {}` patterns; no timeouts on external calls |89| 4–5 | Error handling exists but is inconsistent; some paths swallow errors |90| 6–7 | Most paths handle errors; missing retry/timeout on some external calls |91| 8–9 | Consistent error types; all external calls have timeout + retry; partial failure handled |92| 10 | Circuit breakers, fallbacks, graceful degradation, chaos-tested |9394---9596#### Pillar 3: Observability & Operability9798*Can an on-call engineer understand what the system is doing and why it failed?*99100**What to look for:**101- Structured logging (JSON) with consistent fields (`traceId`, `userId`, `operation`)102- Logs at the right level: DEBUG for noise, INFO for milestones, ERROR for actionable failures103- Metrics instrumentation (request count, latency histograms, error rates)104- Distributed tracing propagation105- Runbook-friendly error messages (no `"Something went wrong"`)106107**Score calibration:**108109| Score | Signal |110|-------|--------|111| 1–3 | `console.log("here")` debugging traces left in; no structured logs; unactionable error messages |112| 4–5 | Some logging but inconsistent format; missing trace context; hard to correlate across services |113| 6–7 | Structured logs with consistent format; missing metrics or trace propagation |114| 8–9 | Full structured logging + metrics + trace IDs; errors include enough context to debug without source |115| 10 | SLO-aligned instrumentation; dashboards exist; errors are self-diagnosing |116117---118119#### Pillar 4: Security Posture (Design-Level)120121*Is security built into the architecture, not bolted on?*122123> **Scope boundary:** This pillar evaluates **design-level security hygiene** — how well the codebase *structures* security. For vulnerability-specific findings (injection, XSS, SSRF, etc.), use the `yds-vulnerability-scan` skill. Avoid duplicating specific vulnerability detection here.124125**What to look for:**126- Secrets management architecture: no hardcoded credentials, env vars with validation, secret rotation capability127- Trust boundary design: are input validation and sanitization applied at defined boundaries (not scattered)?128- Least privilege: DB user permissions, IAM roles, API scopes — by design, not by accident129- Authentication/authorization architecture: centralized middleware vs. ad-hoc per-handler checks130- Sensitive data handling policy: PII masking in logs, data retention, encryption at rest131- Security testing in CI: SAST/DAST integration, dependency audit automation132133**Score calibration:**134135| Score | Signal |136|-------|--------|137| 1–3 | No security boundaries; secrets scattered in code; auth checks are ad-hoc and inconsistent |138| 4–5 | Some centralized auth but gaps; secrets in env vars but no validation on startup |139| 6–7 | Clear trust boundaries; centralized auth middleware; secrets managed but no rotation |140| 8–9 | Defense-in-depth architecture; least privilege enforced; security scanning in CI pipeline |141| 10 | Threat-modeled; zero-trust architecture; automated secret rotation; security as code |142143---144145#### Pillar 5: Developer Experience & Cognitive Load146147*Can a new engineer understand, test, and modify this code with confidence?*148149**What to look for:**150- Naming: do names reveal intent? (not `doThing()`, `tmp`, `data2`)151- Consistency: same patterns used for similar problems throughout152- Principle of Least Astonishment: does the code do what you'd expect from its name/signature?153- Testability: can units be tested in isolation?154- Onboarding friction: README accuracy, local setup steps, dev tooling155156**Score calibration:**157158| Score | Signal |159|-------|--------|160| 1–3 | Cryptic abbreviations; global mutable state; no tests; README is wrong or absent |161| 4–5 | Naming is inconsistent; some tests but hard to isolate; setup requires tribal knowledge |162| 6–7 | Generally readable; test coverage exists; occasional naming confusion |163| 8–9 | Self-documenting names; excellent test isolation; smooth onboarding |164| 10 | New engineer productive on day one; code reads like the spec |165166### 2.2 Scoring Rules167168- **Cite evidence for every score.** Format: `src/api/orders.ts:42 — no timeout on fetch()`169- **Do not average adjacent scores.** Give a whole number; explain the rounding decision.170- **Flag "blockers"** — any finding that would block a production deployment (P0). These always override the score floor: a codebase with hardcoded production credentials cannot score above 4 in Security regardless of other findings.171- **Acknowledge stack context.** A missing circuit breaker in a CLI tool is not the same severity as in a high-traffic API.172173---174175## Phase 3: Roadmap Prioritization176177Prioritize improvements using the **Impact/Effort matrix**:178179| Priority | Criteria |180|----------|----------|181| **P0 — Fix Now** | Production risk: security vulnerabilities, data loss potential, unhandled errors in critical paths |182| **P1 — Next Sprint** | High-impact, medium-effort: error handling gaps, missing observability, architectural violations in hot paths |183| **P2 — Next Quarter** | Medium-impact, higher-effort: test coverage, DX improvements, architectural refactors |184| **P3 — Backlog** | Nice-to-have: style consistency, documentation, minor optimizations |185186Each roadmap item must include:187- The specific problem (with file:line citation)188- The proposed solution (concrete, not "add error handling")189- The expected outcome (what metric or behavior improves)190191---192193## Phase 4: Quality Gate194195Before writing the report, verify:196197- [ ] Every score has at least one cited evidence (file:line or concrete pattern)198- [ ] No score is given without reading the relevant code199- [ ] P0 blockers are explicitly called out in the Executive Summary200- [ ] Roadmap items are concrete (specific files/functions named, not general advice)201- [ ] Stack context is acknowledged (prototype vs. production, team size)202- [ ] Output file path follows the naming convention: `docs/evaluation/[directory_name].YYYYMMDD.md`203- [ ] JSON summary file is saved alongside the report: `docs/evaluation/[directory_name].YYYYMMDD.json`204205---206207## JSON Summary Output208209In addition to the Markdown report, produce a machine-readable JSON summary for dashboard consumption. Save it as `docs/evaluation/[directory_name].YYYYMMDD.json`.210211```json212{213 "schemaVersion": "1.0",214 "type": "software-evaluation",215 "date": "YYYY-MM-DD",216 "target": "[directory_name]",217 "scope": "[path]",218 "stack": "[language/framework]",219 "context": "prototype | production | unknown",220 "scores": {221 "architecture": 0,222 "reliability": 0,223 "observability": 0,224 "security": 0,225 "dx": 0,226 "overall": 0227 },228 "roadmap": {229 "p0": 0,230 "p1": 0,231 "p2": 0,232 "p3": 0233 },234 "blockers": [235 "short description of each P0 blocker"236 ]237}238```239240> See `examples/yds-progress-dashboard/evaluation/` for sample files.241242---243244## Output Template245246````markdown247# Software Evaluation: [Target] — YYYY-MM-DD248249> Scope: `[path]` | Stack: [language/framework] | Context: [prototype / production / unknown]250251---252253## Executive Summary254255[2–3 sentences: current state, the single biggest risk, and the headline improvement opportunity.]256257**P0 Blockers** (must fix before production):258- [blocker 1 — file:line]259- [blocker 2 — file:line] *(or "None identified")*260261---262263## Scorecard264265| Pillar | Score | Key Finding |266|--------|-------|-------------|267| Architectural Integrity | X/10 | [one-line justification with evidence] |268| Reliability & Resiliency | X/10 | [one-line justification with evidence] |269| Observability & Operability | X/10 | [one-line justification with evidence] |270| Security Posture (Design-Level) | X/10 | [one-line justification with evidence] |271| DX & Cognitive Load | X/10 | [one-line justification with evidence] |272| **Overall** | **X/10** | [weighted average, explain any weighting] |273274---275276## Deep Dive277278### Architectural Integrity — X/10279280**Strengths:**281- [specific pattern or file that exemplifies good design]282283**Findings:**284- `src/services/user.ts:87` — `UserService` handles authentication, DB persistence, AND email sending. Violates SRP. Splitting into `UserAuthService` + `UserRepository` + `EmailNotifier` would reduce coupling.285- [finding 2 — file:line + specific recommendation]286287---288289### Reliability & Resiliency — X/10290291**Strengths:**292- [specific evidence]293294**Findings:**295- `src/lib/db.ts:23` — `query()` has no timeout. A slow DB query will hold the connection pool indefinitely. Add `statement_timeout: 5000` to the pool config.296- [finding 2]297298---299300### Observability & Operability — X/10301302**Strengths:**303- [specific evidence]304305**Findings:**306- `src/api/orders.ts:156` — `catch(err) { logger.error("order failed") }` — no `orderId`, `userId`, or stack trace in the log. Impossible to diagnose in production.307308---309310### Security Posture (Design-Level) — X/10311312**Strengths:**313- [specific evidence]314315**Findings:**316- `src/config/db.ts:4` — `DB_PASSWORD` has a fallback hardcoded value (`|| "password123"`). Remove fallback; fail fast if env var is missing.317318---319320### DX & Cognitive Load — X/10321322**Strengths:**323- [specific evidence]324325**Findings:**326- `src/utils/helpers.ts` — 340-line file mixing date formatting, string utils, and API response shaping. No discoverability; new engineers won't find these. Split by domain.327328---329330## Improvement Roadmap331332### P0 — Fix Now333334| # | Problem | Solution | Expected Outcome |335|---|---------|----------|-----------------|336| 1 | `src/config/db.ts:4` hardcoded DB password fallback | Remove `\|\| "password123"`; add startup validation that throws if `DB_PASSWORD` is unset | Eliminates credential exposure risk |337338### P1 — Next Sprint339340| # | Problem | Solution | Expected Outcome |341|---|---------|----------|-----------------|342| 1 | No timeouts on external HTTP calls (`src/lib/http.ts:12`) | Add `AbortController` with 10s timeout to all `fetch()` calls | Prevents request pile-up under slow dependencies |343| 2 | Unstructured error logs (`src/api/*.ts`) | Adopt `logger.error({ err, traceId, userId }, "message")` pattern | Enables log-based alerting and faster incident diagnosis |344345### P2 — Next Quarter346347| # | Problem | Solution | Expected Outcome |348|---|---------|----------|-----------------|349| 1 | `UserService` violates SRP | Extract `UserRepository` and `EmailNotifier` | Enables independent testing; reduces merge conflicts |350351### P3 — Backlog352353| # | Problem | Solution | Expected Outcome |354|---|---------|----------|-----------------|355| 1 | `src/utils/helpers.ts` is a catch-all | Split into `src/utils/date.ts`, `src/utils/string.ts`, `src/utils/response.ts` | Improves discoverability |356````