@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,1076 @@
1
+ # State Management Anti-Patterns
2
+
3
+ > Domain: Code | Applies to: All frameworks and languages with stateful logic
4
+ > Severity range: Medium to Critical | Module version: 1.0.0
5
+
6
+ State management is the single largest source of bugs in modern applications. Every
7
+ user-visible glitch -- a stale form, a phantom spinner, a lost edit -- traces back to
8
+ state that was duplicated, desynchronized, mutated behind someone's back, or simply
9
+ never modeled correctly. This module catalogs 20 recurring anti-patterns, drawn from
10
+ production incidents, framework issue trackers, and community post-mortems across
11
+ React, Angular, Vue, Flutter, SwiftUI, and backend systems in Java, Python, and Go.
12
+
13
+ ---
14
+
15
+ ## Anti-Pattern 1: Global Mutable Singleton
16
+
17
+ **Also known as:** God Object State, Ambient State, Service Locator State
18
+
19
+ **Frequency:** Very High | **Severity:** High | **Detection difficulty:** Medium
20
+
21
+ ### What it looks like
22
+
23
+ A singleton class or module-level variable holds mutable application state accessible
24
+ from anywhere. In Java, a `SessionManager.getInstance().currentUser` mutated by
25
+ multiple threads. In Python, a module-level dictionary imported across files. In
26
+ JavaScript, a plain object on `window` or a module-scope `let` that multiple
27
+ components read and write.
28
+
29
+ ### Why developers do it
30
+
31
+ It is the shortest path from "I need this data everywhere" to working code. Frameworks
32
+ historically encouraged it (e.g., AngularJS services, Android Application subclass).
33
+ Junior developers copy patterns from tutorials that skip dependency injection setup.
34
+
35
+ ### What goes wrong
36
+
37
+ - **Concurrency bugs.** Two threads or two async callbacks mutate the same field; the
38
+ last writer wins silently. An IEEE study (2020) found classes utilizing mutable
39
+ global state are measurably more defect-prone.
40
+ - **Test pollution.** Test A mutates the singleton; test B reads stale values. Tests
41
+ pass individually, fail when run together. Ordering-dependent test suites follow.
42
+ - **Hidden coupling.** Any file can import and mutate the singleton, creating invisible
43
+ dependency graphs that resist refactoring.
44
+ - **Name collisions.** Third-party libraries using the same global key overwrite your
45
+ state silently.
46
+
47
+ ### The fix
48
+
49
+ Use dependency injection to pass state explicitly. In frontend apps, use scoped state
50
+ management (React Context, provider trees, Zustand stores). In backend systems, pass
51
+ state through function parameters or request-scoped containers. If a singleton is
52
+ truly needed, make it immutable and expose mutation only through controlled methods
53
+ with synchronization.
54
+
55
+ ### Detection rule
56
+
57
+ ```
58
+ Grep for module-level `let`/`var` assignments that are reassigned in multiple files.
59
+ Flag singleton classes with public mutable fields. In Java, flag `static` non-final
60
+ fields. In Python, flag module-scope mutable assignments imported by >2 modules.
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Anti-Pattern 2: State Duplication
66
+
67
+ **Also known as:** Denormalized State, Copy-Paste State, Dual Source of Truth
68
+
69
+ **Frequency:** Very High | **Severity:** High | **Detection difficulty:** Medium
70
+
71
+ ### What it looks like
72
+
73
+ The same business entity exists in two or more places in the state tree. A user's
74
+ name lives in `authStore.user.name` and also in `profileStore.displayName`. An order
75
+ total is stored both on the order object and in a summary widget's local state. When
76
+ one copy updates, the other does not.
77
+
78
+ ### Why developers do it
79
+
80
+ Different features are built by different teams or at different times. Each feature
81
+ grabs a snapshot of the data it needs. "I'll just copy it here so I don't have to
82
+ prop-drill." Denormalization feels like a performance optimization.
83
+
84
+ ### What goes wrong
85
+
86
+ - **Drift.** User updates their name in settings; the header still shows the old name
87
+ until full page reload.
88
+ - **Conflicting writes.** Two components update their local copy; the last write to
89
+ the server wins, but the UI shows a mix of old and new data.
90
+ - **Reducer complexity explodes.** Every action that changes a shared entity must now
91
+ update N locations, or you need cross-slice synchronization logic.
92
+
93
+ ### The fix
94
+
95
+ Establish a single source of truth for each entity. Reference entities by ID and look
96
+ them up from a single normalized store. Use selectors or computed properties to derive
97
+ views. If denormalization is needed for performance, treat it as a read-only cache with
98
+ explicit invalidation.
99
+
100
+ ### Detection rule
101
+
102
+ ```
103
+ In Redux/Zustand: flag identical entity types stored under multiple top-level keys.
104
+ In any codebase: search for the same API response being spread into multiple state
105
+ locations without a shared reference.
106
+ ```
107
+
108
+ ---
109
+
110
+ ## Anti-Pattern 3: Derived State Stored Separately
111
+
112
+ **Also known as:** Computed State in Store, The Synchronization Tax, Stale Derivation
113
+
114
+ **Frequency:** Very High | **Severity:** Medium | **Detection difficulty:** Low
115
+
116
+ ### What it looks like
117
+
118
+ A value that can be computed from existing state is instead stored as its own state
119
+ variable. Example: storing both `items` (an array) and `itemCount` (a number). Storing
120
+ both `cart` and `cartTotal`. Using `useEffect` to update `fullName` whenever
121
+ `firstName` or `lastName` changes.
122
+
123
+ ### Why developers do it
124
+
125
+ It feels like an optimization -- "why recompute every render?" Developers coming from
126
+ imperative backgrounds think in terms of cache variables. React's `useEffect` makes it
127
+ easy to set up "sync" logic that stores derived values.
128
+
129
+ ### What goes wrong
130
+
131
+ - **Synchronization bugs.** The derived value lags the source by one render cycle, or
132
+ the `useEffect` dependency array is incomplete, so it never updates.
133
+ - **Double renders.** Setting state inside `useEffect` triggers an extra render cycle
134
+ that is completely unnecessary.
135
+ - **Bug surface area.** Every stored derivation is another variable that can fall out
136
+ of sync, creating "impossible" UI states.
137
+
138
+ ### The fix
139
+
140
+ Compute derived values inline during render. For expensive computations, use
141
+ memoization (`useMemo`, `computed()` in Vue/MobX, `createSelector` in Redux). The
142
+ principle: "Don't sync state -- derive it." Store the minimal canonical state and
143
+ compute everything else.
144
+
145
+ ### Detection rule
146
+
147
+ ```
148
+ Flag useEffect calls where the body contains only a setState call derived from other
149
+ state/props. Flag state variables whose names are prefixes/suffixes of other state
150
+ (e.g., items/itemCount, cart/cartTotal).
151
+ ```
152
+
153
+ ---
154
+
155
+ ## Anti-Pattern 4: Mutable State Updates
156
+
157
+ **Also known as:** Direct Mutation, Reference Stomping, Shallow Copy Bypass
158
+
159
+ **Frequency:** High | **Severity:** High | **Detection difficulty:** Medium
160
+
161
+ ### What it looks like
162
+
163
+ State is mutated in place instead of creating new references. Pushing to an array
164
+ with `state.items.push(newItem)` instead of `[...state.items, newItem]`. Assigning
165
+ `state.user.name = 'new'` directly. In Flutter, mutating a list and calling
166
+ `setState` without creating a new list instance.
167
+
168
+ ### Why developers do it
169
+
170
+ Immutable updates are verbose. Developers from imperative backgrounds (Java, Python,
171
+ C++) think mutation is normal. The code "works" in simple cases because the component
172
+ happens to re-render for other reasons.
173
+
174
+ ### What goes wrong
175
+
176
+ - **Silent render skips.** React, Flutter, and SwiftUI use reference equality checks.
177
+ Mutating in place means the reference does not change, so the framework skips the
178
+ re-render and the UI shows stale data.
179
+ - **Time-travel debugging breaks.** Redux DevTools and similar tools depend on
180
+ immutable snapshots. Mutation makes every snapshot point to the same (current) object.
181
+ - **Undo/redo is impossible.** Without distinct state snapshots, there is no previous
182
+ state to restore.
183
+
184
+ ### The fix
185
+
186
+ Use immutable update patterns: spread operators, `Object.assign`, or libraries like
187
+ Immer that let you write mutation syntax while producing immutable updates under the
188
+ hood. In Dart/Flutter, use `copyWith` patterns. Enable linting rules that catch direct
189
+ mutations on state objects.
190
+
191
+ ### Detection rule
192
+
193
+ ```
194
+ ESLint: no-param-reassign on reducer parameters. In Redux Toolkit, Immer is built in.
195
+ Flag .push(), .splice(), .sort() on state arrays. Flag direct property assignment on
196
+ state objects outside of Immer produce() blocks.
197
+ ```
198
+
199
+ ---
200
+
201
+ ## Anti-Pattern 5: Scattered State
202
+
203
+ **Also known as:** State Spaghetti, FrankenState, Orphaned State
204
+
205
+ **Frequency:** High | **Severity:** Medium | **Detection difficulty:** Hard
206
+
207
+ ### What it looks like
208
+
209
+ Application state is spread across local component state, multiple context providers,
210
+ a Redux store, URL query parameters, localStorage, cookies, and in-memory caches --
211
+ with no clear ownership boundaries. A developer must check five different locations to
212
+ understand what data a screen is actually displaying.
213
+
214
+ ### Why developers do it
215
+
216
+ Organic growth. The first feature used useState. The second needed sharing, so Context
217
+ was added. The third needed persistence, so localStorage was added. The fourth needed
218
+ server sync, so React Query appeared. Nobody drew a boundary diagram.
219
+
220
+ ### What goes wrong
221
+
222
+ - **Contradictory state.** The URL says page 2 but the store says page 1. The cache
223
+ says the item exists but localStorage says it was deleted.
224
+ - **Onboarding cost.** New developers cannot predict where to find or update a given
225
+ piece of state without reading the entire codebase.
226
+ - **Refactoring paralysis.** Moving state from one location to another requires
227
+ touching every consumer, so nobody does it.
228
+
229
+ ### The fix
230
+
231
+ Categorize state into layers with clear ownership: (1) UI state stays local (open/close,
232
+ hover, focus), (2) Client state goes in a single client store (auth, preferences,
233
+ feature flags), (3) Server state is managed by a server-cache library (React Query,
234
+ SWR, Apollo), (4) URL state lives in the router. Document the boundary and enforce
235
+ it in code review.
236
+
237
+ ### Detection rule
238
+
239
+ ```
240
+ Audit: count distinct state management mechanisms in use. If >3, review whether
241
+ boundaries are documented. Flag components that read from both a global store and
242
+ local storage for the same entity.
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Anti-Pattern 6: Over-Centralized State
248
+
249
+ **Also known as:** Everything Store, God Store, Redux Maximalism
250
+
251
+ **Frequency:** High | **Severity:** Medium | **Detection difficulty:** Low
252
+
253
+ ### What it looks like
254
+
255
+ Every piece of state -- including form input values, modal open/close flags, tooltip
256
+ visibility, and scroll position -- is stored in the global Redux/Vuex/NgRx store.
257
+ The store has hundreds of keys. Every keystroke dispatches an action through middleware.
258
+
259
+ ### Why developers do it
260
+
261
+ "Single source of truth" is misunderstood as "single location for all state." Teams
262
+ adopt a rule like "all state in Redux" for consistency without evaluating what belongs
263
+ there. Tutorials demonstrate forms wired to Redux, and teams generalize.
264
+
265
+ ### What goes wrong
266
+
267
+ - **Performance death.** Each dispatched action runs through every reducer. Broad
268
+ selectors cause unrelated components to re-render on every keystroke.
269
+ - **Boilerplate explosion.** Action types, action creators, and reducer cases for
270
+ opening a tooltip. Developer velocity drops.
271
+ - **Tight coupling.** Deleting a modal component requires also deleting its slice,
272
+ actions, and selectors from a shared store, making components non-portable.
273
+
274
+ ### The fix
275
+
276
+ Reserve global state for data that genuinely crosses component boundaries (auth tokens,
277
+ feature flags, entities shared by multiple routes). Keep ephemeral UI state local to
278
+ the component. Use server-cache libraries for API data instead of manually putting
279
+ fetch results into the store.
280
+
281
+ ### Detection rule
282
+
283
+ ```
284
+ Flag store keys that are read by exactly one component. Flag actions dispatched only
285
+ from the component that also reduces them. Measure store key count: >50 keys warrants
286
+ a review.
287
+ ```
288
+
289
+ ---
290
+
291
+ ## Anti-Pattern 7: Missing Loading and Error States
292
+
293
+ **Also known as:** Happy Path Only, Optimistic Amnesia, Partial State Modeling
294
+
295
+ **Frequency:** Very High | **Severity:** Medium | **Detection difficulty:** Low
296
+
297
+ ### What it looks like
298
+
299
+ An async operation has a state like `{ data: User | null }` with no representation
300
+ for loading or error. Or it has `isLoading` and `isError` as separate booleans that
301
+ can be true simultaneously, creating impossible combinations. The UI shows a blank
302
+ screen or stale data while a request is in flight.
303
+
304
+ ### Why developers do it
305
+
306
+ The happy path is the first thing built and demoed. Loading and error states are "I'll
307
+ add those later" items that never get addressed. Separate booleans are the obvious
308
+ (but wrong) modeling choice.
309
+
310
+ ### What goes wrong
311
+
312
+ - **Blank screens.** Data is null during loading; the component renders nothing or
313
+ crashes on `.map()` of null.
314
+ - **Phantom spinners.** `isLoading` is set to true but never set to false on error,
315
+ so the spinner runs forever.
316
+ - **Impossible states.** `isLoading: true, isError: true, data: staleData` -- the UI
317
+ cannot decide what to render.
318
+
319
+ ### The fix
320
+
321
+ Model async state as a discriminated union / tagged enum: `idle | loading | success
322
+ | error`. Each variant carries only the data relevant to that state. In TypeScript:
323
+ `type State = { status: 'idle' } | { status: 'loading' } | { status: 'success';
324
+ data: T } | { status: 'error'; error: Error }`. Use server-cache libraries that
325
+ model this correctly by default (React Query, SWR).
326
+
327
+ ### Detection rule
328
+
329
+ ```
330
+ Flag state objects with separate isLoading/isError/isSuccess booleans. Flag async
331
+ functions that set isLoading = true but have no finally/catch that resets it.
332
+ ```
333
+
334
+ ---
335
+
336
+ ## Anti-Pattern 8: Stale Closure over State
337
+
338
+ **Also known as:** Zombie Callback, Captured State, Closure Time Warp
339
+
340
+ **Frequency:** High | **Severity:** High | **Detection difficulty:** Hard
341
+
342
+ ### What it looks like
343
+
344
+ A callback or effect captures a state variable at creation time and continues to
345
+ reference that stale value after state updates. Classic example: a `setInterval`
346
+ inside `useEffect` that always logs `count` as 0 because it closed over the initial
347
+ render's value. An event listener registered once that reads state from its creation
348
+ scope.
349
+
350
+ ### Why developers do it
351
+
352
+ Closures are a fundamental JavaScript mechanism and are invisible. Developers expect
353
+ the variable to "just have the latest value." The mental model of state as a box that
354
+ updates in place conflicts with React's model of state as a snapshot per render.
355
+
356
+ ### What goes wrong
357
+
358
+ - **Silent data loss.** A save handler captures stale form data and overwrites the
359
+ server with old values.
360
+ - **Infinite loops.** A stale dependency causes an effect to re-run when it should not,
361
+ or never run when it should.
362
+ - **Intermittent bugs.** The bug only manifests when state changes between callback
363
+ creation and callback execution -- timing-dependent and hard to reproduce.
364
+
365
+ ### The fix
366
+
367
+ Use functional state updates: `setCount(prev => prev + 1)` instead of
368
+ `setCount(count + 1)`. Use refs for values that need to be read by callbacks without
369
+ triggering re-renders (`useRef` + `useEffect` to keep ref in sync). Use the
370
+ `eslint-plugin-react-hooks` exhaustive-deps rule. In newer React, `useEffectEvent`
371
+ (experimental) solves this by design.
372
+
373
+ ### Detection rule
374
+
375
+ ```
376
+ ESLint react-hooks/exhaustive-deps will flag most cases. Additionally flag
377
+ setInterval/setTimeout callbacks that reference state variables without using
378
+ functional updates.
379
+ ```
380
+
381
+ ---
382
+
383
+ ## Anti-Pattern 9: Async State Race Conditions
384
+
385
+ **Also known as:** Last-Write-Wins, Stale Response, Out-of-Order Updates
386
+
387
+ **Frequency:** High | **Severity:** Critical | **Detection difficulty:** Hard
388
+
389
+ ### What it looks like
390
+
391
+ User types in a search box. Requests for "a", "ab", "abc" fire in sequence. The
392
+ response for "a" arrives last (network jitter) and overwrites the correct result for
393
+ "abc." A rapid click on "Save" sends two requests; the second completes first, then
394
+ the first overwrites it. A component unmounts before its fetch completes and the
395
+ callback calls setState on an unmounted component.
396
+
397
+ ### Why developers do it
398
+
399
+ Developers write `fetch(url).then(data => setState(data))` without considering that
400
+ multiple calls can be in flight simultaneously. The single-threaded mental model of
401
+ JavaScript obscures the fact that multiple promises can resolve in any order.
402
+
403
+ ### What goes wrong
404
+
405
+ - **Wrong data displayed.** The UI shows results for a query the user has already
406
+ moved past.
407
+ - **Data corruption.** An older mutation response overwrites a newer one on the server
408
+ or in the client cache.
409
+ - **Memory leaks and warnings.** Setting state on unmounted components.
410
+
411
+ ### The fix
412
+
413
+ Use an abort controller: `const controller = new AbortController()` passed to fetch,
414
+ and abort in the cleanup function. Or use a boolean ignore flag:
415
+ `useEffect(() => { let ignore = false; fetch().then(d => { if (!ignore) setData(d) });
416
+ return () => { ignore = true } })`. Prefer libraries like React Query / SWR / Apollo
417
+ that handle cancellation and deduplication automatically.
418
+
419
+ ### Detection rule
420
+
421
+ ```
422
+ Flag useEffect with async fetch calls that do not return a cleanup function. Flag
423
+ setState calls inside .then() without a guard. ESLint plugin eslint-plugin-react-hooks
424
+ flags missing cleanup in some cases.
425
+ ```
426
+
427
+ ---
428
+
429
+ ## Anti-Pattern 10: Optimistic UI without Rollback
430
+
431
+ **Also known as:** Fire-and-Forget Optimism, Hope-Driven UI
432
+
433
+ **Frequency:** Medium | **Severity:** High | **Detection difficulty:** Medium
434
+
435
+ ### What it looks like
436
+
437
+ The UI immediately reflects a user action (like deleting an item) without waiting for
438
+ the server response, but has no mechanism to revert the change if the server returns
439
+ an error. The item disappears from the list, the server rejects the delete (403), and
440
+ the item is gone from the UI but still exists on the server. A refresh brings it back,
441
+ confusing the user.
442
+
443
+ ### Why developers do it
444
+
445
+ Optimistic UI is presented as a UX best practice -- "make the app feel instant." The
446
+ happy path is implemented first; rollback is deferred and forgotten. Rolling back is
447
+ genuinely hard when multiple optimistic mutations are queued.
448
+
449
+ ### What goes wrong
450
+
451
+ - **Phantom state.** The UI and server disagree on reality. Users take further actions
452
+ based on the phantom state, compounding the inconsistency.
453
+ - **Lost edits.** Optimistic create succeeds in UI, server rejects, user adds data to
454
+ the phantom entity, all of which is lost on refresh.
455
+ - **Cascading failures.** Multiple optimistic updates build on each other; rolling back
456
+ one requires rolling back all dependents.
457
+
458
+ ### The fix
459
+
460
+ Always pair optimistic updates with a rollback path. Cache the previous state before
461
+ applying the optimistic change. On server error, restore the cached state and show a
462
+ user-facing error. Use libraries with built-in optimistic mutation support (React
463
+ Query's `onMutate` / `onError` / `onSettled`, Apollo's `optimisticResponse`). Avoid
464
+ optimistic UI for operations with high failure rates or irreversible consequences.
465
+
466
+ ### Detection rule
467
+
468
+ ```
469
+ Flag mutation functions that call setState before awaiting the server response but
470
+ have no catch/error handler that restores previous state. Review optimistic update
471
+ implementations for the presence of rollback logic.
472
+ ```
473
+
474
+ ---
475
+
476
+ ## Anti-Pattern 11: State Management Library Overkill
477
+
478
+ **Also known as:** Redux for a Counter, Ceremony-Driven Development, Premature Architecture
479
+
480
+ **Frequency:** High | **Severity:** Low | **Detection difficulty:** Low
481
+
482
+ ### What it looks like
483
+
484
+ A small application with 3-5 pieces of shared state uses Redux (or NgRx, or Vuex)
485
+ with full action/reducer/middleware/selector ceremony. A simple form has action types
486
+ like `SET_FIRST_NAME`, `SET_LAST_NAME`, `SET_EMAIL`. The boilerplate exceeds the
487
+ business logic by 5:1.
488
+
489
+ ### Why developers do it
490
+
491
+ "We might scale later." Blog posts and conference talks showcase Redux for large apps,
492
+ and teams cargo-cult the same setup for a to-do app. Hiring managers list Redux as a
493
+ requirement, so developers use it everywhere to stay practiced.
494
+
495
+ ### What goes wrong
496
+
497
+ - **Velocity death.** Adding a feature requires creating a slice, actions, selectors,
498
+ and possibly sagas -- for something `useState` handles in one line.
499
+ - **Cognitive overhead.** New developers are overwhelmed by indirection before they
500
+ even see the business logic.
501
+ - **Abandoned migration.** The team later wants to remove Redux but it is wired into
502
+ everything, so it stays as legacy weight.
503
+
504
+ ### The fix
505
+
506
+ Start with the simplest state mechanism (`useState`, `useReducer`, Context). Add a
507
+ state library only when you observe a concrete problem: prop drilling through 4+
508
+ levels, frequent cross-component state sharing, or need for time-travel debugging.
509
+ For server data, use a server-cache library instead of manually putting API data into
510
+ Redux.
511
+
512
+ ### Detection rule
513
+
514
+ ```
515
+ Count actions and reducers vs. components. If the ratio of actions to components
516
+ exceeds 3:1 and the app has fewer than 20 routes, evaluate whether the library is
517
+ justified.
518
+ ```
519
+
520
+ ---
521
+
522
+ ## Anti-Pattern 12: Implicit State Machines (Boolean Soup)
523
+
524
+ **Also known as:** Boolean Flag Hell, Impossible States, Ad-Hoc State Modeling
525
+
526
+ **Frequency:** Very High | **Severity:** High | **Detection difficulty:** Low
527
+
528
+ ### What it looks like
529
+
530
+ A component manages its state with multiple independent booleans: `isLoading`,
531
+ `isError`, `isSuccess`, `isRetrying`, `isOpen`, `isAnimating`. With 6 booleans
532
+ there are 64 possible combinations, but only 5-8 are valid. Nothing in the code
533
+ prevents the other 56+ impossible combinations.
534
+
535
+ ### Why developers do it
536
+
537
+ Each boolean is added incrementally as new requirements emerge. "We need a loading
538
+ state" -- add a boolean. "Now we need error handling" -- add another boolean. The
539
+ cognitive load of each addition is small, but the combinatorial explosion is not
540
+ visible until bugs appear.
541
+
542
+ ### What goes wrong
543
+
544
+ - **Impossible states.** `isLoading: true` AND `isError: true` simultaneously. The UI
545
+ shows a spinner overlaid on an error message.
546
+ - **Missing transitions.** The code forgets to set `isLoading = false` in the error
547
+ path. The spinner runs forever.
548
+ - **Untestable.** Testing 64 combinations is impractical, so edge cases go uncovered.
549
+ Kent C. Dodds: "Stop using isLoading booleans."
550
+
551
+ ### The fix
552
+
553
+ Replace boolean flags with a single status field modeled as a discriminated union or
554
+ enum: `type Status = 'idle' | 'loading' | 'success' | 'error'`. For complex flows,
555
+ use a state machine library (XState, Robot) that makes transitions explicit and
556
+ impossible states unreachable by construction.
557
+
558
+ ### Detection rule
559
+
560
+ ```
561
+ Flag components with 3+ boolean state variables whose names start with is/has/should.
562
+ Flag setState calls that set multiple booleans simultaneously. Static analysis: count
563
+ boolean state variables per component.
564
+ ```
565
+
566
+ ---
567
+
568
+ ## Anti-Pattern 13: Zombie Child Problem
569
+
570
+ **Also known as:** Stale Props, Ghost Subscriber, Undead Component
571
+
572
+ **Frequency:** Medium | **Severity:** High | **Detection difficulty:** Hard
573
+
574
+ ### What it looks like
575
+
576
+ A parent component renders a list of children connected to a global store. An action
577
+ deletes an entity from the store. The child component's subscription fires before the
578
+ parent re-renders and removes the child. The child tries to read the deleted entity
579
+ from the store, gets `undefined`, and throws. This was a well-documented issue in
580
+ React-Redux v5-v7 and remains possible with hooks-based store subscriptions.
581
+
582
+ ### Why developers do it
583
+
584
+ External store subscriptions (Zustand, Redux with `useSelector`, custom pub-sub) do
585
+ not follow React's top-down rendering order. Child subscriptions can fire before
586
+ parent subscriptions, creating a window where the child exists but its data does not.
587
+
588
+ ### What goes wrong
589
+
590
+ - **Runtime crashes.** `Cannot read property 'name' of undefined` on a component that
591
+ is about to unmount but has not yet.
592
+ - **Inconsistent UI.** For a brief moment (often a single frame), the child renders
593
+ with missing or default data before being unmounted.
594
+ - **Hard to reproduce.** Depends on subscription ordering and timing; may not appear
595
+ in development but crashes in production under load.
596
+
597
+ ### The fix
598
+
599
+ Defensive selectors: always guard against missing data (`const item = useSelector(s =>
600
+ s.items[id] ?? EMPTY_ITEM)`). React-Redux's `useSelector` catches errors thrown during
601
+ store-update-triggered selector execution and forces a re-render. When building custom
602
+ subscription hooks, implement stale-check guards. Libraries like Zustand handle this
603
+ via `useSyncExternalStore`.
604
+
605
+ ### Detection rule
606
+
607
+ ```
608
+ Flag selectors that access store properties via dynamic IDs without null/undefined
609
+ guards. Flag connected child components in lists that do not handle the case where
610
+ their entity has been deleted.
611
+ ```
612
+
613
+ ---
614
+
615
+ ## Anti-Pattern 14: Props as Initial State
616
+
617
+ **Also known as:** Snapshot State, Stale Initialization, One-Time Copy
618
+
619
+ **Frequency:** High | **Severity:** Medium | **Detection difficulty:** Low
620
+
621
+ ### What it looks like
622
+
623
+ A child component receives a prop and copies it into local state in the constructor
624
+ or `useState` initializer: `const [name, setName] = useState(props.name)`. When the
625
+ parent updates `props.name`, the child continues to display the old value because
626
+ `useState` only uses the initial value on mount.
627
+
628
+ ### Why developers do it
629
+
630
+ The component needs to allow local edits (e.g., a form pre-filled from props). The
631
+ developer reaches for `useState` because they know the child needs its own mutable
632
+ copy. In class components, `getInitialState` from props was a common tutorial pattern.
633
+
634
+ ### What goes wrong
635
+
636
+ - **Stale display.** Parent updates the entity; child shows outdated data until
637
+ remounted.
638
+ - **Data loss.** User edits the child form, parent re-renders (but does not remount
639
+ the child), user's edits are preserved but the prop change is lost. Or worse, a key
640
+ change remounts the child and wipes user edits.
641
+ - **Source of truth confusion.** Is the parent or the child authoritative? Neither
642
+ developer nor user can tell.
643
+
644
+ ### The fix
645
+
646
+ If the child should always reflect the parent's data, do not use state -- use the prop
647
+ directly. If the child needs an editable copy, use a `key` prop tied to the entity ID
648
+ so React remounts on entity change: `<Editor key={user.id} user={user} />`. Name
649
+ initial-value props clearly: `initialValue` or `defaultValue` to signal intent. Use
650
+ controlled components where the parent owns both the value and the change handler.
651
+
652
+ ### Detection rule
653
+
654
+ ```
655
+ Flag useState calls where the initializer is a prop that is not named initial* or
656
+ default*. Flag components that both receive a prop and have state of the same name.
657
+ ```
658
+
659
+ ---
660
+
661
+ ## Anti-Pattern 15: Two-Way Data Binding Chaos
662
+
663
+ **Also known as:** Bidirectional Mutation, Digest Cycle Storms, Ping-Pong State
664
+
665
+ **Frequency:** Medium | **Severity:** High | **Detection difficulty:** Medium
666
+
667
+ ### What it looks like
668
+
669
+ Two or more components are bound bidirectionally to the same data source. Changing
670
+ component A updates the model, which triggers component B to update, which triggers
671
+ a watcher that updates the model again. In AngularJS, this manifested as infinite
672
+ digest cycles. In modern frameworks, it appears as circular `useEffect` chains or
673
+ Vue watchers that trigger each other.
674
+
675
+ ### Why developers do it
676
+
677
+ Two-way binding is convenient for forms and feels natural: "the input and the model
678
+ should always agree." AngularJS made it the default. Vue's `v-model` encourages it.
679
+ Developers extend the pattern beyond simple inputs to complex cross-component
680
+ synchronization.
681
+
682
+ ### What goes wrong
683
+
684
+ - **Infinite loops.** A changes B, B changes A, repeat. AngularJS had a hard limit of
685
+ 10 digest cycles before throwing. Modern frameworks may produce infinite re-render
686
+ loops that freeze the browser.
687
+ - **Performance degradation.** Every binding creates watchers. Hundreds of bindings
688
+ cause page lag on every keystroke.
689
+ - **Unpredictable data flow.** With bidirectional flows, data can arrive at a component
690
+ from multiple directions, making debugging which source caused a change very
691
+ difficult.
692
+
693
+ ### The fix
694
+
695
+ Prefer unidirectional data flow: parent passes data down, child emits events up. Use
696
+ two-way binding only for leaf-level form inputs. For complex forms, use a form library
697
+ that manages the binding lifecycle (React Hook Form, Formik, Angular Reactive Forms).
698
+ Never create circular watcher/effect dependencies.
699
+
700
+ ### Detection rule
701
+
702
+ ```
703
+ Flag circular dependencies between useEffect hooks (effect A sets state that is a
704
+ dependency of effect B, and vice versa). Flag Vue watchers that modify the same data
705
+ they observe. In AngularJS, flag $watch callbacks that trigger $apply/$digest.
706
+ ```
707
+
708
+ ---
709
+
710
+ ## Anti-Pattern 16: State Stored in DOM
711
+
712
+ **Also known as:** DOM as Database, jQuery State Management, Data Attribute Abuse
713
+
714
+ **Frequency:** Medium (declining) | **Severity:** Medium | **Detection difficulty:** Low
715
+
716
+ ### What it looks like
717
+
718
+ Application state is stored in DOM elements: data attributes, hidden input fields,
719
+ CSS class names toggled to represent state, or jQuery's `$.data()` cache. A "selected"
720
+ state is tracked by the presence of a `.selected` CSS class rather than a JavaScript
721
+ variable. Form data is read from the DOM instead of maintained in a model.
722
+
723
+ ### Why developers do it
724
+
725
+ This was the dominant pattern in the jQuery era. Developers new to frameworks sometimes
726
+ carry the habit forward. It is the path of least resistance when there is no state
727
+ management layer. Server-rendered pages with progressive enhancement sometimes start
728
+ this way.
729
+
730
+ ### What goes wrong
731
+
732
+ - **Performance.** Reading state from the DOM requires DOM queries, which are orders of
733
+ magnitude slower than reading a JavaScript variable.
734
+ - **Fragility.** A CSS refactor removes the `.selected` class, and the state mechanism
735
+ silently breaks. DOM structure changes break querySelector-based state lookups.
736
+ - **No reactivity.** DOM mutations do not trigger framework-level re-renders. The UI
737
+ and the "state" can diverge without any error.
738
+ - **Testability.** Testing requires a full DOM environment (JSDOM or a browser), making
739
+ unit tests slow and brittle.
740
+
741
+ ### The fix
742
+
743
+ Separate state from presentation. Store state in JavaScript variables, and let the
744
+ framework render the DOM from that state. If progressive enhancement is needed, read
745
+ initial state from DOM/data attributes once at startup and then manage it in JavaScript.
746
+
747
+ ### Detection rule
748
+
749
+ ```
750
+ Flag jQuery $.data() usage in codebases using React/Vue/Angular. Flag
751
+ document.querySelector used for reading state. Flag CSS class checks used in
752
+ conditional logic (classList.contains in business logic).
753
+ ```
754
+
755
+ ---
756
+
757
+ ## Anti-Pattern 17: Storing Computed Values in State
758
+
759
+ **Also known as:** Redundant State, Memoization Confusion, Cache-in-State
760
+
761
+ **Frequency:** High | **Severity:** Low | **Detection difficulty:** Low
762
+
763
+ ### What it looks like
764
+
765
+ State contains values that are purely derived from other state: `fullName` stored
766
+ alongside `firstName` and `lastName`. `filteredItems` stored alongside `items` and
767
+ `filterQuery`. `isValid` stored alongside the form fields it validates. These values
768
+ are updated via effects or event handlers that "sync" them with their sources.
769
+
770
+ ### Why developers do it
771
+
772
+ It feels like caching. Developers worry about re-computing on every render. In class
773
+ components, there was no `useMemo` equivalent, so storing computed values was the norm.
774
+ Some developers confuse memoization with state management.
775
+
776
+ ### What goes wrong
777
+
778
+ - **Sync bugs.** The computed value is updated in one code path but not another.
779
+ `fullName` reflects a name change from the form but not from a server push.
780
+ - **Extra renders.** Setting state inside `useEffect` to "sync" triggers a second
781
+ render cycle per update.
782
+ - **Increased state surface.** More state means more reducer cases, more tests, and
783
+ more potential for inconsistency.
784
+
785
+ ### The fix
786
+
787
+ Compute values inline: `const fullName = \`\${firstName} \${lastName}\``. For expensive
788
+ computations, use `useMemo` (React), `computed` (Vue/MobX), or `createSelector`
789
+ (Redux). These are memoization, not state, and they have no sync bugs because they
790
+ derive from the source directly.
791
+
792
+ ### Detection rule
793
+
794
+ ```
795
+ Flag state variables whose setter is only ever called inside useEffect with
796
+ dependencies that are other state variables. Flag state variables that are never set
797
+ by user actions, only by other state changes.
798
+ ```
799
+
800
+ ---
801
+
802
+ ## Anti-Pattern 18: Not Normalizing Relational Data
803
+
804
+ **Also known as:** Nested State Tree, Deep Copy Hell, Entity Spaghetti
805
+
806
+ **Frequency:** High | **Severity:** Medium | **Detection difficulty:** Medium
807
+
808
+ ### What it looks like
809
+
810
+ API responses are stored in state exactly as received: deeply nested objects with
811
+ embedded related entities. A `Post` object contains an array of `Comment` objects,
812
+ each containing a `User` object. Updating a user's avatar requires finding every post,
813
+ then every comment by that user, and updating each nested copy.
814
+
815
+ ### Why developers do it
816
+
817
+ The API response shape is convenient -- it matches the UI hierarchy. Normalizing feels
818
+ like premature optimization. The initial code is simpler: just `setState(apiResponse)`.
819
+
820
+ ### What goes wrong
821
+
822
+ - **Update complexity.** Changing one entity requires deep traversal and immutable
823
+ updates at every nesting level. Reducers become deeply nested spread operations.
824
+ - **Inconsistency.** The same user appears in 15 comments with 15 copies of their
825
+ avatar URL. Updating one and missing the others creates visual inconsistency.
826
+ - **Performance.** Deeply nested equality checks are expensive. Any change to any
827
+ comment causes the entire post tree to be treated as changed.
828
+
829
+ ### The fix
830
+
831
+ Normalize data into flat lookup tables: `{ users: { byId: {}, allIds: [] }, posts:
832
+ { byId: {}, allIds: [] }, comments: { byId: {}, allIds: [] } }`. Use libraries like
833
+ `normalizr` to automate the transformation from API responses. Reference related
834
+ entities by ID. Use selectors to denormalize for display.
835
+
836
+ ### Detection rule
837
+
838
+ ```
839
+ Flag state objects nested more than 3 levels deep. Flag reducer spread operations
840
+ with more than 2 levels of nesting. Flag API responses stored directly in state
841
+ without transformation.
842
+ ```
843
+
844
+ ---
845
+
846
+ ## Anti-Pattern 19: Exposing Internal State Implementation
847
+
848
+ **Also known as:** Leaky State Abstraction, Public Internals, State Coupling
849
+
850
+ **Frequency:** Medium | **Severity:** Medium | **Detection difficulty:** Medium
851
+
852
+ ### What it looks like
853
+
854
+ A component or module exposes its internal state structure to consumers. A store's
855
+ shape becomes a public API contract: consumers directly access `store.state.ui.
856
+ modals.confirmDialog.isOpen` instead of calling `store.isConfirmDialogOpen()`. A class
857
+ exposes a mutable collection via a getter, allowing external code to modify internal
858
+ state without going through methods.
859
+
860
+ ### Why developers do it
861
+
862
+ Direct property access is faster to write than defining a selector or method.
863
+ Encapsulation feels like over-engineering for "simple" state. In Redux, the state
864
+ shape is inherently visible to all selectors, making it easy to couple deeply.
865
+
866
+ ### What goes wrong
867
+
868
+ - **Refactoring paralysis.** Renaming a state key or restructuring the state tree
869
+ breaks every consumer that accessed it directly. What should be an internal change
870
+ becomes a cross-codebase migration.
871
+ - **Invariant violations.** External code modifies internal state without going through
872
+ validation logic, putting the module into an inconsistent state.
873
+ - **Brittle tests.** Tests assert against internal state shape instead of observable
874
+ behavior, breaking on every internal refactor.
875
+
876
+ ### The fix
877
+
878
+ Expose state through selectors, computed properties, or accessor methods. In Redux,
879
+ co-locate selectors with the slice and export only selectors, not the state shape.
880
+ In OOP, return defensive copies of collections, not references. In classes, make state
881
+ fields private and expose behavior through methods.
882
+
883
+ ### Detection rule
884
+
885
+ ```
886
+ Flag external files importing and accessing store state paths deeper than 2 levels.
887
+ Flag public mutable fields on state-holding classes. Flag tests that assert against
888
+ internal state structure rather than observable behavior.
889
+ ```
890
+
891
+ ---
892
+
893
+ ## Anti-Pattern 20: Cache as Source of Truth
894
+
895
+ **Also known as:** Cache Statization, Client Mirror, Optimistic Cache
896
+
897
+ **Frequency:** Medium | **Severity:** High | **Detection difficulty:** Medium
898
+
899
+ ### What it looks like
900
+
901
+ The application treats its client-side cache (Redux store, Apollo cache, React Query
902
+ cache) as the authoritative source of data rather than the server. Components read
903
+ from the cache and never re-fetch, even after mutations. Cache entries are manually
904
+ updated to avoid re-fetching, creating a parallel "database" in the browser. The
905
+ server and client gradually diverge.
906
+
907
+ ### Why developers do it
908
+
909
+ Re-fetching feels wasteful. Cache updates are faster than round-trips. The app "works"
910
+ in demo environments where the user is the only client. Developers conflate "cache for
911
+ performance" with "cache as state."
912
+
913
+ ### What goes wrong
914
+
915
+ - **Stale data.** Another user (or another tab) modifies the data on the server. The
916
+ client never learns about it because it trusts its cache.
917
+ - **Cache invalidation bugs.** Manually updating cache entries after mutations is
918
+ error-prone. Miss one cache key and the UI shows contradictory data.
919
+ - **Offline divergence.** The cache and server diverge during offline periods. Merging
920
+ them back is a distributed systems problem that most apps are not equipped to solve.
921
+ - **FrankenState.** Half the data is managed as "state" in Redux, half as "cache" in
922
+ React Query. Boundaries blur and data is duplicated across both.
923
+
924
+ ### The fix
925
+
926
+ Treat the server as the source of truth and the client as a cache. Use server-cache
927
+ libraries (React Query, SWR, Apollo) with proper cache invalidation strategies:
928
+ refetch on mount, refetch on window focus, invalidate after mutations. Set appropriate
929
+ stale times. For truly offline-first apps, use dedicated offline sync solutions (e.g.,
930
+ WatermelonDB, PouchDB) rather than ad-hoc cache management.
931
+
932
+ ### Detection rule
933
+
934
+ ```
935
+ Flag manual cache.writeQuery / queryClient.setQueryData calls that are not
936
+ accompanied by an invalidation or refetch. Flag applications where server data is
937
+ only fetched once (on mount) and never refreshed. Flag store data that is >5 minutes
938
+ old with no TTL mechanism.
939
+ ```
940
+
941
+ ---
942
+
943
+ ## Root Cause Analysis
944
+
945
+ Most state management anti-patterns trace back to five root causes:
946
+
947
+ ### 1. No Ownership Model
948
+
949
+ When nobody defines which layer owns each piece of state, state proliferates across
950
+ layers and duplicates. Every team or feature creates its own state silo. The fix is
951
+ to create a state ownership diagram early and enforce it in code review.
952
+
953
+ ### 2. Imperative Mental Model
954
+
955
+ Developers with imperative backgrounds think of state as mutable boxes. Frameworks
956
+ like React, Flutter, and SwiftUI are declarative and use value semantics for change
957
+ detection. The clash produces mutation bugs, stale closures, and missed re-renders.
958
+
959
+ ### 3. Premature Abstraction
960
+
961
+ Adopting a state management library (Redux, MobX, Vuex) before understanding the
962
+ problem leads to over-engineering. The library's patterns become the architecture
963
+ instead of serving it. Start simple, add complexity when concrete problems arise.
964
+
965
+ ### 4. Ignoring Async Complexity
966
+
967
+ Synchronous state management is straightforward. Most bugs live at the boundary
968
+ between sync and async: race conditions, stale closures, optimistic updates, and
969
+ cache invalidation. Developers underestimate this complexity because the happy path
970
+ works in development.
971
+
972
+ ### 5. Missing State Modeling
973
+
974
+ State is treated as a bag of variables instead of a model with defined states and
975
+ transitions. Boolean flags replace finite state machines. Loading/error/success is
976
+ an afterthought. The fix is to model state as a type system with discriminated unions
977
+ or state machines before writing any UI code.
978
+
979
+ ---
980
+
981
+ ## Self-Check Questions
982
+
983
+ Use these questions during code review or architecture discussions:
984
+
985
+ 1. **Can I point to exactly one location in the codebase that owns this data?**
986
+ If you find 2+ locations, you have state duplication (Anti-Pattern 2).
987
+
988
+ 2. **If I delete this state variable, can I recompute it from other state?**
989
+ If yes, it is derived state and should not be stored (Anti-Patterns 3, 17).
990
+
991
+ 3. **What happens if two async operations complete out of order?**
992
+ If the answer is "the wrong data displays," you have a race condition
993
+ (Anti-Pattern 9).
994
+
995
+ 4. **Can this component be in a state that should be impossible?**
996
+ List all boolean state variables. If 2^N exceeds your valid states by more than
997
+ 2x, you need a state machine (Anti-Pattern 12).
998
+
999
+ 5. **What happens when the server says no to our optimistic update?**
1000
+ If there is no rollback path, you have Anti-Pattern 10.
1001
+
1002
+ 6. **Is this state management library earning its keep?**
1003
+ If more than 60% of actions are consumed by a single component, the library is
1004
+ overkill (Anti-Pattern 11).
1005
+
1006
+ 7. **How many state management mechanisms are in this app?**
1007
+ If the answer is >3 (e.g., Redux + Context + localStorage + URL params + React
1008
+ Query), review boundaries (Anti-Pattern 5).
1009
+
1010
+ 8. **Would a new developer know where to find the state for this feature?**
1011
+ If it takes more than 30 seconds to locate, state is too scattered (Anti-Pattern 5)
1012
+ or too coupled to internals (Anti-Pattern 19).
1013
+
1014
+ 9. **If I refactor the internal state shape, how many files break?**
1015
+ If more than the module itself, you are exposing internal state (Anti-Pattern 19).
1016
+
1017
+ 10. **When was this cached data last validated against the server?**
1018
+ If the answer is "only on initial load," you may be treating cache as source of
1019
+ truth (Anti-Pattern 20).
1020
+
1021
+ ---
1022
+
1023
+ ## Code Smell Quick Reference
1024
+
1025
+ | Smell | Anti-Pattern | Severity |
1026
+ |---|---|---|
1027
+ | Module-scope `let` imported by multiple files | #1 Global Mutable Singleton | High |
1028
+ | Same entity type in 2+ store slices | #2 State Duplication | High |
1029
+ | `useEffect` that only calls `setState` | #3 Derived State Stored | Medium |
1030
+ | `.push()` / `.splice()` on state array | #4 Mutable State Updates | High |
1031
+ | 3+ state mechanisms (Redux + Context + localStorage) | #5 Scattered State | Medium |
1032
+ | Store key read by exactly 1 component | #6 Over-Centralized State | Medium |
1033
+ | `data: null` with no `loading`/`error` status | #7 Missing Loading/Error | Medium |
1034
+ | `setInterval` referencing state without functional update | #8 Stale Closure | High |
1035
+ | `.then(setData)` without abort/ignore guard | #9 Async Race Condition | Critical |
1036
+ | Optimistic setState with no catch/rollback | #10 Optimistic without Rollback | High |
1037
+ | Action-to-component ratio > 3:1 in small app | #11 Library Overkill | Low |
1038
+ | 3+ boolean `is*` state variables in one component | #12 Boolean Soup | High |
1039
+ | Selector accessing `store[id]` without null guard | #13 Zombie Child | High |
1040
+ | `useState(props.x)` where prop is not named `initial*` | #14 Props as Initial State | Medium |
1041
+ | Circular `useEffect` / watcher dependencies | #15 Two-Way Binding Chaos | High |
1042
+ | `document.querySelector` in React conditional logic | #16 State in DOM | Medium |
1043
+ | State variable only set inside `useEffect` | #17 Computed Values in State | Low |
1044
+ | State objects nested 3+ levels deep | #18 Non-Normalized Data | Medium |
1045
+ | External file accessing `store.state.a.b.c.d` | #19 Exposed Internal State | Medium |
1046
+ | Server data fetched once, never refreshed | #20 Cache as Source of Truth | High |
1047
+
1048
+ ---
1049
+
1050
+ ## Sources
1051
+
1052
+ - [Redux Anti-Patterns - State Management (Minko Gechev)](https://blog.mgechev.com/2017/12/07/redux-anti-patterns-race-conditions-state-management-duplication/)
1053
+ - [State Management Anti Patterns (Source Allies)](https://www.sourceallies.com/2020/11/state-management-anti-patterns/)
1054
+ - [Global Mutable State (Eric Normand)](https://ericnormand.me/article/global-mutable-state)
1055
+ - [Impact of Mutable Global State on Defect Proneness (IEEE Xplore)](https://ieeexplore.ieee.org/document/9118816)
1056
+ - [Stop Using isLoading Booleans (Kent C. Dodds)](https://kentcdodds.com/blog/stop-using-isloading-booleans)
1057
+ - [Make Impossible States Impossible (Kent C. Dodds)](https://kentcdodds.com/blog/make-impossible-states-impossible)
1058
+ - [Don't Sync State. Derive It! (Kent C. Dodds)](https://kentcdodds.com/blog/dont-sync-state-derive-it)
1059
+ - [You Probably Don't Need Derived State (React Blog)](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html)
1060
+ - [Be Aware of Stale Closures when Using React Hooks (Dmitri Pavlutin)](https://dmitripavlutin.com/react-hooks-stale-closures/)
1061
+ - [5 Mistakes to Avoid When Using React Hooks (Dmitri Pavlutin)](https://dmitripavlutin.com/react-hooks-mistakes-to-avoid/)
1062
+ - [Stale Props and Zombie Children in Redux (Kai Hao)](https://kaihao.dev/posts/Stale-props-and-zombie-children-in-Redux)
1063
+ - [React-Redux Roadmap: Context, Subscriptions, and Hooks (GitHub Issue #1177)](https://github.com/reduxjs/react-redux/issues/1177)
1064
+ - [Normalizing State Shape (Redux Docs)](https://redux.js.org/usage/structuring-reducers/normalizing-state-shape)
1065
+ - [Props in Initial State is an Anti-pattern (React Patterns)](https://reactpatterns.js.org/docs/props-in-initial-state-is-an-anti-pattern/)
1066
+ - [Avoiding Mutable Global State in Browser JS (Josh Wulf)](https://www.joshwulf.com/blog/2020/02/avoid-global-state/)
1067
+ - [Why Singleton Design Pattern is Considered an Anti-pattern (GeeksforGeeks)](https://www.geeksforgeeks.org/why-is-singleton-design-pattern-is-considered-an-anti-pattern/)
1068
+ - [Hooks, Dependencies and Stale Closures (TkDodo)](https://tkdodo.eu/blog/hooks-dependencies-and-stale-closures)
1069
+ - [Optimistic Updates (TanStack Query)](https://tanstack.com/query/v4/docs/react/guides/optimistic-updates)
1070
+ - [useState Race Conditions and Gotchas in React (Leonardo)](https://leo88.medium.com/usestate-race-conditions-gotchas-in-react-and-how-to-fix-them-48f0cddb9702)
1071
+ - [Why Most React Bugs Come From State Inconsistency, Async Updates, and Race Conditions](https://medium.com/@rahulkengale1110/why-inconsistent-state-async-updates-and-race-conditions-cause-most-react-and-frontend-bugs-3bd141602e0a)
1072
+ - [React State Management in 2025 (Nadia Makarevich)](https://www.developerway.com/posts/react-state-management-2025)
1073
+ - [Global Variables and States: Why So Much Hate? (The Valuable Dev)](https://thevaluable.dev/global-variable-explained/)
1074
+ - [The Consequences of Using State over Cache (Arthur.place)](https://arthur.place/implications-of-cache-or-state)
1075
+ - [React useEffectEvent: Goodbye to Stale Closure Headaches (LogRocket)](https://blog.logrocket.com/react-useeffectevent/)
1076
+ - [Stop Using useEffect for Derived State (DreamerKumar)](https://medium.com/@dreamerkumar/stop-using-useeffect-for-derived-state-a-react-anti-pattern-thats-killing-your-app-s-performance-8dcb83b48805)