@kinqs/brainrouter-mcp-server 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/.env.example +144 -0
  2. package/README.md +56 -0
  3. package/agents/README.md +120 -0
  4. package/agents/code-reviewer.md +97 -0
  5. package/agents/security-auditor.md +101 -0
  6. package/agents/test-engineer.md +95 -0
  7. package/dist/__tests__/agent_mode.test.d.ts +1 -0
  8. package/dist/__tests__/api-routes.test.d.ts +1 -0
  9. package/dist/__tests__/api-routes.test.js +170 -0
  10. package/dist/__tests__/crypto.test.d.ts +1 -0
  11. package/dist/__tests__/crypto.test.js +28 -0
  12. package/dist/__tests__/host-integrations.test.d.ts +1 -0
  13. package/dist/__tests__/host-integrations.test.js +82 -0
  14. package/dist/__tests__/integration.test.d.ts +1 -0
  15. package/dist/__tests__/integration.test.js +50 -0
  16. package/dist/__tests__/loader.test.d.ts +1 -0
  17. package/dist/__tests__/loader.test.js +89 -0
  18. package/dist/__tests__/neural-spark.test.d.ts +1 -0
  19. package/dist/__tests__/neural-spark.test.js +112 -0
  20. package/dist/__tests__/pagination.test.d.ts +1 -0
  21. package/dist/__tests__/pagination.test.js +23 -0
  22. package/dist/__tests__/redaction.test.d.ts +1 -0
  23. package/dist/__tests__/redaction.test.js +17 -0
  24. package/dist/__tests__/registry.test.d.ts +1 -0
  25. package/dist/__tests__/registry.test.js +56 -0
  26. package/dist/__tests__/retry.test.d.ts +1 -0
  27. package/dist/__tests__/retry.test.js +30 -0
  28. package/dist/__tests__/skill-activation.test.d.ts +1 -0
  29. package/dist/__tests__/skill-activation.test.js +112 -0
  30. package/dist/__tests__/working-memory.test.d.ts +1 -0
  31. package/dist/__tests__/working-memory.test.js +200 -0
  32. package/dist/__tests__/workspace-paths.test.d.ts +1 -0
  33. package/dist/__tests__/workspace-paths.test.js +56 -0
  34. package/dist/__tests__/writer.test.d.ts +1 -0
  35. package/dist/__tests__/writer.test.js +94 -0
  36. package/dist/api/auth/crypto.d.ts +4 -0
  37. package/dist/api/auth/crypto.js +54 -0
  38. package/dist/api/middleware/auth.d.ts +12 -0
  39. package/dist/api/middleware/auth.js +90 -0
  40. package/dist/api/pagination.d.ts +18 -0
  41. package/dist/api/pagination.js +32 -0
  42. package/dist/api/routes/auth.d.ts +1 -0
  43. package/dist/api/routes/auth.js +130 -0
  44. package/dist/api/routes/chat-completions.d.ts +7 -0
  45. package/dist/api/routes/chat-completions.js +474 -0
  46. package/dist/api/routes/contradictions.d.ts +1 -0
  47. package/dist/api/routes/contradictions.js +28 -0
  48. package/dist/api/routes/evidence.d.ts +1 -0
  49. package/dist/api/routes/evidence.js +59 -0
  50. package/dist/api/routes/governance.d.ts +1 -0
  51. package/dist/api/routes/governance.js +95 -0
  52. package/dist/api/routes/graph.d.ts +1 -0
  53. package/dist/api/routes/graph.js +25 -0
  54. package/dist/api/routes/hooks.d.ts +1 -0
  55. package/dist/api/routes/hooks.js +88 -0
  56. package/dist/api/routes/memories.d.ts +1 -0
  57. package/dist/api/routes/memories.js +92 -0
  58. package/dist/api/routes/persona.d.ts +1 -0
  59. package/dist/api/routes/persona.js +9 -0
  60. package/dist/api/routes/scenes.d.ts +1 -0
  61. package/dist/api/routes/scenes.js +35 -0
  62. package/dist/api/routes/skills.d.ts +1 -0
  63. package/dist/api/routes/skills.js +14 -0
  64. package/dist/api/routes/stats.d.ts +1 -0
  65. package/dist/api/routes/stats.js +8 -0
  66. package/dist/api/routes/users.d.ts +1 -0
  67. package/dist/api/routes/users.js +82 -0
  68. package/dist/api/routes/working.d.ts +1 -0
  69. package/dist/api/routes/working.js +88 -0
  70. package/dist/index.d.ts +2 -0
  71. package/dist/index.js +492 -0
  72. package/dist/integrations/claude-code.d.ts +12 -0
  73. package/dist/integrations/claude-code.js +35 -0
  74. package/dist/integrations/codex.d.ts +12 -0
  75. package/dist/integrations/codex.js +34 -0
  76. package/dist/integrations/generic-mcp.d.ts +52 -0
  77. package/dist/integrations/generic-mcp.js +118 -0
  78. package/dist/loader.d.ts +29 -0
  79. package/dist/loader.js +200 -0
  80. package/dist/memory/capture.d.ts +35 -0
  81. package/dist/memory/capture.js +230 -0
  82. package/dist/memory/config.d.ts +2 -0
  83. package/dist/memory/config.js +3 -0
  84. package/dist/memory/engine.d.ts +203 -0
  85. package/dist/memory/engine.js +626 -0
  86. package/dist/memory/llm-semaphore.d.ts +41 -0
  87. package/dist/memory/llm-semaphore.js +81 -0
  88. package/dist/memory/memory-type-config.d.ts +11 -0
  89. package/dist/memory/memory-type-config.js +65 -0
  90. package/dist/memory/pipeline/cognitive-contradiction.d.ts +7 -0
  91. package/dist/memory/pipeline/cognitive-contradiction.js +59 -0
  92. package/dist/memory/pipeline/cognitive-dedup.d.ts +23 -0
  93. package/dist/memory/pipeline/cognitive-dedup.js +38 -0
  94. package/dist/memory/pipeline/cognitive-extractor.d.ts +21 -0
  95. package/dist/memory/pipeline/cognitive-extractor.js +183 -0
  96. package/dist/memory/pipeline/contextual-focus-builder.d.ts +13 -0
  97. package/dist/memory/pipeline/contextual-focus-builder.js +135 -0
  98. package/dist/memory/pipeline/focus-direction-shift.d.ts +10 -0
  99. package/dist/memory/pipeline/focus-direction-shift.js +27 -0
  100. package/dist/memory/pipeline/graph-builder.d.ts +11 -0
  101. package/dist/memory/pipeline/graph-builder.js +88 -0
  102. package/dist/memory/pipeline/graph-recall.d.ts +13 -0
  103. package/dist/memory/pipeline/graph-recall.js +55 -0
  104. package/dist/memory/pipeline/identity-distiller.d.ts +15 -0
  105. package/dist/memory/pipeline/identity-distiller.js +40 -0
  106. package/dist/memory/pipeline/l1-contradiction.d.ts +7 -0
  107. package/dist/memory/pipeline/l1-contradiction.js +66 -0
  108. package/dist/memory/pipeline/l1-dedup.d.ts +23 -0
  109. package/dist/memory/pipeline/l1-dedup.js +39 -0
  110. package/dist/memory/pipeline/l1-extractor.d.ts +21 -0
  111. package/dist/memory/pipeline/l1-extractor.js +180 -0
  112. package/dist/memory/pipeline/l2-direction-shift.d.ts +10 -0
  113. package/dist/memory/pipeline/l2-direction-shift.js +27 -0
  114. package/dist/memory/pipeline/l2-scene.d.ts +15 -0
  115. package/dist/memory/pipeline/l2-scene.js +140 -0
  116. package/dist/memory/pipeline/l3-distiller.d.ts +15 -0
  117. package/dist/memory/pipeline/l3-distiller.js +40 -0
  118. package/dist/memory/pipeline/neural-spark.d.ts +27 -0
  119. package/dist/memory/pipeline/neural-spark.js +78 -0
  120. package/dist/memory/pipeline/skill-prewarm.d.ts +63 -0
  121. package/dist/memory/pipeline/skill-prewarm.js +127 -0
  122. package/dist/memory/pipeline/task-queue.d.ts +54 -0
  123. package/dist/memory/pipeline/task-queue.js +117 -0
  124. package/dist/memory/prompts/cognitive-contradiction.d.ts +1 -0
  125. package/dist/memory/prompts/cognitive-contradiction.js +25 -0
  126. package/dist/memory/prompts/cognitive-extraction.d.ts +10 -0
  127. package/dist/memory/prompts/cognitive-extraction.js +114 -0
  128. package/dist/memory/prompts/core-identity.d.ts +6 -0
  129. package/dist/memory/prompts/core-identity.js +60 -0
  130. package/dist/memory/prompts/focus-direction-shift.d.ts +5 -0
  131. package/dist/memory/prompts/focus-direction-shift.js +32 -0
  132. package/dist/memory/prompts/focus-scene-cluster.d.ts +2 -0
  133. package/dist/memory/prompts/focus-scene-cluster.js +33 -0
  134. package/dist/memory/prompts/focus-scene.d.ts +7 -0
  135. package/dist/memory/prompts/focus-scene.js +40 -0
  136. package/dist/memory/prompts/graph-extraction-batch.d.ts +14 -0
  137. package/dist/memory/prompts/graph-extraction-batch.js +54 -0
  138. package/dist/memory/prompts/graph-extraction.d.ts +2 -0
  139. package/dist/memory/prompts/graph-extraction.js +53 -0
  140. package/dist/memory/prompts/l1-contradiction-batch.d.ts +16 -0
  141. package/dist/memory/prompts/l1-contradiction-batch.js +47 -0
  142. package/dist/memory/prompts/l1-contradiction.d.ts +1 -0
  143. package/dist/memory/prompts/l1-contradiction.js +25 -0
  144. package/dist/memory/prompts/l1-extraction.d.ts +10 -0
  145. package/dist/memory/prompts/l1-extraction.js +114 -0
  146. package/dist/memory/prompts/l2-direction-shift.d.ts +5 -0
  147. package/dist/memory/prompts/l2-direction-shift.js +32 -0
  148. package/dist/memory/prompts/l2-scene-cluster.d.ts +2 -0
  149. package/dist/memory/prompts/l2-scene-cluster.js +33 -0
  150. package/dist/memory/prompts/l2-scene.d.ts +7 -0
  151. package/dist/memory/prompts/l2-scene.js +40 -0
  152. package/dist/memory/prompts/l3-persona.d.ts +6 -0
  153. package/dist/memory/prompts/l3-persona.js +60 -0
  154. package/dist/memory/recall.d.ts +47 -0
  155. package/dist/memory/recall.js +427 -0
  156. package/dist/memory/redaction.d.ts +1 -0
  157. package/dist/memory/redaction.js +24 -0
  158. package/dist/memory/retry.d.ts +13 -0
  159. package/dist/memory/retry.js +53 -0
  160. package/dist/memory/scheduler.d.ts +9 -0
  161. package/dist/memory/scheduler.js +16 -0
  162. package/dist/memory/skill-hints-loader.d.ts +30 -0
  163. package/dist/memory/skill-hints-loader.js +100 -0
  164. package/dist/memory/store/embedding.d.ts +16 -0
  165. package/dist/memory/store/embedding.js +68 -0
  166. package/dist/memory/store/reranker.d.ts +24 -0
  167. package/dist/memory/store/reranker.js +83 -0
  168. package/dist/memory/store/sqlite.d.ts +167 -0
  169. package/dist/memory/store/sqlite.js +1816 -0
  170. package/dist/memory/store/types.d.ts +101 -0
  171. package/dist/memory/store/types.js +1 -0
  172. package/dist/memory/types.d.ts +207 -0
  173. package/dist/memory/types.js +7 -0
  174. package/dist/memory/validation.d.ts +441 -0
  175. package/dist/memory/validation.js +129 -0
  176. package/dist/memory/working/canvas.d.ts +5 -0
  177. package/dist/memory/working/canvas.js +43 -0
  178. package/dist/memory/working/offload.d.ts +71 -0
  179. package/dist/memory/working/offload.js +211 -0
  180. package/dist/memory/working/step-log.d.ts +16 -0
  181. package/dist/memory/working/step-log.js +35 -0
  182. package/dist/registry.d.ts +34 -0
  183. package/dist/registry.js +305 -0
  184. package/dist/resolver.d.ts +17 -0
  185. package/dist/resolver.js +126 -0
  186. package/dist/scripts/validate-foreign-workspace-path.d.ts +1 -0
  187. package/dist/scripts/validate-foreign-workspace-path.js +39 -0
  188. package/dist/tools/agent_memory_tools.d.ts +485 -0
  189. package/dist/tools/agent_memory_tools.js +793 -0
  190. package/dist/tools/create_skill.d.ts +46 -0
  191. package/dist/tools/create_skill.js +46 -0
  192. package/dist/tools/get_doc.d.ts +21 -0
  193. package/dist/tools/get_doc.js +24 -0
  194. package/dist/tools/get_persona.d.ts +15 -0
  195. package/dist/tools/get_persona.js +20 -0
  196. package/dist/tools/get_reference.d.ts +15 -0
  197. package/dist/tools/get_reference.js +20 -0
  198. package/dist/tools/get_skill.d.ts +34 -0
  199. package/dist/tools/get_skill.js +65 -0
  200. package/dist/tools/get_template_doc.d.ts +21 -0
  201. package/dist/tools/get_template_doc.js +24 -0
  202. package/dist/tools/list_docs.d.ts +15 -0
  203. package/dist/tools/list_docs.js +16 -0
  204. package/dist/tools/list_skills.d.ts +18 -0
  205. package/dist/tools/list_skills.js +17 -0
  206. package/dist/tools/list_template_docs.d.ts +15 -0
  207. package/dist/tools/list_template_docs.js +16 -0
  208. package/dist/tools/memory-engineering.d.ts +225 -0
  209. package/dist/tools/memory-engineering.js +284 -0
  210. package/dist/tools/memory-explain.d.ts +34 -0
  211. package/dist/tools/memory-explain.js +109 -0
  212. package/dist/tools/memory-governance.d.ts +171 -0
  213. package/dist/tools/memory-governance.js +224 -0
  214. package/dist/tools/memory-hooks.d.ts +67 -0
  215. package/dist/tools/memory-hooks.js +102 -0
  216. package/dist/tools/memory-working.d.ts +98 -0
  217. package/dist/tools/memory-working.js +101 -0
  218. package/dist/tools/memory_capture_turn.d.ts +66 -0
  219. package/dist/tools/memory_capture_turn.js +85 -0
  220. package/dist/tools/memory_consolidate.d.ts +55 -0
  221. package/dist/tools/memory_consolidate.js +176 -0
  222. package/dist/tools/memory_contradictions.d.ts +53 -0
  223. package/dist/tools/memory_contradictions.js +52 -0
  224. package/dist/tools/memory_graph_query.d.ts +51 -0
  225. package/dist/tools/memory_graph_query.js +35 -0
  226. package/dist/tools/memory_mark_cited.d.ts +43 -0
  227. package/dist/tools/memory_mark_cited.js +63 -0
  228. package/dist/tools/memory_recall.d.ts +77 -0
  229. package/dist/tools/memory_recall.js +81 -0
  230. package/dist/tools/memory_register_skill_hints.d.ts +49 -0
  231. package/dist/tools/memory_register_skill_hints.js +55 -0
  232. package/dist/tools/memory_resolve_session.d.ts +24 -0
  233. package/dist/tools/memory_resolve_session.js +133 -0
  234. package/dist/tools/memory_search.d.ts +146 -0
  235. package/dist/tools/memory_search.js +84 -0
  236. package/dist/tools/search_skills.d.ts +18 -0
  237. package/dist/tools/search_skills.js +17 -0
  238. package/dist/tools/update_doc.d.ts +24 -0
  239. package/dist/tools/update_doc.js +35 -0
  240. package/dist/tools/update_skill.d.ts +30 -0
  241. package/dist/tools/update_skill.js +80 -0
  242. package/dist/types.d.ts +81 -0
  243. package/dist/types.js +4 -0
  244. package/dist/writer.d.ts +30 -0
  245. package/dist/writer.js +220 -0
  246. package/docs/TEMPLATE ONLY +1 -0
  247. package/docs/api/API.md +64 -0
  248. package/docs/api/security/SECURITY.md +58 -0
  249. package/docs/deployment/DockerDeployment.md +30 -0
  250. package/docs/design/Design.md +59 -0
  251. package/docs/design/themes/apple.md +101 -0
  252. package/docs/design/themes/dieter-grid.md +100 -0
  253. package/docs/design/themes/gallery-white.md +100 -0
  254. package/docs/design/themes/pinterest.md +101 -0
  255. package/docs/design/themes/realty-open-house.md +101 -0
  256. package/docs/design/themes/vodafone.md +101 -0
  257. package/docs/hooks/Hooks.md +30 -0
  258. package/docs/schema/Schema.md +35 -0
  259. package/docs/strategy/ScalingStrategy.md +19 -0
  260. package/package.json +88 -0
  261. package/references/accessibility-checklist.md +160 -0
  262. package/references/orchestration-patterns.md +370 -0
  263. package/references/performance-checklist.md +153 -0
  264. package/references/security-checklist.md +134 -0
  265. package/references/testing-patterns.md +236 -0
  266. package/skills/agent/adr-skill/SKILL.md +299 -0
  267. package/skills/agent/agentic-engineering-workflow/SKILL.md +95 -0
  268. package/skills/agent/bootstrap-skill/SKILL.md +103 -0
  269. package/skills/agent/context-engineering/SKILL.md +307 -0
  270. package/skills/agent/debugging-and-error-recovery/SKILL.md +308 -0
  271. package/skills/agent/developer-growth-analysis/SKILL.md +328 -0
  272. package/skills/agent/doubt-driven-skill/SKILL.md +249 -0
  273. package/skills/agent/handover-skill/SKILL.md +112 -0
  274. package/skills/agent/idea-refine-skill/SKILL.md +185 -0
  275. package/skills/agent/idea-refine-skill/examples.md +238 -0
  276. package/skills/agent/idea-refine-skill/frameworks.md +99 -0
  277. package/skills/agent/idea-refine-skill/refinement-criteria.md +113 -0
  278. package/skills/agent/interview-skill/SKILL.md +226 -0
  279. package/skills/agent/planning-skill/SKILL.md +270 -0
  280. package/skills/agent/skill-authoring/SKILL.md +189 -0
  281. package/skills/agent/source-driven-skill/SKILL.md +197 -0
  282. package/skills/agent/spec-driven-skill/SKILL.md +221 -0
  283. package/skills/agent/sync-skill/SKILL.md +92 -0
  284. package/skills/agent/using-agent-skills/SKILL.md +189 -0
  285. package/skills/api/a11y-skill/SKILL.md +88 -0
  286. package/skills/api/api-skill/SKILL.md +123 -0
  287. package/skills/api/auth-skill/SKILL.md +80 -0
  288. package/skills/api/debug-skill/SKILL.md +535 -0
  289. package/skills/api/performance-skill/SKILL.md +100 -0
  290. package/skills/api/testing-skill/SKILL.md +100 -0
  291. package/skills/codebase/code-review-and-quality/SKILL.md +228 -0
  292. package/skills/codebase/code-simplification/SKILL.md +352 -0
  293. package/skills/codebase/code-structure-cleanup/SKILL.md +142 -0
  294. package/skills/codebase/concerns-skill/SKILL.md +89 -0
  295. package/skills/codebase/conventions-skill/SKILL.md +95 -0
  296. package/skills/codebase/doc-management-skill/SKILL.md +47 -0
  297. package/skills/codebase/git-workflow-skill/SKILL.md +312 -0
  298. package/skills/communication/1-3-1-rule/SKILL.md +120 -0
  299. package/skills/design/brutalist-skill/SKILL.md +131 -0
  300. package/skills/design/concept-diagrams/SKILL.md +387 -0
  301. package/skills/design/concept-diagrams/examples/apartment-floor-plan-conversion.md +244 -0
  302. package/skills/design/concept-diagrams/examples/automated-password-reset-flow.md +276 -0
  303. package/skills/design/concept-diagrams/examples/autonomous-llm-research-agent-flow.md +240 -0
  304. package/skills/design/concept-diagrams/examples/banana-journey-tree-to-smoothie.md +161 -0
  305. package/skills/design/concept-diagrams/examples/commercial-aircraft-structure.md +209 -0
  306. package/skills/design/concept-diagrams/examples/cpu-ooo-microarchitecture.md +236 -0
  307. package/skills/design/concept-diagrams/examples/electricity-grid-flow.md +182 -0
  308. package/skills/design/concept-diagrams/examples/feature-film-production-pipeline.md +172 -0
  309. package/skills/design/concept-diagrams/examples/hospital-emergency-department-flow.md +165 -0
  310. package/skills/design/concept-diagrams/examples/ml-benchmark-grouped-bar-chart.md +114 -0
  311. package/skills/design/concept-diagrams/examples/place-order-uml-sequence.md +325 -0
  312. package/skills/design/concept-diagrams/examples/smart-city-infrastructure.md +173 -0
  313. package/skills/design/concept-diagrams/examples/smartphone-layer-anatomy.md +154 -0
  314. package/skills/design/concept-diagrams/examples/sn2-reaction-mechanism.md +247 -0
  315. package/skills/design/concept-diagrams/examples/wind-turbine-structure.md +338 -0
  316. package/skills/design/concept-diagrams/references/dashboard-patterns.md +43 -0
  317. package/skills/design/concept-diagrams/references/infrastructure-patterns.md +144 -0
  318. package/skills/design/concept-diagrams/references/physical-shape-cookbook.md +42 -0
  319. package/skills/design/concept-diagrams/templates/template.html +174 -0
  320. package/skills/design/gpt-tasteskill/SKILL.md +114 -0
  321. package/skills/design/minimalist-skill/SKILL.md +116 -0
  322. package/skills/design/output-skill/SKILL.md +87 -0
  323. package/skills/design/redesign-skill/SKILL.md +213 -0
  324. package/skills/design/soft-skill/SKILL.md +132 -0
  325. package/skills/design/stitch-skill/EXAMPLE.md +121 -0
  326. package/skills/design/stitch-skill/SKILL.md +222 -0
  327. package/skills/design/taste-skill/SKILL.md +269 -0
  328. package/skills/devops/ci-cd-skill/SKILL.md +402 -0
  329. package/skills/devops/docker-skill/SKILL.md +297 -0
  330. package/skills/devops/domain-skill/SKILL.md +234 -0
  331. package/skills/lifecycle/changelog-generator/SKILL.md +135 -0
  332. package/skills/lifecycle/incremental-skill/SKILL.md +257 -0
  333. package/skills/lifecycle/migration-skill/SKILL.md +218 -0
  334. package/skills/lifecycle/shipping-skill/SKILL.md +321 -0
  335. package/skills/memory/agent-memory/SKILL.md +122 -0
  336. package/skills/qa/browser-testing-skill/SKILL.md +314 -0
  337. package/skills/ux/adversarial-ux-skill/SKILL.md +168 -0
@@ -0,0 +1,535 @@
1
+ ---
2
+ name: debug-skill
3
+ description: Diagnoses and recovers from complex REST and GraphQL API failures. Enforces reproduction before fixing and verifies via runtime inspection.
4
+ hints: |
5
+ - Systematically isolate the failing networking layer from DNS to application semantics before patching.
6
+ - Inspect GraphQL response payloads closely for inner "errors" arrays even when status is 200 OK.
7
+ - Differentiate between connection timeouts (firewalls/network) and read timeouts (slow server compute).
8
+ - Capture and log vendor-specific request tracking IDs (e.g. X-Request-Id) to streamline external support.
9
+ - Build reproducer curl commands or Vitest regression scripts to isolate and confirm fixed behaviors.
10
+ ---
11
+
12
+ # API Testing & Debugging
13
+
14
+ Drive REST and GraphQL diagnosis through standard terminal tools (`curl`, `nslookup`, `openssl`) and script execution. Isolate the failing layer before guessing at the fix.
15
+
16
+ ## When to Use
17
+
18
+ - API returns unexpected status or body
19
+ - Auth fails (401/403 after token refresh, OAuth, API key)
20
+ - Works in Postman but fails in code
21
+ - Webhook / callback integration debugging
22
+ - Building or reviewing API integration tests
23
+ - Rate limiting or pagination issues
24
+
25
+ Skip for UI rendering, DB query tuning, or DNS/firewall infra (escalate).
26
+
27
+ ## Core Principle
28
+
29
+ **Isolate the layer, then fix.** A 200 OK can hide broken data. A 500 can mask a one-character auth typo. Walk the chain in order; never skip a step.
30
+
31
+ ```
32
+ 1. Connectivity → can we reach the host at all?
33
+ 1.5 Timeouts → connect-slow vs read-slow?
34
+ 2. TLS/SSL → cert valid and trusted?
35
+ 3. Auth → credentials correct and unexpired?
36
+ 4. Request format → payload shape match server expectations?
37
+ 5. Response parse → does our code accept what came back?
38
+ 6. Semantics → does the data mean what we assume?
39
+ ```
40
+
41
+ ## 5-Minute Quickstart
42
+
43
+ ### REST via terminal
44
+
45
+ ```python
46
+ # Verbose request/response exchange
47
+ terminal('curl -v https://api.example.com/users/1')
48
+
49
+ # POST with JSON
50
+ terminal("""curl -X POST https://api.example.com/users \\
51
+ -H 'Content-Type: application/json' \\
52
+ -H "Authorization: Bearer $TOKEN" \\
53
+ -d '{"name":"test","email":"test@example.com"}'""")
54
+
55
+ # Headers only
56
+ terminal('curl -sI https://api.example.com/health')
57
+
58
+ # Pretty-print JSON
59
+ terminal('curl -s https://api.example.com/users | python3 -m json.tool')
60
+ ```
61
+
62
+ ### GraphQL via terminal
63
+
64
+ ```python
65
+ terminal("""curl -X POST https://api.example.com/graphql \\
66
+ -H 'Content-Type: application/json' \\
67
+ -H "Authorization: Bearer $TOKEN" \\
68
+ -d '{"query":"{ user(id: 1) { name email } }"}'""")
69
+ ```
70
+
71
+ **GraphQL gotcha:** servers often return HTTP 200 even when the query failed. Always inspect the `errors` field regardless of status code:
72
+
73
+ ```python
74
+ execute_code('''
75
+ import os, requests
76
+ resp = requests.post(
77
+ "https://api.example.com/graphql",
78
+ json={"query": "{ user(id: 1) { name email } }"},
79
+ headers={"Authorization": f"Bearer {os.environ['TOKEN']}"},
80
+ timeout=10,
81
+ )
82
+ data = resp.json()
83
+ if data.get("errors"):
84
+ for err in data["errors"]:
85
+ print(f"GraphQL error: {err['message']} (path: {err.get('path')})")
86
+ print(data.get("data"))
87
+ ''')
88
+ ```
89
+
90
+ ### Python (requests) via execute_code
91
+
92
+ ```python
93
+ execute_code('''
94
+ import requests
95
+ resp = requests.get(
96
+ "https://api.example.com/users/1",
97
+ headers={"Authorization": "Bearer <TOKEN>"},
98
+ timeout=(3.05, 30), # (connect, read)
99
+ )
100
+ print(resp.status_code, dict(resp.headers))
101
+ print(resp.text[:500])
102
+ ''')
103
+ ```
104
+
105
+ ## Layered Debug Flow
106
+
107
+ ### Step 1 — Connectivity
108
+
109
+ ```python
110
+ terminal('nslookup api.example.com')
111
+ terminal('curl -v --connect-timeout 5 https://api.example.com/health')
112
+ ```
113
+
114
+ Failures: DNS not resolving, firewall, VPN required, proxy missing.
115
+
116
+ ### Step 1.5 — Timeouts
117
+
118
+ Distinguish *can't reach* from *reaches but slow*:
119
+
120
+ ```python
121
+ terminal('''curl -w "dns:%{time_namelookup}s connect:%{time_connect}s tls:%{time_appconnect}s ttfb:%{time_starttransfer}s total:%{time_total}s\\n" \\
122
+ -o /dev/null -s https://api.example.com/endpoint''')
123
+ ```
124
+
125
+ In Python, always pass a tuple timeout — `requests` has no default and will hang forever:
126
+
127
+ ```python
128
+ execute_code('''
129
+ import requests
130
+ from requests.exceptions import ConnectTimeout, ReadTimeout
131
+ try:
132
+ requests.get(url, timeout=(3.05, 30))
133
+ except ConnectTimeout:
134
+ print("Cannot reach host — DNS, firewall, VPN")
135
+ except ReadTimeout:
136
+ print("Connected but server is slow")
137
+ ''')
138
+ ```
139
+
140
+ Diagnosis: high `time_connect` is network/firewall; high `time_starttransfer` with low `time_connect` is a slow server.
141
+
142
+ ### Step 2 — TLS/SSL
143
+
144
+ ```python
145
+ terminal('curl -vI https://api.example.com 2>&1 | grep -E "SSL|subject|expire|issuer"')
146
+ ```
147
+
148
+ Failures: expired cert, self-signed, hostname mismatch, missing CA bundle. Use `-k` only for ad-hoc debug, never in code.
149
+
150
+ ### Step 3 — Authentication
151
+
152
+ ```python
153
+ # Token validity check
154
+ terminal('curl -s -o /dev/null -w "%{http_code}\\n" -H "Authorization: Bearer $TOKEN" https://api.example.com/me')
155
+
156
+ # Decode JWT exp claim — handles base64url padding correctly
157
+ execute_code('''
158
+ import json, base64, os
159
+ tok = os.environ["TOKEN"]
160
+ payload = tok.split(".")[1]
161
+ payload += "=" * (-len(payload) % 4)
162
+ print(json.dumps(json.loads(base64.urlsafe_b64decode(payload)), indent=2))
163
+ ''')
164
+ ```
165
+
166
+ Checklist:
167
+ - Token expired? (`exp` claim in JWT)
168
+ - Right scheme? Bearer vs Basic vs Token vs `X-Api-Key`
169
+ - Right environment? Staging key on prod is a classic
170
+ - API key in header vs query param (`?api_key=…`)?
171
+
172
+ ### Step 4 — Request Format
173
+
174
+ ```python
175
+ terminal("""curl -v -X POST https://api.example.com/endpoint \\
176
+ -H 'Content-Type: application/json' \\
177
+ -d '{"key":"value"}' 2>&1""")
178
+ ```
179
+
180
+ **Content-Type / body mismatch — the silent 415/400:**
181
+
182
+ ```python
183
+ # WRONG — data= sends form-encoded, header lies
184
+ requests.post(url, data='{"k":"v"}', headers={"Content-Type": "application/json"})
185
+
186
+ # RIGHT — json= auto-sets header AND serializes
187
+ requests.post(url, json={"k": "v"})
188
+
189
+ # WRONG — Accept says XML, code calls .json()
190
+ requests.get(url, headers={"Accept": "text/xml"})
191
+
192
+ # RIGHT — let requests build multipart with boundary
193
+ requests.post(url, files={"file": open("doc.pdf", "rb")})
194
+ ```
195
+
196
+ Common: form-encoded vs JSON, missing required fields, wrong HTTP method, unencoded query params.
197
+
198
+ ### Step 5 — Response Parsing
199
+
200
+ Always inspect content-type before calling `.json()`:
201
+
202
+ ```python
203
+ execute_code('''
204
+ import requests
205
+ resp = requests.post(url, json=payload, timeout=10)
206
+ print(f"status={resp.status_code}")
207
+ print(f"headers={dict(resp.headers)}")
208
+ ct = resp.headers.get("Content-Type", "")
209
+ if "application/json" in ct:
210
+ print(resp.json())
211
+ else:
212
+ print(f"unexpected content-type {ct!r}, body={resp.text[:500]!r}")
213
+ ''')
214
+ ```
215
+
216
+ Failures: HTML error page where JSON expected, empty body, wrong charset.
217
+
218
+ ### Step 6 — Semantic Validation
219
+
220
+ Parsed cleanly — but is the data *correct*?
221
+
222
+ - Does `"status": "active"` mean what your code thinks?
223
+ - ID in response matches the one requested?
224
+ - Timestamps in expected timezone?
225
+ - Pagination returning all results, or just page 1?
226
+
227
+ ## HTTP Status Playbook
228
+
229
+ ### 401 Unauthorized — credentials missing or invalid
230
+
231
+ 1. `Authorization` header actually present? (`curl -v` to confirm)
232
+ 2. Token correct and unexpired?
233
+ 3. Right auth scheme? (`Bearer` vs `Basic` vs `Token`)
234
+ 4. Some APIs use query param (`?api_key=…`) instead of header.
235
+
236
+ ### 403 Forbidden — authenticated but not authorized
237
+
238
+ 1. Token has the required scopes/permissions?
239
+ 2. Resource owned by a different account?
240
+ 3. IP allowlist blocking you?
241
+ 4. CORS in browser? (check `Access-Control-Allow-Origin`)
242
+
243
+ ### 404 Not Found — resource doesn't exist or URL is wrong
244
+
245
+ 1. Path correct? (trailing slash, typo, version prefix)
246
+ 2. Resource ID exists?
247
+ 3. Right API version (`/v1/` vs `/v2/`)?
248
+ 4. Right base URL (staging vs prod)?
249
+
250
+ ### 409 Conflict — state collision
251
+
252
+ 1. Resource already exists (duplicate create)?
253
+ 2. Stale `ETag` / `If-Match`?
254
+ 3. Concurrent modification by another process?
255
+
256
+ ### 422 Unprocessable Entity — valid JSON, invalid data
257
+
258
+ The error body usually names the bad fields. Check:
259
+ - Field types (string vs int, date format)
260
+ - Required vs optional
261
+ - Enum values inside the allowed set
262
+
263
+ ### 429 Too Many Requests — rate limited
264
+
265
+ Check `Retry-After` and `X-RateLimit-*` headers. Exponential backoff:
266
+
267
+ ```python
268
+ execute_code('''
269
+ import time, requests
270
+
271
+ def with_backoff(method, url, **kwargs):
272
+ for attempt in range(5):
273
+ resp = requests.request(method, url, **kwargs)
274
+ if resp.status_code != 429:
275
+ return resp
276
+ wait = int(resp.headers.get("Retry-After", 2 ** attempt))
277
+ time.sleep(wait)
278
+ return resp
279
+ ''')
280
+ ```
281
+
282
+ ### 5xx — server-side, usually not your fault
283
+
284
+ - **500** — server bug. Capture correlation ID, file with provider.
285
+ - **502** — upstream down. Backoff + retry.
286
+ - **503** — overloaded / maintenance. Check status page.
287
+ - **504** — upstream timeout. Reduce payload or raise timeout.
288
+
289
+ For all 5xx: backoff with jitter, alert on persistence.
290
+
291
+ ## Pagination & Idempotency
292
+
293
+ **Pagination.** Verify you're getting *all* results. Look for `next_cursor`, `next_page`, `total_count`. Two patterns:
294
+ - Offset (`?limit=100&offset=200`) — simple, can skip items if data shifts.
295
+ - Cursor (`?cursor=abc123`) — preferred for live or large datasets.
296
+
297
+ **Idempotency.** For non-idempotent operations (POST), send `Idempotency-Key: <uuid>` so retries don't double-charge / double-create. Mandatory for payments and orders.
298
+
299
+ ## Contract Validation
300
+
301
+ Catch schema drift before it hits production:
302
+
303
+ ```python
304
+ execute_code('''
305
+ import requests
306
+
307
+ def validate_user(data: dict) -> list[str]:
308
+ errors = []
309
+ required = {"id": int, "email": str, "created_at": str}
310
+ for field, expected in required.items():
311
+ if field not in data:
312
+ errors.append(f"missing field: {field}")
313
+ elif not isinstance(data[field], expected):
314
+ errors.append(f"{field}: want {expected.__name__}, got {type(data[field]).__name__}")
315
+ return errors
316
+
317
+ resp = requests.get(f"{BASE}/users/1", headers=HEADERS, timeout=10)
318
+ issues = validate_user(resp.json())
319
+ if issues:
320
+ print(f"contract violations: {issues}")
321
+ ''')
322
+ ```
323
+
324
+ Run after API upgrades, when integrating new third parties, or in CI smoke tests.
325
+
326
+ ## Correlation IDs
327
+
328
+ Always capture the provider's request ID — fastest path to vendor support:
329
+
330
+ ```python
331
+ execute_code('''
332
+ import requests
333
+ resp = requests.post(url, json=payload, headers=headers, timeout=10)
334
+ request_id = (
335
+ resp.headers.get("X-Request-Id")
336
+ or resp.headers.get("X-Trace-Id")
337
+ or resp.headers.get("CF-Ray") # Cloudflare
338
+ )
339
+ if resp.status_code >= 400:
340
+ print(f"failed status={resp.status_code} req_id={request_id} ts={resp.headers.get('Date')}")
341
+ ''')
342
+ ```
343
+
344
+ **Vendor bug-report template:**
345
+
346
+ ```
347
+ Endpoint: POST /api/v1/orders
348
+ Request ID: req_abc123xyz
349
+ Timestamp: 2026-03-17T14:30:00Z
350
+ Status: 500
351
+ Expected: 201 with order object
352
+ Actual: 500 {"error":"internal server error"}
353
+ Repro: curl -X POST … (auth: <REDACTED>)
354
+ ```
355
+
356
+ ## Regression Test Template
357
+
358
+ Drop this into `tests/` and run via `terminal('pytest tests/test_api_smoke.py -v')`:
359
+
360
+ ```python
361
+ import os, requests, pytest
362
+
363
+ BASE_URL = os.environ.get("API_BASE_URL", "https://api.example.com")
364
+ TOKEN = os.environ.get("API_TOKEN", "")
365
+ HEADERS = {"Authorization": f"Bearer {TOKEN}"}
366
+
367
+ class TestAPISmoke:
368
+ def test_health(self):
369
+ resp = requests.get(f"{BASE_URL}/health", timeout=5)
370
+ assert resp.status_code == 200
371
+
372
+ def test_list_users_returns_array(self):
373
+ resp = requests.get(f"{BASE_URL}/users", headers=HEADERS, timeout=10)
374
+ assert resp.status_code == 200
375
+ data = resp.json()
376
+ assert isinstance(data.get("data", data), list)
377
+
378
+ def test_get_user_required_fields(self):
379
+ resp = requests.get(f"{BASE_URL}/users/1", headers=HEADERS, timeout=10)
380
+ assert resp.status_code in (200, 404)
381
+ if resp.status_code == 200:
382
+ user = resp.json()
383
+ assert "id" in user and "email" in user
384
+
385
+ def test_invalid_auth_returns_401(self):
386
+ resp = requests.get(
387
+ f"{BASE_URL}/users",
388
+ headers={"Authorization": "Bearer invalid-token"},
389
+ timeout=10,
390
+ )
391
+ assert resp.status_code == 401
392
+ ```
393
+
394
+ ## Security
395
+
396
+ ### Token handling
397
+ - Never log full tokens. Redact: `Bearer <REDACTED>`.
398
+ - Never hardcode tokens in scripts. Read from env (`os.environ["API_TOKEN"]`) or `~/.hermes/.env`.
399
+ - Rotate immediately if a token surfaces in logs, error messages, or git history.
400
+
401
+ ### Safe logging
402
+
403
+ ```python
404
+ def redact_auth(headers: dict) -> dict:
405
+ sensitive = {"authorization", "x-api-key", "cookie", "set-cookie"}
406
+ return {k: ("<REDACTED>" if k.lower() in sensitive else v) for k, v in headers.items()}
407
+ ```
408
+
409
+ ### Leak checklist
410
+
411
+ - [ ] **Credentials in URLs.** API keys in query strings end up in server logs, browser history, referrer headers — use headers.
412
+ - [ ] **PII in error responses.** `404 on /users/123` shouldn't reveal whether the user exists (enumeration).
413
+ - [ ] **Stack traces in prod.** 500s shouldn't leak file paths, framework versions.
414
+ - [ ] **Internal hostnames/IPs.** `10.x.x.x`, `internal-api.corp.local` in error bodies.
415
+ - [ ] **Tokens echoed back.** Some APIs include the auth token in error details. Verify they don't.
416
+ - [ ] **Verbose `Server` / `X-Powered-By`.** Stack-info leaks. Note for security review.
417
+
418
+ ## Hermes Tool Patterns
419
+
420
+ ### terminal — for curl, dig, openssl
421
+
422
+ ```python
423
+ terminal('curl -sI https://api.example.com')
424
+ terminal('openssl s_client -connect api.example.com:443 -servername api.example.com </dev/null 2>/dev/null | openssl x509 -noout -dates')
425
+ ```
426
+
427
+ ### execute_code — for multi-step Python flows
428
+
429
+ When debugging spans auth → fetch → paginate → validate, use `execute_code`. Variables persist for the script, results print to stdout, no risk of token spam in your context:
430
+
431
+ ```python
432
+ execute_code('''
433
+ import os, requests
434
+
435
+ token = os.environ["API_TOKEN"]
436
+ base = "https://api.example.com"
437
+ H = {"Authorization": f"Bearer {token}"}
438
+
439
+ # 1. auth
440
+ me = requests.get(f"{base}/me", headers=H, timeout=10)
441
+ print(f"auth {me.status_code}")
442
+
443
+ # 2. paginate
444
+ all_users, cursor = [], None
445
+ while True:
446
+ params = {"cursor": cursor} if cursor else {}
447
+ r = requests.get(f"{base}/users", headers=H, params=params, timeout=10)
448
+ body = r.json()
449
+ all_users.extend(body["data"])
450
+ cursor = body.get("next_cursor")
451
+ if not cursor:
452
+ break
453
+ print(f"users={len(all_users)}")
454
+ ''')
455
+ ```
456
+
457
+ ### web_extract — for vendor API docs
458
+
459
+ Pull the spec for the endpoint you're debugging instead of guessing:
460
+
461
+ ```python
462
+ web_extract(urls=["https://docs.example.com/api/v1/users"])
463
+ ```
464
+
465
+ ### delegate_task — for full CRUD test sweeps
466
+
467
+ ```python
468
+ delegate_task(
469
+ goal="Test all CRUD endpoints for /api/v1/users",
470
+ context="""
471
+ Follow the rest-graphql-debug skill (optional-skills/software-development/rest-graphql-debug).
472
+ Base URL: https://api.example.com
473
+ Auth: Bearer token from API_TOKEN env var.
474
+
475
+ For each verb (POST, GET, PATCH, DELETE):
476
+ - happy path: assert status + response schema
477
+ - error cases: 400, 404, 422
478
+ - log a repro curl for any failure (redact tokens)
479
+
480
+ Output: pass/fail per endpoint + correlation IDs for failures.
481
+ """,
482
+ toolsets=["terminal", "file"],
483
+ )
484
+ ```
485
+
486
+ ## Output Format
487
+
488
+ When reporting findings:
489
+
490
+ ```
491
+ ## Finding
492
+ Endpoint: POST /api/v1/users
493
+ Status: 422 Unprocessable Entity
494
+ Req ID: req_abc123xyz
495
+
496
+ ## Repro
497
+ curl -X POST https://api.example.com/api/v1/users \
498
+ -H 'Content-Type: application/json' \
499
+ -H 'Authorization: Bearer <REDACTED>' \
500
+ -d '{"name":"test"}'
501
+
502
+ ## Root Cause
503
+ Missing required field `email`. Server validation rejects before processing.
504
+
505
+ ## Fix
506
+ -d '{"name":"test","email":"test@example.com"}'
507
+ ```
508
+
509
+ ## Related
510
+
511
+ - `systematic-debugging` — once the failing API layer is isolated, root-cause your code
512
+ - `test-driven-development` — write the regression test before shipping the fix
513
+
514
+ ## Common Rationalizations
515
+
516
+ | Rationalization | Reality |
517
+ |---|---|
518
+ | "I'll guess the fix based on the exception text." | Guessing leads to trial-and-error changes that bloat the git history and introduce side effects. Always isolate the network layer first. |
519
+ | "A 200 OK status means the API request succeeded." | Many APIs (especially GraphQL) return 200 OK but include structured exceptions or partial data. Always parse and validate payload bodies. |
520
+ | "We don't need a formal reproducer for simple bugs." | If you can't reliably reproduce a failure, you can't verify that your change was the active fix rather than transient environmental behavior. |
521
+
522
+ ## Red Flags
523
+
524
+ - Guessing or modifying source code without replicating the bug locally or via curl first.
525
+ - Blindly ignoring SSL certificate warnings (`-k` or `NODE_TLS_REJECT_UNAUTHORIZED=0`) in production code.
526
+ - Swallowing internal exception messages inside catch blocks without mapping, logging, or reporting them.
527
+ - Sharing full API auth headers, Bearer tokens, or passwords inside plain text logs or vendor bug reports.
528
+
529
+ ## Verification
530
+
531
+ After completing the debugging process, verify:
532
+ - [ ] Network layer is successfully isolated and localized (Connectivity, TLS, Auth, Payload, or Application logic).
533
+ - [ ] A reproducible test scenario (curl command, script, or test case) predictably fails.
534
+ - [ ] The identified fix is applied and verified as passing using the same reproducer criteria.
535
+ - [ ] All sensitive credentials, tokens, or PII are redacted from diagnostics, curl statements, and debug scripts.
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: performance-skill
3
+ description: Redis caching, Postgres replication, query indexing, and connection management rules for performance and scalability. Use when writing database queries, configuring caching layers, or auditing backend load speeds.
4
+ hints: |
5
+ - Use Cache-Aside pattern for read-heavy, slowly changing data models.
6
+ - Actively invalidate cache keys upon data modifications (POST, PATCH, DELETE).
7
+ - Explicitly route read-only operations to database replicas and mutations to the primary host.
8
+ - Run EXPLAIN ANALYZE on complex database queries to ensure active index coverage.
9
+ - Avoid executing heavy calculations or string manipulations inside SQL queries.
10
+ ---
11
+
12
+ # Performance & Scalability Skill
13
+
14
+ ## Overview
15
+
16
+ This skill ensures backend API structures remain fast, responsive, and resource-efficient as user traffic and data volume grow. Enforcing strict caching architectures, database replication rules, indexing profiles, and application-layer calculations prevents latency spikes and keeps resource usage optimized.
17
+
18
+ ## Workflow
19
+
20
+ - **[PERF-001] Cache-Aside Pattern**
21
+ - Use the "Cache-Aside" strategy for frequently read, slowly changing data structures.
22
+ - Workflow: Check Cache (Redis) -> If hit, return -> If miss, query Database -> Set Cache (Redis) with TTL -> Return.
23
+ - Set reasonable TTLs (e.g., 5-10 minutes) based on data volatility.
24
+
25
+ - **[PERF-002] Proactive Cache Invalidation**
26
+ - When data is modified (POST, PATCH, DELETE), proactively invalidate the associated cache keys using `cache.del(key)`.
27
+ - Use namespace-based key patterns (e.g., `spots:detail:*`) to invalidate multiple related caches simultaneously.
28
+
29
+ - **[PERF-003] Read/Write Replication**
30
+ - Route all read operations (`SELECT`) to database replicas to distribute read load.
31
+ - Route all mutations (`INSERT`, `UPDATE`, `DELETE`) to the primary database.
32
+ - Exception: Use the primary database for "Read-after-Write" scenarios where replication lag would cause visual inconsistency for the active user.
33
+
34
+ - **[PERF-004] Index-First Design**
35
+ - Every column used in a `WHERE`, `JOIN`, or `ORDER BY` clause must have a corresponding database index.
36
+ - Use database performance profiling tools (e.g., `EXPLAIN ANALYZE`) to verify query plans before merging database alterations.
37
+
38
+ - **[PERF-005] No Heavy Computations in SQL**
39
+ - Avoid executing complex arithmetic, string formatters, or business logic inside SQL queries. Keep the database focused on fast indexing and retrieval; run formatting and calculations in the application layer.
40
+
41
+ ## Implementation Pattern
42
+
43
+ ```typescript
44
+ import { cache } from '../../utils/redis';
45
+ import { readQuery } from '../../database/replication';
46
+
47
+ export const getVibes = async (req: Request, res: Response) => {
48
+ const CACHE_KEY = 'vibes:list:v1';
49
+
50
+ // 1. Check Cache [PERF-001]
51
+ const cached = await cache.get(CACHE_KEY);
52
+ if (cached) return sendSuccess(res, { vibes: cached });
53
+
54
+ // 2. Hit Read-Replica [PERF-003]
55
+ const result = await readQuery('SELECT id, name FROM categories ORDER BY name ASC');
56
+ const vibes = result.rows;
57
+
58
+ // 3. Set Cache [PERF-001]
59
+ await cache.set(CACHE_KEY, vibes, 600); // 10 min TTL
60
+
61
+ return sendSuccess(res, { vibes });
62
+ };
63
+ ```
64
+
65
+ ---
66
+
67
+ ## When to Use
68
+
69
+ - Writing new database queries (SQL, Prisma models, ORMs) or API response endpoints.
70
+ - Setting up or tuning Redis caching layers for frequently accessed data structures.
71
+ - Auditing database query plans, slow query logs, or indexing schemas.
72
+ - Configuring database replication routing (primary vs. read-replicas).
73
+
74
+ **When NOT to use:**
75
+ - Local static CLI tools or developer setups where data fits entirely in memory and has no persistent database.
76
+ - Trivial, low-frequency administration actions that run off-peak and do not impact core application user latency.
77
+
78
+ ## Common Rationalizations
79
+
80
+ | Rationalization | Reality |
81
+ |---|---|
82
+ | "The database is fast enough; we don't need caching yet." | Caching reduces origin server load and eliminates roundtrips. Waiting for database saturation to implement caching causes high-severity production outages. |
83
+ | "I'll let the cache expire on its own via TTL." | Relying solely on TTL means users will see stale data for long periods. Proactive invalidation on update guarantees visual consistency and real-time freshness. |
84
+ | "Adding indexes on every column is always safe." | Too many indexes degrade write and update speeds because the database must update the indexes for every write. Focus indexing on columns actually used in filter/sort criteria. |
85
+
86
+ ## Red Flags
87
+
88
+ - Fetching full database rows (`SELECT *` or unrestricted ORM relations) when only a subset of fields is used.
89
+ - Heavy reads targeting the primary database instance when read-replicas are available.
90
+ - Heavy aggregate calculations, string operations, or custom formatting executed inside SQL database statements.
91
+ - Implementing caching without a clear, proactive invalidation mechanism (`cache.del(key)` or pattern-based invalidations) on state changes.
92
+
93
+ ## Verification
94
+
95
+ After completing the performance implementation, verify:
96
+ - [ ] Redis caching hit rate is confirmed (cached reads bypass database entirely).
97
+ - [ ] Associated cache keys are successfully removed or updated upon resource mutations.
98
+ - [ ] Database query profiles (`EXPLAIN ANALYZE` or ORM profiling) show active index scans rather than sequential table scans.
99
+ - [ ] Core mutations write to the primary database, while read-only routes hit replica pools.
100
+ - [ ] Clean performance data is gathered and validated against latency targets (e.g. sub-100ms API response).