@booklib/core 2.0.0

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 (374) hide show
  1. package/.cursor/rules/booklib-standards.mdc +40 -0
  2. package/.gemini/context.md +372 -0
  3. package/AGENTS.md +166 -0
  4. package/CHANGELOG.md +226 -0
  5. package/CLAUDE.md +81 -0
  6. package/CODE_OF_CONDUCT.md +31 -0
  7. package/CONTRIBUTING.md +304 -0
  8. package/LICENSE +21 -0
  9. package/PLAN.md +28 -0
  10. package/README.ja.md +198 -0
  11. package/README.ko.md +198 -0
  12. package/README.md +503 -0
  13. package/README.pt-BR.md +198 -0
  14. package/README.uk.md +241 -0
  15. package/README.zh-CN.md +198 -0
  16. package/SECURITY.md +9 -0
  17. package/agents/architecture-reviewer.md +136 -0
  18. package/agents/booklib-reviewer.md +90 -0
  19. package/agents/data-reviewer.md +107 -0
  20. package/agents/jvm-reviewer.md +146 -0
  21. package/agents/python-reviewer.md +128 -0
  22. package/agents/rust-reviewer.md +115 -0
  23. package/agents/ts-reviewer.md +110 -0
  24. package/agents/ui-reviewer.md +117 -0
  25. package/assets/logo.svg +36 -0
  26. package/bin/booklib-mcp.js +304 -0
  27. package/bin/booklib.js +1705 -0
  28. package/bin/skills.cjs +1292 -0
  29. package/booklib-router.mdc +36 -0
  30. package/booklib.config.json +19 -0
  31. package/commands/animation-at-work.md +10 -0
  32. package/commands/clean-code-reviewer.md +10 -0
  33. package/commands/data-intensive-patterns.md +10 -0
  34. package/commands/data-pipelines.md +10 -0
  35. package/commands/design-patterns.md +10 -0
  36. package/commands/domain-driven-design.md +10 -0
  37. package/commands/effective-java.md +10 -0
  38. package/commands/effective-kotlin.md +10 -0
  39. package/commands/effective-python.md +10 -0
  40. package/commands/effective-typescript.md +10 -0
  41. package/commands/kotlin-in-action.md +10 -0
  42. package/commands/lean-startup.md +10 -0
  43. package/commands/microservices-patterns.md +10 -0
  44. package/commands/programming-with-rust.md +10 -0
  45. package/commands/refactoring-ui.md +10 -0
  46. package/commands/rust-in-action.md +10 -0
  47. package/commands/skill-router.md +10 -0
  48. package/commands/spring-boot-in-action.md +10 -0
  49. package/commands/storytelling-with-data.md +10 -0
  50. package/commands/system-design-interview.md +10 -0
  51. package/commands/using-asyncio-python.md +10 -0
  52. package/commands/web-scraping-python.md +10 -0
  53. package/community/registry.json +1616 -0
  54. package/hooks/hooks.json +23 -0
  55. package/hooks/posttooluse-capture.mjs +67 -0
  56. package/hooks/suggest.js +153 -0
  57. package/lib/agent-behaviors.js +40 -0
  58. package/lib/agent-detector.js +96 -0
  59. package/lib/config-loader.js +39 -0
  60. package/lib/conflict-resolver.js +148 -0
  61. package/lib/context-builder.js +574 -0
  62. package/lib/discovery-engine.js +298 -0
  63. package/lib/doctor/hook-installer.js +83 -0
  64. package/lib/doctor/usage-tracker.js +87 -0
  65. package/lib/engine/ai-features.js +253 -0
  66. package/lib/engine/auditor.js +103 -0
  67. package/lib/engine/bm25-index.js +178 -0
  68. package/lib/engine/capture.js +120 -0
  69. package/lib/engine/corrections.js +198 -0
  70. package/lib/engine/doctor.js +195 -0
  71. package/lib/engine/graph-injector.js +137 -0
  72. package/lib/engine/graph.js +161 -0
  73. package/lib/engine/handoff.js +405 -0
  74. package/lib/engine/indexer.js +242 -0
  75. package/lib/engine/parser.js +53 -0
  76. package/lib/engine/query-expander.js +42 -0
  77. package/lib/engine/reranker.js +40 -0
  78. package/lib/engine/rrf.js +59 -0
  79. package/lib/engine/scanner.js +151 -0
  80. package/lib/engine/searcher.js +139 -0
  81. package/lib/engine/session-coordinator.js +306 -0
  82. package/lib/engine/session-manager.js +429 -0
  83. package/lib/engine/synthesizer.js +70 -0
  84. package/lib/installer.js +70 -0
  85. package/lib/instinct-block.js +33 -0
  86. package/lib/mcp-config-writer.js +88 -0
  87. package/lib/paths.js +57 -0
  88. package/lib/profiles/design.md +19 -0
  89. package/lib/profiles/general.md +16 -0
  90. package/lib/profiles/research-analysis.md +22 -0
  91. package/lib/profiles/software-development.md +23 -0
  92. package/lib/profiles/writing-content.md +19 -0
  93. package/lib/project-initializer.js +916 -0
  94. package/lib/registry/skills.js +102 -0
  95. package/lib/registry-searcher.js +99 -0
  96. package/lib/rules/rules-manager.js +169 -0
  97. package/lib/skill-fetcher.js +333 -0
  98. package/lib/well-known-builder.js +70 -0
  99. package/lib/wizard/index.js +404 -0
  100. package/lib/wizard/integration-detector.js +41 -0
  101. package/lib/wizard/project-detector.js +100 -0
  102. package/lib/wizard/prompt.js +156 -0
  103. package/lib/wizard/registry-embeddings.js +107 -0
  104. package/lib/wizard/skill-recommender.js +69 -0
  105. package/llms-full.txt +254 -0
  106. package/llms.txt +70 -0
  107. package/package.json +45 -0
  108. package/research-reports/2026-04-01-current-architecture.md +160 -0
  109. package/research-reports/IDEAS.md +93 -0
  110. package/rules/common/clean-code.md +42 -0
  111. package/rules/java/effective-java.md +42 -0
  112. package/rules/kotlin/effective-kotlin.md +37 -0
  113. package/rules/python/effective-python.md +38 -0
  114. package/rules/rust/rust.md +37 -0
  115. package/rules/typescript/effective-typescript.md +42 -0
  116. package/scripts/gen-llms-full.mjs +36 -0
  117. package/scripts/gen-og.mjs +142 -0
  118. package/scripts/validate-frontmatter.js +25 -0
  119. package/skills/animation-at-work/SKILL.md +270 -0
  120. package/skills/animation-at-work/assets/example_asset.txt +1 -0
  121. package/skills/animation-at-work/evals/evals.json +44 -0
  122. package/skills/animation-at-work/evals/results.json +13 -0
  123. package/skills/animation-at-work/examples/after.md +64 -0
  124. package/skills/animation-at-work/examples/before.md +35 -0
  125. package/skills/animation-at-work/references/api_reference.md +369 -0
  126. package/skills/animation-at-work/references/review-checklist.md +79 -0
  127. package/skills/animation-at-work/scripts/audit_animations.py +295 -0
  128. package/skills/animation-at-work/scripts/example.py +1 -0
  129. package/skills/clean-code-reviewer/SKILL.md +444 -0
  130. package/skills/clean-code-reviewer/audit.json +35 -0
  131. package/skills/clean-code-reviewer/evals/evals.json +185 -0
  132. package/skills/clean-code-reviewer/evals/results.json +13 -0
  133. package/skills/clean-code-reviewer/examples/after.md +48 -0
  134. package/skills/clean-code-reviewer/examples/before.md +33 -0
  135. package/skills/clean-code-reviewer/references/api_reference.md +158 -0
  136. package/skills/clean-code-reviewer/references/practices-catalog.md +282 -0
  137. package/skills/clean-code-reviewer/references/review-checklist.md +254 -0
  138. package/skills/clean-code-reviewer/scripts/pre-review.py +206 -0
  139. package/skills/data-intensive-patterns/SKILL.md +267 -0
  140. package/skills/data-intensive-patterns/assets/example_asset.txt +1 -0
  141. package/skills/data-intensive-patterns/evals/evals.json +54 -0
  142. package/skills/data-intensive-patterns/evals/results.json +13 -0
  143. package/skills/data-intensive-patterns/examples/after.md +61 -0
  144. package/skills/data-intensive-patterns/examples/before.md +38 -0
  145. package/skills/data-intensive-patterns/references/api_reference.md +34 -0
  146. package/skills/data-intensive-patterns/references/patterns-catalog.md +551 -0
  147. package/skills/data-intensive-patterns/references/review-checklist.md +193 -0
  148. package/skills/data-intensive-patterns/scripts/adr.py +213 -0
  149. package/skills/data-intensive-patterns/scripts/example.py +1 -0
  150. package/skills/data-pipelines/SKILL.md +259 -0
  151. package/skills/data-pipelines/assets/example_asset.txt +1 -0
  152. package/skills/data-pipelines/evals/evals.json +45 -0
  153. package/skills/data-pipelines/evals/results.json +13 -0
  154. package/skills/data-pipelines/examples/after.md +97 -0
  155. package/skills/data-pipelines/examples/before.md +37 -0
  156. package/skills/data-pipelines/references/api_reference.md +301 -0
  157. package/skills/data-pipelines/references/review-checklist.md +181 -0
  158. package/skills/data-pipelines/scripts/example.py +1 -0
  159. package/skills/data-pipelines/scripts/new_pipeline.py +444 -0
  160. package/skills/design-patterns/SKILL.md +271 -0
  161. package/skills/design-patterns/assets/example_asset.txt +1 -0
  162. package/skills/design-patterns/evals/evals.json +46 -0
  163. package/skills/design-patterns/evals/results.json +13 -0
  164. package/skills/design-patterns/examples/after.md +52 -0
  165. package/skills/design-patterns/examples/before.md +29 -0
  166. package/skills/design-patterns/references/api_reference.md +1 -0
  167. package/skills/design-patterns/references/patterns-catalog.md +726 -0
  168. package/skills/design-patterns/references/review-checklist.md +173 -0
  169. package/skills/design-patterns/scripts/example.py +1 -0
  170. package/skills/design-patterns/scripts/scaffold.py +807 -0
  171. package/skills/domain-driven-design/SKILL.md +142 -0
  172. package/skills/domain-driven-design/assets/example_asset.txt +1 -0
  173. package/skills/domain-driven-design/evals/evals.json +48 -0
  174. package/skills/domain-driven-design/evals/results.json +13 -0
  175. package/skills/domain-driven-design/examples/after.md +80 -0
  176. package/skills/domain-driven-design/examples/before.md +43 -0
  177. package/skills/domain-driven-design/references/api_reference.md +1 -0
  178. package/skills/domain-driven-design/references/patterns-catalog.md +545 -0
  179. package/skills/domain-driven-design/references/review-checklist.md +158 -0
  180. package/skills/domain-driven-design/scripts/example.py +1 -0
  181. package/skills/domain-driven-design/scripts/scaffold.py +421 -0
  182. package/skills/effective-java/SKILL.md +227 -0
  183. package/skills/effective-java/assets/example_asset.txt +1 -0
  184. package/skills/effective-java/evals/evals.json +46 -0
  185. package/skills/effective-java/evals/results.json +13 -0
  186. package/skills/effective-java/examples/after.md +83 -0
  187. package/skills/effective-java/examples/before.md +37 -0
  188. package/skills/effective-java/references/api_reference.md +1 -0
  189. package/skills/effective-java/references/items-catalog.md +955 -0
  190. package/skills/effective-java/references/review-checklist.md +216 -0
  191. package/skills/effective-java/scripts/checkstyle_setup.py +211 -0
  192. package/skills/effective-java/scripts/example.py +1 -0
  193. package/skills/effective-kotlin/SKILL.md +271 -0
  194. package/skills/effective-kotlin/assets/example_asset.txt +1 -0
  195. package/skills/effective-kotlin/audit.json +29 -0
  196. package/skills/effective-kotlin/evals/evals.json +45 -0
  197. package/skills/effective-kotlin/evals/results.json +13 -0
  198. package/skills/effective-kotlin/examples/after.md +36 -0
  199. package/skills/effective-kotlin/examples/before.md +38 -0
  200. package/skills/effective-kotlin/references/api_reference.md +1 -0
  201. package/skills/effective-kotlin/references/practices-catalog.md +1228 -0
  202. package/skills/effective-kotlin/references/review-checklist.md +126 -0
  203. package/skills/effective-kotlin/scripts/example.py +1 -0
  204. package/skills/effective-python/SKILL.md +441 -0
  205. package/skills/effective-python/evals/evals.json +44 -0
  206. package/skills/effective-python/evals/results.json +13 -0
  207. package/skills/effective-python/examples/after.md +56 -0
  208. package/skills/effective-python/examples/before.md +40 -0
  209. package/skills/effective-python/ref-01-pythonic-thinking.md +202 -0
  210. package/skills/effective-python/ref-02-lists-and-dicts.md +146 -0
  211. package/skills/effective-python/ref-03-functions.md +186 -0
  212. package/skills/effective-python/ref-04-comprehensions-generators.md +211 -0
  213. package/skills/effective-python/ref-05-classes-interfaces.md +188 -0
  214. package/skills/effective-python/ref-06-metaclasses-attributes.md +209 -0
  215. package/skills/effective-python/ref-07-concurrency.md +213 -0
  216. package/skills/effective-python/ref-08-robustness-performance.md +248 -0
  217. package/skills/effective-python/ref-09-testing-debugging.md +253 -0
  218. package/skills/effective-python/ref-10-collaboration.md +175 -0
  219. package/skills/effective-python/references/api_reference.md +218 -0
  220. package/skills/effective-python/references/practices-catalog.md +483 -0
  221. package/skills/effective-python/references/review-checklist.md +190 -0
  222. package/skills/effective-python/scripts/lint.py +173 -0
  223. package/skills/effective-typescript/SKILL.md +262 -0
  224. package/skills/effective-typescript/audit.json +29 -0
  225. package/skills/effective-typescript/evals/evals.json +37 -0
  226. package/skills/effective-typescript/evals/results.json +13 -0
  227. package/skills/effective-typescript/examples/after.md +70 -0
  228. package/skills/effective-typescript/examples/before.md +47 -0
  229. package/skills/effective-typescript/references/api_reference.md +118 -0
  230. package/skills/effective-typescript/references/practices-catalog.md +371 -0
  231. package/skills/effective-typescript/scripts/review.py +169 -0
  232. package/skills/kotlin-in-action/SKILL.md +261 -0
  233. package/skills/kotlin-in-action/assets/example_asset.txt +1 -0
  234. package/skills/kotlin-in-action/evals/evals.json +43 -0
  235. package/skills/kotlin-in-action/evals/results.json +13 -0
  236. package/skills/kotlin-in-action/examples/after.md +53 -0
  237. package/skills/kotlin-in-action/examples/before.md +39 -0
  238. package/skills/kotlin-in-action/references/api_reference.md +1 -0
  239. package/skills/kotlin-in-action/references/practices-catalog.md +436 -0
  240. package/skills/kotlin-in-action/references/review-checklist.md +204 -0
  241. package/skills/kotlin-in-action/scripts/example.py +1 -0
  242. package/skills/kotlin-in-action/scripts/setup_detekt.py +224 -0
  243. package/skills/lean-startup/SKILL.md +160 -0
  244. package/skills/lean-startup/assets/example_asset.txt +1 -0
  245. package/skills/lean-startup/evals/evals.json +43 -0
  246. package/skills/lean-startup/evals/results.json +13 -0
  247. package/skills/lean-startup/examples/after.md +80 -0
  248. package/skills/lean-startup/examples/before.md +34 -0
  249. package/skills/lean-startup/references/api_reference.md +319 -0
  250. package/skills/lean-startup/references/review-checklist.md +137 -0
  251. package/skills/lean-startup/scripts/example.py +1 -0
  252. package/skills/lean-startup/scripts/new_experiment.py +286 -0
  253. package/skills/microservices-patterns/SKILL.md +384 -0
  254. package/skills/microservices-patterns/evals/evals.json +45 -0
  255. package/skills/microservices-patterns/evals/results.json +13 -0
  256. package/skills/microservices-patterns/examples/after.md +69 -0
  257. package/skills/microservices-patterns/examples/before.md +40 -0
  258. package/skills/microservices-patterns/references/patterns-catalog.md +391 -0
  259. package/skills/microservices-patterns/references/review-checklist.md +169 -0
  260. package/skills/microservices-patterns/scripts/new_service.py +583 -0
  261. package/skills/programming-with-rust/SKILL.md +209 -0
  262. package/skills/programming-with-rust/evals/evals.json +37 -0
  263. package/skills/programming-with-rust/evals/results.json +13 -0
  264. package/skills/programming-with-rust/examples/after.md +107 -0
  265. package/skills/programming-with-rust/examples/before.md +59 -0
  266. package/skills/programming-with-rust/references/api_reference.md +152 -0
  267. package/skills/programming-with-rust/references/practices-catalog.md +335 -0
  268. package/skills/programming-with-rust/scripts/review.py +142 -0
  269. package/skills/refactoring-ui/SKILL.md +362 -0
  270. package/skills/refactoring-ui/assets/example_asset.txt +1 -0
  271. package/skills/refactoring-ui/evals/evals.json +45 -0
  272. package/skills/refactoring-ui/evals/results.json +13 -0
  273. package/skills/refactoring-ui/examples/after.md +85 -0
  274. package/skills/refactoring-ui/examples/before.md +58 -0
  275. package/skills/refactoring-ui/references/api_reference.md +355 -0
  276. package/skills/refactoring-ui/references/review-checklist.md +114 -0
  277. package/skills/refactoring-ui/scripts/audit_css.py +250 -0
  278. package/skills/refactoring-ui/scripts/example.py +1 -0
  279. package/skills/rust-in-action/SKILL.md +350 -0
  280. package/skills/rust-in-action/evals/evals.json +38 -0
  281. package/skills/rust-in-action/evals/results.json +13 -0
  282. package/skills/rust-in-action/examples/after.md +156 -0
  283. package/skills/rust-in-action/examples/before.md +56 -0
  284. package/skills/rust-in-action/references/practices-catalog.md +346 -0
  285. package/skills/rust-in-action/scripts/review.py +147 -0
  286. package/skills/skill-router/SKILL.md +186 -0
  287. package/skills/skill-router/evals/evals.json +38 -0
  288. package/skills/skill-router/evals/results.json +13 -0
  289. package/skills/skill-router/examples/after.md +63 -0
  290. package/skills/skill-router/examples/before.md +39 -0
  291. package/skills/skill-router/references/api_reference.md +24 -0
  292. package/skills/skill-router/references/routing-heuristics.md +89 -0
  293. package/skills/skill-router/references/skill-catalog.md +174 -0
  294. package/skills/skill-router/scripts/route.py +266 -0
  295. package/skills/spring-boot-in-action/SKILL.md +340 -0
  296. package/skills/spring-boot-in-action/evals/evals.json +39 -0
  297. package/skills/spring-boot-in-action/evals/results.json +13 -0
  298. package/skills/spring-boot-in-action/examples/after.md +185 -0
  299. package/skills/spring-boot-in-action/examples/before.md +84 -0
  300. package/skills/spring-boot-in-action/references/practices-catalog.md +403 -0
  301. package/skills/spring-boot-in-action/scripts/review.py +184 -0
  302. package/skills/storytelling-with-data/SKILL.md +241 -0
  303. package/skills/storytelling-with-data/assets/example_asset.txt +1 -0
  304. package/skills/storytelling-with-data/evals/evals.json +47 -0
  305. package/skills/storytelling-with-data/evals/results.json +13 -0
  306. package/skills/storytelling-with-data/examples/after.md +50 -0
  307. package/skills/storytelling-with-data/examples/before.md +33 -0
  308. package/skills/storytelling-with-data/references/api_reference.md +379 -0
  309. package/skills/storytelling-with-data/references/review-checklist.md +111 -0
  310. package/skills/storytelling-with-data/scripts/chart_review.py +301 -0
  311. package/skills/storytelling-with-data/scripts/example.py +1 -0
  312. package/skills/system-design-interview/SKILL.md +233 -0
  313. package/skills/system-design-interview/assets/example_asset.txt +1 -0
  314. package/skills/system-design-interview/evals/evals.json +46 -0
  315. package/skills/system-design-interview/evals/results.json +13 -0
  316. package/skills/system-design-interview/examples/after.md +94 -0
  317. package/skills/system-design-interview/examples/before.md +27 -0
  318. package/skills/system-design-interview/references/api_reference.md +582 -0
  319. package/skills/system-design-interview/references/review-checklist.md +201 -0
  320. package/skills/system-design-interview/scripts/example.py +1 -0
  321. package/skills/system-design-interview/scripts/new_design.py +421 -0
  322. package/skills/using-asyncio-python/SKILL.md +290 -0
  323. package/skills/using-asyncio-python/assets/example_asset.txt +1 -0
  324. package/skills/using-asyncio-python/evals/evals.json +43 -0
  325. package/skills/using-asyncio-python/evals/results.json +13 -0
  326. package/skills/using-asyncio-python/examples/after.md +68 -0
  327. package/skills/using-asyncio-python/examples/before.md +39 -0
  328. package/skills/using-asyncio-python/references/api_reference.md +267 -0
  329. package/skills/using-asyncio-python/references/review-checklist.md +149 -0
  330. package/skills/using-asyncio-python/scripts/check_blocking.py +270 -0
  331. package/skills/using-asyncio-python/scripts/example.py +1 -0
  332. package/skills/web-scraping-python/SKILL.md +280 -0
  333. package/skills/web-scraping-python/assets/example_asset.txt +1 -0
  334. package/skills/web-scraping-python/evals/evals.json +46 -0
  335. package/skills/web-scraping-python/evals/results.json +13 -0
  336. package/skills/web-scraping-python/examples/after.md +109 -0
  337. package/skills/web-scraping-python/examples/before.md +40 -0
  338. package/skills/web-scraping-python/references/api_reference.md +393 -0
  339. package/skills/web-scraping-python/references/review-checklist.md +163 -0
  340. package/skills/web-scraping-python/scripts/example.py +1 -0
  341. package/skills/web-scraping-python/scripts/new_scraper.py +231 -0
  342. package/skills/writing-plans/audit.json +34 -0
  343. package/tests/agent-detector.test.js +83 -0
  344. package/tests/corrections.test.js +245 -0
  345. package/tests/doctor/hook-installer.test.js +72 -0
  346. package/tests/doctor/usage-tracker.test.js +140 -0
  347. package/tests/engine/benchmark-eval.test.js +31 -0
  348. package/tests/engine/bm25-index.test.js +85 -0
  349. package/tests/engine/capture-command.test.js +35 -0
  350. package/tests/engine/capture.test.js +17 -0
  351. package/tests/engine/graph-augmented-search.test.js +107 -0
  352. package/tests/engine/graph-injector.test.js +44 -0
  353. package/tests/engine/graph.test.js +216 -0
  354. package/tests/engine/hybrid-searcher.test.js +74 -0
  355. package/tests/engine/indexer-bm25.test.js +37 -0
  356. package/tests/engine/mcp-tools.test.js +73 -0
  357. package/tests/engine/project-initializer-mcp.test.js +99 -0
  358. package/tests/engine/query-expander.test.js +36 -0
  359. package/tests/engine/reranker.test.js +51 -0
  360. package/tests/engine/rrf.test.js +49 -0
  361. package/tests/engine/srag-prefix.test.js +47 -0
  362. package/tests/instinct-block.test.js +23 -0
  363. package/tests/mcp-config-writer.test.js +60 -0
  364. package/tests/project-initializer-new-agents.test.js +48 -0
  365. package/tests/rules/rules-manager.test.js +230 -0
  366. package/tests/well-known-builder.test.js +40 -0
  367. package/tests/wizard/integration-detector.test.js +31 -0
  368. package/tests/wizard/project-detector.test.js +51 -0
  369. package/tests/wizard/prompt-session.test.js +61 -0
  370. package/tests/wizard/prompt.test.js +16 -0
  371. package/tests/wizard/registry-embeddings.test.js +35 -0
  372. package/tests/wizard/skill-recommender.test.js +34 -0
  373. package/tests/wizard/slot-count.test.js +25 -0
  374. package/vercel.json +21 -0
@@ -0,0 +1,286 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Lean Startup — MVP Experiment Document Generator.
4
+
5
+ Usage (interactive): python new_experiment.py
6
+ Usage (one-shot): python new_experiment.py --name "X" --hypothesis "Y" \
7
+ --mvp-type landing-page --metric "signups" \
8
+ --threshold "100 signups" --duration "2 weeks" \
9
+ --output experiment.md
10
+ """
11
+
12
+ import argparse
13
+ import sys
14
+ from datetime import date, timedelta
15
+ from pathlib import Path
16
+
17
+ MVP_TYPES = ["concierge", "wizard-of-oz", "landing-page", "smoke-test"]
18
+
19
+ MVP_DESCRIPTIONS = {
20
+ "concierge": (
21
+ "Manually deliver the service to early customers without automation. "
22
+ "You act as the 'product' to learn what customers actually want before building."
23
+ ),
24
+ "wizard-of-oz": (
25
+ "Present a working product interface to customers, but fulfil requests manually "
26
+ "behind the scenes. Validates demand without engineering the full solution."
27
+ ),
28
+ "landing-page": (
29
+ "Publish a description and sign-up form for a product that does not yet exist. "
30
+ "Measures intent-to-use at near-zero cost."
31
+ ),
32
+ "smoke-test": (
33
+ "Run a small paid-acquisition experiment (e.g., Google Ads) to a landing page. "
34
+ "Measures real purchase intent before building anything."
35
+ ),
36
+ }
37
+
38
+ WHY_NOT_BUILD = {
39
+ "concierge": (
40
+ "Building the full automated product before understanding the exact workflow "
41
+ "customers need risks expensive re-work. Manual delivery surfaces the real "
42
+ "job-to-be-done faster and cheaper."
43
+ ),
44
+ "wizard-of-oz": (
45
+ "Engineering the back-end automation is costly and time-consuming. "
46
+ "Validating that customers use and value the front-end experience first "
47
+ "eliminates the biggest unknown before we invest in automation."
48
+ ),
49
+ "landing-page": (
50
+ "Writing code for a product nobody wants is pure waste. "
51
+ "A landing page lets us measure whether the value proposition resonates "
52
+ "with the target segment in days, not months."
53
+ ),
54
+ "smoke-test": (
55
+ "Acquiring real paying customers validates both the value hypothesis and "
56
+ "the growth hypothesis simultaneously. Building first would delay this "
57
+ "signal by weeks and obscure whether demand is organic or forced."
58
+ ),
59
+ }
60
+
61
+ PIVOT_OPTIONS = [
62
+ "Zoom-in pivot: narrow scope to the single highest-value feature",
63
+ "Customer-segment pivot: target a different customer segment with the same product",
64
+ "Value-capture pivot: change the monetisation model (subscription vs. one-time)",
65
+ "Channel pivot: switch acquisition channel (e.g., outbound sales → content marketing)",
66
+ "Technology pivot: solve the same problem with a different underlying technology",
67
+ "Platform pivot: move from application to platform or vice versa",
68
+ ]
69
+
70
+
71
+ def prompt(label: str, default: str = "") -> str:
72
+ suffix = f" [{default}]" if default else ""
73
+ while True:
74
+ value = input(f"{label}{suffix}: ").strip()
75
+ if value:
76
+ return value
77
+ if default:
78
+ return default
79
+ print(" (required — please enter a value)")
80
+
81
+
82
+ def prompt_choice(label: str, choices: list[str]) -> str:
83
+ print(f"\n{label}")
84
+ for i, c in enumerate(choices, 1):
85
+ print(f" {i}. {c}")
86
+ while True:
87
+ raw = input("Enter number: ").strip()
88
+ if raw.isdigit() and 1 <= int(raw) <= len(choices):
89
+ return choices[int(raw) - 1]
90
+ print(f" Please enter a number between 1 and {len(choices)}.")
91
+
92
+
93
+ def gather_interactive() -> dict:
94
+ print("\n=== Lean Startup — New MVP Experiment ===\n")
95
+ print("Answer each prompt. Press Enter to accept the default.\n")
96
+ data: dict = {}
97
+ data["name"] = prompt("Product / feature name")
98
+ data["value_hypothesis"] = prompt(
99
+ "Value hypothesis (customers will value X because Y)"
100
+ )
101
+ data["growth_hypothesis"] = prompt(
102
+ "Growth hypothesis (new customers will find us via ...)"
103
+ )
104
+ data["mvp_type"] = prompt_choice("MVP type", MVP_TYPES)
105
+ data["metric"] = prompt("Primary metric to track (e.g., 'weekly active users')")
106
+ data["baseline"] = prompt("Current baseline for this metric (e.g., '0', 'unknown')", "0")
107
+ data["threshold"] = prompt("Success threshold (e.g., '50 sign-ups in 2 weeks')")
108
+ data["duration"] = prompt("Experiment duration (e.g., '2 weeks')", "2 weeks")
109
+ data["team"] = prompt("Team / owner", "Product team")
110
+ return data
111
+
112
+
113
+ def parse_duration_weeks(duration_str: str) -> int:
114
+ """Very simple heuristic: look for a number before 'week'."""
115
+ import re
116
+ m = re.search(r"(\d+)\s*week", duration_str, re.IGNORECASE)
117
+ if m:
118
+ return int(m.group(1))
119
+ m = re.search(r"(\d+)\s*day", duration_str, re.IGNORECASE)
120
+ if m:
121
+ return max(1, int(m.group(1)) // 7)
122
+ return 2 # default
123
+
124
+
125
+ def render_document(data: dict) -> str:
126
+ today = date.today()
127
+ weeks = parse_duration_weeks(data["duration"])
128
+ decision_date = today + timedelta(weeks=weeks)
129
+ mvp_type = data["mvp_type"]
130
+
131
+ lines = [
132
+ f"# MVP Experiment: {data['name']}",
133
+ "",
134
+ f"**Date created:** {today} ",
135
+ f"**Owner:** {data['team']} ",
136
+ f"**Pivot/Persevere decision by:** {decision_date} ",
137
+ f"**Duration:** {data['duration']} ",
138
+ "",
139
+ "---",
140
+ "",
141
+ "## 1. Leap-of-Faith Assumptions",
142
+ "",
143
+ "### Value Hypothesis",
144
+ f"> {data['value_hypothesis']}",
145
+ "",
146
+ "This is the core belief we are testing. If customers do not behave as",
147
+ "predicted, we learn this assumption is false and must pivot.",
148
+ "",
149
+ "### Growth Hypothesis",
150
+ f"> {data['growth_hypothesis']}",
151
+ "",
152
+ "---",
153
+ "",
154
+ "## 2. Why NOT Build the Full Product Yet",
155
+ "",
156
+ WHY_NOT_BUILD[mvp_type],
157
+ "",
158
+ "Building the full solution before validating these assumptions would be",
159
+ "**premature scaling** — one of the most common causes of startup failure",
160
+ "according to the Lean Startup framework.",
161
+ "",
162
+ "---",
163
+ "",
164
+ f"## 3. MVP Design — {mvp_type.replace('-', ' ').title()}",
165
+ "",
166
+ f"**Type:** {mvp_type}",
167
+ "",
168
+ MVP_DESCRIPTIONS[mvp_type],
169
+ "",
170
+ "### What we will build / do",
171
+ "",
172
+ "- [ ] Define the exact customer action we want to observe",
173
+ "- [ ] Set up measurement (analytics, tracking, manual log)",
174
+ "- [ ] Recruit initial participants / drive initial traffic",
175
+ "- [ ] Execute the experiment and collect data",
176
+ "- [ ] Analyse results against the success threshold below",
177
+ "",
178
+ "### What we will NOT build",
179
+ "",
180
+ "- Full back-end automation",
181
+ "- Production-quality UI beyond what is needed to trigger the measured action",
182
+ "- Scalability infrastructure",
183
+ "",
184
+ "---",
185
+ "",
186
+ "## 4. Innovation Accounting",
187
+ "",
188
+ "| Metric | Baseline | Target | How We Measure |",
189
+ "|--------|----------|--------|----------------|",
190
+ f"| {data['metric']} | {data['baseline']} | {data['threshold']} | [instrument] |",
191
+ "| Retention (week 2) | — | >30% | Cohort analysis |",
192
+ "| NPS / qualitative | — | Positive themes | Customer interviews |",
193
+ "",
194
+ "Measurements should be **actionable, accessible, auditable** (Three A's).",
195
+ "Avoid vanity metrics (total page views, total registered users).",
196
+ "",
197
+ "---",
198
+ "",
199
+ "## 5. Pivot / Persevere Criteria",
200
+ "",
201
+ f"**Decision date:** {decision_date} ",
202
+ f"**Decision owner:** {data['team']}",
203
+ "",
204
+ "### Persevere if",
205
+ f"- The primary metric reaches or exceeds **{data['threshold']}** by {decision_date}.",
206
+ "- Customer interviews reveal consistent, strong pull — not polite feedback.",
207
+ "- At least one customer takes an unexpected high-engagement action.",
208
+ "",
209
+ "### Pivot if",
210
+ f"- The primary metric is below **{data['threshold']}** with no strong upward trend.",
211
+ "- Qualitative feedback reveals the problem is not painful enough to act on.",
212
+ "- A significantly different customer segment shows stronger signal.",
213
+ "",
214
+ "### Pre-populated Pivot Options",
215
+ "",
216
+ ]
217
+ for opt in PIVOT_OPTIONS:
218
+ lines.append(f"- {opt}")
219
+
220
+ lines += [
221
+ "",
222
+ "---",
223
+ "",
224
+ "## 6. References",
225
+ "",
226
+ "- Ries, E. (2011). *The Lean Startup*. Crown Business.",
227
+ "- Build-Measure-Learn loop: build the smallest thing that generates the",
228
+ " most learning, not the smallest shippable product.",
229
+ "",
230
+ "---",
231
+ "",
232
+ "*Generated by `new_experiment.py` — Lean Startup skill.*",
233
+ ]
234
+ return "\n".join(lines) + "\n"
235
+
236
+
237
+ def main() -> None:
238
+ parser = argparse.ArgumentParser(description="Generate a Lean Startup MVP experiment doc.")
239
+ parser.add_argument("--name", help="Product or feature name")
240
+ parser.add_argument("--hypothesis", help="Value hypothesis")
241
+ parser.add_argument("--mvp-type", choices=MVP_TYPES, dest="mvp_type")
242
+ parser.add_argument("--metric", help="Primary metric")
243
+ parser.add_argument("--threshold", help="Success threshold")
244
+ parser.add_argument("--duration", default="2 weeks", help="Experiment duration")
245
+ parser.add_argument("--output", type=Path, help="Output file (default: stdout)")
246
+ args = parser.parse_args()
247
+
248
+ # Determine mode: fully specified vs interactive
249
+ required = ["name", "hypothesis", "mvp_type", "metric", "threshold"]
250
+ if all(getattr(args, f.replace("-", "_"), None) for f in required):
251
+ data = {
252
+ "name": args.name,
253
+ "value_hypothesis": args.hypothesis,
254
+ "growth_hypothesis": "To be determined after initial validation.",
255
+ "mvp_type": args.mvp_type,
256
+ "metric": args.metric,
257
+ "baseline": "0",
258
+ "threshold": args.threshold,
259
+ "duration": args.duration,
260
+ "team": "Product team",
261
+ }
262
+ else:
263
+ if any(getattr(args, f.replace("-", "_"), None) for f in required):
264
+ print(
265
+ "WARNING: Some flags provided but not all required flags are set. "
266
+ "Falling back to interactive mode.",
267
+ file=sys.stderr,
268
+ )
269
+ try:
270
+ data = gather_interactive()
271
+ except (KeyboardInterrupt, EOFError):
272
+ print("\nAborted.", file=sys.stderr)
273
+ sys.exit(1)
274
+
275
+ document = render_document(data)
276
+
277
+ if args.output:
278
+ args.output.write_text(document)
279
+ print(f"\nExperiment document written to: {args.output}")
280
+ print(f"Next: schedule the pivot/persevere meeting for the decision date shown in the doc.")
281
+ else:
282
+ sys.stdout.write(document)
283
+
284
+
285
+ if __name__ == "__main__":
286
+ main()
@@ -0,0 +1,384 @@
1
+ ---
2
+ name: microservices-patterns
3
+ version: "1.0"
4
+ license: MIT
5
+ tags: [microservices, architecture, distributed-systems]
6
+ description: >
7
+ Generate and review microservices code using patterns from Chris Richardson's
8
+ "Microservices Patterns." Use this skill whenever the user asks about microservices
9
+ architecture, wants to generate service code, design distributed systems, review
10
+ microservices code, implement sagas, set up CQRS, configure API gateways, handle
11
+ inter-service communication, or anything related to breaking apart monoliths. Trigger
12
+ on phrases like "microservice", "saga pattern", "event sourcing", "CQRS", "API gateway",
13
+ "service mesh", "domain-driven design for services", "distributed transactions",
14
+ "decompose my monolith", or "review my microservice."
15
+ ---
16
+
17
+ # Microservices Patterns Skill
18
+
19
+ You are an expert microservices architect grounded in the patterns and principles from
20
+ Chris Richardson's *Microservices Patterns*. You help developers in two modes:
21
+
22
+ 1. **Code Generation** — Produce well-structured, pattern-compliant microservice code
23
+ 2. **Code Review** — Analyze existing code and recommend improvements based on proven patterns
24
+
25
+ ## How to Decide Which Mode
26
+
27
+ - If the user asks you to *build*, *create*, *generate*, *implement*, or *scaffold* something → **Code Generation**
28
+ - If the user asks you to *review*, *check*, *improve*, *audit*, or *critique* code → **Code Review**
29
+ - If ambiguous, ask briefly which mode they'd prefer
30
+
31
+ ---
32
+
33
+ ## Mode 1: Code Generation
34
+
35
+ When generating microservice code, follow this decision flow:
36
+
37
+ ### Step 1 — Understand the Domain
38
+
39
+ Ask (or infer from context) what the business domain is. Good microservice boundaries
40
+ come from the business, not from technical layers. Think in terms of:
41
+
42
+ - **Business capabilities** — what the organization does (e.g., Order Management, Delivery, Accounting)
43
+ - **DDD subdomains** — bounded contexts that map to services
44
+
45
+ If the user already has a domain model, work with it. If not, help them sketch one.
46
+
47
+ ### Step 2 — Select the Right Patterns
48
+
49
+ Read `references/patterns-catalog.md` for the full pattern details. Here's a quick decision guide:
50
+
51
+ | Problem | Pattern to Apply |
52
+ |---------|-----------------|
53
+ | How to decompose? | Decompose by Business Capability or by Subdomain |
54
+ | How do services communicate synchronously? | REST or gRPC with service discovery |
55
+ | How do services communicate asynchronously? | Messaging (publish/subscribe, message channels) |
56
+ | How do clients access services? | API Gateway or Backend for Frontend (BFF) |
57
+ | How to manage data consistency across services? | Saga (choreography or orchestration) |
58
+ | How to query data spread across services? | API Composition or CQRS |
59
+ | How to structure business logic? | Aggregate pattern (DDD) |
60
+ | How to reliably publish events + store state? | Event Sourcing |
61
+ | How to handle partial failures? | Circuit Breaker pattern |
62
+
63
+ ### Step 3 — Generate the Code
64
+
65
+ Follow these principles when writing code:
66
+
67
+ - **One service, one database** — each service owns its data store exclusively
68
+ - **API-first design** — define the service's API contract before writing implementation
69
+ - **Loose coupling** — services communicate through well-defined APIs or events, never share databases
70
+ - **Aggregates as transaction boundaries** — a single transaction only modifies one aggregate
71
+ - **Compensating transactions in sagas** — every forward step in a saga has a compensating action for rollback
72
+ - **Explicit durable saga states** — saga orchestrators should persist named states (e.g., `PENDING_INVENTORY`, `PENDING_PAYMENT`, `PENDING_SHIPPING`, `CONFIRMED`, `FAILED`) to a saga state table so the saga can be resumed or audited after a crash
73
+ - **Idempotent message handlers** — design consumers to safely handle duplicate messages
74
+ - **Domain events for integration** — publish events when aggregate state changes so other services can react
75
+
76
+ When generating code, produce:
77
+
78
+ 1. **Service API definition** (REST endpoints or gRPC proto, or async message channels)
79
+ 2. **Domain model** (entities, value objects, aggregates)
80
+ 3. **Event definitions** (domain events the service publishes/consumes)
81
+ 4. **Saga orchestration** (if cross-service coordination is needed)
82
+ 5. **Data access layer** (repository pattern for the service's private database)
83
+
84
+ Use the user's preferred language/framework. If unspecified, default to Java with Spring Boot
85
+ (the book's primary example stack), but adapt freely to Node.js, Python, Go, etc.
86
+
87
+ ### Code Generation Examples
88
+
89
+ **Example 1 — Order Service with Saga:**
90
+ ```
91
+ User: "Create an order service that coordinates with kitchen and payment services"
92
+
93
+ You should generate:
94
+ - Order aggregate with states (PENDING, APPROVED, REJECTED, CANCELLED)
95
+ - CreateOrderSaga orchestrator with steps:
96
+ 1. Create order (pending)
97
+ 2. Authorize payment → on failure: reject order
98
+ 3. Confirm kitchen ticket → on failure: reverse payment, reject order
99
+ 4. Approve order
100
+ - REST API: POST /orders, GET /orders/{id}
101
+ - Domain events: OrderCreated, OrderApproved, OrderRejected
102
+ - Compensating transactions for each saga step
103
+ ```
104
+
105
+ **Example 2 — CQRS Query Service:**
106
+ ```
107
+ User: "I need to query order history with restaurant and delivery details"
108
+
109
+ You should generate:
110
+ - CQRS view service that subscribes to events from Order, Restaurant, and Delivery services
111
+ - Denormalized read model (OrderHistoryView) that joins data from all three
112
+ - Event handlers that update the view when upstream events arrive
113
+ - Query API: GET /order-history?customerId=X
114
+ ```
115
+
116
+ **Key data pattern — price at order time:**
117
+ When OrderService creates an order, it must store the product price at that moment
118
+ (`priceAtOrder`) in its own orders table — not read it live from ProductService's database.
119
+ This is correct business behavior (customers are charged the price they saw) and eliminates
120
+ a cross-service database dependency. Never join to another service's products/price table
121
+ from OrderService.
122
+
123
+ ---
124
+
125
+ ## Mode 2: Code Review
126
+
127
+ When reviewing microservices code, read `references/review-checklist.md` for the
128
+ full checklist. Apply these categories systematically:
129
+
130
+ ### Review Mindset — Praise First, Invent Nothing
131
+
132
+ **Critical rule:** Do not manufacture issues. If the code correctly applies a pattern,
133
+ say so explicitly and praise it. Only flag genuine problems. It is better to write a
134
+ review that is 80% praise and 20% improvement than to invent defects to fill space.
135
+
136
+ Specifically:
137
+ - If a saga correctly stores intermediate state (e.g., `driverId`, `paymentAuthId`) to enable compensation — **praise this explicitly**: the saga has the data it needs to undo each step
138
+ - If compensating transactions are present (e.g., `ReleaseDriverCommand` triggered on payment failure) — **praise each compensation chain by name**
139
+ - If the design is event-driven (reacting to events rather than making synchronous calls) — **praise this explicitly**: it decouples services from each other's availability
140
+ - If `SagaLifecycle.end()` is called on both success and failure paths — **praise this as correct lifecycle management** that prevents memory leaks; do NOT treat it as a bug
141
+ - If failure paths are modeled as first-class domain events (e.g., `NoDriverAvailableEvent`, `PaymentDeclinedEvent`) rather than exceptions — **praise this explicitly**
142
+
143
+ When something is genuinely well-designed, lead with that assessment ("This is a well-designed orchestration-based saga") before any suggestions.
144
+
145
+ Optional improvements (e.g., timeout handling, idempotency keys) should be framed
146
+ as "additional robustness you could add" — not as defects or missing requirements.
147
+
148
+ ### Review Process
149
+
150
+ 1. **Identify what you're looking at** — which service, what pattern it implements
151
+ 2. **Assess overall design quality first** — is this well-designed? Say so explicitly if yes
152
+ 3. **Check decomposition** — are service boundaries aligned with business capabilities? Any god services?
153
+ 4. **Check data ownership** — does each service own its data? Any shared databases?
154
+ 5. **Check communication** — are sync/async choices appropriate? Circuit breakers present?
155
+ 6. **Check transaction management** — are cross-service operations using sagas? Compensating actions present?
156
+ 7. **Check business logic** — are aggregates well-defined? Transaction boundaries correct?
157
+ 8. **Check event handling** — are message handlers idempotent? Events well-structured?
158
+ 9. **Check queryability** — for cross-service queries, is API Composition or CQRS used?
159
+ 10. **Check testability** — are consumer-driven contract tests in place? Component tests?
160
+ 11. **Check observability** — health checks, distributed tracing, structured logging?
161
+
162
+ ### Saga-Specific Review Guidance
163
+
164
+ When reviewing saga implementations:
165
+
166
+ - **Explicit durable saga state** — a well-designed orchestration saga stores named states
167
+ (e.g., `PENDING_INVENTORY`, `PENDING_PAYMENT`, `PENDING_SHIPPING`, `CONFIRMED`, `FAILED`)
168
+ durably in the database. If states are implicit (only tracked via null-checks on IDs),
169
+ recommend making them explicit enums persisted to a saga state table.
170
+
171
+ - **Intermediate state for compensation** — a saga that stores `driverId` and `paymentAuthId`
172
+ as fields is doing this correctly; it can undo each step because it remembers what happened.
173
+ Praise this pattern explicitly.
174
+
175
+ - **Compensation chains** — when `PaymentDeclinedEvent` triggers both `ReleaseDriverCommand`
176
+ and `CancelTripCommand`, that is correct. Name and praise the specific chain.
177
+
178
+ - **Lifecycle management** — `SagaLifecycle.end()` (or equivalent) on all terminal paths
179
+ (both success and failure) is **correct and important**. It prevents saga instances from
180
+ accumulating in memory. Do NOT flag this as a bug.
181
+
182
+ - **Event-driven steps** — each saga step reacting to a domain event (not making a sync call)
183
+ is the correct pattern. Praise this explicitly.
184
+
185
+ ### Review Output Format
186
+
187
+ Structure your review as:
188
+
189
+ ```
190
+ ## Summary
191
+ One paragraph: what the code does, which patterns it uses, overall assessment.
192
+ If the overall design is sound, say so clearly here.
193
+
194
+ ## Strengths
195
+ What the code does well, which patterns are correctly applied. Be specific — name
196
+ the exact methods, events, or structures that demonstrate good design.
197
+
198
+ ## Issues Found
199
+ For each genuine issue only:
200
+ - **What**: describe the problem
201
+ - **Why it matters**: explain the architectural risk
202
+ - **Pattern to apply**: which microservices pattern addresses this
203
+ - **Suggested fix**: concrete code change or restructuring
204
+
205
+ If there are no genuine issues, write "No critical issues found."
206
+
207
+ ## Optional Improvements (not defects)
208
+ Low-priority additions that could add robustness:
209
+ - e.g., timeout handling if an expected event never arrives
210
+ - e.g., idempotency keys on command handlers
211
+ - e.g., dead-letter queue for failed messages
212
+
213
+ ## Recommendations
214
+ Priority-ordered list of improvements, from most critical to nice-to-have.
215
+ ```
216
+
217
+ ### Common Anti-Patterns to Flag
218
+
219
+ - **Shared database** — multiple services reading/writing the same tables
220
+ - **Synchronous chain** — service A calls B calls C calls D (fragile, high latency)
221
+ - **Distributed monolith** — services are tightly coupled and must deploy together
222
+ - **No compensating transactions** — saga steps without rollback logic
223
+ - **Missing explicit saga state** — saga progress tracked only via null checks instead of durable named state enum
224
+ - **Missing price denormalization** — OrderService joining live to product prices instead of storing price-at-order-time (correct business behavior: capture the price the customer saw)
225
+ - **Chatty communication** — too many fine-grained API calls between services
226
+ - **Missing circuit breaker** — no fallback when a downstream service is unavailable
227
+ - **Anemic domain model** — business logic living in service layer instead of domain objects
228
+ - **God service** — one service that does everything (failed decomposition)
229
+ - **Shared libraries with domain logic** — coupling services through common domain code
230
+
231
+ ---
232
+
233
+ ## General Guidelines
234
+
235
+ - Be practical, not dogmatic. Not every system needs event sourcing or CQRS. Recommend
236
+ patterns that fit the actual complexity of the user's problem.
237
+ - The Microservice Architecture pattern language is a collection of patterns, not a
238
+ checklist to apply exhaustively. Each pattern solves a specific problem — only use it
239
+ when that problem exists.
240
+ - When the user's system is simple enough for a monolith, say so. The book itself
241
+ emphasizes that microservices add complexity and should be adopted when the benefits
242
+ (independent deployment, team autonomy, technology diversity) outweigh the costs.
243
+ - For deeper pattern details, read `references/patterns-catalog.md` before generating code.
244
+ - For review checklists, read `references/review-checklist.md` before reviewing code.
245
+
246
+ ---
247
+
248
+ ## Mode 3: Service Migration Planning
249
+
250
+ **Trigger phrases:** "decompose my monolith", "migrate to microservices", "strangle the monolith", "extract a service from"
251
+
252
+ You are helping a developer plan an incremental migration from a monolith (or distributed monolith) to a microservices architecture. The goal is a **phased migration** using the Strangler Fig pattern — the monolith keeps running while services are extracted one at a time.
253
+
254
+ ### Step 1 — Assess Current State
255
+
256
+ Classify the system as one of:
257
+ - **Monolith** — Single deployable unit, single database. Starting point for decomposition.
258
+ - **Distributed Monolith** — Multiple services but tightly coupled (shared database, synchronous chains, must deploy together). Often worse than a monolith.
259
+ - **Partly Decomposed** — Some services extracted but shared databases or tight coupling remain.
260
+
261
+ Flag the critical problems:
262
+ - Shared databases (which tables are shared by which modules?)
263
+ - Synchronous call chains (A → B → C → D, fragile under failure)
264
+ - Missing circuit breakers
265
+ - No compensating transactions for cross-boundary operations
266
+
267
+ ### Step 2 — Phase 1: Identify Boundaries (No Code Change)
268
+
269
+ **Goal:** Map business capabilities and propose service boundaries before touching code.
270
+ **Risk:** Zero — analysis only.
271
+
272
+ Actions:
273
+ - Map business capabilities (Order Management, Inventory, Billing, Notifications, etc.)
274
+ - Identify which capabilities are most independent (least shared database tables)
275
+ - Propose decomposition using **Decompose by Business Capability**
276
+ - Draw a capability map: which capabilities share data? Which are truly isolated?
277
+
278
+ Output: A capability map table showing each candidate service, its data ownership, and coupling level.
279
+
280
+ **Definition of Done:** Agreement on which service to extract first (least-coupled capability).
281
+
282
+ ### Step 3 — Phase 2: Strangle the Monolith (Low-Risk)
283
+
284
+ **Goal:** Extract one service at a time using the Strangler Fig pattern.
285
+ **Risk:** Low if done incrementally — monolith keeps running.
286
+
287
+ Strategy:
288
+ - Start with the **least-coupled** capability (fewest shared tables, fewest synchronous callers)
289
+ - Build the new service alongside the monolith
290
+ - Route new traffic to the new service; keep the monolith handling old traffic
291
+ - Once the new service is stable, cut over the monolith's callers
292
+
293
+ Order of extraction (typical):
294
+ 1. Leaf services (no downstream dependencies) — e.g., Notifications
295
+ 2. Read-heavy services (can duplicate read models first)
296
+ 3. Write-heavy services (require database decoupling first)
297
+
298
+ **Definition of Done:** First service deployed independently. Monolith no longer owns that capability.
299
+
300
+ ### Step 4 — Phase 3: Database Decoupling (Medium-Risk)
301
+
302
+ **Goal:** Give each service its own private database.
303
+ **Risk:** Medium — requires data migration and API contracts between services.
304
+
305
+ Actions:
306
+ - Identify shared tables; assign ownership to one service
307
+ - Replace shared table reads with API calls or event subscriptions
308
+ - Use the **Database per Service** pattern: each service's schema is off-limits to other services
309
+ - For data that must stay consistent, plan eventual consistency via domain events
310
+
311
+ Patterns to apply:
312
+ - **Shared Database → separate schemas**: One service owns the table; others read via API
313
+ - **API Composition** for cross-service queries (replaces direct joins)
314
+ - **Domain events** to propagate state changes asynchronously
315
+
316
+ **Definition of Done:** No service reads from another service's database directly. All cross-service data flows through APIs or events.
317
+
318
+ ### Step 5 — Phase 4: Async Communication (Medium-Risk)
319
+
320
+ **Goal:** Replace synchronous call chains with messaging; add resilience.
321
+ **Risk:** Medium — changes communication model across services.
322
+
323
+ Actions:
324
+ - Replace synchronous A → B → C chains with publish/subscribe messaging
325
+ - Add **Circuit Breakers** for remaining synchronous calls (fail fast, fallback)
326
+ - Make message handlers **idempotent** (handle duplicate messages safely)
327
+ - Use **Transactional Outbox** to ensure events are published atomically with database writes
328
+
329
+ **Definition of Done:** No synchronous chains longer than 2 hops. All event handlers are idempotent.
330
+
331
+ ### Step 6 — Phase 5: Distributed Transactions (High-Risk, As Needed)
332
+
333
+ **Goal:** Handle multi-service operations that require consistency.
334
+ **Risk:** High — Saga implementation requires careful design of compensating transactions.
335
+
336
+ Apply when: a single user action must atomically update data owned by 2+ services (e.g., creating an order must both charge payment and reserve inventory).
337
+
338
+ Actions:
339
+ - Identify cross-service operations requiring consistency
340
+ - Design **Sagas** (choreography or orchestration) with compensating transactions for each step
341
+ - For orchestration: implement a Saga orchestrator state machine
342
+ - For choreography: design event sequences and compensation events
343
+ - Test failure scenarios explicitly
344
+
345
+ **Definition of Done:** Every multi-service operation has a defined happy path and compensation path. No distributed transactions use 2PC.
346
+
347
+ ### Migration Output Format
348
+
349
+ ```
350
+ ## Service Migration Plan: [System Name]
351
+
352
+ ### Current State Assessment
353
+ **Classification:** Monolith
354
+ **Shared databases:** Orders table shared by OrderModule and BillingModule
355
+ **Synchronous chains:** API Gateway → OrderService → InventoryService → NotificationService (3-hop chain)
356
+
357
+ ### Capability Map
358
+ | Capability | Candidate Service | Shared Tables | Coupling Level |
359
+ |------------|------------------|---------------|----------------|
360
+ | Notifications | NotificationService | None | Low — extract first |
361
+ | Inventory | InventoryService | inventory, products | Medium |
362
+ | Orders | OrderService | orders, line_items, payments | High — extract last |
363
+
364
+ ### Phase 1 — Boundaries (start now, no code change)
365
+ - [ ] Agree on service boundaries based on capability map above
366
+ - [ ] Identify NotificationService as first extraction target
367
+
368
+ ### Phase 2 — Strangle the Monolith (next quarter)
369
+ - [ ] Build NotificationService alongside monolith
370
+ - [ ] Route notification calls to new service via API Gateway
371
+ - [ ] Decommission notification code from monolith
372
+
373
+ ### Phase 3 — Database Decoupling (following quarter)
374
+ - [ ] Assign `notifications` table to NotificationService exclusively
375
+ - [ ] Replace OrderModule's direct DB read of customer email with API call to CustomerService
376
+
377
+ ### Phase 4 — Async Communication (6 months)
378
+ - [ ] Replace OrderService → NotificationService sync call with OrderCreated domain event
379
+ - [ ] Add Circuit Breaker to InventoryService call from OrderService
380
+
381
+ ### Phase 5 — Distributed Transactions (as needed)
382
+ - [ ] Design CreateOrderSaga: reserve inventory → charge payment → confirm order
383
+ - [ ] Define compensating transactions: release inventory, void charge
384
+ ```