@wazir-dev/cli 1.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 (629) hide show
  1. package/AGENTS.md +111 -0
  2. package/CHANGELOG.md +14 -0
  3. package/CONTRIBUTING.md +101 -0
  4. package/LICENSE +21 -0
  5. package/README.md +314 -0
  6. package/assets/composition-engine.mmd +34 -0
  7. package/assets/demo-script.sh +17 -0
  8. package/assets/logo-dark.svg +14 -0
  9. package/assets/logo.svg +14 -0
  10. package/assets/pipeline.mmd +39 -0
  11. package/assets/record-demo.sh +51 -0
  12. package/docs/README.md +51 -0
  13. package/docs/adapters/context-mode.md +60 -0
  14. package/docs/concepts/architecture.md +87 -0
  15. package/docs/concepts/artifact-model.md +60 -0
  16. package/docs/concepts/composition-engine.md +36 -0
  17. package/docs/concepts/indexing-and-recall.md +160 -0
  18. package/docs/concepts/observability.md +41 -0
  19. package/docs/concepts/roles-and-workflows.md +59 -0
  20. package/docs/concepts/terminology-policy.md +27 -0
  21. package/docs/getting-started/01-installation.md +78 -0
  22. package/docs/getting-started/02-first-run.md +102 -0
  23. package/docs/getting-started/03-adding-to-project.md +15 -0
  24. package/docs/getting-started/04-host-setup.md +15 -0
  25. package/docs/guides/ci-integration.md +15 -0
  26. package/docs/guides/creating-skills.md +15 -0
  27. package/docs/guides/expertise-module-authoring.md +15 -0
  28. package/docs/guides/hook-development.md +15 -0
  29. package/docs/guides/memory-and-learnings.md +34 -0
  30. package/docs/guides/multi-host-export.md +15 -0
  31. package/docs/guides/troubleshooting.md +101 -0
  32. package/docs/guides/writing-custom-roles.md +15 -0
  33. package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
  34. package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
  35. package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
  36. package/docs/readmes/INDEX.md +99 -0
  37. package/docs/readmes/features/expertise/README.md +171 -0
  38. package/docs/readmes/features/exports/README.md +222 -0
  39. package/docs/readmes/features/hooks/README.md +103 -0
  40. package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
  41. package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
  42. package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
  43. package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
  44. package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
  45. package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
  46. package/docs/readmes/features/hooks/session-start.md +119 -0
  47. package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
  48. package/docs/readmes/features/roles/README.md +157 -0
  49. package/docs/readmes/features/roles/clarifier.md +152 -0
  50. package/docs/readmes/features/roles/content-author.md +190 -0
  51. package/docs/readmes/features/roles/designer.md +193 -0
  52. package/docs/readmes/features/roles/executor.md +184 -0
  53. package/docs/readmes/features/roles/learner.md +210 -0
  54. package/docs/readmes/features/roles/planner.md +182 -0
  55. package/docs/readmes/features/roles/researcher.md +164 -0
  56. package/docs/readmes/features/roles/reviewer.md +184 -0
  57. package/docs/readmes/features/roles/specifier.md +162 -0
  58. package/docs/readmes/features/roles/verifier.md +215 -0
  59. package/docs/readmes/features/schemas/README.md +178 -0
  60. package/docs/readmes/features/skills/README.md +63 -0
  61. package/docs/readmes/features/skills/brainstorming.md +96 -0
  62. package/docs/readmes/features/skills/debugging.md +148 -0
  63. package/docs/readmes/features/skills/design.md +120 -0
  64. package/docs/readmes/features/skills/prepare-next.md +109 -0
  65. package/docs/readmes/features/skills/run-audit.md +159 -0
  66. package/docs/readmes/features/skills/scan-project.md +109 -0
  67. package/docs/readmes/features/skills/self-audit.md +176 -0
  68. package/docs/readmes/features/skills/tdd.md +137 -0
  69. package/docs/readmes/features/skills/using-skills.md +92 -0
  70. package/docs/readmes/features/skills/verification.md +120 -0
  71. package/docs/readmes/features/skills/writing-plans.md +104 -0
  72. package/docs/readmes/features/tooling/README.md +320 -0
  73. package/docs/readmes/features/workflows/README.md +186 -0
  74. package/docs/readmes/features/workflows/author.md +181 -0
  75. package/docs/readmes/features/workflows/clarify.md +154 -0
  76. package/docs/readmes/features/workflows/design-review.md +171 -0
  77. package/docs/readmes/features/workflows/design.md +169 -0
  78. package/docs/readmes/features/workflows/discover.md +162 -0
  79. package/docs/readmes/features/workflows/execute.md +173 -0
  80. package/docs/readmes/features/workflows/learn.md +167 -0
  81. package/docs/readmes/features/workflows/plan-review.md +165 -0
  82. package/docs/readmes/features/workflows/plan.md +170 -0
  83. package/docs/readmes/features/workflows/prepare-next.md +167 -0
  84. package/docs/readmes/features/workflows/review.md +169 -0
  85. package/docs/readmes/features/workflows/run-audit.md +191 -0
  86. package/docs/readmes/features/workflows/spec-challenge.md +159 -0
  87. package/docs/readmes/features/workflows/specify.md +160 -0
  88. package/docs/readmes/features/workflows/verify.md +177 -0
  89. package/docs/readmes/packages/README.md +50 -0
  90. package/docs/readmes/packages/ajv.md +117 -0
  91. package/docs/readmes/packages/context-mode.md +118 -0
  92. package/docs/readmes/packages/gray-matter.md +116 -0
  93. package/docs/readmes/packages/node-test.md +137 -0
  94. package/docs/readmes/packages/yaml.md +112 -0
  95. package/docs/reference/configuration-reference.md +159 -0
  96. package/docs/reference/expertise-index.md +52 -0
  97. package/docs/reference/git-flow.md +43 -0
  98. package/docs/reference/hooks.md +87 -0
  99. package/docs/reference/host-exports.md +50 -0
  100. package/docs/reference/launch-checklist.md +172 -0
  101. package/docs/reference/marketplace-listings.md +76 -0
  102. package/docs/reference/release-process.md +34 -0
  103. package/docs/reference/roles-reference.md +77 -0
  104. package/docs/reference/skills.md +33 -0
  105. package/docs/reference/templates.md +29 -0
  106. package/docs/reference/tooling-cli.md +94 -0
  107. package/docs/truth-claims.yaml +222 -0
  108. package/expertise/PROGRESS.md +63 -0
  109. package/expertise/README.md +18 -0
  110. package/expertise/antipatterns/PROGRESS.md +56 -0
  111. package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
  112. package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
  113. package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
  114. package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
  115. package/expertise/antipatterns/backend/index.md +24 -0
  116. package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
  117. package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
  118. package/expertise/antipatterns/code/async-antipatterns.md +622 -0
  119. package/expertise/antipatterns/code/code-smells.md +1186 -0
  120. package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
  121. package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
  122. package/expertise/antipatterns/code/index.md +27 -0
  123. package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
  124. package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
  125. package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
  126. package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
  127. package/expertise/antipatterns/design/dark-patterns.md +1121 -0
  128. package/expertise/antipatterns/design/index.md +22 -0
  129. package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
  130. package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
  131. package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
  132. package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
  133. package/expertise/antipatterns/frontend/index.md +23 -0
  134. package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
  135. package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
  136. package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
  137. package/expertise/antipatterns/index.md +31 -0
  138. package/expertise/antipatterns/performance/index.md +20 -0
  139. package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
  140. package/expertise/antipatterns/performance/premature-optimization.md +623 -0
  141. package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
  142. package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
  143. package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
  144. package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
  145. package/expertise/antipatterns/process/index.md +23 -0
  146. package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
  147. package/expertise/antipatterns/security/index.md +20 -0
  148. package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
  149. package/expertise/antipatterns/security/security-theater.md +843 -0
  150. package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
  151. package/expertise/architecture/PROGRESS.md +70 -0
  152. package/expertise/architecture/data/caching-architecture.md +671 -0
  153. package/expertise/architecture/data/data-consistency.md +574 -0
  154. package/expertise/architecture/data/data-modeling.md +536 -0
  155. package/expertise/architecture/data/event-streams-and-queues.md +634 -0
  156. package/expertise/architecture/data/index.md +25 -0
  157. package/expertise/architecture/data/search-architecture.md +663 -0
  158. package/expertise/architecture/data/sql-vs-nosql.md +708 -0
  159. package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
  160. package/expertise/architecture/decisions/build-vs-buy.md +616 -0
  161. package/expertise/architecture/decisions/index.md +23 -0
  162. package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
  163. package/expertise/architecture/decisions/technology-selection.md +616 -0
  164. package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
  165. package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
  166. package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
  167. package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
  168. package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
  169. package/expertise/architecture/distributed/index.md +25 -0
  170. package/expertise/architecture/distributed/saga-pattern.md +797 -0
  171. package/expertise/architecture/foundations/architectural-thinking.md +460 -0
  172. package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
  173. package/expertise/architecture/foundations/design-principles-solid.md +649 -0
  174. package/expertise/architecture/foundations/domain-driven-design.md +719 -0
  175. package/expertise/architecture/foundations/index.md +25 -0
  176. package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
  177. package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
  178. package/expertise/architecture/index.md +34 -0
  179. package/expertise/architecture/integration/api-design-graphql.md +638 -0
  180. package/expertise/architecture/integration/api-design-grpc.md +804 -0
  181. package/expertise/architecture/integration/api-design-rest.md +892 -0
  182. package/expertise/architecture/integration/index.md +25 -0
  183. package/expertise/architecture/integration/third-party-integration.md +795 -0
  184. package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
  185. package/expertise/architecture/integration/websockets-realtime.md +791 -0
  186. package/expertise/architecture/mobile-architecture/index.md +22 -0
  187. package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
  188. package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
  189. package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
  190. package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
  191. package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
  192. package/expertise/architecture/patterns/event-driven.md +797 -0
  193. package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
  194. package/expertise/architecture/patterns/index.md +27 -0
  195. package/expertise/architecture/patterns/layered-architecture.md +736 -0
  196. package/expertise/architecture/patterns/microservices.md +753 -0
  197. package/expertise/architecture/patterns/modular-monolith.md +692 -0
  198. package/expertise/architecture/patterns/monolith.md +626 -0
  199. package/expertise/architecture/patterns/plugin-architecture.md +735 -0
  200. package/expertise/architecture/patterns/serverless.md +780 -0
  201. package/expertise/architecture/scaling/database-scaling.md +615 -0
  202. package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
  203. package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
  204. package/expertise/architecture/scaling/index.md +24 -0
  205. package/expertise/architecture/scaling/multi-tenancy.md +800 -0
  206. package/expertise/architecture/scaling/stateless-design.md +787 -0
  207. package/expertise/backend/embedded-firmware.md +625 -0
  208. package/expertise/backend/go.md +853 -0
  209. package/expertise/backend/index.md +24 -0
  210. package/expertise/backend/java-spring.md +448 -0
  211. package/expertise/backend/node-typescript.md +625 -0
  212. package/expertise/backend/python-fastapi.md +724 -0
  213. package/expertise/backend/rust.md +458 -0
  214. package/expertise/backend/solidity.md +711 -0
  215. package/expertise/composition-map.yaml +443 -0
  216. package/expertise/content/foundations/content-modeling.md +395 -0
  217. package/expertise/content/foundations/editorial-standards.md +449 -0
  218. package/expertise/content/foundations/index.md +24 -0
  219. package/expertise/content/foundations/microcopy.md +455 -0
  220. package/expertise/content/foundations/terminology-governance.md +509 -0
  221. package/expertise/content/index.md +34 -0
  222. package/expertise/content/patterns/accessibility-copy.md +518 -0
  223. package/expertise/content/patterns/index.md +24 -0
  224. package/expertise/content/patterns/notification-content.md +433 -0
  225. package/expertise/content/patterns/sample-content.md +486 -0
  226. package/expertise/content/patterns/state-copy.md +439 -0
  227. package/expertise/design/PROGRESS.md +58 -0
  228. package/expertise/design/disciplines/dark-mode-theming.md +577 -0
  229. package/expertise/design/disciplines/design-systems.md +595 -0
  230. package/expertise/design/disciplines/index.md +25 -0
  231. package/expertise/design/disciplines/information-architecture.md +800 -0
  232. package/expertise/design/disciplines/interaction-design.md +788 -0
  233. package/expertise/design/disciplines/responsive-design.md +552 -0
  234. package/expertise/design/disciplines/usability-testing.md +516 -0
  235. package/expertise/design/disciplines/user-research.md +792 -0
  236. package/expertise/design/foundations/accessibility-design.md +796 -0
  237. package/expertise/design/foundations/color-theory.md +797 -0
  238. package/expertise/design/foundations/iconography.md +795 -0
  239. package/expertise/design/foundations/index.md +26 -0
  240. package/expertise/design/foundations/motion-and-animation.md +653 -0
  241. package/expertise/design/foundations/rtl-design.md +585 -0
  242. package/expertise/design/foundations/spacing-and-layout.md +607 -0
  243. package/expertise/design/foundations/typography.md +800 -0
  244. package/expertise/design/foundations/visual-hierarchy.md +761 -0
  245. package/expertise/design/index.md +32 -0
  246. package/expertise/design/patterns/authentication-flows.md +474 -0
  247. package/expertise/design/patterns/content-consumption.md +789 -0
  248. package/expertise/design/patterns/data-display.md +618 -0
  249. package/expertise/design/patterns/e-commerce.md +1494 -0
  250. package/expertise/design/patterns/feedback-and-states.md +642 -0
  251. package/expertise/design/patterns/forms-and-input.md +819 -0
  252. package/expertise/design/patterns/gamification.md +801 -0
  253. package/expertise/design/patterns/index.md +31 -0
  254. package/expertise/design/patterns/microinteractions.md +449 -0
  255. package/expertise/design/patterns/navigation.md +800 -0
  256. package/expertise/design/patterns/notifications.md +705 -0
  257. package/expertise/design/patterns/onboarding.md +700 -0
  258. package/expertise/design/patterns/search-and-filter.md +601 -0
  259. package/expertise/design/patterns/settings-and-preferences.md +768 -0
  260. package/expertise/design/patterns/social-and-community.md +748 -0
  261. package/expertise/design/platforms/desktop-native.md +612 -0
  262. package/expertise/design/platforms/index.md +25 -0
  263. package/expertise/design/platforms/mobile-android.md +825 -0
  264. package/expertise/design/platforms/mobile-cross-platform.md +983 -0
  265. package/expertise/design/platforms/mobile-ios.md +699 -0
  266. package/expertise/design/platforms/tablet.md +794 -0
  267. package/expertise/design/platforms/web-dashboard.md +790 -0
  268. package/expertise/design/platforms/web-responsive.md +550 -0
  269. package/expertise/design/psychology/behavioral-nudges.md +449 -0
  270. package/expertise/design/psychology/cognitive-load.md +1191 -0
  271. package/expertise/design/psychology/error-psychology.md +778 -0
  272. package/expertise/design/psychology/index.md +22 -0
  273. package/expertise/design/psychology/persuasive-design.md +736 -0
  274. package/expertise/design/psychology/user-mental-models.md +623 -0
  275. package/expertise/design/tooling/open-pencil.md +266 -0
  276. package/expertise/frontend/angular.md +1073 -0
  277. package/expertise/frontend/desktop-electron.md +546 -0
  278. package/expertise/frontend/flutter.md +782 -0
  279. package/expertise/frontend/index.md +27 -0
  280. package/expertise/frontend/native-android.md +409 -0
  281. package/expertise/frontend/native-ios.md +490 -0
  282. package/expertise/frontend/react-native.md +1160 -0
  283. package/expertise/frontend/react.md +808 -0
  284. package/expertise/frontend/vue.md +1089 -0
  285. package/expertise/humanize/domain-rules-code.md +79 -0
  286. package/expertise/humanize/domain-rules-content.md +67 -0
  287. package/expertise/humanize/domain-rules-technical-docs.md +56 -0
  288. package/expertise/humanize/index.md +35 -0
  289. package/expertise/humanize/self-audit-checklist.md +87 -0
  290. package/expertise/humanize/sentence-patterns.md +218 -0
  291. package/expertise/humanize/vocabulary-blacklist.md +105 -0
  292. package/expertise/i18n/PROGRESS.md +65 -0
  293. package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
  294. package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
  295. package/expertise/i18n/advanced/complex-scripts.md +30 -0
  296. package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
  297. package/expertise/i18n/advanced/testing-i18n.md +28 -0
  298. package/expertise/i18n/content/content-adaptation.md +23 -0
  299. package/expertise/i18n/content/locale-specific-formatting.md +23 -0
  300. package/expertise/i18n/content/machine-translation-integration.md +28 -0
  301. package/expertise/i18n/content/translation-management.md +29 -0
  302. package/expertise/i18n/foundations/date-time-calendars.md +67 -0
  303. package/expertise/i18n/foundations/i18n-architecture.md +272 -0
  304. package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
  305. package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
  306. package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
  307. package/expertise/i18n/foundations/string-externalization.md +236 -0
  308. package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
  309. package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
  310. package/expertise/i18n/index.md +38 -0
  311. package/expertise/i18n/platform/backend-i18n.md +31 -0
  312. package/expertise/i18n/platform/flutter-i18n.md +148 -0
  313. package/expertise/i18n/platform/native-android-i18n.md +36 -0
  314. package/expertise/i18n/platform/native-ios-i18n.md +36 -0
  315. package/expertise/i18n/platform/react-i18n.md +103 -0
  316. package/expertise/i18n/platform/web-css-i18n.md +81 -0
  317. package/expertise/i18n/rtl/arabic-specific.md +175 -0
  318. package/expertise/i18n/rtl/hebrew-specific.md +149 -0
  319. package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
  320. package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
  321. package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
  322. package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
  323. package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
  324. package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
  325. package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
  326. package/expertise/i18n/rtl/rtl-typography.md +160 -0
  327. package/expertise/index.md +113 -0
  328. package/expertise/index.yaml +216 -0
  329. package/expertise/infrastructure/cloud-aws.md +597 -0
  330. package/expertise/infrastructure/cloud-gcp.md +599 -0
  331. package/expertise/infrastructure/cybersecurity.md +816 -0
  332. package/expertise/infrastructure/database-mongodb.md +447 -0
  333. package/expertise/infrastructure/database-postgres.md +400 -0
  334. package/expertise/infrastructure/devops-cicd.md +787 -0
  335. package/expertise/infrastructure/index.md +27 -0
  336. package/expertise/performance/PROGRESS.md +50 -0
  337. package/expertise/performance/backend/api-latency.md +1204 -0
  338. package/expertise/performance/backend/background-jobs.md +506 -0
  339. package/expertise/performance/backend/connection-pooling.md +1209 -0
  340. package/expertise/performance/backend/database-query-optimization.md +515 -0
  341. package/expertise/performance/backend/index.md +23 -0
  342. package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
  343. package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
  344. package/expertise/performance/foundations/caching-strategies.md +489 -0
  345. package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
  346. package/expertise/performance/foundations/index.md +24 -0
  347. package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
  348. package/expertise/performance/foundations/memory-management.md +964 -0
  349. package/expertise/performance/foundations/performance-budgets.md +1314 -0
  350. package/expertise/performance/index.md +31 -0
  351. package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
  352. package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
  353. package/expertise/performance/infrastructure/index.md +22 -0
  354. package/expertise/performance/infrastructure/load-balancing.md +1081 -0
  355. package/expertise/performance/infrastructure/observability.md +1079 -0
  356. package/expertise/performance/mobile/index.md +23 -0
  357. package/expertise/performance/mobile/mobile-animations.md +544 -0
  358. package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
  359. package/expertise/performance/mobile/mobile-network.md +452 -0
  360. package/expertise/performance/mobile/mobile-rendering.md +599 -0
  361. package/expertise/performance/mobile/mobile-startup-time.md +505 -0
  362. package/expertise/performance/platform-specific/flutter-performance.md +647 -0
  363. package/expertise/performance/platform-specific/index.md +22 -0
  364. package/expertise/performance/platform-specific/node-performance.md +1307 -0
  365. package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
  366. package/expertise/performance/platform-specific/react-performance.md +1403 -0
  367. package/expertise/performance/web/bundle-optimization.md +1239 -0
  368. package/expertise/performance/web/image-and-media.md +636 -0
  369. package/expertise/performance/web/index.md +24 -0
  370. package/expertise/performance/web/network-optimization.md +1133 -0
  371. package/expertise/performance/web/rendering-performance.md +1098 -0
  372. package/expertise/performance/web/ssr-and-hydration.md +918 -0
  373. package/expertise/performance/web/web-vitals.md +1374 -0
  374. package/expertise/quality/accessibility.md +985 -0
  375. package/expertise/quality/evidence-based-verification.md +499 -0
  376. package/expertise/quality/index.md +24 -0
  377. package/expertise/quality/ml-model-audit.md +614 -0
  378. package/expertise/quality/performance.md +600 -0
  379. package/expertise/quality/testing-api.md +891 -0
  380. package/expertise/quality/testing-mobile.md +496 -0
  381. package/expertise/quality/testing-web.md +849 -0
  382. package/expertise/security/PROGRESS.md +54 -0
  383. package/expertise/security/agentic-identity.md +540 -0
  384. package/expertise/security/compliance-frameworks.md +601 -0
  385. package/expertise/security/data/data-encryption.md +364 -0
  386. package/expertise/security/data/data-privacy-gdpr.md +692 -0
  387. package/expertise/security/data/database-security.md +1171 -0
  388. package/expertise/security/data/index.md +22 -0
  389. package/expertise/security/data/pii-handling.md +531 -0
  390. package/expertise/security/foundations/authentication.md +1041 -0
  391. package/expertise/security/foundations/authorization.md +603 -0
  392. package/expertise/security/foundations/cryptography.md +1001 -0
  393. package/expertise/security/foundations/index.md +25 -0
  394. package/expertise/security/foundations/owasp-top-10.md +1354 -0
  395. package/expertise/security/foundations/secrets-management.md +1217 -0
  396. package/expertise/security/foundations/secure-sdlc.md +700 -0
  397. package/expertise/security/foundations/supply-chain-security.md +698 -0
  398. package/expertise/security/index.md +31 -0
  399. package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
  400. package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
  401. package/expertise/security/infrastructure/container-security.md +721 -0
  402. package/expertise/security/infrastructure/incident-response.md +1295 -0
  403. package/expertise/security/infrastructure/index.md +24 -0
  404. package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
  405. package/expertise/security/infrastructure/network-security.md +1337 -0
  406. package/expertise/security/mobile/index.md +23 -0
  407. package/expertise/security/mobile/mobile-android-security.md +1218 -0
  408. package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
  409. package/expertise/security/mobile/mobile-data-storage.md +1265 -0
  410. package/expertise/security/mobile/mobile-ios-security.md +1401 -0
  411. package/expertise/security/mobile/mobile-network-security.md +1520 -0
  412. package/expertise/security/smart-contract-security.md +594 -0
  413. package/expertise/security/testing/index.md +22 -0
  414. package/expertise/security/testing/penetration-testing.md +1258 -0
  415. package/expertise/security/testing/security-code-review.md +1765 -0
  416. package/expertise/security/testing/threat-modeling.md +1074 -0
  417. package/expertise/security/testing/vulnerability-scanning.md +1062 -0
  418. package/expertise/security/web/api-security.md +586 -0
  419. package/expertise/security/web/cors-and-headers.md +433 -0
  420. package/expertise/security/web/csrf.md +562 -0
  421. package/expertise/security/web/file-upload.md +1477 -0
  422. package/expertise/security/web/index.md +25 -0
  423. package/expertise/security/web/injection.md +1375 -0
  424. package/expertise/security/web/session-management.md +1101 -0
  425. package/expertise/security/web/xss.md +1158 -0
  426. package/exports/README.md +17 -0
  427. package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
  428. package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
  429. package/exports/hosts/claude/.claude/agents/designer.md +55 -0
  430. package/exports/hosts/claude/.claude/agents/executor.md +55 -0
  431. package/exports/hosts/claude/.claude/agents/learner.md +51 -0
  432. package/exports/hosts/claude/.claude/agents/planner.md +53 -0
  433. package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
  434. package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
  435. package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
  436. package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
  437. package/exports/hosts/claude/.claude/commands/author.md +42 -0
  438. package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
  439. package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
  440. package/exports/hosts/claude/.claude/commands/design.md +44 -0
  441. package/exports/hosts/claude/.claude/commands/discover.md +37 -0
  442. package/exports/hosts/claude/.claude/commands/execute.md +48 -0
  443. package/exports/hosts/claude/.claude/commands/learn.md +38 -0
  444. package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
  445. package/exports/hosts/claude/.claude/commands/plan.md +39 -0
  446. package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
  447. package/exports/hosts/claude/.claude/commands/review.md +40 -0
  448. package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
  449. package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
  450. package/exports/hosts/claude/.claude/commands/specify.md +38 -0
  451. package/exports/hosts/claude/.claude/commands/verify.md +37 -0
  452. package/exports/hosts/claude/.claude/settings.json +34 -0
  453. package/exports/hosts/claude/CLAUDE.md +19 -0
  454. package/exports/hosts/claude/export.manifest.json +38 -0
  455. package/exports/hosts/claude/host-package.json +67 -0
  456. package/exports/hosts/codex/AGENTS.md +19 -0
  457. package/exports/hosts/codex/export.manifest.json +38 -0
  458. package/exports/hosts/codex/host-package.json +41 -0
  459. package/exports/hosts/cursor/.cursor/hooks.json +16 -0
  460. package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
  461. package/exports/hosts/cursor/export.manifest.json +38 -0
  462. package/exports/hosts/cursor/host-package.json +42 -0
  463. package/exports/hosts/gemini/GEMINI.md +19 -0
  464. package/exports/hosts/gemini/export.manifest.json +38 -0
  465. package/exports/hosts/gemini/host-package.json +41 -0
  466. package/hooks/README.md +18 -0
  467. package/hooks/definitions/loop_cap_guard.yaml +21 -0
  468. package/hooks/definitions/post_tool_capture.yaml +24 -0
  469. package/hooks/definitions/pre_compact_summary.yaml +19 -0
  470. package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
  471. package/hooks/definitions/protected_path_write_guard.yaml +19 -0
  472. package/hooks/definitions/session_start.yaml +19 -0
  473. package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
  474. package/hooks/loop-cap-guard +17 -0
  475. package/hooks/post-tool-lint +36 -0
  476. package/hooks/protected-path-write-guard +17 -0
  477. package/hooks/session-start +41 -0
  478. package/llms-full.txt +2355 -0
  479. package/llms.txt +43 -0
  480. package/package.json +79 -0
  481. package/roles/README.md +20 -0
  482. package/roles/clarifier.md +42 -0
  483. package/roles/content-author.md +63 -0
  484. package/roles/designer.md +55 -0
  485. package/roles/executor.md +55 -0
  486. package/roles/learner.md +51 -0
  487. package/roles/planner.md +53 -0
  488. package/roles/researcher.md +43 -0
  489. package/roles/reviewer.md +54 -0
  490. package/roles/specifier.md +47 -0
  491. package/roles/verifier.md +71 -0
  492. package/schemas/README.md +24 -0
  493. package/schemas/accepted-learning.schema.json +20 -0
  494. package/schemas/author-artifact.schema.json +156 -0
  495. package/schemas/clarification.schema.json +19 -0
  496. package/schemas/design-artifact.schema.json +80 -0
  497. package/schemas/docs-claim.schema.json +18 -0
  498. package/schemas/export-manifest.schema.json +20 -0
  499. package/schemas/hook.schema.json +67 -0
  500. package/schemas/host-export-package.schema.json +18 -0
  501. package/schemas/implementation-plan.schema.json +19 -0
  502. package/schemas/proposed-learning.schema.json +19 -0
  503. package/schemas/research.schema.json +18 -0
  504. package/schemas/review.schema.json +29 -0
  505. package/schemas/run-manifest.schema.json +18 -0
  506. package/schemas/spec-challenge.schema.json +18 -0
  507. package/schemas/spec.schema.json +20 -0
  508. package/schemas/usage.schema.json +102 -0
  509. package/schemas/verification-proof.schema.json +29 -0
  510. package/schemas/wazir-manifest.schema.json +173 -0
  511. package/skills/README.md +40 -0
  512. package/skills/brainstorming/SKILL.md +77 -0
  513. package/skills/debugging/SKILL.md +50 -0
  514. package/skills/design/SKILL.md +61 -0
  515. package/skills/dispatching-parallel-agents/SKILL.md +128 -0
  516. package/skills/executing-plans/SKILL.md +70 -0
  517. package/skills/finishing-a-development-branch/SKILL.md +169 -0
  518. package/skills/humanize/SKILL.md +123 -0
  519. package/skills/init-pipeline/SKILL.md +124 -0
  520. package/skills/prepare-next/SKILL.md +20 -0
  521. package/skills/receiving-code-review/SKILL.md +123 -0
  522. package/skills/requesting-code-review/SKILL.md +105 -0
  523. package/skills/requesting-code-review/code-reviewer.md +108 -0
  524. package/skills/run-audit/SKILL.md +197 -0
  525. package/skills/scan-project/SKILL.md +41 -0
  526. package/skills/self-audit/SKILL.md +153 -0
  527. package/skills/subagent-driven-development/SKILL.md +154 -0
  528. package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
  529. package/skills/subagent-driven-development/implementer-prompt.md +102 -0
  530. package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
  531. package/skills/tdd/SKILL.md +23 -0
  532. package/skills/using-git-worktrees/SKILL.md +163 -0
  533. package/skills/using-skills/SKILL.md +95 -0
  534. package/skills/verification/SKILL.md +22 -0
  535. package/skills/wazir/SKILL.md +463 -0
  536. package/skills/writing-plans/SKILL.md +30 -0
  537. package/skills/writing-skills/SKILL.md +157 -0
  538. package/skills/writing-skills/anthropic-best-practices.md +122 -0
  539. package/skills/writing-skills/persuasion-principles.md +50 -0
  540. package/templates/README.md +20 -0
  541. package/templates/artifacts/README.md +10 -0
  542. package/templates/artifacts/accepted-learning.md +19 -0
  543. package/templates/artifacts/accepted-learning.template.json +12 -0
  544. package/templates/artifacts/author.md +74 -0
  545. package/templates/artifacts/author.template.json +19 -0
  546. package/templates/artifacts/clarification.md +21 -0
  547. package/templates/artifacts/clarification.template.json +12 -0
  548. package/templates/artifacts/execute-notes.md +19 -0
  549. package/templates/artifacts/implementation-plan.md +21 -0
  550. package/templates/artifacts/implementation-plan.template.json +11 -0
  551. package/templates/artifacts/learning-proposal.md +19 -0
  552. package/templates/artifacts/next-run-handoff.md +21 -0
  553. package/templates/artifacts/plan-review.md +19 -0
  554. package/templates/artifacts/proposed-learning.template.json +12 -0
  555. package/templates/artifacts/research.md +21 -0
  556. package/templates/artifacts/research.template.json +12 -0
  557. package/templates/artifacts/review-findings.md +19 -0
  558. package/templates/artifacts/review.template.json +11 -0
  559. package/templates/artifacts/run-manifest.template.json +8 -0
  560. package/templates/artifacts/spec-challenge.md +19 -0
  561. package/templates/artifacts/spec-challenge.template.json +11 -0
  562. package/templates/artifacts/spec.md +21 -0
  563. package/templates/artifacts/spec.template.json +12 -0
  564. package/templates/artifacts/verification-proof.md +19 -0
  565. package/templates/artifacts/verification-proof.template.json +11 -0
  566. package/templates/examples/accepted-learning.example.json +14 -0
  567. package/templates/examples/author.example.json +152 -0
  568. package/templates/examples/clarification.example.json +15 -0
  569. package/templates/examples/docs-claim.example.json +8 -0
  570. package/templates/examples/export-manifest.example.json +7 -0
  571. package/templates/examples/host-export-package.example.json +11 -0
  572. package/templates/examples/implementation-plan.example.json +17 -0
  573. package/templates/examples/proposed-learning.example.json +13 -0
  574. package/templates/examples/research.example.json +15 -0
  575. package/templates/examples/research.example.md +6 -0
  576. package/templates/examples/review.example.json +17 -0
  577. package/templates/examples/run-manifest.example.json +9 -0
  578. package/templates/examples/spec-challenge.example.json +14 -0
  579. package/templates/examples/spec.example.json +21 -0
  580. package/templates/examples/verification-proof.example.json +21 -0
  581. package/templates/examples/wazir-manifest.example.yaml +65 -0
  582. package/templates/task-definition-schema.md +99 -0
  583. package/tooling/README.md +20 -0
  584. package/tooling/src/adapters/context-mode.js +50 -0
  585. package/tooling/src/capture/command.js +376 -0
  586. package/tooling/src/capture/store.js +99 -0
  587. package/tooling/src/capture/usage.js +270 -0
  588. package/tooling/src/checks/branches.js +50 -0
  589. package/tooling/src/checks/brand-truth.js +110 -0
  590. package/tooling/src/checks/changelog.js +231 -0
  591. package/tooling/src/checks/command-registry.js +36 -0
  592. package/tooling/src/checks/commits.js +102 -0
  593. package/tooling/src/checks/docs-drift.js +103 -0
  594. package/tooling/src/checks/docs-truth.js +201 -0
  595. package/tooling/src/checks/runtime-surface.js +156 -0
  596. package/tooling/src/cli.js +116 -0
  597. package/tooling/src/command-options.js +56 -0
  598. package/tooling/src/commands/validate.js +320 -0
  599. package/tooling/src/doctor/command.js +91 -0
  600. package/tooling/src/export/command.js +77 -0
  601. package/tooling/src/export/compiler.js +498 -0
  602. package/tooling/src/guards/loop-cap-guard.js +52 -0
  603. package/tooling/src/guards/protected-path-write-guard.js +67 -0
  604. package/tooling/src/index/command.js +152 -0
  605. package/tooling/src/index/storage.js +1061 -0
  606. package/tooling/src/index/summarizers.js +261 -0
  607. package/tooling/src/loaders.js +18 -0
  608. package/tooling/src/project-root.js +22 -0
  609. package/tooling/src/recall/command.js +225 -0
  610. package/tooling/src/schema-validator.js +30 -0
  611. package/tooling/src/state-root.js +40 -0
  612. package/tooling/src/status/command.js +71 -0
  613. package/wazir.manifest.yaml +135 -0
  614. package/workflows/README.md +19 -0
  615. package/workflows/author.md +42 -0
  616. package/workflows/clarify.md +38 -0
  617. package/workflows/design-review.md +46 -0
  618. package/workflows/design.md +44 -0
  619. package/workflows/discover.md +37 -0
  620. package/workflows/execute.md +48 -0
  621. package/workflows/learn.md +38 -0
  622. package/workflows/plan-review.md +42 -0
  623. package/workflows/plan.md +39 -0
  624. package/workflows/prepare-next.md +37 -0
  625. package/workflows/review.md +40 -0
  626. package/workflows/run-audit.md +41 -0
  627. package/workflows/spec-challenge.md +41 -0
  628. package/workflows/specify.md +38 -0
  629. package/workflows/verify.md +37 -0
@@ -0,0 +1,1186 @@
1
+ # Code Smells
2
+
3
+ > Code smells are surface-level indicators of deeper structural problems. They are not bugs -- the code compiles, the tests pass -- but they signal design weaknesses that compound over time, slow development, and breed defects. Martin Fowler and Kent Beck cataloged them in *Refactoring* (1999); the list here extends and modernizes that catalog with real-world incidents.
4
+
5
+ > **Domain:** Code
6
+ > **Anti-patterns covered:** 20
7
+ > **Highest severity:** Critical
8
+
9
+ ## Anti-Patterns
10
+
11
+ ### AP-01: God Class / God Object
12
+
13
+ **Also known as:** Blob, Monster Class, Kitchen Sink
14
+ **Frequency:** Very Common
15
+ **Severity:** Critical
16
+ **Detection difficulty:** Easy
17
+
18
+ **What it looks like:**
19
+
20
+ A single class that centralizes most of the application logic, accumulating hundreds of methods and dozens of fields across unrelated responsibilities.
21
+
22
+ ```java
23
+ class ApplicationManager {
24
+ // 143 methods, 31 attributes
25
+ void handleLogin() { ... }
26
+ void calculateTax() { ... }
27
+ void sendEmail() { ... }
28
+ void renderDashboard() { ... }
29
+ void processPayment() { ... }
30
+ void generateReport() { ... }
31
+ // ... 137 more methods
32
+ }
33
+ ```
34
+
35
+ **Why developers do it:**
36
+
37
+ Sprint pressure and approaching deadlines cause developers to pack new functionality into whatever class is already "doing things." The god class grows incrementally -- no single commit looks unreasonable, but the cumulative result is catastrophic.
38
+
39
+ **What goes wrong:**
40
+
41
+ The jEdit text editor's `JEdit` class grew to 143 methods and 31 attributes accessing 28 attributes from 13 different classes, becoming nearly impossible to modify without regression. In any god class, a change to one responsibility (e.g., email formatting) can silently break unrelated functionality (e.g., tax calculation) because they share mutable state. Merge conflicts become constant as every developer touches the same file.
42
+
43
+ **The fix:**
44
+
45
+ Extract classes by responsibility using the Single Responsibility Principle.
46
+
47
+ ```java
48
+ // Before: one god class
49
+ class ApplicationManager { /* everything */ }
50
+
51
+ // After: cohesive, focused classes
52
+ class AuthenticationService { void handleLogin() { ... } }
53
+ class TaxCalculator { BigDecimal calculateTax(Order o) { ... } }
54
+ class EmailService { void sendEmail(Message m) { ... } }
55
+ class DashboardRenderer { void render(DashboardModel m) { ... } }
56
+ ```
57
+
58
+ **Detection rule:**
59
+
60
+ Flag classes with more than 20 public methods OR more than 10 fields OR more than 500 lines of code.
61
+
62
+ ---
63
+
64
+ ### AP-02: Copy-Paste Programming
65
+
66
+ **Also known as:** Duplicated Code, Clone-and-Own, Shotgun Cloning
67
+ **Frequency:** Very Common
68
+ **Severity:** Critical
69
+ **Detection difficulty:** Moderate
70
+
71
+ **What it looks like:**
72
+
73
+ Identical or near-identical blocks of code appear in multiple locations. When a bug is fixed in one copy, the other copies remain broken.
74
+
75
+ ```python
76
+ # File: billing.py
77
+ def calculate_total(items):
78
+ total = 0
79
+ for item in items:
80
+ total += item.price * item.quantity
81
+ if item.taxable:
82
+ total += item.price * item.quantity * 0.08
83
+ return total
84
+
85
+ # File: reporting.py (copy-pasted, same logic)
86
+ def get_order_total(items):
87
+ total = 0
88
+ for item in items:
89
+ total += item.price * item.quantity
90
+ if item.taxable:
91
+ total += item.price * item.quantity * 0.08 # tax rate hardcoded
92
+ return total
93
+ ```
94
+
95
+ **Why developers do it:**
96
+
97
+ It feels faster to copy working code than to extract and parameterize a shared function. Developers fear breaking the original by refactoring it.
98
+
99
+ **What goes wrong:**
100
+
101
+ Apple's "goto fail" SSL vulnerability (CVE-2014-1266) is the canonical example. Code was copied from `SSLDecodeSignedServerKeyExchange` to `SSLVerifySignedServerKeyExchange`, and during the copy a duplicate `goto fail;` line was introduced. This single duplicated line meant SSL/TLS certificate verification was silently skipped on every connection in iOS 6.x/7.x and OS X 10.9.x, exposing millions of devices to man-in-the-middle attacks. The fix was deleting one line of code. Research by Li et al. (CP-Miner) found that 20-28% of code in certain Linux kernel modules was copy-pasted, with bugs routinely propagating through clones. When a vulnerability exists in duplicated code, fixing one copy leaves the others exploitable -- a pattern documented in OpenSSL and multiple e-commerce platforms.
102
+
103
+ **The fix:**
104
+
105
+ Extract shared logic into a single function. Use parameterization for variations.
106
+
107
+ ```python
108
+ # Shared module
109
+ def calculate_total(items, tax_rate=0.08):
110
+ total = 0
111
+ for item in items:
112
+ subtotal = item.price * item.quantity
113
+ total += subtotal
114
+ if item.taxable:
115
+ total += subtotal * tax_rate
116
+ return total
117
+ ```
118
+
119
+ **Detection rule:**
120
+
121
+ Flag code blocks of 6+ lines that are identical or differ only in variable names. Tools: PMD CPD, jscpd, SonarQube duplication detection.
122
+
123
+ ---
124
+
125
+ ### AP-03: Primitive Obsession
126
+
127
+ **Also known as:** Stringly Typed, Weakly Modeled Domain
128
+ **Frequency:** Very Common
129
+ **Severity:** Critical
130
+ **Detection difficulty:** Hard
131
+
132
+ **What it looks like:**
133
+
134
+ Using primitive types (int, string, double) to represent domain concepts that deserve their own types, losing all semantic safety.
135
+
136
+ ```java
137
+ // Dangerous: both are just doubles
138
+ double thrustNewtons = computeThrust();
139
+ double thrustPoundForce = sensor.readThrust();
140
+
141
+ // Nothing prevents mixing them
142
+ double totalThrust = thrustNewtons + thrustPoundForce; // unit mismatch!
143
+ ```
144
+
145
+ **Why developers do it:**
146
+
147
+ Creating wrapper types feels like overengineering. Primitives are easy, familiar, and require no extra classes. The type mismatch risk feels theoretical -- until it is not.
148
+
149
+ **What goes wrong:**
150
+
151
+ The Mars Climate Orbiter ($327.6 million) was destroyed on September 23, 1999, because Lockheed Martin's ground software produced thrust values in pound-force seconds while NASA's navigation software expected Newton seconds. Both systems used raw `double` values with no type-level unit distinction. A typed wrapper (e.g., `Force<Newtons>` vs. `Force<PoundForce>`) would have caught the mismatch at compile time. The Ariane 5 explosion (1996, ~$370 million) had a related cause: a 64-bit floating-point value representing horizontal velocity was converted to a 16-bit signed integer without bounds checking. The value exceeded 32,767, causing an overflow that crashed the inertial reference system 40 seconds after launch.
152
+
153
+ **The fix:**
154
+
155
+ Introduce value objects or wrapper types for domain concepts.
156
+
157
+ ```java
158
+ // After: units are enforced by the type system
159
+ record Newtons(double value) {}
160
+ record PoundForce(double value) {}
161
+
162
+ Newtons toNewtons(PoundForce pf) {
163
+ return new Newtons(pf.value() * 4.44822);
164
+ }
165
+
166
+ // Compiler rejects: addThrust(Newtons, PoundForce) -- type mismatch
167
+ ```
168
+
169
+ **Detection rule:**
170
+
171
+ Flag methods with more than 2 parameters of the same primitive type. Flag `String` parameters named `*id`, `*code`, `*type`, `*status`, `*currency`.
172
+
173
+ ---
174
+
175
+ ### AP-04: Long Method / Long Function
176
+
177
+ **Also known as:** Mega-Function, Do-Everything Method
178
+ **Frequency:** Very Common
179
+ **Severity:** High
180
+ **Detection difficulty:** Easy
181
+
182
+ **What it looks like:**
183
+
184
+ A single function that spans hundreds of lines, mixing multiple levels of abstraction and responsibilities.
185
+
186
+ ```python
187
+ def process_order(order):
188
+ # Validate (lines 1-45)
189
+ # Apply discounts (lines 46-90)
190
+ # Calculate tax (lines 91-130)
191
+ # Check inventory (lines 131-180)
192
+ # Process payment (lines 181-240)
193
+ # Send confirmation email (lines 241-290)
194
+ # Update analytics (lines 291-340)
195
+ # ... total: 340 lines
196
+ ```
197
+
198
+ **Why developers do it:**
199
+
200
+ Adding a few lines to an existing function is the path of least resistance. Extracting methods feels like unnecessary ceremony, especially under deadline pressure.
201
+
202
+ **What goes wrong:**
203
+
204
+ Long methods are the primary driver of high cyclomatic complexity. Research by SonarSource shows that functions exceeding cognitive complexity thresholds are disproportionately associated with bug-introducing commits. Each additional responsibility interleaved in a long method multiplies the number of states a developer must hold in working memory. In practice, developers modifying a 300-line function routinely introduce bugs in logic paths they did not intend to touch, because they cannot see all the interacting state.
205
+
206
+ **The fix:**
207
+
208
+ Extract method by responsibility. Each extracted method should operate at one level of abstraction.
209
+
210
+ ```python
211
+ def process_order(order):
212
+ validated = validate_order(order)
213
+ discounted = apply_discounts(validated)
214
+ taxed = calculate_tax(discounted)
215
+ check_inventory(taxed)
216
+ charge = process_payment(taxed)
217
+ send_confirmation(order, charge)
218
+ update_analytics(order)
219
+ ```
220
+
221
+ **Detection rule:**
222
+
223
+ Flag functions exceeding 30 lines of logic (excluding blank lines and comments). Flag cyclomatic complexity > 10.
224
+
225
+ ---
226
+
227
+ ### AP-05: Deep Nesting / Arrow Code
228
+
229
+ **Also known as:** Pyramid of Doom, Arrowhead Anti-Pattern, Callback Hell
230
+ **Frequency:** Very Common
231
+ **Severity:** High
232
+ **Detection difficulty:** Easy
233
+
234
+ **What it looks like:**
235
+
236
+ Control flow nested 4+ levels deep, forming an arrow shape when the code is viewed sideways.
237
+
238
+ ```javascript
239
+ function processRequest(req) {
240
+ if (req) {
241
+ if (req.user) {
242
+ if (req.user.isActive) {
243
+ if (req.body) {
244
+ if (req.body.items) {
245
+ if (req.body.items.length > 0) {
246
+ // actual logic buried here
247
+ }
248
+ }
249
+ }
250
+ }
251
+ }
252
+ }
253
+ }
254
+ ```
255
+
256
+ **Why developers do it:**
257
+
258
+ Each additional condition feels like a small, reasonable guard. The nesting accumulates one `if` at a time across multiple commits.
259
+
260
+ **What goes wrong:**
261
+
262
+ Code beyond 3 levels of nesting has high cognitive complexity, forcing developers to track multiple conditions simultaneously. Research from TU Delft shows this directly correlates with increased bug density. Bugs hide in obscure branches because reviewers cannot hold all the conditional paths in working memory. In async code (Node.js callbacks, nested promises), this pattern creates "callback hell" where error handling paths become untraceable.
263
+
264
+ **The fix:**
265
+
266
+ Use early returns (guard clauses) to flatten the nesting.
267
+
268
+ ```javascript
269
+ function processRequest(req) {
270
+ if (!req?.user?.isActive) return;
271
+ if (!req.body?.items?.length) return;
272
+
273
+ // actual logic at top level
274
+ processItems(req.body.items);
275
+ }
276
+ ```
277
+
278
+ **Detection rule:**
279
+
280
+ Flag any code block nested more than 3 levels deep. Flag cognitive complexity > 15 per function.
281
+
282
+ ---
283
+
284
+ ### AP-06: Feature Envy
285
+
286
+ **Also known as:** Misplaced Method, Data Jealousy
287
+ **Frequency:** Common
288
+ **Severity:** High
289
+ **Detection difficulty:** Moderate
290
+
291
+ **What it looks like:**
292
+
293
+ A method that uses more data and methods from another class than from its own.
294
+
295
+ ```java
296
+ class OrderPrinter {
297
+ String formatOrder(Order order) {
298
+ return order.getCustomer().getName() + "\n"
299
+ + order.getCustomer().getAddress().getStreet() + "\n"
300
+ + order.getCustomer().getAddress().getCity() + ", "
301
+ + order.getCustomer().getAddress().getState() + " "
302
+ + order.getCustomer().getAddress().getZip() + "\n"
303
+ + "Total: $" + order.getTotal();
304
+ }
305
+ }
306
+ ```
307
+
308
+ **Why developers do it:**
309
+
310
+ The developer has the data available through getters and builds logic where they happen to be working, rather than putting the method where the data lives.
311
+
312
+ **What goes wrong:**
313
+
314
+ Feature envy binds classes together tightly. When `Customer` or `Address` changes its internal representation, `OrderPrinter` breaks -- even though `OrderPrinter` has no business knowing the internal structure of addresses. This coupling is a leading cause of shotgun surgery (AP-10). Research shows feature-envious methods are involved in bug-introducing commits at a significantly higher rate than well-placed methods, because changes to the envied class propagate unpredictably.
315
+
316
+ **The fix:**
317
+
318
+ Move the method to the class whose data it uses.
319
+
320
+ ```java
321
+ class Customer {
322
+ String formatAddress() {
323
+ return name + "\n" + address.format();
324
+ }
325
+ }
326
+
327
+ class Address {
328
+ String format() {
329
+ return street + "\n" + city + ", " + state + " " + zip;
330
+ }
331
+ }
332
+ ```
333
+
334
+ **Detection rule:**
335
+
336
+ Flag methods where more than 50% of accessed fields/methods belong to a different class. Tools: IntelliJ IDEA structural search, JDeodorant.
337
+
338
+ ---
339
+
340
+ ### AP-07: Data Clumps
341
+
342
+ **Also known as:** Parameter Clusters, Traveling Data
343
+ **Frequency:** Common
344
+ **Severity:** Medium
345
+ **Detection difficulty:** Moderate
346
+
347
+ **What it looks like:**
348
+
349
+ The same group of parameters appears together across multiple method signatures.
350
+
351
+ ```python
352
+ def create_user(first_name, last_name, street, city, state, zip_code):
353
+ ...
354
+
355
+ def update_address(user_id, street, city, state, zip_code):
356
+ ...
357
+
358
+ def validate_shipping(street, city, state, zip_code):
359
+ ...
360
+ ```
361
+
362
+ **Why developers do it:**
363
+
364
+ Each parameter is "just one more." The clump forms incrementally, and introducing a new class for a group of parameters feels heavyweight early on.
365
+
366
+ **What goes wrong:**
367
+
368
+ Data clumps force every caller to know the exact order and types of parameters. When a new field is needed (e.g., `country`), every function signature and every call site must change -- a combinatorial maintenance burden. Martin Fowler notes that data clumps are often primitive values that nobody thinks to turn into an object, leading to duplicated validation logic scattered across every function that receives the clump.
369
+
370
+ **The fix:**
371
+
372
+ Extract a parameter object.
373
+
374
+ ```python
375
+ @dataclass
376
+ class Address:
377
+ street: str
378
+ city: str
379
+ state: str
380
+ zip_code: str
381
+
382
+ def create_user(first_name: str, last_name: str, address: Address):
383
+ ...
384
+
385
+ def update_address(user_id: int, address: Address):
386
+ ...
387
+
388
+ def validate_shipping(address: Address):
389
+ ...
390
+ ```
391
+
392
+ **Detection rule:**
393
+
394
+ Flag 3+ parameters that co-occur in 3+ method signatures. Flag any method with more than 4 parameters.
395
+
396
+ ---
397
+
398
+ ### AP-08: Magic Numbers and Strings
399
+
400
+ **Also known as:** Unnamed Constants, Hard-Coded Values
401
+ **Frequency:** Very Common
402
+ **Severity:** Medium
403
+ **Detection difficulty:** Easy
404
+
405
+ **What it looks like:**
406
+
407
+ Literal values embedded directly in logic with no explanation of what they represent.
408
+
409
+ ```python
410
+ def calculate_shipping(weight):
411
+ if weight > 50:
412
+ return weight * 0.45 + 8.99
413
+ elif weight > 20:
414
+ return weight * 0.35 + 4.99
415
+ else:
416
+ return 3.99
417
+
418
+ if user.role == "ADMN": # typo? or valid code?
419
+ grant_access()
420
+ ```
421
+
422
+ **Why developers do it:**
423
+
424
+ The meaning is obvious to the person writing it. Adding named constants feels verbose when "everyone knows" what 0.45 means.
425
+
426
+ **What goes wrong:**
427
+
428
+ When the shipping rate changes, a developer must find every occurrence of `0.45` across the codebase -- and distinguish it from other uses of `0.45` (tax rate? discount factor?). The string `"ADMN"` is a typo waiting to happen with no compiler protection. In the Ariane 5 failure, hardcoded assumptions about maximum horizontal velocity values (appropriate for Ariane 4 but not Ariane 5) were embedded directly in the inertial reference system code rather than being parameterized, contributing to the overflow that destroyed the rocket.
429
+
430
+ **The fix:**
431
+
432
+ Extract named constants. Use enums for categorical values.
433
+
434
+ ```python
435
+ HEAVY_WEIGHT_THRESHOLD = 50
436
+ MEDIUM_WEIGHT_THRESHOLD = 20
437
+ HEAVY_RATE_PER_KG = 0.45
438
+ HEAVY_BASE_FEE = 8.99
439
+ MEDIUM_RATE_PER_KG = 0.35
440
+ MEDIUM_BASE_FEE = 4.99
441
+ LIGHT_FLAT_FEE = 3.99
442
+
443
+ class Role(Enum):
444
+ ADMIN = "ADMIN"
445
+ USER = "USER"
446
+ ```
447
+
448
+ **Detection rule:**
449
+
450
+ Flag numeric literals other than 0, 1, -1 in logic code (not declarations). Flag string comparisons used for branching.
451
+
452
+ ---
453
+
454
+ ### AP-09: Dead Code
455
+
456
+ **Also known as:** Zombie Code, Unreachable Code, Vestigial Code
457
+ **Frequency:** Common
458
+ **Severity:** Critical
459
+ **Detection difficulty:** Moderate
460
+
461
+ **What it looks like:**
462
+
463
+ Code that is never executed: unreachable branches, unused functions, commented-out blocks, obsolete feature flags.
464
+
465
+ ```java
466
+ // Deprecated in 2003, never removed
467
+ void executePowerPeg(Order order) {
468
+ // Legacy market-making algorithm
469
+ while (order.isOpen()) {
470
+ placeAggressiveTrade(order);
471
+ }
472
+ }
473
+ ```
474
+
475
+ **Why developers do it:**
476
+
477
+ "We might need it later." Deleting code feels risky. Commented-out code serves as a "backup." Feature flags are left in place long after the feature ships.
478
+
479
+ **What goes wrong:**
480
+
481
+ Knight Capital Group, August 1, 2012: During deployment of a new trading system (RLP), only 7 of 8 servers received the update. The 8th server still contained dormant "Power Peg" code from 2003 that was never fully removed. A reused configuration flag accidentally reactivated Power Peg, which began executing an obsolete aggressive market-making strategy. In 45 minutes, the algorithm acquired $7.65 billion in unwanted positions across 154 stocks, resulting in a $440 million loss. Knight Capital's stock dropped 75%, and the company was forced to sell itself. The root cause was dead code that should have been deleted a decade earlier.
482
+
483
+ **The fix:**
484
+
485
+ Delete dead code. Version control is your backup. Remove obsolete feature flags. Use time-bounded feature flags with automatic expiration.
486
+
487
+ ```java
488
+ // Before: dead code left in place "just in case"
489
+ // void executePowerPeg(Order order) { ... }
490
+
491
+ // After: deleted entirely.
492
+ // If needed, recover from git history: git log --all -p -- PowerPeg.java
493
+ ```
494
+
495
+ **Detection rule:**
496
+
497
+ Flag functions with zero callers. Flag commented-out code blocks > 3 lines. Flag feature flags older than 90 days. Tools: IntelliJ "unused declaration," ESLint no-unreachable, SonarQube dead code detection.
498
+
499
+ ---
500
+
501
+ ### AP-10: Shotgun Surgery
502
+
503
+ **Also known as:** Scattered Change, Ripple Effect
504
+ **Frequency:** Common
505
+ **Severity:** High
506
+ **Detection difficulty:** Hard
507
+
508
+ **What it looks like:**
509
+
510
+ A single logical change requires modifications across many files and classes.
511
+
512
+ ```
513
+ Adding a new "currency" field requires changes in:
514
+ - UserModel.java (add field)
515
+ - UserDTO.java (add field)
516
+ - UserMapper.java (add mapping)
517
+ - UserValidator.java (add validation)
518
+ - UserRepository.java (update query)
519
+ - UserController.java (add parameter)
520
+ - UserService.java (pass through)
521
+ - user-form.html (add input)
522
+ - user-api.yaml (update spec)
523
+ - UserTest.java (update fixtures)
524
+ ```
525
+
526
+ **Why developers do it:**
527
+
528
+ It emerges from poorly factored abstractions, often due to copy-paste (AP-02) or feature envy (AP-06). Each individual class looks reasonable in isolation; the problem is only visible when making a cross-cutting change.
529
+
530
+ **What goes wrong:**
531
+
532
+ Shotgun surgery is the inverse of divergent change (AP-11). Every change becomes a multi-file commit with high risk of missing one location. Wikipedia notes that due to commercial pressure, developers often resort to copy-paste rather than refactoring, which compounds the shotgun surgery pattern. Missing one file in the change set produces silent bugs -- the system compiles, tests may pass, but one code path uses stale logic.
533
+
534
+ **The fix:**
535
+
536
+ Consolidate related logic using Move Method and Move Field. If multiple classes change together for every feature, they likely belong in one module.
537
+
538
+ ```java
539
+ // Before: currency scattered across 10 files
540
+ // After: currency encapsulated in a Money value object
541
+ record Money(BigDecimal amount, Currency currency) {
542
+ // All currency logic in one place
543
+ Money convertTo(Currency target, ExchangeRate rate) { ... }
544
+ String format() { ... }
545
+ }
546
+ ```
547
+
548
+ **Detection rule:**
549
+
550
+ Flag commits that modify more than 5 files for a single logical change. Track co-change frequency in version history. Tools: CodeScene temporal coupling analysis.
551
+
552
+ ---
553
+
554
+ ### AP-11: Divergent Change
555
+
556
+ **Also known as:** Swiss Army Class, Multiple Reasons to Change
557
+ **Frequency:** Common
558
+ **Severity:** High
559
+ **Detection difficulty:** Moderate
560
+
561
+ **What it looks like:**
562
+
563
+ A single class is modified for many different, unrelated reasons. This is the sibling of shotgun surgery, but in the opposite direction: instead of one change touching many classes, many different changes touch one class.
564
+
565
+ ```python
566
+ class ReportGenerator:
567
+ def generate_pdf(self, data): ... # changed for PDF library updates
568
+ def fetch_from_database(self, q): ... # changed for schema migrations
569
+ def apply_business_rules(self, d): ... # changed for policy updates
570
+ def send_email(self, report): ... # changed for email provider switches
571
+ ```
572
+
573
+ **Why developers do it:**
574
+
575
+ The class started with one responsibility and accumulated others because "it already has the data" or "it's the natural place." Each addition seemed small.
576
+
577
+ **What goes wrong:**
578
+
579
+ Every team member working on a different concern (PDF rendering, database, email) must modify the same file, causing constant merge conflicts and increasing the risk that a database schema change accidentally breaks email sending. This is the god class (AP-01) in its early growth phase.
580
+
581
+ **The fix:**
582
+
583
+ Extract classes by axis of change.
584
+
585
+ ```python
586
+ class DataFetcher:
587
+ def fetch(self, query): ...
588
+
589
+ class BusinessRuleEngine:
590
+ def apply(self, data): ...
591
+
592
+ class PdfRenderer:
593
+ def render(self, report): ...
594
+
595
+ class ReportEmailer:
596
+ def send(self, report): ...
597
+ ```
598
+
599
+ **Detection rule:**
600
+
601
+ Flag classes modified in more than 5 unrelated pull requests within 30 days. Track distinct commit message topics per file.
602
+
603
+ ---
604
+
605
+ ### AP-12: Speculative Generality
606
+
607
+ **Also known as:** YAGNI Violation, Premature Abstraction, Crystal Ball Coding
608
+ **Frequency:** Common
609
+ **Severity:** Medium
610
+ **Detection difficulty:** Moderate
611
+
612
+ **What it looks like:**
613
+
614
+ Abstractions, interfaces, and extension points built for hypothetical future requirements that never materialize.
615
+
616
+ ```java
617
+ // Interface with exactly one implementation
618
+ interface DataProcessor<T extends Serializable & Comparable<T>> {
619
+ ProcessResult<T> process(ProcessContext<T> ctx, ProcessOptions opts);
620
+ }
621
+
622
+ // Abstract factory for the one processor that exists
623
+ abstract class DataProcessorFactory<T extends Serializable & Comparable<T>> {
624
+ abstract DataProcessor<T> create(FactoryConfig config);
625
+ }
626
+
627
+ // The only concrete implementation
628
+ class CsvDataProcessor implements DataProcessor<String> {
629
+ // ... the actual logic
630
+ }
631
+ ```
632
+
633
+ **Why developers do it:**
634
+
635
+ Anticipating future requirements feels like good engineering. "What if we need to support XML later?" The developer builds the abstraction now to avoid refactoring later.
636
+
637
+ **What goes wrong:**
638
+
639
+ The unused abstractions add cognitive overhead for every developer who reads the code. They must understand the generic type parameters, the factory pattern, and the interface -- all to find the one class that does the actual work. The YAGNI principle (You Aren't Gonna Need It) exists precisely because speculative abstractions are wrong more often than they are right, and the cost of maintaining them exceeds the cost of adding them later when actually needed. Test cases become the only users of speculative classes, which is a direct indicator of this smell.
640
+
641
+ **The fix:**
642
+
643
+ Delete unused abstractions. Add them back when (and only when) a second concrete need arises.
644
+
645
+ ```java
646
+ // Before: interface + factory + abstract class + one implementation
647
+ // After: just the implementation
648
+ class CsvDataProcessor {
649
+ ProcessResult process(List<String> records) { ... }
650
+ }
651
+ ```
652
+
653
+ **Detection rule:**
654
+
655
+ Flag interfaces with exactly one implementation. Flag abstract classes with exactly one subclass. Flag type parameters used in only one concrete type. Flag classes whose only callers are tests.
656
+
657
+ ---
658
+
659
+ ### AP-13: Boolean Blindness
660
+
661
+ **Also known as:** Boolean Trap, Flag Arguments
662
+ **Frequency:** Common
663
+ **Severity:** Medium
664
+ **Detection difficulty:** Moderate
665
+
666
+ **What it looks like:**
667
+
668
+ Boolean parameters that obscure meaning at the call site, or boolean return values that erase the semantic information they represent.
669
+
670
+ ```python
671
+ # What does True mean here?
672
+ widget.render(True, False, True)
673
+
674
+ # Does this sell alcohol to minors or prevent it?
675
+ sell_alcohol(user, lambda u: u.age >= 21) # returns bool, but what does True mean?
676
+
677
+ # Caller must remember parameter order
678
+ create_user("Alice", True, False, True)
679
+ # ^ ^ ^
680
+ # admin? active? verified?
681
+ ```
682
+
683
+ **Why developers do it:**
684
+
685
+ Booleans are the simplest type. Adding a parameter to toggle behavior feels cleaner than creating separate methods or enum types.
686
+
687
+ **What goes wrong:**
688
+
689
+ At every call site, the reader must look up the method signature to understand what `True` and `False` mean. Adam Johnson documented the "boolean trap" in Python type hints, showing how boolean parameters become a persistent source of inverted-logic bugs. When `create_user("Alice", True, False, True)` is called, swapping two adjacent booleans produces a user who is active but not admin -- a silent, type-safe bug that passes all compile-time checks.
690
+
691
+ **The fix:**
692
+
693
+ Replace booleans with enums or named types. Use keyword arguments.
694
+
695
+ ```python
696
+ class Permission(Enum):
697
+ ADMIN = "admin"
698
+ USER = "user"
699
+
700
+ class Status(Enum):
701
+ ACTIVE = "active"
702
+ INACTIVE = "inactive"
703
+
704
+ create_user("Alice", permission=Permission.ADMIN,
705
+ status=Status.ACTIVE, verified=True)
706
+
707
+ # Or separate methods
708
+ widget.render_expanded()
709
+ widget.render_collapsed()
710
+ ```
711
+
712
+ **Detection rule:**
713
+
714
+ Flag methods with more than 1 boolean parameter. Flag call sites with boolean literals. Flag `def foo(..., flag: bool)` patterns.
715
+
716
+ ---
717
+
718
+ ### AP-14: Comments as Deodorant
719
+
720
+ **Also known as:** Comment Overcompensation, Explaining Bad Code
721
+ **Frequency:** Very Common
722
+ **Severity:** Medium
723
+ **Detection difficulty:** Easy
724
+
725
+ **What it looks like:**
726
+
727
+ Long comments that explain what confusing code does, instead of rewriting the code to be self-explanatory.
728
+
729
+ ```java
730
+ // Check if the user is eligible for discount:
731
+ // The user must be active (status == 1), must have been
732
+ // a member for at least 2 years (joining date before
733
+ // 730 days ago), and must not be on the blacklist
734
+ // (blacklist flag == 0), and their order total must
735
+ // exceed $100
736
+ if (u.s == 1 && daysSince(u.j) > 730 && u.b == 0 && o.t > 100) {
737
+ applyDiscount(o);
738
+ }
739
+ ```
740
+
741
+ **Why developers do it:**
742
+
743
+ Writing a comment is faster than refactoring the code. The developer recognizes the code is unclear but addresses the symptom (readability) rather than the cause (poor naming, cryptic logic).
744
+
745
+ **What goes wrong:**
746
+
747
+ Research by Lin et al. (2024) found that code-comment inconsistencies are 1.5x more likely to be involved in bug-introducing commits than consistent changes. Comments drift from code as the code evolves. A documented Mozilla case showed an outdated comment causing a developer to build a feature on assumed behavior that no longer existed, introducing a bug in a later version. The comment above will eventually become wrong when the discount rules change, but the cryptic variable names (`u.s`, `u.j`, `u.b`) will remain opaque forever.
748
+
749
+ **The fix:**
750
+
751
+ Make the code self-documenting. Reserve comments for "why," not "what."
752
+
753
+ ```java
754
+ boolean isEligibleForDiscount =
755
+ user.isActive()
756
+ && user.membershipYears() >= 2
757
+ && !user.isBlacklisted()
758
+ && order.total() > MINIMUM_DISCOUNT_THRESHOLD;
759
+
760
+ if (isEligibleForDiscount) {
761
+ applyDiscount(order);
762
+ }
763
+ ```
764
+
765
+ **Detection rule:**
766
+
767
+ Flag comments that begin with "check if," "this code does," or "the following." Flag functions where comment lines exceed code lines. Flag single-letter variable names adjacent to explanatory comments.
768
+
769
+ ---
770
+
771
+ ### AP-15: Stringly-Typed Code
772
+
773
+ **Also known as:** String Abuse, Type Erasure by Convention
774
+ **Frequency:** Common
775
+ **Severity:** High
776
+ **Detection difficulty:** Moderate
777
+
778
+ **What it looks like:**
779
+
780
+ Using strings where enums, types, or structured data would be safer.
781
+
782
+ ```python
783
+ def move_robot(x: str, y: str, direction: str):
784
+ if direction == "up":
785
+ ...
786
+ elif direction == "dwon": # typo: undetected
787
+ ...
788
+
789
+ def process_event(event_type: str, payload: str):
790
+ if event_type == "user.created":
791
+ data = json.loads(payload)
792
+ ...
793
+ ```
794
+
795
+ **Why developers do it:**
796
+
797
+ Strings are universal. They work across serialization boundaries, require no type definitions, and are quick to add. "Just pass a string" is the fastest path to a working prototype.
798
+
799
+ **What goes wrong:**
800
+
801
+ Scott Hanselman coined "stringly typed" to contrast with "strongly typed." String-based dispatch has no compiler support: typos like `"dwon"` instead of `"down"` are valid strings that silently take the wrong branch. Every consumer must independently know and correctly spell the valid values. Refactoring is impossible without full-text search. In a Hacker News discussion (2024), developers documented production incidents where stringly-typed event systems silently dropped events because the string constants drifted between producer and consumer codebases.
802
+
803
+ **The fix:**
804
+
805
+ Replace strings with enums or algebraic types.
806
+
807
+ ```python
808
+ class Direction(Enum):
809
+ UP = "up"
810
+ DOWN = "down"
811
+ LEFT = "left"
812
+ RIGHT = "right"
813
+
814
+ def move_robot(x: int, y: int, direction: Direction):
815
+ match direction:
816
+ case Direction.UP: ...
817
+ case Direction.DOWN: ...
818
+ # compiler warns about unhandled cases
819
+ ```
820
+
821
+ **Detection rule:**
822
+
823
+ Flag `if x == "literal_string"` chains with 3+ branches. Flag method parameters of type `String` named `*type`, `*status`, `*mode`, `*action`, `*event`.
824
+
825
+ ---
826
+
827
+ ### AP-16: Message Chains / Train Wrecks
828
+
829
+ **Also known as:** Law of Demeter Violation, Dot-Dot-Dot
830
+ **Frequency:** Common
831
+ **Severity:** Medium
832
+ **Detection difficulty:** Easy
833
+
834
+ **What it looks like:**
835
+
836
+ A chain of method calls traversing an object graph: `a.getB().getC().getD().doSomething()`.
837
+
838
+ ```java
839
+ String cityName = order
840
+ .getCustomer()
841
+ .getAddress()
842
+ .getCity()
843
+ .getName()
844
+ .toUpperCase();
845
+ ```
846
+
847
+ **Why developers do it:**
848
+
849
+ The data is "right there," reachable by traversing the object graph. Creating intermediary methods feels like unnecessary indirection.
850
+
851
+ **What goes wrong:**
852
+
853
+ The calling code is now coupled to the entire chain structure. If `Address` is refactored to split `city` into `city` and `region`, every chain that traverses through `getCity()` breaks -- even code in modules that have no business knowing about address internals. Null/undefined at any link in the chain causes a NullPointerException at a location that reveals the entire internal structure to the error log. The code is also extremely difficult to mock in tests, as documented in industrial testing literature on "mock trainwrecks."
854
+
855
+ **The fix:**
856
+
857
+ Apply the Law of Demeter: "talk only to your immediate friends." Use delegation methods.
858
+
859
+ ```java
860
+ // Order delegates to Customer, which delegates to Address
861
+ class Order {
862
+ String getShippingCity() {
863
+ return customer.getShippingCity();
864
+ }
865
+ }
866
+
867
+ class Customer {
868
+ String getShippingCity() {
869
+ return address.getCityName();
870
+ }
871
+ }
872
+
873
+ // Caller
874
+ String city = order.getShippingCity();
875
+ ```
876
+
877
+ **Detection rule:**
878
+
879
+ Flag chains of 3+ method calls on return values (excluding builders and fluent APIs). Tools: PMD `LawOfDemeter` rule.
880
+
881
+ ---
882
+
883
+ ### AP-17: Middle Man
884
+
885
+ **Also known as:** Thin Wrapper, Pass-Through Class, Bureaucrat
886
+ **Frequency:** Occasional
887
+ **Severity:** Medium
888
+ **Detection difficulty:** Moderate
889
+
890
+ **What it looks like:**
891
+
892
+ A class that delegates almost all its work to another class, adding no logic of its own.
893
+
894
+ ```java
895
+ class CustomerService {
896
+ private CustomerRepository repo;
897
+
898
+ Customer find(int id) { return repo.find(id); }
899
+ void save(Customer c) { repo.save(c); }
900
+ void delete(int id) { repo.delete(id); }
901
+ List<Customer> findAll() { return repo.findAll(); }
902
+ // Every method is a one-line delegation
903
+ }
904
+ ```
905
+
906
+ **Why developers do it:**
907
+
908
+ Architectural patterns (service layers, facades) encourage indirection. Developers create a "service" class because the pattern says to, even when there is no business logic to put there yet.
909
+
910
+ **What goes wrong:**
911
+
912
+ Every new repository method requires a corresponding pass-through in the service, doubling the maintenance surface. The middle man obscures the actual dependency, making navigation harder during debugging. When combined with speculative generality (AP-12), the codebase accumulates layers of empty indirection.
913
+
914
+ **The fix:**
915
+
916
+ If the class adds no logic, remove it and let callers use the delegate directly. If business logic will be added later, add the class when the logic arrives.
917
+
918
+ ```java
919
+ // Before: callers -> CustomerService -> CustomerRepository
920
+ // After: callers -> CustomerRepository (until business logic is needed)
921
+
922
+ // When business logic appears, THEN introduce the service:
923
+ class CustomerService {
924
+ private CustomerRepository repo;
925
+
926
+ Customer findOrThrow(int id) {
927
+ return repo.find(id)
928
+ .orElseThrow(() -> new CustomerNotFoundException(id));
929
+ }
930
+ // Now the class earns its existence
931
+ }
932
+ ```
933
+
934
+ **Detection rule:**
935
+
936
+ Flag classes where >80% of public methods are single-line delegations to the same field.
937
+
938
+ ---
939
+
940
+ ### AP-18: Refused Bequest
941
+
942
+ **Also known as:** Inheritance Misuse, Broken Liskov, Fake-Is-A
943
+ **Frequency:** Occasional
944
+ **Severity:** High
945
+ **Detection difficulty:** Moderate
946
+
947
+ **What it looks like:**
948
+
949
+ A subclass inherits from a parent but ignores, overrides with no-ops, or throws exceptions for inherited methods.
950
+
951
+ ```python
952
+ class Bird:
953
+ def fly(self):
954
+ return "flying"
955
+
956
+ def eat(self):
957
+ return "eating"
958
+
959
+ class Penguin(Bird):
960
+ def fly(self):
961
+ raise NotImplementedError("Penguins can't fly") # refused bequest
962
+ ```
963
+
964
+ **Why developers do it:**
965
+
966
+ The subclass needs some of the parent's functionality, and inheritance seems quicker than composition. "A penguin *is* a bird" feels logically correct, even though the behavioral contract breaks.
967
+
968
+ **What goes wrong:**
969
+
970
+ This violates the Liskov Substitution Principle: code that accepts `Bird` and calls `fly()` will crash on `Penguin`. The Java `Stack` class inheriting from `Vector` is a classic real-world refused bequest -- `Stack` inherits methods like `insertElementAt(index)` that violate stack semantics (you should not be able to insert in the middle of a stack). Clients using `Stack` as a `Vector` bypass LIFO ordering with no compiler warning.
971
+
972
+ **The fix:**
973
+
974
+ Replace inheritance with composition (delegation).
975
+
976
+ ```python
977
+ class Bird:
978
+ def eat(self):
979
+ return "eating"
980
+
981
+ class FlyingBird(Bird):
982
+ def fly(self):
983
+ return "flying"
984
+
985
+ class Penguin(Bird):
986
+ # No fly() method -- does not promise what it cannot deliver
987
+ def swim(self):
988
+ return "swimming"
989
+ ```
990
+
991
+ **Detection rule:**
992
+
993
+ Flag subclass methods that throw `NotImplementedError`, `UnsupportedOperationException`, or return `null`/no-op for inherited methods. Flag subclasses that override >50% of parent methods.
994
+
995
+ ---
996
+
997
+ ### AP-19: Data Class
998
+
999
+ **Also known as:** Anemic Domain Model, Dumb Container, Struct Syndrome
1000
+ **Frequency:** Common
1001
+ **Severity:** Medium
1002
+ **Detection difficulty:** Easy
1003
+
1004
+ **What it looks like:**
1005
+
1006
+ A class that contains only fields and getters/setters, with all behavior living in other classes.
1007
+
1008
+ ```java
1009
+ class Customer {
1010
+ private String name;
1011
+ private String email;
1012
+ private List<Order> orders;
1013
+ // 15 getters and setters, zero behavior
1014
+ }
1015
+
1016
+ class CustomerService {
1017
+ boolean isVip(Customer c) {
1018
+ return c.getOrders().stream()
1019
+ .mapToDouble(Order::getTotal)
1020
+ .sum() > 10000;
1021
+ }
1022
+
1023
+ String formatDisplayName(Customer c) {
1024
+ return c.getName() + " (" + c.getEmail() + ")";
1025
+ }
1026
+ }
1027
+ ```
1028
+
1029
+ **Why developers do it:**
1030
+
1031
+ Many frameworks (JPA, Hibernate, serialization libraries) encourage POJOs with getters/setters. MVC patterns place all logic in services. The "data class" feels clean and simple.
1032
+
1033
+ **What goes wrong:**
1034
+
1035
+ Martin Fowler calls this the "Anemic Domain Model" anti-pattern. Business logic that belongs with the data scatters across service classes, causing feature envy (AP-06) and shotgun surgery (AP-10). The data class exposes its internals, making it impossible to enforce invariants. Any service can set invalid state because the data class has no self-defense.
1036
+
1037
+ **The fix:**
1038
+
1039
+ Move behavior to the data class. Encapsulate invariants.
1040
+
1041
+ ```java
1042
+ class Customer {
1043
+ private String name;
1044
+ private String email;
1045
+ private List<Order> orders;
1046
+
1047
+ boolean isVip() {
1048
+ return orders.stream()
1049
+ .mapToDouble(Order::getTotal)
1050
+ .sum() > VIP_THRESHOLD;
1051
+ }
1052
+
1053
+ String displayName() {
1054
+ return name + " (" + email + ")";
1055
+ }
1056
+
1057
+ void addOrder(Order order) {
1058
+ Objects.requireNonNull(order);
1059
+ this.orders.add(order);
1060
+ }
1061
+ }
1062
+ ```
1063
+
1064
+ **Detection rule:**
1065
+
1066
+ Flag classes where public methods are exclusively getters/setters. Flag classes with >5 fields and zero non-accessor methods.
1067
+
1068
+ ---
1069
+
1070
+ ### AP-20: Misleading / Outdated Comments
1071
+
1072
+ **Also known as:** Comment Rot, Lying Documentation, Stale Comments
1073
+ **Frequency:** Very Common
1074
+ **Severity:** High
1075
+ **Detection difficulty:** Very Hard
1076
+
1077
+ **What it looks like:**
1078
+
1079
+ Comments that describe behavior the code no longer exhibits, creating a trap for future developers.
1080
+
1081
+ ```python
1082
+ def calculate_tax(amount):
1083
+ """Calculates tax at 7% rate for domestic orders."""
1084
+ # Updated to 8.5% per 2024 regulation
1085
+ # Actually updated again to 9% for 2025
1086
+ return amount * 0.085 # Neither comment matches the code
1087
+ ```
1088
+
1089
+ **Why developers do it:**
1090
+
1091
+ Developers update code but forget to update comments. Comment maintenance has no enforcement mechanism. Code reviews focus on logic, not comment accuracy.
1092
+
1093
+ **What goes wrong:**
1094
+
1095
+ Research by Lin et al. (2024, arXiv:2409.10781) found that code-comment inconsistencies are approximately 1.5x more likely to appear in bug-introducing commits. A documented Mozilla incident showed that an outdated comment persisted across versions, leading a developer to build new functionality based on the documented (but no longer actual) behavior, resulting in a reported bug. In one case study, a developer trusting an outdated comment about pricing logic built a feature that relied on the documented behavior, producing a pricing bug that cost thousands of dollars before detection.
1096
+
1097
+ **The fix:**
1098
+
1099
+ Delete comments that describe "what." Keep comments that describe "why" (design decisions, regulatory constraints, non-obvious tradeoffs). Treat comment accuracy as a code review checklist item.
1100
+
1101
+ ```python
1102
+ def calculate_tax(amount):
1103
+ """Apply current tax rate per regulation XYZ-2025."""
1104
+ return amount * CURRENT_TAX_RATE # rate defined in config
1105
+ ```
1106
+
1107
+ **Detection rule:**
1108
+
1109
+ Flag TODO/FIXME comments older than 90 days. Flag functions where the docstring mentions different constants than the code uses. Automated: compare function names/docstrings against actual behavior using LLM-based analysis.
1110
+
1111
+ ---
1112
+
1113
+ ## Root Cause Analysis
1114
+
1115
+ | Root Cause | Contributing Smells | Systemic Fix |
1116
+ |---|---|---|
1117
+ | **Time pressure / sprint deadlines** | God Class, Long Method, Copy-Paste, Deep Nesting | Allocate refactoring budget per sprint (15-20% of velocity) |
1118
+ | **Missing domain modeling** | Primitive Obsession, Data Clumps, Stringly Typed, Magic Numbers | Domain-Driven Design workshops; value object patterns |
1119
+ | **Path of least resistance** | Feature Envy, Divergent Change, Dead Code | Architectural fitness functions; automated smell detection in CI |
1120
+ | **Fear of deletion** | Dead Code, Speculative Generality, Comments as Deodorant | Git history as backup; feature flag TTL enforcement |
1121
+ | **Framework-driven design** | Data Class, Middle Man, Shotgun Surgery | Challenge framework defaults; add behavior to domain objects |
1122
+ | **Misapplied patterns** | Speculative Generality, Middle Man, Refused Bequest | "Three strikes" rule before abstracting; favor composition |
1123
+ | **Inadequate code review** | Copy-Paste, Misleading Comments, Boolean Blindness | Smell-specific review checklists; automated reviewers (SonarQube, CodeClimate) |
1124
+ | **Solo development / knowledge silos** | God Class, Long Method, Magic Numbers | Pair programming; mob programming; mandatory review |
1125
+ | **Weak type system usage** | Primitive Obsession, Stringly Typed, Boolean Blindness | Strict compiler settings; custom lint rules for domain types |
1126
+ | **Incremental accumulation** | All smells | Track code health metrics over time; set quality gates |
1127
+
1128
+ ## Self-Check Questions
1129
+
1130
+ 1. **God Class:** Does any class in the codebase have more than 20 public methods or more than 500 lines? Can you describe its responsibility in a single sentence without using "and"?
1131
+
1132
+ 2. **Copy-Paste:** If you fix a bug in this function, is there an identical block somewhere else that also needs the fix? Search for a distinctive line from the function -- do you get multiple hits?
1133
+
1134
+ 3. **Primitive Obsession:** Are you passing raw `int`, `double`, or `String` values that represent domain concepts (money, distance, user IDs, status codes)? Could two values of the same primitive type be accidentally swapped?
1135
+
1136
+ 4. **Long Method:** Can you read and understand this function without scrolling? Does it operate at a single level of abstraction, or does it mix HTTP parsing with business logic with database calls?
1137
+
1138
+ 5. **Deep Nesting:** Is any code block nested more than 3 levels deep? Can you explain the conditions required to reach the innermost block without re-reading the function?
1139
+
1140
+ 6. **Feature Envy:** Does this method access more fields from another class than from its own? Would it be simpler if it lived in the other class?
1141
+
1142
+ 7. **Dead Code:** Are there functions with zero callers? Commented-out code blocks? Feature flags that shipped months ago and were never cleaned up?
1143
+
1144
+ 8. **Shotgun Surgery:** When you add a new field to a domain object, how many files do you need to touch? Is the answer greater than 3?
1145
+
1146
+ 9. **Boolean Blindness:** At any call site, can you understand what each `True`/`False` argument means without looking up the method signature?
1147
+
1148
+ 10. **Magic Numbers:** If a business rule changes (tax rate, threshold, timeout), can you change it in exactly one place? Or must you grep for a numeric literal?
1149
+
1150
+ 11. **Data Class:** Do any classes consist entirely of getters and setters? Is all the behavior in separate "service" classes that pull data out, process it, and push it back in?
1151
+
1152
+ 12. **Speculative Generality:** Are there interfaces with exactly one implementation? Abstract classes with one subclass? Can you delete an abstraction layer and have everything still compile?
1153
+
1154
+ 13. **Message Chains:** Do you see chains of 3+ method calls like `a.getB().getC().getD()`? If any intermediate object changes its structure, how many call sites break?
1155
+
1156
+ 14. **Misleading Comments:** Pick any comment in the codebase. Does it accurately describe what the adjacent code does *right now*? When was the comment last updated relative to the code?
1157
+
1158
+ 15. **Refused Bequest:** Do any subclasses override parent methods to throw exceptions or return no-ops? Could clients of the parent type be surprised by the subclass behavior?
1159
+
1160
+ ## Code Smell Quick Reference
1161
+
1162
+ | Smell | AKA | Severity | Frequency | Key Signal | First Action |
1163
+ |---|---|---|---|---|---|
1164
+ | God Class | Blob | Critical | Very Common | >500 LOC, >20 methods | Extract Class |
1165
+ | Copy-Paste | Duplicated Code | Critical | Very Common | Identical blocks in 2+ places | Extract Method |
1166
+ | Primitive Obsession | Stringly Typed | Critical | Very Common | Raw primitives for domain concepts | Introduce Value Object |
1167
+ | Long Method | Mega-Function | High | Very Common | >30 LOC of logic | Extract Method |
1168
+ | Deep Nesting | Arrow Code | High | Very Common | >3 levels of indentation | Guard Clauses |
1169
+ | Feature Envy | Misplaced Method | High | Common | Method uses other class's data | Move Method |
1170
+ | Data Clumps | Parameter Clusters | Medium | Common | Same params in 3+ signatures | Introduce Parameter Object |
1171
+ | Magic Numbers | Unnamed Constants | Medium | Very Common | Literal numbers in logic | Extract Constant |
1172
+ | Dead Code | Zombie Code | Critical | Common | Zero callers, commented blocks | Delete (git is your backup) |
1173
+ | Shotgun Surgery | Scattered Change | High | Common | 5+ files changed for one feature | Move Method/Field |
1174
+ | Divergent Change | Swiss Army Class | High | Common | Class changed for unrelated reasons | Extract Class |
1175
+ | Speculative Generality | YAGNI Violation | Medium | Common | Interface with 1 implementation | Collapse Hierarchy |
1176
+ | Boolean Blindness | Boolean Trap | Medium | Common | `foo(true, false, true)` | Replace with Enum |
1177
+ | Comments as Deodorant | Explaining Bad Code | Medium | Very Common | Comment longer than code it explains | Rename + Extract |
1178
+ | Stringly Typed | String Abuse | High | Common | String comparison chains | Introduce Enum |
1179
+ | Message Chains | Train Wreck | Medium | Common | `a.b().c().d()` | Hide Delegate |
1180
+ | Middle Man | Pass-Through | Medium | Occasional | >80% one-line delegations | Remove Middle Man |
1181
+ | Refused Bequest | Broken Liskov | High | Occasional | Override with throw/no-op | Replace Inheritance with Delegation |
1182
+ | Data Class | Anemic Model | Medium | Common | All getters, no behavior | Move behavior to data class |
1183
+ | Misleading Comments | Comment Rot | High | Very Common | Comment contradicts code | Delete or update comment |
1184
+
1185
+ ---
1186
+ *Researched: 2026-03-08 | Sources: Fowler, "Refactoring" (1999, 2018); Beck & Fowler code smell catalog; Apple goto fail CVE-2014-1266 (dwheeler.com); Mars Climate Orbiter mishap (NASA/JPL); Ariane 5 Flight 501 Inquiry Board Report; Knight Capital SEC filing and post-mortem (henricodolfing.ch); Heartbleed CVE-2014-0160 (heartbleed.com); Li et al. CP-Miner (UIUC); Lin et al. code-comment inconsistency study (arXiv:2409.10781); SonarSource cognitive complexity whitepaper; refactoring.guru; sourcemaking.com; luzkan.github.io/smells*