@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,663 @@
1
+ # Search Architecture — Architecture Expertise Module
2
+
3
+ > Search architecture covers full-text search, faceted search, autocomplete, and increasingly vector/semantic search for AI applications. The key decision is whether to use your primary database's built-in search (PostgreSQL full-text) or a dedicated search engine (Elasticsearch, Typesense, Meilisearch). Most apps should start with database search and add a dedicated engine only when complexity or scale demands it.
4
+
5
+ > **Category:** Data
6
+ > **Complexity:** Complex
7
+ > **Applies when:** Applications needing full-text search, faceted filtering, autocomplete, fuzzy matching, or vector/semantic search
8
+
9
+ ---
10
+
11
+ ## What This Is
12
+
13
+ ### The Core Concepts
14
+
15
+ Search architecture is the set of data structures, indexing strategies, ranking algorithms, and system topologies that let users find information in a corpus of documents. "Documents" here means any searchable entity — product listings, articles, user profiles, log entries, code, support tickets. The architecture sits between write-path (how data enters the index) and read-path (how queries are executed and results are ranked).
16
+
17
+ There are five fundamental capabilities that any search architecture must address, whether using a built-in database feature or a dedicated engine:
18
+
19
+ **Full-Text Search.** Given a query string, find all documents containing those terms, rank them by relevance, and return the top N. This requires an inverted index — a data structure that maps every distinct term to the list of documents containing it. When you search for "distributed consensus", the engine looks up "distributed" in the inverted index (returning document IDs 4, 17, 42, 91), then "consensus" (returning 17, 42, 88), intersects the sets, scores the results, and returns them ranked. PostgreSQL's `tsvector`/`tsquery`, Elasticsearch, Typesense, and Meilisearch all implement this core primitive. The critical difference between implementations is in their analyzers (how text is tokenized, stemmed, and normalized), their ranking algorithms (TF-IDF vs BM25 vs custom), and their performance at scale.
20
+
21
+ **Faceted Search.** Given a set of search results, compute aggregation counts across categorical dimensions. "Show me laptops, and on the left sidebar tell me there are 42 results from Dell, 38 from Lenovo, 31 from Apple, and that prices range from $400 to $3,200." Faceted search requires both the inverted index (to find matching documents) and columnar aggregation (to compute counts per category). Elasticsearch excels here with its aggregation framework. PostgreSQL can approximate it with `GROUP BY` queries but lacks the tight integration between search results and aggregation that dedicated engines provide.
22
+
23
+ **Autocomplete / Typeahead.** As the user types, suggest completions in real time (under 100ms per keystroke). This requires a different index structure than full-text search: edge n-grams (breaking "elasticsearch" into "e", "el", "ela", "elas", ...) or prefix tries. The challenge is not just finding matches but ranking them by popularity, recency, and personalization. LinkedIn's Cleo library implements a multi-layer architecture for typeahead: browser cache, web-tier cache, result aggregator, and backend services with inverted/forward indexes, bloom filters, and scorers. At the simplest level, a PostgreSQL `LIKE 'prefix%'` query with a B-tree index works for small datasets, but dedicated autocomplete requires specialized data structures.
24
+
25
+ **Fuzzy Matching.** Handle typos, misspellings, and phonetic variations. "elasticsaerch" should still match "elasticsearch". This is implemented via edit distance (Levenshtein distance), n-gram overlap, or phonetic algorithms (Soundex, Metaphone). Typesense enables typo tolerance by default with configurable thresholds. Elasticsearch requires explicit configuration of fuzzy queries or custom analyzers. PostgreSQL's `pg_trgm` extension provides trigram-based similarity matching but with limited configurability.
26
+
27
+ **Vector / Semantic Search.** Instead of matching keywords, match meaning. A query for "affordable laptop for students" should match a document about "budget-friendly notebooks for college" even though the terms differ. This requires converting text into dense vector embeddings (using models like OpenAI's text-embedding-3, Cohere's embed-v3, or open-source alternatives like BGE/E5) and performing approximate nearest neighbor (ANN) search in high-dimensional space. Vector search has become the foundation of RAG (Retrieval-Augmented Generation) pipelines in 2025-2026, where LLMs need relevant context retrieved from a knowledge base. Hybrid search — combining BM25 keyword matching with vector similarity — consistently outperforms either method alone.
28
+
29
+ ### The Inverted Index — The Foundation
30
+
31
+ Every full-text search system is built on the inverted index. Understanding it is essential to understanding search architecture.
32
+
33
+ A **forward index** maps documents to terms:
34
+ ```
35
+ Document 1 → ["the", "quick", "brown", "fox"]
36
+ Document 2 → ["the", "lazy", "brown", "dog"]
37
+ Document 3 → ["quick", "fox", "jumps", "high"]
38
+ ```
39
+
40
+ An **inverted index** reverses this, mapping terms to documents:
41
+ ```
42
+ "the" → [Doc 1, Doc 2]
43
+ "quick" → [Doc 1, Doc 3]
44
+ "brown" → [Doc 1, Doc 2]
45
+ "fox" → [Doc 1, Doc 3]
46
+ "lazy" → [Doc 2]
47
+ "dog" → [Doc 2]
48
+ "jumps" → [Doc 3]
49
+ "high" → [Doc 3]
50
+ ```
51
+
52
+ Searching for "quick fox" means: look up "quick" (Doc 1, Doc 3), look up "fox" (Doc 1, Doc 3), intersect = [Doc 1, Doc 3]. This operation is O(n) in the number of matching documents, not O(n) in the total corpus size — which is why search engines can query billions of documents in milliseconds.
53
+
54
+ In practice, inverted indexes store more than just document IDs. They store **term frequencies** (how many times the term appears in each document), **positions** (where in the document the term appears, enabling phrase queries), and **offsets** (character positions, enabling highlighting). This additional metadata enables relevance scoring and advanced query types but increases index size.
55
+
56
+ ### Analyzers and Tokenizers
57
+
58
+ Before text enters the inverted index, it passes through an analysis pipeline:
59
+
60
+ 1. **Character filters** — strip HTML, normalize Unicode, map characters (e.g., convert `&` to "and")
61
+ 2. **Tokenizer** — split text into tokens. The standard tokenizer splits on whitespace and punctuation. The n-gram tokenizer generates overlapping character sequences. The edge n-gram tokenizer generates prefixes for autocomplete.
62
+ 3. **Token filters** — lowercase, remove stop words ("the", "a", "is"), stem ("running" -> "run"), apply synonyms ("laptop" -> "laptop", "notebook"), transliterate accented characters
63
+
64
+ The choice of analyzer dramatically affects search quality. An English stemmer maps "running", "runs", and "ran" to the same root "run", so a search for "running" matches documents containing "ran". But stemming can also cause false positives: "university" and "universe" both stem to "univers". Language-specific analyzers, synonym dictionaries, and custom token filters are where much of the relevance tuning effort goes.
65
+
66
+ PostgreSQL's `tsvector` uses a similar pipeline: text is parsed into lexemes (normalized tokens) using dictionaries for stemming and stop-word removal. The `english` text search configuration applies English stemming and stop-word removal by default.
67
+
68
+ ---
69
+
70
+ ## When to Use Built-in Database Search (PostgreSQL FTS)
71
+
72
+ ### The 80% Case
73
+
74
+ PostgreSQL full-text search handles the majority of application search needs without adding any infrastructure. Before reaching for Elasticsearch, honestly evaluate whether your requirements fall within what PostgreSQL provides.
75
+
76
+ **PostgreSQL FTS is sufficient when:**
77
+
78
+ **Simple text search on structured data.** Searching product names, article titles, user profiles, or support tickets where the schema is well-defined and the query patterns are predictable. A SaaS application with 500K users searching their own data within their tenant — PostgreSQL FTS handles this trivially.
79
+
80
+ **Document count under 10 million.** PostgreSQL FTS with GIN indexes performs well for corpuses up to roughly 10M documents on modern hardware. With persistent `tsvector` columns (precomputed at write time rather than computed at query time) and proper GIN indexing, query latency stays under 50ms for most workloads at this scale.
81
+
82
+ **No complex faceting requirements.** If your search results page shows a list of matching items with basic sorting (by relevance, date, price) but does not need dynamic facet counts ("42 results in Electronics, 18 in Books"), PostgreSQL is fine. You can approximate facets with additional `GROUP BY` queries, but this becomes expensive at scale.
83
+
84
+ **Team does not have search infrastructure expertise.** Running an Elasticsearch cluster requires operational knowledge — shard sizing, JVM tuning, cluster health monitoring, rolling upgrades, index lifecycle management. If your team is 3-5 developers building a product, the operational overhead of Elasticsearch may exceed the benefit. PostgreSQL FTS requires zero additional infrastructure.
85
+
86
+ **Transactional consistency matters.** PostgreSQL FTS operates within the same transaction as your data writes. When you insert a new product, it is immediately searchable — no eventual consistency, no sync lag, no dual-write problem. This is a significant advantage for applications where search results must always reflect the latest state.
87
+
88
+ ### PostgreSQL FTS Implementation Pattern
89
+
90
+ ```sql
91
+ -- 1. Add a persistent tsvector column with GIN index
92
+ ALTER TABLE products ADD COLUMN search_vector tsvector
93
+ GENERATED ALWAYS AS (
94
+ setweight(to_tsvector('english', coalesce(name, '')), 'A') ||
95
+ setweight(to_tsvector('english', coalesce(description, '')), 'B') ||
96
+ setweight(to_tsvector('english', coalesce(category, '')), 'C')
97
+ ) STORED;
98
+
99
+ CREATE INDEX idx_products_search ON products USING GIN (search_vector);
100
+
101
+ -- 2. Query with ranking
102
+ SELECT id, name, ts_rank(search_vector, query) AS rank
103
+ FROM products, plainto_tsquery('english', 'wireless headphones') query
104
+ WHERE search_vector @@ query
105
+ ORDER BY rank DESC
106
+ LIMIT 20;
107
+ ```
108
+
109
+ The `setweight` function assigns priority tiers (A highest, D lowest) so matches in the product name rank higher than matches in the description. The `GENERATED ALWAYS AS ... STORED` clause precomputes the tsvector at write time, avoiding runtime text processing during queries. The GIN index makes the `@@` match operator use the inverted index rather than a sequential scan.
110
+
111
+ ### PostgreSQL FTS Limitations
112
+
113
+ **Relevance tuning is limited.** PostgreSQL offers `ts_rank` and `ts_rank_cd` (which considers term proximity), but these are basic compared to Elasticsearch's function_score queries, decay functions, field boosting, and scripted scoring. If you need "boost results from the last 7 days" or "boost results with more reviews", PostgreSQL requires application-level post-processing.
114
+
115
+ **No built-in autocomplete.** PostgreSQL has no native edge n-gram or completion suggester. You can approximate autocomplete with `LIKE 'prefix%'` on a B-tree indexed column or use `pg_trgm` for trigram-based fuzzy matching, but these lack the speed and sophistication of dedicated autocomplete engines.
116
+
117
+ **Faceted aggregations are expensive.** Computing facet counts requires separate `GROUP BY` queries that do not share execution with the search query. For a product search page with 10 facet categories, this means 10+ additional queries per search request.
118
+
119
+ **No distributed scaling.** PostgreSQL FTS runs on a single node. Read replicas can distribute query load, but the index itself is not sharded. For corpuses significantly beyond 10M documents or query rates beyond what a single node handles, you hit a ceiling.
120
+
121
+ **Ranking is I/O bound.** Scoring requires reading the `tsvector` of every matching document. For broad queries that match millions of documents, the ranking step becomes the bottleneck since PostgreSQL must fetch and score each match, unlike Elasticsearch which can use early termination and distributed scoring.
122
+
123
+ ---
124
+
125
+ ## When to Use a Dedicated Search Engine
126
+
127
+ ### The Qualifying Conditions
128
+
129
+ Adopt a dedicated search engine (Elasticsearch, OpenSearch, Typesense, Meilisearch) when **two or more** of these are true:
130
+
131
+ **Complex relevance tuning.** Your search quality depends on boosting by recency, popularity, user behavior, geographic proximity, or business rules. You need A/B testing of ranking algorithms. You need function scores that combine text relevance with numerical signals. Elasticsearch's `function_score` query DSL and learning-to-rank plugin are purpose-built for this. Airbnb's search system uses Elasticsearch for geo-based queries combined with ML-trained relevance models that factor in booking probability, host response rate, and listing quality.
132
+
133
+ **Faceted search with dynamic aggregations.** Your UI shows filter panels with counts that update as the user refines their search. E-commerce product search, job boards, real estate listings — any application where users narrow results through multiple dimensions simultaneously. Elasticsearch's aggregation framework handles nested, filtered, and pipeline aggregations efficiently within a single query.
134
+
135
+ **Real-time autocomplete and suggestions.** You need sub-50ms typeahead with fuzzy matching, typo tolerance, and personalized suggestions. Elasticsearch's completion suggester uses an in-memory FST (finite state transducer) data structure optimized for prefix lookups. Typesense provides typo-tolerant autocomplete out of the box.
136
+
137
+ **Scale beyond a single node.** Your corpus exceeds 10M documents, you need to index hundreds of thousands of documents per minute, or your query rate exceeds what a single PostgreSQL instance can serve. Elasticsearch distributes data across shards and nodes, enabling horizontal scaling. Clusters at Netflix, Uber, and LinkedIn handle billions of documents across hundreds of nodes.
138
+
139
+ **Multi-language, multi-field search.** Your application serves content in 20+ languages, each requiring different analyzers, stemmers, and stop-word lists. Elasticsearch's per-field analyzer configuration and multi-field mappings (index the same field with different analyzers) handle this cleanly.
140
+
141
+ **Vector/hybrid search at scale.** You are building a RAG pipeline, semantic search, or recommendation system that requires vector similarity search combined with keyword filtering. Elasticsearch 8.x+ supports dense vector fields with ANN search, and can combine vector scores with BM25 scores in a single query.
142
+
143
+ ### Real-World Case Studies
144
+
145
+ **Airbnb** — Uses Elasticsearch as the backbone of its listing search. The search system handles geo-spatial queries (find listings within a bounding box), full-text search on listing descriptions, faceted filtering (price range, amenities, property type), and ML-based relevance ranking that factors in conversion probability. The data pipeline syncs listing data from MySQL to Elasticsearch via Kafka, with Redis caching hot query results.
146
+
147
+ **GitHub** — Code search across 200M+ repositories uses a custom search infrastructure built on Elasticsearch principles. The challenge is indexing source code (which has different tokenization needs than natural language) and handling queries that mix text search with structural filters (language, repository, file path).
148
+
149
+ **Netflix** — Uses Elasticsearch for internal content search, device log analysis, and operational intelligence across 260M+ subscribers. The search infrastructure processes billions of events daily, with separate clusters for different use cases (content metadata search vs. log analytics).
150
+
151
+ **Shopify** — Product search across millions of merchants uses Elasticsearch with custom relevance tuning per merchant. The indexing pipeline must handle the "long tail" of small merchants (few products, sparse data) alongside large merchants (millions of SKUs).
152
+
153
+ ---
154
+
155
+ ## When NOT to Use a Dedicated Search Engine
156
+
157
+ This section is deliberately thorough because the most common architectural mistake in search is adopting Elasticsearch too early. The operational cost of running a search cluster is substantial and ongoing.
158
+
159
+ ### The Operational Burden Is Real
160
+
161
+ **Cluster management is a full-time job.** Running Elasticsearch in production requires understanding shard allocation strategies, node roles (master, data, coordinating, ingest), JVM heap sizing, garbage collection tuning, and circuit breaker configuration. Many organizations dedicate entire teams to Elasticsearch operations. If you are a team of 5 building a product, you cannot afford to spend 20% of your engineering capacity on search infrastructure.
162
+
163
+ **The JVM is unforgiving.** Elasticsearch runs on the JVM. Memory management issues manifest as stop-the-world garbage collection pauses that spike query latency from 10ms to 10 seconds. Heap sizing must be carefully tuned — too small and you get frequent GC pauses, too large and you waste memory that the OS could use for filesystem cache. The "rule of thumb" (50% of available RAM for heap, 50% for filesystem cache) is well-known but insufficient for production tuning.
164
+
165
+ **Shard management is an ongoing concern.** Each Elasticsearch index is divided into shards. Too few shards and you cannot distribute load. Too many shards and cluster state management becomes expensive (each shard consumes ~50MB of heap on the master node). Oversharding is the most common operational problem in Elasticsearch clusters — teams create an index-per-day pattern for logs and end up with thousands of shards that degrade cluster performance. Index lifecycle management (ILM) policies help but add configuration complexity.
166
+
167
+ **Split-brain scenarios threaten data integrity.** In a distributed Elasticsearch cluster, network partitions can cause a split-brain condition where two subsets of nodes each elect themselves as master and accept writes independently. When the partition heals, conflicting data must be reconciled. Modern Elasticsearch mitigates this with the voting configuration and minimum_master_nodes setting, but the risk requires monitoring and operational readiness.
168
+
169
+ ### The Data Sync Problem
170
+
171
+ **Dual-write is a distributed systems problem.** When your source of truth is PostgreSQL and your search index is Elasticsearch, every write must reach both systems. The naive approach (write to Postgres, then write to Elasticsearch in the same request) fails when either write succeeds and the other fails, leaving the systems out of sync. The correct approaches — Change Data Capture (CDC) via Debezium, event sourcing, or transactional outbox pattern — add significant infrastructure complexity.
172
+
173
+ **Eventual consistency creates user-visible bugs.** A user creates a product listing and immediately searches for it. If the Elasticsearch index lags by 2 seconds (which is normal), the user sees stale results and reports a bug. "I just created this, why can't I find it?" Every team that adopts Elasticsearch for search while keeping a relational database as the source of truth encounters this problem. Workarounds (query both Postgres and ES, merge results) add application complexity.
174
+
175
+ **Reindexing is a production risk.** When you change an Elasticsearch mapping (add a field, change an analyzer), you must reindex all documents. For large indexes (hundreds of millions of documents), reindexing takes hours or days. During this period, you are running two indexes simultaneously, consuming double the storage and compute. Reindexing failures — due to cluster instability, resource exhaustion, or mapping conflicts — can leave you in a partially-migrated state that requires manual intervention.
176
+
177
+ ### When PostgreSQL Is Enough — Real Examples
178
+
179
+ **Internal admin search.** An operations dashboard where staff search customer records, orders, or support tickets. The corpus is under 5M records, queries are simple keyword matches, and the users are trained staff who do not need fuzzy matching or autocomplete. PostgreSQL FTS with a GIN index handles this with zero additional infrastructure.
180
+
181
+ **Blog or CMS search.** A content site with 50K articles. Full-text search on title and body, sorted by relevance or date. PostgreSQL FTS handles this trivially. Adding Elasticsearch for a blog search is using a sledgehammer to hang a picture frame.
182
+
183
+ **Multi-tenant SaaS search within tenant boundaries.** Each tenant has at most 100K searchable records. Queries are always scoped to a single tenant via a `WHERE tenant_id = ?` clause. The effective search corpus per query is small. PostgreSQL handles this efficiently with a composite index on `(tenant_id)` and a GIN index on the search vector.
184
+
185
+ **MVP and early-stage products.** You do not yet know your search requirements. Starting with PostgreSQL FTS lets you ship quickly, learn from real user behavior, and adopt a dedicated engine only when you have concrete evidence that PostgreSQL is insufficient. Premature adoption of Elasticsearch has killed more MVPs through operational complexity than through search quality limitations.
186
+
187
+ **Simple autocomplete on a single field.** Searching user names, product codes, or city names with prefix matching. A B-tree index on the column with `LIKE 'prefix%'` or `pg_trgm` with a GiST index handles this without a search engine.
188
+
189
+ ---
190
+
191
+ ## How It Works — The Search Pipeline
192
+
193
+ ### 1. Indexing Pipeline (Write Path)
194
+
195
+ The indexing pipeline transforms raw data into searchable index structures:
196
+
197
+ ```
198
+ Source Data → Extract → Transform → Analyze → Index
199
+ (DB) (CDC) (enrich) (tokenize) (inverted index)
200
+ ```
201
+
202
+ **Extraction.** Data enters the indexing pipeline from the source of truth. For real-time indexing, this is typically CDC (Change Data Capture) via tools like Debezium that tail the database's write-ahead log and emit change events to Kafka. For batch indexing, a periodic job reads from the database and bulk-indexes into the search engine.
203
+
204
+ **Transformation.** Raw database rows are transformed into search documents. This often involves denormalization (joining product with category and brand into a single flat document), enrichment (adding computed fields like popularity scores), and field mapping (deciding which fields are searchable, filterable, sortable, or stored).
205
+
206
+ **Analysis.** Text fields pass through the analyzer pipeline (character filters, tokenizer, token filters) to produce normalized tokens. Numeric and date fields are stored for range queries. Keyword fields (category IDs, status codes) are stored verbatim for exact matching and faceting.
207
+
208
+ **Indexing.** Tokens are written to the inverted index. Document values are written to columnar storage (doc values) for sorting and aggregations. Vector embeddings are written to ANN index structures (HNSW graphs) for vector search.
209
+
210
+ ### 2. Relevance Scoring — TF-IDF, BM25, and Beyond
211
+
212
+ **TF-IDF (Term Frequency - Inverse Document Frequency)** is the foundational relevance scoring algorithm. The intuition: a term is relevant to a document if it appears frequently in that document (TF) but rarely across all documents (IDF). "The" appears in every document, so it has low IDF and contributes little to relevance. "Elasticsearch" appears in few documents, so it has high IDF and is a strong relevance signal.
213
+
214
+ ```
215
+ TF-IDF(t, d) = TF(t, d) * IDF(t)
216
+ where TF(t, d) = count of term t in document d
217
+ IDF(t) = log(total documents / documents containing t)
218
+ ```
219
+
220
+ **BM25 (Best Matching 25)** is the successor to TF-IDF and the default ranking algorithm in Elasticsearch, OpenSearch, and Apache Lucene. BM25 improves on TF-IDF in two critical ways:
221
+
222
+ 1. **Term frequency saturation.** In TF-IDF, a term appearing 100 times scores 100x higher than a term appearing once. BM25 introduces a saturation curve controlled by the parameter `k1` (default 1.2): after a certain frequency, additional occurrences contribute diminishing returns. This prevents long documents that repeat a term from dominating results.
223
+
224
+ 2. **Document length normalization.** BM25 normalizes by document length, controlled by parameter `b` (default 0.75). A 10-page document mentioning "search" 5 times is treated differently from a 1-paragraph document mentioning "search" 5 times. The short document has higher term density and should rank higher for that query.
225
+
226
+ ```
227
+ BM25(t, d) = IDF(t) * (TF(t,d) * (k1 + 1)) / (TF(t,d) + k1 * (1 - b + b * |d|/avgdl))
228
+ ```
229
+
230
+ **Learning to Rank (LTR).** For applications where BM25 alone is insufficient, machine learning models can re-rank search results. The approach: use BM25 for initial retrieval (find the top 1000 candidates), then apply an ML model (LambdaMART, neural rankers) that considers additional features — click-through rate, user behavior signals, freshness, geographic proximity, business rules. Elasticsearch provides an LTR plugin, and all major search platforms at scale (Google, Airbnb, LinkedIn) use ML-based re-ranking. The training data comes from user interaction logs: which results users clicked, how long they spent on the page, whether they converted.
231
+
232
+ ### 3. Facets and Aggregations
233
+
234
+ Faceted search requires a different data structure than full-text search. While the inverted index maps terms to documents, aggregations need columnar storage that maps documents to field values efficiently.
235
+
236
+ Elasticsearch uses **doc values** — an on-disk columnar data structure that stores field values per document. When computing facet counts ("how many products in each category"), Elasticsearch iterates through the doc values for the category field across all matching documents and counts occurrences. This is efficient because columnar storage enables sequential reads and good cache behavior.
237
+
238
+ Aggregation types in Elasticsearch:
239
+ - **Terms aggregation** — count documents per distinct value (category facets)
240
+ - **Range aggregation** — count documents in numeric/date ranges (price ranges)
241
+ - **Histogram aggregation** — count documents in fixed-width buckets
242
+ - **Nested aggregation** — aggregate on nested object fields
243
+ - **Filter aggregation** — compute sub-aggregations on a filtered subset
244
+ - **Pipeline aggregation** — compute metrics on the results of other aggregations (moving averages, derivatives)
245
+
246
+ ### 4. Autocomplete Strategies
247
+
248
+ There are four common approaches to implementing autocomplete, each with different trade-offs:
249
+
250
+ **Edge n-grams.** Index each term as all its prefixes: "search" becomes ["s", "se", "sea", "sear", "searc", "search"]. A query for "sea" matches the inverted index entry for "sea" and returns all documents containing words starting with "sea". This is simple and works well for small-to-medium vocabularies but increases index size significantly (each term generates O(n) entries where n is the term length).
251
+
252
+ **Completion suggester (Elasticsearch).** An in-memory FST (finite state transducer) data structure optimized for prefix lookups. Extremely fast (sub-millisecond) but requires a dedicated field type and cannot be combined with full-text queries in the same request. Best for simple prefix-based suggestions.
253
+
254
+ **Search-as-you-type field (Elasticsearch).** A multi-field mapping that automatically creates edge n-gram, shingle (word-level n-gram), and standard sub-fields. Queries match against all sub-fields and combine scores. More flexible than the completion suggester but slower.
255
+
256
+ **Trie-based custom implementation.** For high-traffic autocomplete (Google-scale), a custom in-memory trie data structure that stores the top-K suggestions at each prefix node. LinkedIn's Cleo library uses this approach with a multi-layer architecture: inverted index for candidate retrieval, bloom filters for fast negative lookups, and a scoring function that combines popularity, recency, and personalization signals.
257
+
258
+ ### 5. Vector Search and Hybrid Architecture
259
+
260
+ Vector search converts text (or images, audio, etc.) into dense numerical vectors using embedding models, then finds the most similar vectors using approximate nearest neighbor (ANN) algorithms.
261
+
262
+ **Embedding generation.** Text is passed through a neural network (transformer-based models like OpenAI text-embedding-3-large, Cohere embed-v3, or open-source models like BGE-M3 and E5-mistral) that produces a fixed-size vector (768 to 3072 dimensions typically). Similar meanings produce similar vectors: "affordable laptop for students" and "budget notebook for college" will have high cosine similarity even though they share no keywords.
263
+
264
+ **ANN indexing.** Exact nearest neighbor search in high-dimensional space is O(n) — you must compare the query vector against every indexed vector. For millions of vectors, this is too slow. ANN algorithms trade a small amount of accuracy for dramatic speed improvements:
265
+
266
+ - **HNSW (Hierarchical Navigable Small World)** — builds a multi-layer graph where each node connects to its nearest neighbors. Query traversal starts at the top layer (sparse, long-range connections) and descends to lower layers (dense, short-range connections). Used by Elasticsearch, pgvector, Weaviate, and Qdrant. Offers excellent recall (>95%) with sub-millisecond latency but requires significant memory.
267
+ - **IVF (Inverted File Index)** — clusters vectors into Voronoi cells, then searches only the closest cells at query time. Used by FAISS. Lower memory than HNSW but requires careful tuning of the number of clusters and probes.
268
+ - **Product Quantization (PQ)** — compresses vectors by quantizing sub-vectors, reducing memory by 4-16x at the cost of some accuracy. Often combined with IVF (IVF-PQ) for large-scale deployments.
269
+
270
+ **Hybrid search (keyword + vector).** BM25 keyword search combined with vector similarity consistently outperforms either method alone. The architecture:
271
+
272
+ 1. Execute BM25 query to get top-K keyword matches with scores
273
+ 2. Execute vector query to get top-K semantic matches with scores
274
+ 3. Normalize both score sets to the same scale
275
+ 4. Combine using Reciprocal Rank Fusion (RRF) or weighted linear combination
276
+ 5. Re-rank the merged results
277
+
278
+ Elasticsearch 8.x, OpenSearch 2.x, Weaviate, and Vespa all support hybrid search natively. Google Cloud's Vertex AI Vector Search supports hybrid queries combining dense and sparse (BM25/SPLADE) embeddings in a single index.
279
+
280
+ ---
281
+
282
+ ## Trade-Offs Matrix
283
+
284
+ | Dimension | PostgreSQL FTS | Elasticsearch / OpenSearch | Typesense | Meilisearch | Algolia (SaaS) | pgvector | Pinecone / Weaviate |
285
+ |---|---|---|---|---|---|---|---|
286
+ | **Setup complexity** | Zero (built-in) | High (cluster, JVM, shards) | Low (single binary) | Low (single binary) | Zero (hosted) | Low (extension) | Low (hosted / single binary) |
287
+ | **Operational burden** | None | High (dedicated team for large clusters) | Low-Medium | Low | None | Low | Low (hosted) / Medium (self-hosted) |
288
+ | **Full-text search quality** | Good (basic BM25 via ts_rank) | Excellent (full BM25, custom analyzers, function_score) | Very Good (typo-tolerant, fast) | Very Good (AI-powered, typo-tolerant) | Excellent (hosted, tuned) | N/A (not its purpose) | Basic (secondary feature) |
289
+ | **Faceted search** | Poor (manual GROUP BY) | Excellent (native aggregations) | Good (built-in filtering) | Good (built-in faceting) | Excellent | N/A | Limited |
290
+ | **Autocomplete** | Poor (manual LIKE/pg_trgm) | Excellent (completion suggester, search-as-you-type) | Excellent (default typo tolerance) | Excellent (instant search focus) | Excellent | N/A | N/A |
291
+ | **Vector search** | N/A | Good (8.x+ dense vectors, HNSW) | Basic (2024+) | Basic (AI search, 2024+) | N/A | Good (HNSW, IVF) | Excellent (purpose-built) |
292
+ | **Hybrid search** | N/A | Good (RRF, linear combination) | Limited | Limited | N/A | Manual (combine with FTS) | Good (native hybrid) |
293
+ | **Max corpus size** | ~10M documents per node | Billions (distributed) | ~100M per cluster | ~100M per node | Billions (hosted) | ~10M vectors per node | Billions (hosted) |
294
+ | **Query latency (p50)** | 5-50ms | 5-20ms | 1-10ms | 1-10ms | 5-15ms | 5-50ms | 5-20ms |
295
+ | **Data consistency** | Strong (transactional) | Eventual (refresh interval, default 1s) | Eventual | Eventual | Eventual | Strong (transactional) | Eventual |
296
+ | **Cost at scale** | Low (included in DB) | High (cluster compute + storage) | Medium | Medium | Very High (per-search pricing) | Low (included in DB) | High (hosted) / Medium (self-hosted) |
297
+ | **Learning curve** | Low (SQL-based) | High (custom DSL, cluster concepts) | Low (REST API, dashboard) | Low (REST API, dashboard) | Low (dashboard, client SDKs) | Low (SQL-based) | Medium |
298
+
299
+ ---
300
+
301
+ ## Evolution Path
302
+
303
+ ### Phase 1: PostgreSQL Full-Text Search (Day 1)
304
+
305
+ Start here. Add a `tsvector` generated column and GIN index to your primary searchable tables. Use `plainto_tsquery` for user input and `ts_rank` for relevance ordering. This covers basic search with zero additional infrastructure. Add `pg_trgm` for fuzzy matching on names and short text fields.
306
+
307
+ ```
308
+ Effort: 1-2 days
309
+ Serves: 0 to ~5M documents, simple search UI
310
+ Limitation: No facets, no autocomplete, basic relevance
311
+ ```
312
+
313
+ ### Phase 2: PostgreSQL + Application-Level Enhancements (Month 3-6)
314
+
315
+ As search requirements grow, add application-level features without changing infrastructure. Implement autocomplete with a denormalized suggestions table and B-tree prefix index. Add basic faceting with parallel `GROUP BY` queries (cache the results). Implement search analytics to understand what users search for and where they fail to find results.
316
+
317
+ ```
318
+ Effort: 1-2 weeks
319
+ Serves: Growing product with emerging search needs
320
+ Limitation: Facets are slow, autocomplete lacks sophistication
321
+ ```
322
+
323
+ ### Phase 3: Dedicated Search Engine (Month 6-18)
324
+
325
+ When you have concrete evidence that PostgreSQL FTS is insufficient — users complain about relevance, facets are too slow, autocomplete needs typo tolerance — adopt a dedicated engine. For most applications, **Typesense or Meilisearch** is the right first step: they deliver 80% of Elasticsearch's search quality with 20% of the operational complexity.
326
+
327
+ If you need enterprise-scale faceted search, complex aggregations, or will index more than 100M documents, go directly to **Elasticsearch or OpenSearch**.
328
+
329
+ Set up a data sync pipeline: CDC (Debezium) or application-level events via Kafka. Keep PostgreSQL as the source of truth.
330
+
331
+ ```
332
+ Effort: 2-4 weeks (including sync pipeline)
333
+ Serves: Product-market fit stage with real search requirements
334
+ Limitation: Data sync complexity, eventual consistency
335
+ ```
336
+
337
+ ### Phase 4: Vector/Hybrid Search (When AI Features Arrive)
338
+
339
+ When you need semantic search, RAG, or AI-powered recommendations, add vector search capabilities. Options:
340
+
341
+ - **pgvector** if your vector corpus is under 10M and you want to stay in PostgreSQL
342
+ - **Elasticsearch dense vectors** if you already run ES and want hybrid keyword+vector in one system
343
+ - **Dedicated vector DB** (Weaviate, Qdrant, Pinecone) if vector search is a primary use case with billions of vectors
344
+
345
+ For most applications, pgvector or Elasticsearch's vector capabilities are sufficient. Dedicated vector databases are warranted only when vector search is the core product feature (recommendation engines, visual search, large-scale RAG).
346
+
347
+ ```
348
+ Effort: 1-3 weeks (excluding embedding model selection and tuning)
349
+ Serves: AI-powered search, RAG pipelines, semantic search
350
+ Limitation: Embedding model quality is the bottleneck, not the database
351
+ ```
352
+
353
+ ---
354
+
355
+ ## Failure Modes
356
+
357
+ ### Index Out of Sync with Source of Truth
358
+
359
+ **Symptoms.** Users report "I just created X but search doesn't show it." Or worse: search returns items that were deleted from the database.
360
+
361
+ **Root cause.** The sync pipeline between the source of truth (PostgreSQL) and the search index (Elasticsearch) has lag, gaps, or failures. Common triggers: Kafka consumer falls behind, Debezium connector loses its replication slot, a bulk indexing job fails partway through and is not retried.
362
+
363
+ **Prevention.** Implement a reconciliation job that periodically compares document counts and checksums between the source database and the search index. Add monitoring on sync lag (time between database write and index availability). Set alerting thresholds: warn at 5s lag, page at 30s lag.
364
+
365
+ **Mitigation.** For user-facing writes, implement a "write-through" pattern: after writing to the database, immediately index the document to Elasticsearch via the synchronous API (not the async pipeline). This ensures the user's own writes are immediately searchable, while the async pipeline handles bulk updates and consistency.
366
+
367
+ ### Relevance Degradation Over Time
368
+
369
+ **Symptoms.** Search result quality gradually worsens. Click-through rates on search results decline. Users increasingly rely on browsing or direct links instead of search.
370
+
371
+ **Root cause.** The data distribution has shifted since the search was configured. New content types were added without updating analyzers. Synonym dictionaries are stale. Popular queries return stale or low-quality results because relevance tuning was done once and never revisited.
372
+
373
+ **Prevention.** Implement search analytics: track queries, click-through rates, zero-result queries, and query refinements (user searches, gets poor results, modifies query). Review the zero-result and low-CTR query reports monthly. A/B test relevance changes before deploying them.
374
+
375
+ **Mitigation.** Regularly review and update synonym dictionaries, stop words, and field boosting weights. Use the Elasticsearch `_explain` API to understand why specific documents rank where they do. For high-traffic search, invest in learning-to-rank models trained on click data.
376
+
377
+ ### Elasticsearch Cluster Instability
378
+
379
+ **Symptoms.** Query latency spikes from 20ms to 5+ seconds. Cluster health goes yellow (missing replicas) or red (missing primary shards). Indexing requests are rejected with `429 Too Many Requests`.
380
+
381
+ **Root causes:**
382
+ - **JVM heap pressure.** GC pauses spike when heap usage exceeds 75%. Monitor `jvm.mem.heap_used_percent` and `jvm.gc.collectors.old.collection_time_in_millis`.
383
+ - **Oversharding.** Thousands of small shards consume master node heap for cluster state management. Each shard uses ~50MB of heap on the master. A cluster with 10,000 shards requires 500GB of master heap just for cluster state.
384
+ - **Disk pressure.** Data nodes hitting the flood-stage watermark (95% disk usage by default) go read-only, rejecting all index operations.
385
+ - **Split brain.** Network partition causes two master nodes to be elected independently. Both accept writes. When the partition heals, data conflicts exist. Modern Elasticsearch (7.x+) mitigates this with the voting configuration, but misconfigured clusters remain vulnerable.
386
+
387
+ **Prevention.** Follow the shard sizing guidelines: aim for 20-40GB per shard, no more than 20 shards per GB of heap on data nodes. Use index lifecycle management (ILM) to roll over time-based indexes and delete old data. Monitor cluster health with dedicated dashboards (Kibana, Grafana, Datadog).
388
+
389
+ ### Reindexing Downtime
390
+
391
+ **Symptoms.** A mapping change or analyzer update requires a full reindex. During reindexing, search results are stale, incomplete, or unavailable.
392
+
393
+ **Root cause.** Elasticsearch mappings are immutable once created. Changing a field type, adding a new analyzer, or restructuring the document schema requires creating a new index with the updated mapping and copying all documents from the old index.
394
+
395
+ **Prevention.** Use index aliases. The application always queries the alias (e.g., `products`), which points to the active index (`products_v3`). To reindex, create `products_v4` with the new mapping, reindex documents into it, then atomically swap the alias to point to `products_v4`. Zero downtime if executed correctly.
396
+
397
+ **Mitigation.** For large indexes (100M+ documents), plan reindexing as a multi-day operation. Use `_reindex` with `slices` for parallelism. Monitor progress via the `_tasks` API. Have a rollback plan: keep the old index until the new one is verified.
398
+
399
+ ### Vector Search Quality Collapse
400
+
401
+ **Symptoms.** Semantic search returns irrelevant results. Users report that keyword search works better than "AI search." RAG pipelines hallucinate because retrieved context is wrong.
402
+
403
+ **Root cause.** The embedding model is not suited to the domain. General-purpose embeddings (trained on web text) perform poorly on domain-specific content (medical records, legal documents, code). Or: the chunking strategy is wrong — documents are split at arbitrary boundaries, destroying semantic meaning.
404
+
405
+ **Prevention.** Evaluate embedding models on your actual data before committing. Create a benchmark set of queries and expected results. Measure recall@10 and NDCG. Fine-tune embeddings on domain-specific data if general models underperform. Test multiple chunking strategies (fixed-size, sentence-based, semantic-boundary) and measure retrieval quality for each.
406
+
407
+ ---
408
+
409
+ ## Technology Landscape
410
+
411
+ ### Full-Text Search Engines
412
+
413
+ **PostgreSQL Full-Text Search.** Built into PostgreSQL since version 8.3 (2008). Uses `tsvector` for document representation and GIN indexes for fast lookup. Supports language-specific stemming, stop-word removal, and weighted fields. Sufficient for most applications under 10M documents. The major advantage is zero operational overhead and transactional consistency with your data.
414
+
415
+ **Elasticsearch / OpenSearch.** The dominant dedicated search engine. Built on Apache Lucene. Distributed, horizontally scalable, supports sharding and replication. Full BM25 scoring, custom analyzers, aggregations, completion suggesters, and (since 8.x) dense vector search. OpenSearch is the AWS-forked open-source continuation after Elastic changed Elasticsearch's license in 2021. Operationally complex but unmatched in feature breadth for large-scale search.
416
+
417
+ **Typesense.** Written in C++ for maximum performance. Delivers sub-50ms search results with built-in typo tolerance, faceting, and geo-search. Designed for developer experience — simple REST API, sensible defaults, minimal configuration. Supports high availability via Raft consensus with replicated nodes. Does not shard data (each node holds the full dataset), so the ceiling is whatever fits on a single node (practically tens of millions of documents on modern hardware). Best for: applications that need fast, typo-tolerant search without Elasticsearch's operational complexity.
418
+
419
+ **Meilisearch.** Written in Rust. Focused on instant search experiences for end-user-facing applications. Extremely fast indexing and querying for datasets up to ~100M documents on a single node. Built-in typo tolerance, faceting, filtering, and (since 2024) AI-powered semantic search. Does not support distributed/sharded deployments as of 2026 — single-node only. Best for: developer-friendly instant search in small-to-medium applications, especially those wanting quick setup.
420
+
421
+ **Algolia.** Fully managed search-as-a-service. Highest ease of use: dashboard-based configuration, client SDKs for every platform, built-in analytics. No infrastructure to manage. Pricing is per-search-request, which becomes expensive at scale ($1+ per 1000 searches). Best for: teams that want zero operational burden and can afford the pricing. Not suitable for large-scale or cost-sensitive deployments.
422
+
423
+ **Apache Solr.** The original Lucene-based search platform, predating Elasticsearch. Still used in legacy deployments and by organizations with deep Solr expertise. Functionally similar to Elasticsearch but with a smaller ecosystem, less active development, and declining market share. New projects should generally choose Elasticsearch/OpenSearch over Solr.
424
+
425
+ ### Vector Search
426
+
427
+ **pgvector.** PostgreSQL extension for vector similarity search. Supports HNSW and IVFFlat indexes. Competitive with dedicated vector databases at under 10M vectors — achieves 471 QPS at 99% recall with pgvectorscale. The major advantage is operational simplicity: vectors live in the same database as your relational data, enabling SQL joins between vector search results and business data. Cost-effective: 79% lower monthly cost than Pinecone when self-hosted on equivalent hardware.
428
+
429
+ **Pinecone.** Fully managed vector database. Purpose-built for vector search at scale (billions of vectors). Simple API, no infrastructure management. Highest ease of use for vector search but premium pricing. Best for: teams that need enterprise-scale vector search without ops investment.
430
+
431
+ **Weaviate.** Open-source vector database with native hybrid search (keyword + vector in a single query). Supports multiple embedding model integrations. Can run self-hosted or managed. Best for: applications requiring tight integration between keyword relevance and semantic similarity.
432
+
433
+ **Qdrant.** Written in Rust. Open-source vector database with strong performance characteristics and flexible filtering. Supports payload-based filtering combined with vector search. Growing ecosystem in 2025-2026.
434
+
435
+ **Elasticsearch Dense Vectors.** Since version 8.0, Elasticsearch supports dense vector fields with HNSW-based ANN search. Enables hybrid search (BM25 + vector) within a single query using RRF or scripted scoring. Best for: organizations already running Elasticsearch that want to add vector search without a separate system.
436
+
437
+ ### Emerging Trends (2025-2026)
438
+
439
+ **Graph-enhanced vector retrieval.** Combining knowledge graphs with vector search to improve retrieval quality. Instead of relying solely on embedding similarity, the system traverses graph relationships to find contextually relevant documents. Expected to become a standard architecture by 2027.
440
+
441
+ **Multimodal embeddings.** In 2026, vector databases support embeddings for text, images, video, audio, and 3D models in the same index. A query "red leather couch" can match against both product descriptions and product images.
442
+
443
+ **Adaptive embedding models.** Models that automatically align to specific tasks and domains, reducing the need for fine-tuning. Running natively on low-power devices for edge search scenarios.
444
+
445
+ ---
446
+
447
+ ## Decision Tree
448
+
449
+ ```
450
+ START: Do you need search beyond simple WHERE/LIKE queries?
451
+
452
+ ├─ NO → Use database queries. You do not need search architecture.
453
+
454
+ └─ YES → Is your corpus under 10M documents?
455
+
456
+ ├─ YES → Do you need faceted search, autocomplete, or complex relevance?
457
+ │ │
458
+ │ ├─ NO → PostgreSQL FTS with tsvector + GIN index.
459
+ │ │ Add pg_trgm for fuzzy matching if needed.
460
+ │ │
461
+ │ └─ YES → Do you need instant typo-tolerant autocomplete?
462
+ │ │
463
+ │ ├─ YES → Typesense or Meilisearch.
464
+ │ │ Low ops burden, fast setup, excellent autocomplete.
465
+ │ │
466
+ │ └─ NO (but need facets/aggregations) → Elasticsearch or OpenSearch.
467
+ │ More setup, but unmatched aggregation capabilities.
468
+
469
+ └─ NO (>10M documents) → Do you need vector/semantic search as the primary use case?
470
+
471
+ ├─ YES → Is your vector corpus under 10M?
472
+ │ │
473
+ │ ├─ YES → pgvector (if using PostgreSQL) or Elasticsearch dense vectors.
474
+ │ │
475
+ │ └─ NO → Dedicated vector DB (Weaviate for hybrid, Pinecone for managed,
476
+ │ Qdrant for self-hosted performance).
477
+
478
+ └─ NO (keyword search at scale) → Elasticsearch or OpenSearch.
479
+ Distributed, sharded, handles billions of documents.
480
+ Budget for operational investment (dedicated team or managed service).
481
+
482
+ ALWAYS ASK: Can you afford the operational complexity?
483
+ ├─ NO → Managed service (Algolia for keyword, Pinecone for vector)
484
+ │ or simpler engine (Typesense, Meilisearch).
485
+ └─ YES → Elasticsearch/OpenSearch gives maximum flexibility.
486
+ ```
487
+
488
+ ---
489
+
490
+ ## Implementation Sketch
491
+
492
+ ### PostgreSQL FTS — Minimal Setup
493
+
494
+ ```sql
495
+ -- Enable trigram extension for fuzzy matching
496
+ CREATE EXTENSION IF NOT EXISTS pg_trgm;
497
+
498
+ -- Create table with search vector
499
+ CREATE TABLE articles (
500
+ id SERIAL PRIMARY KEY,
501
+ title TEXT NOT NULL,
502
+ body TEXT NOT NULL,
503
+ category TEXT,
504
+ published TIMESTAMPTZ DEFAULT NOW(),
505
+ search_vec tsvector GENERATED ALWAYS AS (
506
+ setweight(to_tsvector('english', coalesce(title, '')), 'A') ||
507
+ setweight(to_tsvector('english', coalesce(body, '')), 'B')
508
+ ) STORED
509
+ );
510
+
511
+ -- GIN index for full-text search
512
+ CREATE INDEX idx_articles_search ON articles USING GIN (search_vec);
513
+
514
+ -- Trigram index for fuzzy autocomplete on title
515
+ CREATE INDEX idx_articles_title_trgm ON articles USING GIN (title gin_trgm_ops);
516
+
517
+ -- Full-text search query with ranking
518
+ SELECT id, title,
519
+ ts_rank(search_vec, query) AS relevance
520
+ FROM articles, plainto_tsquery('english', $1) query
521
+ WHERE search_vec @@ query
522
+ ORDER BY relevance DESC
523
+ LIMIT 20;
524
+
525
+ -- Fuzzy autocomplete on title (trigram similarity)
526
+ SELECT id, title, similarity(title, $1) AS sim
527
+ FROM articles
528
+ WHERE title % $1 -- uses trigram similarity threshold (default 0.3)
529
+ ORDER BY sim DESC
530
+ LIMIT 10;
531
+ ```
532
+
533
+ ### Elasticsearch — Index Mapping and Query
534
+
535
+ ```json
536
+ // Index mapping with search-optimized fields
537
+ PUT /products
538
+ {
539
+ "settings": {
540
+ "analysis": {
541
+ "analyzer": {
542
+ "autocomplete_analyzer": {
543
+ "type": "custom",
544
+ "tokenizer": "autocomplete_tokenizer",
545
+ "filter": ["lowercase"]
546
+ }
547
+ },
548
+ "tokenizer": {
549
+ "autocomplete_tokenizer": {
550
+ "type": "edge_ngram",
551
+ "min_gram": 2,
552
+ "max_gram": 20,
553
+ "token_chars": ["letter", "digit"]
554
+ }
555
+ }
556
+ }
557
+ },
558
+ "mappings": {
559
+ "properties": {
560
+ "name": {
561
+ "type": "text",
562
+ "analyzer": "standard",
563
+ "fields": {
564
+ "autocomplete": {
565
+ "type": "text",
566
+ "analyzer": "autocomplete_analyzer",
567
+ "search_analyzer": "standard"
568
+ }
569
+ }
570
+ },
571
+ "description": { "type": "text" },
572
+ "category": { "type": "keyword" },
573
+ "price": { "type": "float" },
574
+ "rating": { "type": "float" },
575
+ "embedding": {
576
+ "type": "dense_vector",
577
+ "dims": 1536,
578
+ "index": true,
579
+ "similarity": "cosine"
580
+ }
581
+ }
582
+ }
583
+ }
584
+ ```
585
+
586
+ ```json
587
+ // Hybrid search: BM25 + vector + facets in a single query
588
+ POST /products/_search
589
+ {
590
+ "query": {
591
+ "bool": {
592
+ "must": [
593
+ {
594
+ "multi_match": {
595
+ "query": "wireless noise cancelling headphones",
596
+ "fields": ["name^3", "description"],
597
+ "type": "best_fields"
598
+ }
599
+ }
600
+ ],
601
+ "filter": [
602
+ { "term": { "category": "electronics" } },
603
+ { "range": { "price": { "gte": 50, "lte": 300 } } }
604
+ ]
605
+ }
606
+ },
607
+ "knn": {
608
+ "field": "embedding",
609
+ "query_vector": [0.12, -0.34, ...],
610
+ "k": 20,
611
+ "num_candidates": 100
612
+ },
613
+ "rank": {
614
+ "rrf": { "window_size": 100, "rank_constant": 60 }
615
+ },
616
+ "aggs": {
617
+ "categories": { "terms": { "field": "category", "size": 20 } },
618
+ "price_ranges": {
619
+ "range": {
620
+ "field": "price",
621
+ "ranges": [
622
+ { "to": 50 },
623
+ { "from": 50, "to": 100 },
624
+ { "from": 100, "to": 200 },
625
+ { "from": 200 }
626
+ ]
627
+ }
628
+ },
629
+ "avg_rating": { "avg": { "field": "rating" } }
630
+ },
631
+ "size": 20
632
+ }
633
+ ```
634
+
635
+ ### Data Sync Pipeline — Debezium + Kafka Pattern
636
+
637
+ ```
638
+ ┌──────────┐ CDC ┌─────────┐ Stream ┌──────────────┐ Bulk API ┌───────────────┐
639
+ │PostgreSQL│──────────→│ Kafka │──────────→│ Transformer │────────────→│ Elasticsearch │
640
+ │ (source │ Debezium │ │ │ (enrich, │ │ (search index)│
641
+ │ of truth)│ │ │ │ denormalize)│ │ │
642
+ └──────────┘ └─────────┘ └──────────────┘ └───────────────┘
643
+
644
+ Embedding Model
645
+ (for vector fields)
646
+ ```
647
+
648
+ Key implementation details:
649
+ - **Debezium** tails PostgreSQL's WAL (write-ahead log) and emits change events to Kafka topics
650
+ - **Kafka** provides durable, ordered delivery with at-least-once semantics
651
+ - **Transformer service** consumes Kafka events, denormalizes data (joins related entities), generates embeddings for vector fields, and bulk-indexes to Elasticsearch
652
+ - **Idempotent indexing** — use document ID as Elasticsearch `_id` so duplicate events overwrite rather than create duplicates
653
+ - **Dead letter queue** — failed indexing attempts go to a DLQ for investigation rather than blocking the pipeline
654
+ - **Reconciliation job** — hourly job compares document counts and checksums between PostgreSQL and Elasticsearch, re-indexes any discrepancies
655
+
656
+ ---
657
+
658
+ ## Cross-References
659
+
660
+ - **[data-modeling](../data/data-modeling.md)** — How you model your data affects what can be searched and how. Denormalization for search documents vs. normalized relational schema for writes.
661
+ - **[sql-vs-nosql](../data/sql-vs-nosql.md)** — PostgreSQL FTS keeps you in the relational world; dedicated search engines are document stores with different consistency models.
662
+ - **[caching-architecture](../data/caching-architecture.md)** — Cache hot search queries and facet results to reduce load on the search cluster. Redis is commonly used for search result caching (Airbnb pattern).
663
+ - **[event-streams-and-queues](../data/event-streams-and-queues.md)** — Kafka-based CDC pipelines are the standard pattern for syncing data from the source of truth to the search index.