@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,1118 @@
1
+ # Naming & Abstraction Anti-Patterns
2
+
3
+ > **Domain:** Code
4
+ > **Anti-patterns covered:** 20
5
+ > **Highest severity:** High
6
+
7
+ ---
8
+
9
+ ## Introduction
10
+
11
+ Naming is the most pervasive act in software development. Every variable, function, class, module, and abstraction boundary carries a name, and that name shapes every reader's mental model forever after. Bad names are not merely aesthetic failures — they are correctness failures. A function named `processData` that silently mutates global state, a class named `Utils` that accumulates 3,000 lines over two years, an abstraction named `IRepository` that leaks SQL dialect details: each of these is a defect that static analysis cannot catch but that costs teams real hours every sprint.
12
+
13
+ Abstraction anti-patterns compound naming problems. An abstraction exists to let the reader stop thinking about one level of detail. When the abstraction is premature, wrong, or inverted, it forces the reader to hold *more* levels simultaneously, not fewer. The result is cognitive overhead that compounds with codebase growth.
14
+
15
+ This module catalogues 20 concrete anti-patterns across naming and abstraction, with real-world evidence, machine-applicable detection rules, and before/after fixes.
16
+
17
+ ---
18
+
19
+ ## AP-1: Meaningless Names
20
+
21
+ **Also known as:** Noise words, placeholder names left in production, data/info/temp variables
22
+ **Frequency:** Very Common
23
+ **Severity:** High
24
+ **Detection difficulty:** Easy
25
+
26
+ **What it looks like:**
27
+
28
+ ```python
29
+ def process(data, info, temp):
30
+ x = data["val"]
31
+ y = info.get("thing")
32
+ result2 = x + y
33
+ return result2
34
+ ```
35
+
36
+ **Why developers do it:**
37
+ Placeholder names are created during exploratory coding and never replaced. Developers are in flow state and treat naming as something to "fix later." Under deadline pressure, "later" never arrives.
38
+
39
+ **What goes wrong:**
40
+ Every future reader must reverse-engineer meaning from context. `data` could be a dict, a DataFrame, a byte buffer, or a domain object. Bugs hide in plain sight because variable misuse is invisible when names carry no semantics. Code reviews become ineffective — reviewers cannot spot a logic error when they cannot distinguish `temp` from `result2`.
41
+
42
+ **The fix:**
43
+
44
+ ```python
45
+ # Before
46
+ def process(data, info, temp):
47
+ x = data["val"]
48
+ y = info.get("thing")
49
+ result2 = x + y
50
+ return result2
51
+
52
+ # After
53
+ def calculate_order_total(order: Order, pricing_config: PricingConfig) -> Decimal:
54
+ base_price = order.unit_price
55
+ discount_rate = pricing_config.get("discount_rate", Decimal("0"))
56
+ total = base_price * (1 - discount_rate)
57
+ return total
58
+ ```
59
+
60
+ **Detection rule:**
61
+ Flag any identifier matching: `data`, `info`, `temp`, `tmp`, `result[0-9]*`, `val`, `thing`, `stuff`, `x`, `y`, `z`, `foo`, `bar`, `baz` outside of test fixtures and mathematical algorithms where single-letter names are conventional.
62
+
63
+ ---
64
+
65
+ ## AP-2: Misleading Names
66
+
67
+ **Also known as:** Lying names, deceptive identifiers, semantic mismatch
68
+ **Frequency:** Common
69
+ **Severity:** High
70
+ **Detection difficulty:** Hard
71
+
72
+ **What it looks like:**
73
+
74
+ ```javascript
75
+ // isReady actually means "has the component been mounted at least once"
76
+ // It returns false during SSR and true after first hydration
77
+ class ComponentTracker {
78
+ isReady() {
79
+ return this._mountCount > 0;
80
+ }
81
+
82
+ // "save" actually sends an HTTP request AND updates local cache AND emits an event
83
+ save(payload) {
84
+ return fetch('/api/save', { method: 'POST', body: JSON.stringify(payload) })
85
+ .then(() => { this._cache.set(payload.id, payload); this._emitter.emit('saved'); });
86
+ }
87
+ }
88
+ ```
89
+
90
+ **Why developers do it:**
91
+ The name was accurate when first written, then behavior evolved. Refactors add responsibilities without renaming. Or the developer chose an optimistic name hoping to match an intended final state.
92
+
93
+ **What goes wrong:**
94
+ Callers build mental models from the name, not from reading the implementation. Code that calls `if (tracker.isReady())` expects a readiness check, not a mount-count check. Bugs appear at integration boundaries where callers behave according to the name's implicit contract, not the implementation's actual contract.
95
+
96
+ **The fix:**
97
+
98
+ ```javascript
99
+ // Before
100
+ isReady() { return this._mountCount > 0; }
101
+ save(payload) { /* fetches, caches, and emits */ }
102
+
103
+ // After
104
+ hasBeenMountedAtLeastOnce() { return this._mountCount > 0; }
105
+ // or: wasMounted, isHydrated
106
+
107
+ persistAndNotify(payload) {
108
+ return this._apiClient.persist(payload)
109
+ .then(() => {
110
+ this._cache.set(payload.id, payload);
111
+ this._eventBus.emit('record:saved', payload);
112
+ });
113
+ }
114
+ ```
115
+
116
+ **Detection rule:**
117
+ Automated detection is limited. Heuristic: flag boolean-returning functions named `is*` or `has*` whose implementation contains arithmetic, comparisons against non-boolean values, or side effects.
118
+
119
+ ---
120
+
121
+ ## AP-3: Abbreviations That Obscure Meaning
122
+
123
+ **Also known as:** Cryptic abbreviations, terse naming, compressed identifiers
124
+ **Frequency:** Very Common
125
+ **Severity:** Medium
126
+ **Detection difficulty:** Moderate
127
+
128
+ **What it looks like:**
129
+
130
+ ```java
131
+ public class OrdProc {
132
+ private CustMgr cm;
133
+ private InvSvc invSvc;
134
+
135
+ public OrdRes procOrd(OrdReq req, UsrCtx uctx) {
136
+ Cust c = cm.getCust(uctx.getCustId());
137
+ Inv inv = invSvc.chkInv(req.getProdId(), req.getQty());
138
+ // ...
139
+ }
140
+ }
141
+ ```
142
+
143
+ **Why developers do it:**
144
+ Developers optimize for typing speed, imitate legacy codebases where line length was constrained, or confuse brevity with clarity. Domain-specific abbreviations feel obvious to their author.
145
+
146
+ **What goes wrong:**
147
+ Abbreviations have no canonical expansion. `OrdProc` could be OrderProcessor, OrderProcessing, OrderProcedure, or OrderProduct. New team members spend weeks building a mental glossary. Code search becomes unreliable — searching for "Order" misses `Ord` references. IDEs handle autocomplete, so typing cost is imaginary.
148
+
149
+ **The fix:**
150
+
151
+ ```java
152
+ // Before
153
+ public OrdRes procOrd(OrdReq req, UsrCtx uctx)
154
+
155
+ // After
156
+ public OrderResponse processOrder(OrderRequest request, UserContext userContext)
157
+ ```
158
+
159
+ **Detection rule:**
160
+ Flag identifiers shorter than 4 characters (excluding loop counters `i`, `j`, `k` and mathematical variables), and identifiers matching common abbreviation patterns: `[A-Z][a-z]{0,2}[A-Z]` (camelCase abbreviations), `Mgr`, `Svc`, `Proc`, `Req`, `Res`, `Ctx`, `Usr`, `Cust`, `Ord`, `Inv`, `Prd`.
161
+
162
+ ---
163
+
164
+ ## AP-4: Hungarian Notation in Modern Languages
165
+
166
+ **Also known as:** Type-encoded names, systems Hungarian, strPrefix naming
167
+ **Frequency:** Common (in legacy codebases), Occasional (in new code)
168
+ **Severity:** Medium
169
+ **Detection difficulty:** Easy
170
+
171
+ **What it looks like:**
172
+
173
+ ```typescript
174
+ const strUserName: string = "Alice";
175
+ const nItemCount: number = 42;
176
+ const bIsActive: boolean = true;
177
+ const arrProductList: Product[] = [];
178
+ const objUserConfig: UserConfig = {};
179
+ const fnHandleClick = (e: Event) => {};
180
+ ```
181
+
182
+ **Why developers do it:**
183
+ Hungarian notation was recommended in early Windows API documentation and spread widely. Developers carry it forward from C/C++ habits into typed languages. The original intent — encoding *kind* (not type) in names — was sound, but systems Hungarian (encoding types) became the dominant misapplication.
184
+
185
+ **What goes wrong:**
186
+ Modern IDEs show types on hover. Compilers enforce types at compile time. The prefix provides zero information not already available from the type system, while adding noise that the brain must filter on every read. When types change during refactoring (e.g., `strCount` becomes a number), the prefix becomes actively misleading. As Herb Sutter noted, the notation forces code to read like "hieroglyphics" rather than natural language.
187
+
188
+ **The fix:**
189
+
190
+ ```typescript
191
+ // Before
192
+ const strUserName: string = "Alice";
193
+ const arrProductList: Product[] = [];
194
+ const bIsActive: boolean = true;
195
+
196
+ // After
197
+ const userName: string = "Alice";
198
+ const products: Product[] = [];
199
+ const isActive: boolean = true;
200
+ ```
201
+
202
+ **Detection rule:**
203
+ Flag identifiers with type-encoding prefixes: `str`, `n`, `i`, `b`, `arr`, `obj`, `fn`, `d`, `f`, `sz`, `lp`, `p`, `h` followed immediately by a capitalized word, in languages with static or structural type systems (TypeScript, Java, C#, Kotlin, Swift, Go).
204
+
205
+ ---
206
+
207
+ ## AP-5: Naming Booleans Without Semantic Prefix
208
+
209
+ **Also known as:** Ambiguous boolean names, undeclared boolean intent
210
+ **Frequency:** Very Common
211
+ **Severity:** Medium
212
+ **Detection difficulty:** Easy
213
+
214
+ **What it looks like:**
215
+
216
+ ```python
217
+ user = User(active=True, delete=False, login=True, cache=False)
218
+
219
+ if user.active and not user.delete:
220
+ if user.login:
221
+ pass
222
+ ```
223
+
224
+ **Why developers do it:**
225
+ Brevity. The noun or verb form feels "obvious" to the author in context.
226
+
227
+ **What goes wrong:**
228
+ `user.active` could mean "is the user currently active" (state) or "make this user active" (command). `user.delete` is especially dangerous — it reads as a method invocation, not a flag. Reading `not user.delete` requires conscious re-parsing. `user.login` could be a noun (the login value), a verb (perform login), or a state (currently logged in). Booleans without `is/has/should/can/was/will` prefixes are systematically ambiguous.
229
+
230
+ **The fix:**
231
+
232
+ ```python
233
+ # Before
234
+ user = User(active=True, delete=False, login=True, cache=False)
235
+
236
+ # After
237
+ user = User(
238
+ is_active=True,
239
+ is_deleted=False,
240
+ is_logged_in=True,
241
+ should_cache=False
242
+ )
243
+
244
+ if user.is_active and not user.is_deleted:
245
+ if user.is_logged_in:
246
+ pass
247
+ ```
248
+
249
+ **Detection rule:**
250
+ Flag boolean-typed fields, parameters, and variables whose names do not begin with: `is_`, `has_`, `should_`, `can_`, `was_`, `will_`, `needs_`, `allows_`, `enables_`, `supports_` (or their camelCase equivalents).
251
+
252
+ ---
253
+
254
+ ## AP-6: Inconsistent Naming Across Codebase
255
+
256
+ **Also known as:** Naming drift, synonym proliferation, vocabulary fragmentation
257
+ **Frequency:** Very Common
258
+ **Severity:** High
259
+ **Detection difficulty:** Moderate
260
+
261
+ **What it looks like:**
262
+
263
+ ```python
264
+ # In user_service.py
265
+ def get_user(user_id): ...
266
+ def fetch_account(account_id): ...
267
+ def load_profile(profile_id): ...
268
+ def retrieve_member(member_id): ...
269
+
270
+ # In the database layer
271
+ class UserRepository: ...
272
+ class AccountDao: ...
273
+ class ProfileStore: ...
274
+ class MemberModel: ...
275
+
276
+ # In the API layer
277
+ def create_user(): ...
278
+ def register_account(): ...
279
+ def signup_member(): ...
280
+ ```
281
+
282
+ **Why developers do it:**
283
+ Different developers write different layers. Naming conventions are not documented or enforced. The codebase grows organically across teams and time.
284
+
285
+ **What goes wrong:**
286
+ Readers cannot tell if `User`, `Account`, `Profile`, and `Member` refer to the same entity or distinct concepts. Every new developer must map the entire synonym set before reasoning about data flow. Search and refactoring tools produce incomplete results. Domain modeling becomes impossible when the domain vocabulary is undefined.
287
+
288
+ **The fix:**
289
+ Establish and document a ubiquitous language (from Domain-Driven Design). Pick one term per concept codebase-wide:
290
+
291
+ ```python
292
+ # Chosen vocabulary: "user" for the core entity, "fetch" for retrieval
293
+ def fetch_user(user_id): ...
294
+ class UserRepository: ...
295
+ def create_user(): ...
296
+ ```
297
+
298
+ **Detection rule:**
299
+ Build a synonym set from the codebase's identifier vocabulary. Flag entities that appear under multiple names within the same domain layer: detect via clustering of identifiers that share data-type relationships (same field types, same return types) but differ in naming.
300
+
301
+ ---
302
+
303
+ ## AP-7: The Wrong Abstraction
304
+
305
+ **Also known as:** Inappropriate DRY, premature unification, forced reuse
306
+ **Frequency:** Common
307
+ **Severity:** High
308
+ **Detection difficulty:** Hard
309
+
310
+ **What it looks like:**
311
+
312
+ ```ruby
313
+ # Started as a clean abstraction for rendering two similar forms
314
+ def render_form(type:, show_address:, show_phone:, show_email:,
315
+ require_address:, address_label: "Address",
316
+ show_secondary_address:, show_company:,
317
+ company_required: false, skip_validation:,
318
+ legacy_mode:, use_new_layout: false)
319
+ if legacy_mode
320
+ render_legacy_form(...)
321
+ elsif type == :checkout
322
+ # ... 40 lines specific to checkout
323
+ elsif type == :profile
324
+ # ... 40 lines specific to profile
325
+ else
326
+ # ... default path that is now used by nobody
327
+ end
328
+ end
329
+ ```
330
+
331
+ **Why developers do it:**
332
+ Two pieces of code look similar. A developer extracts them into one function to avoid duplication (applying DRY). Later, requirements diverge and the abstraction accumulates parameters to handle each case. As Sandi Metz documented, each new programmer feels obligated to preserve the existing abstraction and adds another parameter rather than questioning it.
333
+
334
+ **What goes wrong:**
335
+ The abstraction becomes a catch-all procedure with combinatorial complexity. Every caller must understand all parameters, most of which are irrelevant to it. Adding a new caller requires understanding (and not breaking) every existing caller's path. The code is harder to read than the original duplication would have been.
336
+
337
+ **The fix:**
338
+ Metz's prescription: inline the abstraction back into every caller, then let each caller have only what it needs. Accept duplication until a genuinely shared pattern emerges.
339
+
340
+ ```ruby
341
+ # Before: one function with 10 parameters serving 3 callers
342
+
343
+ # After: three focused functions
344
+ def render_checkout_form(show_address:, require_address:)
345
+ # only checkout-relevant logic
346
+ end
347
+
348
+ def render_profile_form(show_phone:, show_email:, show_company:)
349
+ # only profile-relevant logic
350
+ end
351
+ ```
352
+
353
+ **Detection rule:**
354
+ Flag functions with: (a) more than 5 boolean/flag parameters, or (b) internal branching on a `type:` / `mode:` / `variant:` parameter with 3 or more branches, or (c) a parameter count that has grown by more than 3 over the git history of the function.
355
+
356
+ ---
357
+
358
+ ## AP-8: Premature Abstraction
359
+
360
+ **Also known as:** Speculative generality, YAGNI violation, over-engineering
361
+ **Frequency:** Common
362
+ **Severity:** High
363
+ **Detection difficulty:** Moderate
364
+
365
+ **What it looks like:**
366
+
367
+ ```typescript
368
+ // Written for a single use case: logging to a file
369
+ interface Logger {
370
+ log(level: LogLevel, message: string, context?: Record<string, unknown>): void;
371
+ flush(): Promise<void>;
372
+ close(): void;
373
+ }
374
+
375
+ abstract class BaseLogger implements Logger {
376
+ protected abstract formatMessage(level: LogLevel, message: string): string;
377
+ protected abstract writeRecord(record: string): Promise<void>;
378
+ // ...
379
+ }
380
+
381
+ class FileLogger extends BaseLogger {
382
+ // The only implementation that ever existed
383
+ }
384
+
385
+ // FileLogger is created through a factory
386
+ class LoggerFactory {
387
+ static create(config: LoggerConfig): Logger {
388
+ return new FileLogger(config); // always FileLogger
389
+ }
390
+ }
391
+ ```
392
+
393
+ **Why developers do it:**
394
+ Developers correctly recognize that "I might need other implementations later." The logger example above is pervasive: it appears in tutorials as a best practice. The problem is not the pattern — it is applying the pattern before the second use case exists.
395
+
396
+ **What goes wrong:**
397
+ Every new team member must navigate the interface, the abstract base, the factory, and the concrete class to understand "we write logs to a file." The abstraction adds four files, two levels of inheritance, and a factory with one code path. When the second use case never arrives (often the case), all this structure becomes permanent overhead. Premature abstraction is the root cause of enterprise framework bloat.
398
+
399
+ **The fix:**
400
+
401
+ ```typescript
402
+ // Before: interface + abstract base + factory + concrete = 4 files, 0 second implementations
403
+ // After: start with the concrete, extract interface when the second use case arrives
404
+
405
+ class FileLogger {
406
+ private readonly stream: WriteStream;
407
+
408
+ constructor(private readonly config: LoggerConfig) {
409
+ this.stream = createWriteStream(config.path, { flags: 'a' });
410
+ }
411
+
412
+ log(level: LogLevel, message: string): void {
413
+ this.stream.write(`[${level}] ${message}\n`);
414
+ }
415
+ }
416
+ ```
417
+
418
+ **Detection rule:**
419
+ Flag: (a) interfaces with exactly one implementing class in the codebase, (b) abstract base classes with exactly one concrete subclass, (c) factory classes whose factory method returns a single concrete type unconditionally.
420
+
421
+ ---
422
+
423
+ ## AP-9: Leaky Abstractions
424
+
425
+ **Also known as:** Implementation bleed-through, abstraction boundary violation
426
+ **Frequency:** Common
427
+ **Severity:** High
428
+ **Detection difficulty:** Hard
429
+
430
+ **What it looks like:**
431
+
432
+ ```python
433
+ class UserRepository:
434
+ """Abstracts database access for users."""
435
+
436
+ def find_users_by_status(self, status: str) -> list[User]:
437
+ # Leaks: caller must know MySQL ENUM values and NULL behavior
438
+ return self._db.query(
439
+ "SELECT * FROM users WHERE status = %s AND deleted_at IS NULL",
440
+ (status,)
441
+ )
442
+
443
+ def find_recent_users(self) -> list[User]:
444
+ # Leaks: caller must know the index name for performance
445
+ # Documented in a comment that belongs in the database schema
446
+ # Use the idx_created_at index — do not add ORDER BY or it will full-scan
447
+ return self._db.query("SELECT * FROM users USE INDEX (idx_created_at) LIMIT 100")
448
+ ```
449
+
450
+ **Why developers do it:**
451
+ Building abstractions is hard. Developers reach through the abstraction layer for performance, for pragmatism, or because the abstraction boundary was never clearly defined.
452
+
453
+ **What goes wrong:**
454
+ Joel Spolsky's Law of Leaky Abstractions states: "All non-trivial abstractions, to some degree, are leaky." The problem is *how much* they leak. When a repository leaks SQL syntax, callers cannot be swapped to a different database without understanding and rewriting every caller. Performance surprises — like the index hint above — require knowing the underlying storage engine. The abstraction provides the vocabulary of the layer above without the isolation.
455
+
456
+ **The fix:**
457
+
458
+ ```python
459
+ class UserRepository:
460
+ def find_active_users(self) -> list[User]:
461
+ # Caller knows: "give me active users" — not how "active" is stored
462
+ return self._db.query(
463
+ "SELECT * FROM users WHERE status = 'active' AND deleted_at IS NULL"
464
+ )
465
+
466
+ def find_recently_registered(self, limit: int = 100) -> list[User]:
467
+ # Performance details are an implementation concern, not caller's concern
468
+ return self._db.query(
469
+ "SELECT * FROM users USE INDEX (idx_created_at) "
470
+ "ORDER BY created_at DESC LIMIT %s", (limit,)
471
+ )
472
+ ```
473
+
474
+ **Detection rule:**
475
+ Flag: (a) SQL strings in non-repository/DAO classes, (b) database-specific syntax (USE INDEX, NOLOCK, ROWNUM) outside the data access layer, (c) HTTP status codes or header names in business logic classes, (d) filesystem paths in domain objects.
476
+
477
+ ---
478
+
479
+ ## AP-10: Abstraction Inversion
480
+
481
+ **Also known as:** Upside-down abstraction, re-implementing built-ins through the abstraction
482
+ **Frequency:** Occasional
483
+ **Severity:** High
484
+ **Detection difficulty:** Hard
485
+
486
+ **What it looks like:**
487
+
488
+ ```csharp
489
+ // The ORM exposes SaveChanges() which handles transactions internally.
490
+ // The repository hides SaveChanges() behind a "unit of work" abstraction.
491
+ // Now callers need transaction semantics, but the abstraction doesn't expose them.
492
+ // Solution: fetch all records and filter in application code.
493
+
494
+ public class OrderService {
495
+ public async Task<List<Order>> GetPendingOrdersForCustomer(int customerId) {
496
+ // Cannot call SQL WHERE because the repository hides it.
497
+ // Must fetch ALL orders and filter here.
498
+ var allOrders = await _repository.GetAllOrders(); // 50,000 rows
499
+ return allOrders.Where(o => o.CustomerId == customerId
500
+ && o.Status == OrderStatus.Pending).ToList();
501
+ }
502
+ }
503
+ ```
504
+
505
+ **Why developers do it:**
506
+ Abstraction inversion happens when an abstraction is designed for one use case (e.g., simple CRUD) and then used for a more complex one (e.g., filtered queries). Rather than extend the abstraction properly, developers implement the missing functionality on top of the abstraction's public API, which re-uses the abstraction's internals without direct access.
507
+
508
+ **What goes wrong:**
509
+ Performance degrades (fetching 50,000 rows to return 3). The workaround becomes load-bearing, persists indefinitely, and is never cleaned up. The abstraction now has the worst of both worlds: it hides complexity without providing the tools to manage that complexity.
510
+
511
+ **The fix:**
512
+
513
+ ```csharp
514
+ // Expose the needed capability at the correct abstraction level
515
+ public interface IOrderRepository {
516
+ Task<List<Order>> GetPendingOrdersByCustomer(int customerId);
517
+ // or: Task<List<Order>> FindOrders(OrderQuery query);
518
+ }
519
+
520
+ public class SqlOrderRepository : IOrderRepository {
521
+ public async Task<List<Order>> GetPendingOrdersByCustomer(int customerId) {
522
+ return await _context.Orders
523
+ .Where(o => o.CustomerId == customerId && o.Status == OrderStatus.Pending)
524
+ .ToListAsync();
525
+ }
526
+ }
527
+ ```
528
+
529
+ **Detection rule:**
530
+ Flag: (a) `GetAll()` calls followed by in-memory LINQ/filter operations in a service layer, (b) loading full collections to find single entities by non-primary-key fields, (c) N+1 query patterns where one call retrieves parents and a loop retrieves children individually.
531
+
532
+ ---
533
+
534
+ ## AP-11: Too Many Layers of Indirection
535
+
536
+ **Also known as:** Over-engineering, Enterprise FizzBuzz, abstraction tax
537
+ **Frequency:** Common
538
+ **Severity:** Medium
539
+ **Detection difficulty:** Moderate
540
+
541
+ **What it looks like:**
542
+
543
+ ```
544
+ GET /users/{id}
545
+ → UserController
546
+ → UserApplicationService
547
+ → UserDomainService
548
+ → UserRepository
549
+ → UserDataMapper
550
+ → UserEntityFactory
551
+ → UserDao
552
+ → DatabaseConnectionPool
553
+ → SELECT * FROM users WHERE id = ?
554
+ ```
555
+
556
+ Ten hops to read one database row. Each layer has its own class, its own interface, and its own test file. The `UserEntityFactory` has one method: `create(row: Row): UserEntity`.
557
+
558
+ **Why developers do it:**
559
+ Architecture guidelines recommend separation of concerns. Clean Architecture diagrams show layered rings. Developers apply these patterns uniformly regardless of domain complexity, producing enterprise patterns around what is effectively a CRUD operation.
560
+
561
+ **What goes wrong:**
562
+ Debugging requires tracing a call stack ten levels deep. Onboarding takes days instead of hours. Every new feature requires touching 8-10 files. The indirection layers add no semantic content — they rename data without transforming it. The fundamental theorem of software engineering ("any problem can be solved by adding a layer of indirection") has a corollary: the solution may introduce more problems than it solves.
563
+
564
+ **The fix:**
565
+ Apply layering proportional to actual complexity. A simple CRUD resource needs: a controller, a repository, and a domain object. Extract additional layers only when they carry distinct responsibilities that differ in rate of change.
566
+
567
+ ```
568
+ GET /users/{id}
569
+ → UserController (HTTP boundary: parse request, render response)
570
+ → UserRepository (data boundary: query + map to domain object)
571
+ → SELECT * FROM users WHERE id = ?
572
+ ```
573
+
574
+ **Detection rule:**
575
+ Flag call chains where more than 4 consecutive classes are single-method pass-throughs (methods that call exactly one other method with no transformation logic).
576
+
577
+ ---
578
+
579
+ ## AP-12: Util/Helper/Manager/Service God Classes
580
+
581
+ **Also known as:** Dunghill anti-pattern, junk drawer class, catch-all module
582
+ **Frequency:** Very Common
583
+ **Severity:** High
584
+ **Detection difficulty:** Easy
585
+
586
+ **What it looks like:**
587
+
588
+ ```python
589
+ # utils.py — 2,847 lines
590
+ def format_date(d): ...
591
+ def validate_email(email): ...
592
+ def calculate_tax(amount, rate): ...
593
+ def send_slack_notification(message): ...
594
+ def parse_csv(path): ...
595
+ def generate_uuid(): ...
596
+ def truncate_string(s, max_len): ...
597
+ def get_current_user_from_request(req): ...
598
+ def deep_merge_dicts(a, b): ...
599
+ def retry_with_backoff(fn, retries): ...
600
+ # ... 200 more functions
601
+ ```
602
+
603
+ **Why developers do it:**
604
+ A utility function does not obviously "belong" to any single domain class. Rather than create a new focused module, the developer drops it into the nearest catch-all. The moment `utils.py` is created, it becomes a gravity well — the path of least resistance for every "I don't know where this goes" function.
605
+
606
+ **What goes wrong:**
607
+ The `utils.py` file becomes untestable (every test must import 2,000 lines of unrelated code), unsearchable (nothing is where you would look for it), and unmaintainable (nobody owns it). Import cycles proliferate because everything imports utils and utils imports everything. New developers cannot discover capability that already exists.
608
+
609
+ **The fix:**
610
+ Every function belongs somewhere specific. When it seems not to belong, it usually belongs on the primary domain object it operates on:
611
+
612
+ ```python
613
+ # Before: utils.format_date(order.created_at)
614
+ # After: order.formatted_created_at (property) or DateFormatter.format(order.created_at)
615
+
616
+ # Before: utils.calculate_tax(order.subtotal, region.tax_rate)
617
+ # After: order.calculate_tax(region) or TaxCalculator(region).calculate(order)
618
+
619
+ # Before: utils.send_slack_notification(message)
620
+ # After: SlackNotifier(config).send(message)
621
+ ```
622
+
623
+ **Detection rule:**
624
+ Flag files/modules named `utils`, `helpers`, `common`, `misc`, `shared`, `tools`, `lib` that contain more than 15 functions, or any class named `*Util`, `*Helper`, `*Manager`, `*Handler` with more than 10 public methods spanning more than 3 distinct responsibility domains.
625
+
626
+ ---
627
+
628
+ ## AP-13: Naming by Implementation, Not Intention
629
+
630
+ **Also known as:** How-naming vs what-naming, implementation-leaking names
631
+ **Frequency:** Common
632
+ **Severity:** Medium
633
+ **Detection difficulty:** Moderate
634
+
635
+ **What it looks like:**
636
+
637
+ ```java
638
+ public class UserService {
639
+ // Name describes mechanism, not purpose
640
+ public User iterateUsersAndFindByEmailUsingHashMap(String email) { ... }
641
+
642
+ // Name exposes storage format
643
+ public List<Order> getOrdersFromRedisCache(int userId) { ... }
644
+
645
+ // Name exposes algorithm
646
+ public List<Product> sortProductsWithQuicksort(List<Product> products) { ... }
647
+
648
+ // Name exposes network call
649
+ public UserProfile callProfileServiceAndDeserializeJson(String userId) { ... }
650
+ }
651
+ ```
652
+
653
+ **Why developers do it:**
654
+ The implementation is fresh in the developer's mind while writing the function. Naming it by mechanism is cognitive shorthand. It also feels precise.
655
+
656
+ **What goes wrong:**
657
+ Implementation names create false coupling. When `getOrdersFromRedisCache` switches storage backends (Redis to Memcached, or cache to database), the name is wrong. Callers who read the name form expectations about caching behavior that may no longer hold. `sortProductsWithQuicksort` prevents the implementation from switching to mergesort without a rename cascade.
658
+
659
+ **The fix:**
660
+
661
+ ```java
662
+ // Before
663
+ public User iterateUsersAndFindByEmailUsingHashMap(String email)
664
+ public List<Order> getOrdersFromRedisCache(int userId)
665
+ public List<Product> sortProductsWithQuicksort(List<Product> products)
666
+
667
+ // After
668
+ public Optional<User> findUserByEmail(String email)
669
+ public List<Order> getRecentOrders(int userId)
670
+ public List<Product> sortByPopularity(List<Product> products)
671
+ ```
672
+
673
+ **Detection rule:**
674
+ Flag method names containing implementation-specific terms: `HashMap`, `ArrayList`, `Redis`, `Mysql`, `Postgres`, `Json`, `Xml`, `Quicksort`, `Bubblesort`, `Iterator`, `Loop`, `Iterate`, `Http`, `Socket`, `Cache` (when used as a mechanism indicator rather than a domain term).
675
+
676
+ ---
677
+
678
+ ## AP-14: Generic Action Names
679
+
680
+ **Also known as:** Vague verbs, do-everything names, handle/process/manage
681
+ **Frequency:** Very Common
682
+ **Severity:** Medium
683
+ **Detection difficulty:** Easy
684
+
685
+ **What it looks like:**
686
+
687
+ ```javascript
688
+ function handleData(data) { ... }
689
+ function processOrder(order) { ... }
690
+ function manageUsers(users) { ... }
691
+ function doStuff(input) { ... }
692
+ function runTask(task) { ... }
693
+ function executeRequest(request) { ... }
694
+ function performAction(action) { ... }
695
+ ```
696
+
697
+ **Why developers do it:**
698
+ Generic verbs defer the decision about what the function actually does. They provide the illusion of naming while conveying no information. "Handle" is the default verb when a developer has not decided what the function's single responsibility is.
699
+
700
+ **What goes wrong:**
701
+ `handleData` communicates that a function receives data and does something with it — which is true of every function in every program. The caller cannot predict behavior, pre-conditions, post-conditions, or side effects from the name alone. When a bug appears inside `handleData`, the name provides no triage information. Functions with these names tend to accumulate unrelated behavior because their names permit it.
702
+
703
+ **The fix:**
704
+
705
+ ```javascript
706
+ // Before: generic
707
+ function handleData(data) { /* validates, transforms, persists, and notifies */ }
708
+
709
+ // After: specific — one name per responsibility
710
+ function validateOrderPayload(payload) { ... }
711
+ function transformOrderToInvoice(order) { ... }
712
+ function persistInvoice(invoice) { ... }
713
+ function notifyCustomerOfInvoice(invoice, customer) { ... }
714
+ ```
715
+
716
+ **Detection rule:**
717
+ Flag function/method names consisting solely of: `handle`, `process`, `manage`, `do`, `run`, `execute`, `perform`, `operate`, `deal`, `take_care_of`, with no domain-specific qualifier following the verb.
718
+
719
+ ---
720
+
721
+ ## AP-15: Negated Boolean Names
722
+
723
+ **Also known as:** Double-negative conditions, inverted flags, isNot* naming
724
+ **Frequency:** Common
725
+ **Severity:** Medium
726
+ **Detection difficulty:** Easy
727
+
728
+ **What it looks like:**
729
+
730
+ ```python
731
+ class User:
732
+ is_not_banned: bool
733
+ is_not_deleted: bool
734
+ cannot_login: bool
735
+ has_no_subscription: bool
736
+
737
+ # Call site creates double negatives
738
+ if not user.is_not_banned:
739
+ # Is this: banned? or not-not-banned?
740
+ block_user(user)
741
+
742
+ if user.is_not_deleted and not user.cannot_login:
743
+ # Reader must parse two negations simultaneously
744
+ allow_login(user)
745
+ ```
746
+
747
+ **Why developers do it:**
748
+ The feature is added incrementally. The default state starts as the negative case ("most users are not banned"), so the flag is named for the default. Or the developer reasons in terms of exceptions and names the flag for the exception.
749
+
750
+ **What goes wrong:**
751
+ `not user.is_not_banned` requires readers to evaluate a double negative, which reliably causes off-by-one reasoning errors. Studies on boolean logic errors consistently show that double negatives increase error rates. Code review becomes inadequate because reviewers mentally "simplify" the double negative and miss bugs in the simplification.
752
+
753
+ **The fix:**
754
+
755
+ ```python
756
+ # Before
757
+ is_not_banned: bool
758
+ cannot_login: bool
759
+
760
+ # After — flip to positive form
761
+ is_banned: bool # default: False
762
+ can_login: bool # default: True
763
+ has_subscription: bool
764
+ is_deleted: bool
765
+
766
+ if user.is_banned:
767
+ block_user(user)
768
+
769
+ if not user.is_deleted and user.can_login:
770
+ allow_login(user)
771
+ ```
772
+
773
+ **Detection rule:**
774
+ Flag boolean identifiers matching patterns: `is_not_*`, `isNot*`, `cannot_*`, `cannot*`, `has_no_*`, `hasNo*`, `no_*` (as boolean prefix), `never_*`, `without_*`, `lacks_*`.
775
+
776
+ ---
777
+
778
+ ## AP-16: Encoding Type in Name
779
+
780
+ **Also known as:** Type suffix naming, redundant type annotations in names
781
+ **Frequency:** Common
782
+ **Severity:** Low
783
+ **Detection difficulty:** Easy
784
+
785
+ **What it looks like:**
786
+
787
+ ```python
788
+ user_list = [] # it's a list, we said so twice
789
+ user_dict = {} # same problem
790
+ product_string = ""
791
+ price_integer = 0
792
+ config_object = {}
793
+ callback_function = lambda: None
794
+ error_exception = ValueError("bad input")
795
+ ```
796
+
797
+ **Why developers do it:**
798
+ A variant of Hungarian notation. Developers want to communicate the data structure to be used "just in case." Also appears when refactoring — a variable named `users` gets renamed to `user_list` to distinguish it from a newly added `users_dict`.
799
+
800
+ **What goes wrong:**
801
+ Types change. `user_list` becomes a generator, a queryset, or a tuple. The name is now wrong and misleading. The type suffix adds noise that readers learn to ignore, which means it contributes nothing after the first read. In statically typed languages the compiler makes it redundant; in dynamically typed languages the type hint makes it redundant.
802
+
803
+ **The fix:**
804
+
805
+ ```python
806
+ # Before
807
+ user_list = []
808
+ user_dict = {}
809
+
810
+ # After — name the content/purpose, let the type be inferred or annotated
811
+ users: list[User] = []
812
+ users_by_id: dict[int, User] = {}
813
+ active_users: QuerySet[User] = User.objects.filter(is_active=True)
814
+ ```
815
+
816
+ **Detection rule:**
817
+ Flag identifiers ending in `_list`, `_dict`, `_array`, `_map`, `_set`, `_tuple`, `_string`, `_int`, `_float`, `_bool`, `_object`, `_function`, `_callback`, `_exception`, `_error` (as type suffix, not domain term).
818
+
819
+ ---
820
+
821
+ ## AP-17: Comments Compensating for Bad Names
822
+
823
+ **Also known as:** Explanatory comments as naming shortcuts, comment-instead-of-rename
824
+ **Frequency:** Very Common
825
+ **Severity:** Medium
826
+ **Detection difficulty:** Moderate
827
+
828
+ **What it looks like:**
829
+
830
+ ```javascript
831
+ // Checks if user can proceed (not just if they're logged in — also checks
832
+ // subscription status, account standing, and rate limit)
833
+ function isReady(user) { ... }
834
+
835
+ // The multiplier for regional pricing adjustment
836
+ const x = 1.23;
837
+
838
+ // Loop through users and filter out inactive ones, then sort by signup date
839
+ function processData(users) { ... }
840
+
841
+ // Flag that tracks whether we've already sent the welcome email this session
842
+ let sent = false;
843
+ ```
844
+
845
+ **Why developers do it:**
846
+ The developer knows the comment is necessary and writes it — but does not take the next step of embedding that comment in the name. It feels faster to add a comment than to rename and update all references.
847
+
848
+ **What goes wrong:**
849
+ Comments lie. The code is the truth; comments are assertions about the code that go stale. When `isReady` evolves to add a fourth check, the comment may or may not be updated. The name `isReady` persists and continues to mislead. Comments are also invisible in call sites — readers of `if (isReady(user))` elsewhere in the codebase see no comment, only the misleading name.
850
+
851
+ **The fix:**
852
+
853
+ ```javascript
854
+ // Before
855
+ // Checks if user can proceed to checkout
856
+ function isReady(user) { ... }
857
+
858
+ // After — name replaces the comment
859
+ function canProceedToCheckout(user) { ... }
860
+
861
+ // Before
862
+ const x = 1.23; // regional pricing multiplier
863
+
864
+ // After
865
+ const REGIONAL_PRICING_MULTIPLIER = 1.23;
866
+
867
+ // Before
868
+ // loop through users, filter inactive, sort by signup
869
+ function processData(users) { ... }
870
+
871
+ // After
872
+ function getActiveUsersSortedBySignupDate(users) { ... }
873
+ ```
874
+
875
+ **Detection rule:**
876
+ Flag inline comments (single-line `//` or `#` comments) that appear on the same line as, or immediately preceding, a variable declaration or function definition. These are almost always naming failures waiting to be fixed.
877
+
878
+ ---
879
+
880
+ ## AP-18: Renaming Without Updating All References
881
+
882
+ **Also known as:** Partial rename, ghost identifiers, alias drift
883
+ **Frequency:** Common
884
+ **Severity:** High
885
+ **Detection difficulty:** Moderate
886
+
887
+ **What it looks like:**
888
+
889
+ ```python
890
+ # Original function
891
+ def get_user(user_id: int) -> User:
892
+ return db.query(User).filter_by(id=user_id).first()
893
+
894
+ # Renamed in user_service.py during a refactor
895
+ def fetch_user_by_id(user_id: int) -> User:
896
+ return db.query(User).filter_by(id=user_id).first()
897
+
898
+ # But 23 other files still call get_user()
899
+ # So both coexist, one as an alias or duplicate
900
+ def get_user(user_id: int) -> User:
901
+ return fetch_user_by_id(user_id) # thin wrapper preserved "for compatibility"
902
+ ```
903
+
904
+ **Why developers do it:**
905
+ Renaming is interrupted. The refactor tool misses dynamic call sites. The developer renames in one module but does not run a global search. Or the rename is intentional: the old name is kept as a "backwards compatible alias" that is never removed.
906
+
907
+ **What goes wrong:**
908
+ The codebase develops two canonical names for the same concept. New code uses the new name; old code uses the old name. The transition never completes. Six months later, neither name is clearly primary, and every junior developer wonders whether `get_user` and `fetch_user_by_id` do different things. Bugs appear when the wrapper alias and the real function diverge.
909
+
910
+ **The fix:**
911
+ Complete renames atomically using IDE refactoring tools. When renaming across a public API boundary, deprecate with a sunset date and a migration guide:
912
+
913
+ ```python
914
+ import warnings
915
+
916
+ def get_user(user_id: int) -> User:
917
+ warnings.warn(
918
+ "get_user() is deprecated; use fetch_user_by_id() instead. "
919
+ "Will be removed in v3.0.",
920
+ DeprecationWarning,
921
+ stacklevel=2
922
+ )
923
+ return fetch_user_by_id(user_id)
924
+ ```
925
+
926
+ **Detection rule:**
927
+ Flag functions/methods where: (a) the body is a single call to another function with the same parameter signature (thin wrappers), (b) the old name appears in a deprecation warning, (c) git log shows a rename event without a corresponding sweep of all call sites.
928
+
929
+ ---
930
+
931
+ ## AP-19: Abstract Class with One Implementation
932
+
933
+ **Also known as:** Speculative inheritance, phantom polymorphism, one-class hierarchy
934
+ **Frequency:** Common
935
+ **Severity:** Medium
936
+ **Detection difficulty:** Easy
937
+
938
+ **What it looks like:**
939
+
940
+ ```java
941
+ public abstract class NotificationSender {
942
+ protected abstract void connect();
943
+ protected abstract void disconnect();
944
+ public abstract void send(Notification notification);
945
+ protected abstract boolean isConnected();
946
+ }
947
+
948
+ public class EmailNotificationSender extends NotificationSender {
949
+ // The only subclass. No other implementation has ever been written.
950
+ @Override protected void connect() { /* SMTP connect */ }
951
+ @Override protected void disconnect() { /* SMTP disconnect */ }
952
+ @Override public void send(Notification notification) { /* send email */ }
953
+ @Override protected boolean isConnected() { return this.smtpClient.isConnected(); }
954
+ }
955
+ ```
956
+
957
+ **Why developers do it:**
958
+ "We might add SMS or push notifications later." The abstract base class is written in anticipation of future polymorphism. The architecture feels clean and extensible.
959
+
960
+ **What goes wrong:**
961
+ The abstract class defines a template that the single concrete class must conform to, even if the template does not fit the concrete implementation well. Adding SMS later requires conforming to an interface designed for SMTP. The abstract class calcifies the wrong abstraction (AP-7) before any second use case has revealed what the right abstraction would be. The overhead: two files instead of one, a template method pattern where none is needed, and forced overrides of methods that may not apply to all future implementors.
962
+
963
+ **The fix:**
964
+
965
+ ```java
966
+ // Start with the concrete class
967
+ public class EmailNotificationSender {
968
+ public void send(Notification notification) { ... }
969
+ }
970
+
971
+ // When SMS arrives, THEN extract the interface based on what both share
972
+ public interface NotificationSender {
973
+ void send(Notification notification);
974
+ }
975
+ ```
976
+
977
+ **Detection rule:**
978
+ Flag abstract classes and interfaces with exactly one non-abstract/non-test implementing class in the codebase. Cross-reference with: (a) the abstract class was introduced in the same commit as its only implementation, (b) no second implementation exists anywhere in the git history.
979
+
980
+ ---
981
+
982
+ ## AP-20: Interface for Every Class
983
+
984
+ **Also known as:** IRepository/IService suffix proliferation, unnecessary interface extraction
985
+ **Frequency:** Common
986
+ **Severity:** Medium
987
+ **Detection difficulty:** Easy
988
+
989
+ **What it looks like:**
990
+
991
+ ```csharp
992
+ // Every class has a matching interface, regardless of need
993
+ public interface IUserService { User GetUser(int id); void UpdateUser(User user); }
994
+ public class UserService : IUserService { ... }
995
+
996
+ public interface IOrderRepository { Order FindById(int id); void Save(Order order); }
997
+ public class OrderRepository : IOrderRepository { ... }
998
+
999
+ public interface IEmailSender { void Send(EmailMessage message); }
1000
+ public class EmailSender : IEmailSender { ... }
1001
+
1002
+ public interface IDateTimeProvider { DateTime UtcNow(); }
1003
+ public class DateTimeProvider : IDateTimeProvider { ... }
1004
+
1005
+ // Result: 40 interfaces for 40 classes, 80 files to navigate
1006
+ ```
1007
+
1008
+ **Why developers do it:**
1009
+ Dependency injection frameworks and unit testing guidance recommend coding to interfaces. This gets cargo-culted into "every class needs an interface." The `I` prefix for interfaces is a C# convention that gets applied universally.
1010
+
1011
+ **What goes wrong:**
1012
+ The codebase doubles in file count with no corresponding increase in flexibility or testability. For the 90% of interfaces with exactly one implementation, the interface adds: one additional file, one additional concept to search, one additional place to maintain method signatures. As the Okta developer blog noted, `IInterface` naming is a code smell that signals over-engineering. The actual benefit — swap implementations for testing — is achievable through other means (virtual methods, subclassing in tests, fakes).
1013
+
1014
+ **The fix:**
1015
+ Extract interfaces when: (a) there are or will imminently be multiple implementations, (b) the interface crosses an architectural boundary (e.g., hexagonal ports), or (c) the interface is needed to break a circular dependency. Not: "for every class, automatically."
1016
+
1017
+ ```csharp
1018
+ // Before: IUserService exists solely so UserService can be mocked in tests
1019
+
1020
+ // After: make UserService methods virtual, subclass in tests
1021
+ public class UserService {
1022
+ public virtual User GetUser(int id) { ... }
1023
+ }
1024
+
1025
+ // In tests
1026
+ public class TestUserService : UserService {
1027
+ public override User GetUser(int id) => _testUsers[id];
1028
+ }
1029
+ ```
1030
+
1031
+ **Detection rule:**
1032
+ Flag `I`-prefixed interfaces (or interfaces following `*Interface`, `*Contract` naming) where: (a) only one non-test class implements the interface, and (b) the interface and its sole implementation were created in the same commit.
1033
+
1034
+ ---
1035
+
1036
+ ## Root Cause Analysis
1037
+
1038
+ | Root Cause | Anti-Patterns Triggered | Primary Driver |
1039
+ |---|---|---|
1040
+ | Naming deferred during flow state | AP-1, AP-17 | Productivity pressure |
1041
+ | Feature evolution without rename discipline | AP-2, AP-18 | Refactoring cost perception |
1042
+ | Legacy conventions carried forward | AP-4, AP-16 | Institutional inertia |
1043
+ | DRY applied as rule rather than heuristic | AP-7, AP-8 | Misapplied principles |
1044
+ | Abstraction defined before second use case | AP-8, AP-19, AP-20 | Speculative design |
1045
+ | No domain vocabulary documented | AP-6, AP-13 | Missing architecture discipline |
1046
+ | Utility-first organization | AP-12 | Missing domain model |
1047
+ | Catch-all verbs used as placeholders | AP-14 | Insufficient domain understanding |
1048
+ | Negative-first reasoning about state | AP-15 | Incremental feature accretion |
1049
+ | Abbreviation culture / line-length habits | AP-3 | Historical constraints misapplied |
1050
+ | Abstraction boundary not designed | AP-9, AP-10, AP-11 | Incomplete architecture definition |
1051
+ | Interface-for-testability cargo cult | AP-20 | Overgeneralized testing guidance |
1052
+
1053
+ ---
1054
+
1055
+ ## Self-Check Questions
1056
+
1057
+ Use these questions during code review or when auditing a codebase for naming and abstraction quality.
1058
+
1059
+ 1. If you removed all comments from a function, could a new team member still understand what it does from names alone? (AP-1, AP-17)
1060
+
1061
+ 2. For every boolean field or parameter, does its name start with `is`, `has`, `should`, `can`, `was`, or `will`? (AP-5, AP-15)
1062
+
1063
+ 3. Does your codebase have exactly one term for each domain concept, used consistently across all layers? (AP-6)
1064
+
1065
+ 4. For every abstraction (class, interface, function), can you name the second use case it serves — not one you imagine in the future, but one that exists today? (AP-8, AP-19, AP-20)
1066
+
1067
+ 5. Can every layer in your call stack be removed without the remaining layers needing to know about the removed layer's implementation details? (AP-9, AP-11)
1068
+
1069
+ 6. If you renamed every function by its implementation details, would the names change? If yes, the current names may be leaking implementation. (AP-13)
1070
+
1071
+ 7. Do you have any files named `utils`, `helpers`, `common`, or `misc` with more than 10 functions? If so, which specific domain does each function belong to? (AP-12)
1072
+
1073
+ 8. For every abstract class and interface, how many concrete implementations exist today? If the answer is one, why does the abstraction exist now? (AP-8, AP-19, AP-20)
1074
+
1075
+ 9. Are there any functions in your codebase whose sole body is a call to another function with the same parameters? (AP-18)
1076
+
1077
+ 10. Are there any functions with more than 5 boolean parameters, or any function whose behavior changes based on a `type` or `mode` parameter? (AP-7)
1078
+
1079
+ 11. Does every function name include at least one domain-specific noun alongside its verb? `processOrder` has a noun; `processData` does not. (AP-14)
1080
+
1081
+ 12. When you search the codebase for a domain concept (e.g., "user"), do you find it under one name or under many (`user`, `account`, `member`, `profile`)? (AP-6)
1082
+
1083
+ 13. Are there places where a higher-level layer fetches all records and filters them in memory when a lower-level query could do it? (AP-10)
1084
+
1085
+ 14. For every variable with a comment explaining it, ask: could the comment be eliminated by putting its content in the variable name? (AP-17)
1086
+
1087
+ 15. Does your codebase have abbreviations that are not defined in a glossary? Would a developer from another team know what `OrdProc` or `CustMgr` means on day one? (AP-3)
1088
+
1089
+ ---
1090
+
1091
+ ## Code Smell Quick Reference
1092
+
1093
+ | Smell | Anti-Pattern | One-Line Rule |
1094
+ |---|---|---|
1095
+ | Variable named `data`, `info`, `temp`, `x` | AP-1 | Every name must answer: "data about what?" |
1096
+ | Function description contradicts its behavior | AP-2 | Read the code, not the name — they should match |
1097
+ | Identifier with `Mgr`, `Svc`, `Proc` suffix | AP-3 | Spell it out; abbreviations are not universal |
1098
+ | Variable prefix `str`, `n`, `b`, `arr` | AP-4 | Remove type prefixes in typed languages |
1099
+ | Boolean field named `active`, `delete`, `login` | AP-5 | Prefix with `is_`, `has_`, `should_` |
1100
+ | Same entity called by 3+ names | AP-6 | One concept, one name; document in a glossary |
1101
+ | Function with 6+ flag parameters | AP-7 | Split into focused functions per use case |
1102
+ | Interface with one implementation, created together | AP-8, AP-20 | Build it when the second use case arrives |
1103
+ | SQL string in a service class | AP-9 | Data access details belong in the data layer |
1104
+ | `GetAll()` + in-memory filter in service | AP-10 | Push filtering to the query layer |
1105
+ | 4+ pass-through wrappers in a call chain | AP-11 | Layers should transform, not just relay |
1106
+ | File named `utils.py` over 200 lines | AP-12 | Every function belongs to a domain |
1107
+ | Method named `getOrdersFromDatabase` | AP-13 | Name the intent; hide the mechanism |
1108
+ | Function named `handleData` or `processRequest` | AP-14 | Add a domain noun: `handlePaymentData` |
1109
+ | Boolean named `isNotDisabled`, `cannot_edit` | AP-15 | Flip to positive: `isEnabled`, `can_edit` |
1110
+ | Variable named `user_list`, `config_dict` | AP-16 | Remove type suffix; use type annotation instead |
1111
+ | Line comment immediately above a function | AP-17 | Move the comment content into the function name |
1112
+ | Two functions that do the same thing | AP-18 | Complete renames atomically; delete the alias |
1113
+ | Abstract class with one concrete subclass | AP-19 | Inline to concrete; extract when second arrives |
1114
+ | `I`-prefixed interface, one implementation | AP-20 | Reserve interfaces for real polymorphism |
1115
+
1116
+ ---
1117
+
1118
+ *Researched: 2026-03-08 | Sources: [The Wrong Abstraction — Sandi Metz](https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction), [The Law of Leaky Abstractions — Joel on Software](https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/), [Abstraction Inversion — Wikipedia](https://en.wikipedia.org/wiki/Abstraction_inversion), [Hungarian Notation Postmortem — SubMain](https://blog.submain.com/hungarian-notation-postmortem-went-wrong/), [IInterface Considered Harmful — Okta Developer](https://developer.okta.com/blog/2019/06/25/iinterface-considered-harmful), [Dunghill Anti-Pattern — Matti Lehtinen](https://mattilehtinen.com/articles/dunghill-anti-pattern-why-utility-classes-and-modules-smell/), [Post-Architecture: Premature Abstraction — Arend Jr](https://www.arendjr.nl/blog/2024/07/post-architecture-premature-abstraction-is-the-root-of-all-evil/), [AHA Programming — Kent C. Dodds](https://kentcdodds.com/blog/aha-programming), [Indirection Is Not Abstraction — Silas Reinagel](https://www.silasreinagel.com/blog/2018/10/30/indirection-is-not-abstraction/)*