minix 0.3.2__tar.gz → 0.3.4__tar.gz

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 (199) hide show
  1. {minix-0.3.2 → minix-0.3.4}/PKG-INFO +344 -7
  2. {minix-0.3.2 → minix-0.3.4}/README.md +337 -6
  3. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/commands/__init__.py +10 -0
  4. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/commands/add_component_scaffold.py +36 -5
  5. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/commands/add_module_scaffold.py +11 -5
  6. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/commands/add_rag.py +6 -1
  7. minix-0.3.4/minix/core/cli/commands/agent_guidance.py +74 -0
  8. minix-0.3.4/minix/core/cli/commands/db.py +246 -0
  9. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/commands/init.py +21 -3
  10. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/commands/init_scaffold.py +5 -2
  11. minix-0.3.4/minix/core/cli/commands/sync_agents.py +105 -0
  12. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/global_settings.py +5 -1
  13. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/minix_settings.py +4 -0
  14. minix-0.3.4/minix/core/conf/project_template/.claude/skills/minix/SKILL.md +60 -0
  15. minix-0.3.4/minix/core/conf/project_template/.claude/skills/minix/references/cli.md +43 -0
  16. minix-0.3.4/minix/core/conf/project_template/.claude/skills/minix/references/concepts.md +181 -0
  17. minix-0.3.4/minix/core/conf/project_template/.claude/skills/minix/references/patterns.md +98 -0
  18. minix-0.3.4/minix/core/conf/project_template/.claude/skills/minix/references/upstream.md +71 -0
  19. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/project_template/AGENTS.md +124 -5
  20. minix-0.3.4/minix/core/conf/project_template/CLAUDE.md +5 -0
  21. {minix-0.3.2 → minix-0.3.4}/minix/core/entity/__init__.py +5 -0
  22. minix-0.3.4/minix/core/entity/pgvector_entity.py +22 -0
  23. minix-0.3.4/minix/core/migrations/__init__.py +21 -0
  24. minix-0.3.4/minix/core/migrations/env.py +102 -0
  25. minix-0.3.4/minix/core/migrations/scaffold.py +117 -0
  26. minix-0.3.4/minix/core/migrations/targets.py +48 -0
  27. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/__init__.py +7 -1
  28. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/config.py +30 -0
  29. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/controllers/oidc_controller.py +60 -5
  30. minix-0.3.4/minix/core/modules/oidc/dependencies.py +238 -0
  31. minix-0.3.4/minix/core/modules/oidc/errors.py +14 -0
  32. minix-0.3.4/minix/core/modules/oidc/hooks.py +17 -0
  33. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/module.py +5 -5
  34. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/services/__init__.py +1 -0
  35. minix-0.3.4/minix/core/modules/oidc/services/oidc_discovery_service.py +195 -0
  36. minix-0.3.4/minix/core/modules/oidc/services/oidc_token_client.py +147 -0
  37. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/services/oidc_user_service.py +27 -5
  38. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/session.py +5 -2
  39. minix-0.3.4/minix/core/modules/oidc/tenant.py +68 -0
  40. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/controllers/rag_controller.py +32 -2
  41. {minix-0.3.2 → minix-0.3.4}/minix/core/repository/__init__.py +2 -0
  42. minix-0.3.4/minix/core/repository/pgvector/__init__.py +1 -0
  43. minix-0.3.4/minix/core/repository/pgvector/pgvector_repository.py +64 -0
  44. {minix-0.3.2 → minix-0.3.4}/minix/core/service/__init__.py +2 -0
  45. minix-0.3.4/minix/core/service/pgvector/__init__.py +1 -0
  46. minix-0.3.4/minix/core/service/pgvector/pgvector_service.py +37 -0
  47. {minix-0.3.2 → minix-0.3.4}/pyproject.toml +11 -1
  48. minix-0.3.2/minix/core/modules/oidc/dependencies.py +0 -137
  49. minix-0.3.2/minix/core/modules/oidc/services/oidc_discovery_service.py +0 -121
  50. {minix-0.3.2 → minix-0.3.4}/minix/__init__.py +0 -0
  51. {minix-0.3.2 → minix-0.3.4}/minix/core/__init__.py +0 -0
  52. {minix-0.3.2 → minix-0.3.4}/minix/core/bootstrap/__init__.py +0 -0
  53. {minix-0.3.2 → minix-0.3.4}/minix/core/bootstrap/bootstrap.py +0 -0
  54. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/__init__.py +0 -0
  55. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/cli.py +0 -0
  56. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/commands/add_component.py +0 -0
  57. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/commands/add_module.py +0 -0
  58. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/commands/init_prompts.py +0 -0
  59. {minix-0.3.2 → minix-0.3.4}/minix/core/cli/options.py +0 -0
  60. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/__init__.py +0 -0
  61. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/builders.py +0 -0
  62. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/env.py +0 -0
  63. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/project_template/.dockerignore +0 -0
  64. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/project_template/.env.example +0 -0
  65. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/project_template/.gitignore +0 -0
  66. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/project_template/Dockerfile +0 -0
  67. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/project_template/config.py +0 -0
  68. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/project_template/docker-compose.yml +0 -0
  69. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/project_template/entries/__init__.py +0 -0
  70. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/project_template/entries/api.py +0 -0
  71. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/project_template/entries/beat.py +0 -0
  72. {minix-0.3.2 → minix-0.3.4}/minix/core/conf/project_template/entries/worker.py +0 -0
  73. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/__init__.py +0 -0
  74. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/connector.py +0 -0
  75. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/object_storage_connector/__init__.py +0 -0
  76. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/object_storage_connector/config.py +0 -0
  77. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/object_storage_connector/connector.py +0 -0
  78. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/qdrant_connector/__init__.py +0 -0
  79. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/qdrant_connector/connector.py +0 -0
  80. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/redis_connector/__init__.py +0 -0
  81. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/redis_connector/redis_connector.py +0 -0
  82. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/sql_connector/__init__.py +0 -0
  83. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/sql_connector/sql_connector.py +0 -0
  84. {minix-0.3.2 → minix-0.3.4}/minix/core/connectors/sql_connector/transaction.py +0 -0
  85. {minix-0.3.2 → minix-0.3.4}/minix/core/consumer/__init__.py +0 -0
  86. {minix-0.3.2 → minix-0.3.4}/minix/core/consumer/async_consumer.py +0 -0
  87. {minix-0.3.2 → minix-0.3.4}/minix/core/controller/__init__.py +0 -0
  88. {minix-0.3.2 → minix-0.3.4}/minix/core/controller/controller.py +0 -0
  89. {minix-0.3.2 → minix-0.3.4}/minix/core/entity/entity.py +0 -0
  90. {minix-0.3.2 → minix-0.3.4}/minix/core/entity/qdrant_entity.py +0 -0
  91. {minix-0.3.2 → minix-0.3.4}/minix/core/entity/redis_entity.py +0 -0
  92. {minix-0.3.2 → minix-0.3.4}/minix/core/entity/sql_entity.py +0 -0
  93. {minix-0.3.2 → minix-0.3.4}/minix/core/install/__init__.py +0 -0
  94. {minix-0.3.2 → minix-0.3.4}/minix/core/install/installable.py +0 -0
  95. {minix-0.3.2 → minix-0.3.4}/minix/core/model/__init__.py +0 -0
  96. {minix-0.3.2 → minix-0.3.4}/minix/core/model/embedding_model.py +0 -0
  97. {minix-0.3.2 → minix-0.3.4}/minix/core/model/mlflow_model.py +0 -0
  98. {minix-0.3.2 → minix-0.3.4}/minix/core/model/model.py +0 -0
  99. {minix-0.3.2 → minix-0.3.4}/minix/core/model/model_registry.py +0 -0
  100. {minix-0.3.2 → minix-0.3.4}/minix/core/module/__init__.py +0 -0
  101. {minix-0.3.2 → minix-0.3.4}/minix/core/module/business_module/__init__.py +0 -0
  102. {minix-0.3.2 → minix-0.3.4}/minix/core/module/business_module/business_module.py +0 -0
  103. {minix-0.3.2 → minix-0.3.4}/minix/core/module/module.py +0 -0
  104. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/__init__.py +0 -0
  105. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/auth/__init__.py +0 -0
  106. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/auth/dependencies.py +0 -0
  107. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/auth/entities/__init__.py +0 -0
  108. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/auth/entities/api_key_entity.py +0 -0
  109. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/auth/module.py +0 -0
  110. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/auth/repositories/__init__.py +0 -0
  111. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/auth/repositories/api_key_repository.py +0 -0
  112. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/auth/services/__init__.py +0 -0
  113. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/auth/services/api_key_service.py +0 -0
  114. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/controllers/__init__.py +0 -0
  115. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/entities/__init__.py +0 -0
  116. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/entities/oidc_user_entity.py +0 -0
  117. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/repositories/__init__.py +0 -0
  118. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/oidc/repositories/oidc_user_repository.py +0 -0
  119. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/__init__.py +0 -0
  120. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/chunking/__init__.py +0 -0
  121. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/chunking/preprocessor.py +0 -0
  122. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/chunking/smart_chunker.py +0 -0
  123. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/config.py +0 -0
  124. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/controllers/__init__.py +0 -0
  125. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/controllers/schemas.py +0 -0
  126. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/document_processor/__init__.py +0 -0
  127. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/document_processor/base.py +0 -0
  128. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/document_processor/factory.py +0 -0
  129. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/document_processor/gpt_processor.py +0 -0
  130. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/document_processor/landingai_processor.py +0 -0
  131. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/embeddings.py +0 -0
  132. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/entities/__init__.py +0 -0
  133. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/entities/chunk_entity.py +0 -0
  134. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/entities/collection_entity.py +0 -0
  135. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/entities/document_entity.py +0 -0
  136. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/entities/job_entity.py +0 -0
  137. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/entities/query_request_entity.py +0 -0
  138. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/entities/search_request_entity.py +0 -0
  139. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/hybrid_retriever.py +0 -0
  140. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/llm_factory.py +0 -0
  141. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/metadata_extractor.py +0 -0
  142. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/module.py +0 -0
  143. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/prompts.py +0 -0
  144. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/qdrant_ops.py +0 -0
  145. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/rag_chain.py +0 -0
  146. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/refusal.py +0 -0
  147. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/repositories/__init__.py +0 -0
  148. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/repositories/chunk_repository.py +0 -0
  149. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/repositories/collection_repository.py +0 -0
  150. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/repositories/document_repository.py +0 -0
  151. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/repositories/job_repository.py +0 -0
  152. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/repositories/query_request_repository.py +0 -0
  153. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/repositories/search_request_repository.py +0 -0
  154. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/retrieval/__init__.py +0 -0
  155. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/retrieval/llm_reranker.py +0 -0
  156. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/retrieval/multi_query_blender.py +0 -0
  157. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/services/__init__.py +0 -0
  158. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/services/access_policy.py +0 -0
  159. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/services/chunk_service.py +0 -0
  160. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/services/collection_service.py +0 -0
  161. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/services/document_service.py +0 -0
  162. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/services/job_service.py +0 -0
  163. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/services/match_service.py +0 -0
  164. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/services/query_request_service.py +0 -0
  165. {minix-0.3.2 → minix-0.3.4}/minix/core/modules/rag/services/search_request_service.py +0 -0
  166. {minix-0.3.2 → minix-0.3.4}/minix/core/object_storage/__init__.py +0 -0
  167. {minix-0.3.2 → minix-0.3.4}/minix/core/object_storage/config.py +0 -0
  168. {minix-0.3.2 → minix-0.3.4}/minix/core/object_storage/connector.py +0 -0
  169. {minix-0.3.2 → minix-0.3.4}/minix/core/registry/__init__.py +0 -0
  170. {minix-0.3.2 → minix-0.3.4}/minix/core/registry/registry.py +0 -0
  171. {minix-0.3.2 → minix-0.3.4}/minix/core/repository/qdrant/__init__.py +0 -0
  172. {minix-0.3.2 → minix-0.3.4}/minix/core/repository/qdrant/qdrant_repository.py +0 -0
  173. {minix-0.3.2 → minix-0.3.4}/minix/core/repository/redis/__init__.py +0 -0
  174. {minix-0.3.2 → minix-0.3.4}/minix/core/repository/redis/redis_repository.py +0 -0
  175. {minix-0.3.2 → minix-0.3.4}/minix/core/repository/repository.py +0 -0
  176. {minix-0.3.2 → minix-0.3.4}/minix/core/repository/sql/__init__.py +0 -0
  177. {minix-0.3.2 → minix-0.3.4}/minix/core/repository/sql/sql_repository.py +0 -0
  178. {minix-0.3.2 → minix-0.3.4}/minix/core/scheduler/__init__.py +0 -0
  179. {minix-0.3.2 → minix-0.3.4}/minix/core/scheduler/scheduler.py +0 -0
  180. {minix-0.3.2 → minix-0.3.4}/minix/core/scheduler/task/__init__.py +0 -0
  181. {minix-0.3.2 → minix-0.3.4}/minix/core/scheduler/task/task.py +0 -0
  182. {minix-0.3.2 → minix-0.3.4}/minix/core/scheduler/task/workflow_tasks.py +0 -0
  183. {minix-0.3.2 → minix-0.3.4}/minix/core/scheduler/workflow.py +0 -0
  184. {minix-0.3.2 → minix-0.3.4}/minix/core/service/base_service.py +0 -0
  185. {minix-0.3.2 → minix-0.3.4}/minix/core/service/helper_service.py +0 -0
  186. {minix-0.3.2 → minix-0.3.4}/minix/core/service/qdrant/__init__.py +0 -0
  187. {minix-0.3.2 → minix-0.3.4}/minix/core/service/qdrant/qdrant_service.py +0 -0
  188. {minix-0.3.2 → minix-0.3.4}/minix/core/service/redis/__init__.py +0 -0
  189. {minix-0.3.2 → minix-0.3.4}/minix/core/service/redis/redis_service.py +0 -0
  190. {minix-0.3.2 → minix-0.3.4}/minix/core/service/service.py +0 -0
  191. {minix-0.3.2 → minix-0.3.4}/minix/core/service/sql/__init__.py +0 -0
  192. {minix-0.3.2 → minix-0.3.4}/minix/core/service/sql/sql_service.py +0 -0
  193. {minix-0.3.2 → minix-0.3.4}/minix/core/utils/__init__.py +0 -0
  194. {minix-0.3.2 → minix-0.3.4}/minix/core/utils/mlflow/__init__.py +0 -0
  195. {minix-0.3.2 → minix-0.3.4}/minix/core/utils/mlflow/log_metric.py +0 -0
  196. {minix-0.3.2 → minix-0.3.4}/minix/core/utils/singleton/__init__.py +0 -0
  197. {minix-0.3.2 → minix-0.3.4}/minix/core/utils/singleton/singleton.py +0 -0
  198. {minix-0.3.2 → minix-0.3.4}/minix/core/utils/string/__init__.py +0 -0
  199. {minix-0.3.2 → minix-0.3.4}/minix/core/utils/string/to_snake_case.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: minix
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: A modular Python framework for backend, AI, and data projects
5
5
  Author: AmirHossein Advari
6
6
  Author-email: amiradvari@gmail.com
@@ -13,11 +13,15 @@ Classifier: Programming Language :: Python :: 3.14
13
13
  Provides-Extra: ai
14
14
  Provides-Extra: clickhouse
15
15
  Provides-Extra: mysql
16
+ Provides-Extra: pgvector
16
17
  Provides-Extra: postgresql
17
18
  Provides-Extra: rag
18
19
  Provides-Extra: vdb
19
20
  Requires-Dist: Pillow (>=10.0.0) ; extra == "rag"
20
21
  Requires-Dist: aiokafka (>=0.12.0,<0.13.0)
22
+ Requires-Dist: alembic (>=1.13) ; extra == "mysql"
23
+ Requires-Dist: alembic (>=1.13) ; extra == "postgresql"
24
+ Requires-Dist: alembic (>=1.13) ; extra == "rag"
21
25
  Requires-Dist: authlib (>=1.3,<2.0)
22
26
  Requires-Dist: boto3 (>=1.39.14,<2.0.0)
23
27
  Requires-Dist: celery (>=5.5.3,<6.0.0)
@@ -37,6 +41,8 @@ Requires-Dist: mlflow (>=2.0) ; extra == "ai"
37
41
  Requires-Dist: numpy (>=1.24) ; extra == "ai"
38
42
  Requires-Dist: numpy (>=1.24) ; extra == "vdb"
39
43
  Requires-Dist: pdf2image (>=1.17.0) ; extra == "rag"
44
+ Requires-Dist: pgvector (>=0.4) ; extra == "pgvector"
45
+ Requires-Dist: psycopg[binary] (>=3.1) ; extra == "pgvector"
40
46
  Requires-Dist: psycopg[binary] (>=3.1) ; extra == "postgresql"
41
47
  Requires-Dist: psycopg[binary] (>=3.1) ; extra == "rag"
42
48
  Requires-Dist: pydantic-settings (>=2.0,<3.0)
@@ -78,10 +84,12 @@ Description-Content-Type: text/markdown
78
84
  - [Entities](#entities)
79
85
  - [SQL Entity](#sql-entity)
80
86
  - [Qdrant Entity (Vector DB)](#qdrant-entity-vector-db)
87
+ - [PGVector Entity (PostgreSQL vectors)](#pgvector-entity-postgresql-vectors)
81
88
  - [Redis Entity](#redis-entity)
82
89
  - [Repositories](#repositories)
83
90
  - [SQL Repository](#sql-repository)
84
91
  - [Qdrant Repository](#qdrant-repository)
92
+ - [PGVector Repository](#pgvector-repository)
85
93
  - [Services](#services)
86
94
  - [Controllers](#controllers)
87
95
  - [Connectors](#connectors)
@@ -104,6 +112,7 @@ Description-Content-Type: text/markdown
104
112
  - [Embedding Model](#embedding-model)
105
113
  - [MLflow Model (requires `ai` extra)](#mlflow-model-requires-ai-extra)
106
114
  - [RAG Module](#rag-module)
115
+ - [OIDC Module](#oidc-module)
107
116
  - [Configuration](#configuration)
108
117
  - [Project config](#project-config)
109
118
  - [Connectors from config](#connectors-from-config)
@@ -112,6 +121,7 @@ Description-Content-Type: text/markdown
112
121
  - [SQL drivers](#sql-drivers)
113
122
  - [AI Capabilities](#ai-capabilities)
114
123
  - [Vector DB (Qdrant)](#vector-db-qdrant)
124
+ - [Vector DB (pgvector)](#vector-db-pgvector)
115
125
  - [ClickHouse Support](#clickhouse-support)
116
126
  - [Install All Extras](#install-all-extras)
117
127
  - [Registry Usage](#registry-usage)
@@ -119,6 +129,13 @@ Description-Content-Type: text/markdown
119
129
  - [Quick map](#quick-map)
120
130
  - [Global options](#global-options)
121
131
  - [`minix init`](#minix-init)
132
+ - [`minix db`](#minix-db)
133
+ - [Migration workflow](#migration-workflow)
134
+ - [Migration commands](#migration-commands)
135
+ - [Revision targets](#revision-targets)
136
+ - [Migration recipes](#migration-recipes)
137
+ - [How migrations work](#how-migrations-work)
138
+ - [Migration troubleshooting](#migration-troubleshooting)
122
139
  - [`minix add module`](#minix-add-module)
123
140
  - [SQL binding (all or none)](#sql-binding-all-or-none)
124
141
  - [Flags](#flags)
@@ -290,6 +307,24 @@ class DocumentEntity(QdrantEntity):
290
307
  return "documents"
291
308
  ```
292
309
 
310
+ #### PGVector Entity (PostgreSQL vectors)
311
+
312
+ Requires the `pgvector` extra and a PostgreSQL server with the `vector` extension.
313
+
314
+ ```python
315
+ from sqlalchemy import Text
316
+ from sqlalchemy.orm import Mapped, mapped_column
317
+ from minix.core.entity import PGVectorEntity
318
+
319
+ class DocumentEmbeddingEntity(PGVectorEntity):
320
+ vector_size = 1536
321
+
322
+ content: Mapped[str] = mapped_column(Text, nullable=False)
323
+ ```
324
+
325
+ PGVector entities are SQL entities: they include `id`, `created_at` and
326
+ `updated_at`, plus a `vector` column of type `VECTOR(vector_size)`.
327
+
293
328
  #### Redis Entity
294
329
 
295
330
  ```python
@@ -360,6 +395,27 @@ class DocumentRepository(QdrantRepository[DocumentEntity]):
360
395
  - `query(entity, top_k)` - Similarity search
361
396
  - `delete(entity_ids)` - Delete vectors
362
397
 
398
+ #### PGVector Repository
399
+
400
+ ```python
401
+ from minix.core.repository import PGVectorRepository
402
+
403
+ class DocumentEmbeddingRepository(PGVectorRepository[DocumentEmbeddingEntity]):
404
+ def get_distance(self) -> str:
405
+ return 'Cosine' # or 'Euclid', 'Dot', 'Manhattan'
406
+ ```
407
+
408
+ It extends `SqlRepository` (all SQL methods above, `sql_transaction()`
409
+ included) and uses the registered `SqlConnector`, which must point at PostgreSQL.
410
+
411
+ **Additional methods:**
412
+ - `create_extension()` - Run `CREATE EXTENSION IF NOT EXISTS vector`
413
+ - `search(vector, top_k, max_distance=None, **kwargs)` - Nearest neighbours, closest first; `kwargs` filter like `get_by`
414
+ - `search_with_distance(vector, top_k, max_distance=None, **kwargs)` - Same, as `(entity, distance)` pairs
415
+
416
+ `PGVectorService` exposes the same `search` / `search_with_distance` methods,
417
+ plus `get_knn(entity, top_k)`, on top of `SqlService`.
418
+
363
419
  ### Services
364
420
 
365
421
  Services contain business logic:
@@ -724,7 +780,7 @@ every request when the key is set but empty): `.env` gets a random key and
724
780
  Repeated `minix add rag` calls leave the generated files unchanged. Afterwards,
725
781
  reinstall (for example `poetry lock && poetry install`), install Poppler for local
726
782
  PDF ingestion, set the model provider's API key in `.env`, and create the SQL tables
727
- as described below.
783
+ with `minix db makemigrations -m "add rag" && minix db migrate` (see [`minix db`](#minix-db)).
728
784
 
729
785
  **Manual registration** — in a project from `minix init` with PostgreSQL as the `default`
730
786
  database, add the module to `installed_modules` in `config.py`:
@@ -739,8 +795,15 @@ installed_modules: list[str] = Field(
739
795
  ```
740
796
 
741
797
  `bootstrap_from_settings()` (already called in `entries/api.py`) then registers
742
- the connectors and installs the module. Create its tables once, or manage the
743
- schema with Alembic:
798
+ the connectors and installs the module. Create its tables with
799
+ [`minix db`](#minix-db):
800
+
801
+ ```bash
802
+ minix db makemigrations -m "add rag"
803
+ minix db migrate
804
+ ```
805
+
806
+ Without migrations, create them once from code instead:
744
807
 
745
808
  ```python
746
809
  from minix.core.connectors import SqlConnector
@@ -825,6 +888,64 @@ through `provides=` on the paired repository and service.
825
888
 
826
889
  ---
827
890
 
891
+ ## OIDC Module
892
+
893
+ `minix.core.modules.oidc` is a standalone OpenID Connect module (it does not depend on the core `auth` module): authorization-code login with a signed session cookie, bearer-token validation against the IdP's JWKS, role mapping, tenant resolution, a token client and a login hook. Add `OidcModule` to `INSTALLED_MODULES` and set at least `OIDC_ISSUER` and `OIDC_CLIENT_ID`.
894
+
895
+ | Setting | Default | Purpose |
896
+ |---|---|---|
897
+ | `OIDC_ISSUER` / `OIDC_CLIENT_ID` / `OIDC_CLIENT_SECRET` | — | IdP issuer URL (discovery) and client credentials |
898
+ | `OIDC_AUDIENCE` | `OIDC_CLIENT_ID` | Accepted `aud` for bearer tokens; a comma-separated list accepts several audiences. ID tokens at the login callback are always checked against `OIDC_CLIENT_ID` |
899
+ | `OIDC_ALGORITHMS` | `RS256,ES256,PS256` | Allowed signing algorithms; `none` and `HS*` are always rejected |
900
+ | `OIDC_ALLOWED_REDIRECT_HOSTS` | empty | Hosts allowed as absolute `redirect` targets on login/logout (otherwise only relative paths) |
901
+ | `OIDC_AUTO_CREATE_TABLE` | `true` | Create the OIDC users table once at startup |
902
+ | `OIDC_TENANT_CLAIM` | `organization` | Token claim holding the user's organization(s); `none` disables tenant resolution (everyone gets their personal tenant) |
903
+ | `OIDC_SCOPES` | `openid profile email` | Add `offline_access` to receive a refresh token. Keycloak only emits the `organization` claim when the `organization` scope is requested, e.g. `openid profile email organization` |
904
+ | `OIDC_ROLE_CLAIM` / `OIDC_ROLE_MAP` / `OIDC_DEFAULT_ROLE` | `realm_access.roles` / — / `user` | Role extraction and mapping |
905
+ | `OIDC_JWKS_TTL` | `3600` | JWKS cache seconds (an unknown `kid` triggers one refetch, at most once per 60 s) |
906
+ | `OIDC_SESSION_SECRET` / `OIDC_SESSION_COOKIE` / `OIDC_SESSION_TTL` / `OIDC_COOKIE_SECURE` | — / `minix_session` / `28800` / `true` | Session cookie |
907
+
908
+ **Dependencies and identity** — `get_oidc_user` and `RequireOidcRole` return an `OidcContext` (`user_id`, `email`, `role`, `claims`, `tenant_id`, `tenant_name`, `tenant_is_personal`) or raise 401/403. `resolve_oidc_context(request)` returns an `OidcContext` or `None` when the request is unauthenticated. `resolve_identity(request, fallbacks)` returns an `OidcContext`, whatever identity the first matching fallback returns, or `None`. `resolve_identity` tries a bearer from the configured issuer, then the minix session cookie, then each fallback (`async (request) -> identity | None`). A bearer from a different issuer is skipped, so the app's own JWTs reach its fallbacks; an invalid bearer from the configured issuer returns `None` without trying fallbacks. An invalid or expired minix session cookie is treated as "no session" and falls through to the fallbacks (unlike an invalid bearer from the configured issuer).
909
+
910
+ **Tenants** — the tenant comes from `OIDC_TENANT_CLAIM`, which may be a single alias string, a list of aliases, or Keycloak's map form `{alias: {"id": ...}}` (the `id` becomes `tenant_id`, the alias `tenant_name`; an entry without `id` uses its alias). With several organizations the caller picks one with the `X-Organization` header (matching id or alias). Users without an organization get a personal tenant `user:{sub}` (`tenant_is_personal=True`); organization ids starting with `user:` are ignored so they cannot collide with personal tenants. `resolve_oidc_context` and `resolve_identity` can raise `HTTPException` 400 (`organization_selection_required`) or 403 (`organization_not_in_token`) for multi-organization users: call them from FastAPI dependencies, or handle the exception. Set `OIDC_TENANT_CLAIM=none` (or `""` in `settings.py`) to disable tenant resolution: every identity gets its personal tenant and `X-Organization` is ignored.
911
+
912
+ For browser sessions, organization membership is a snapshot taken at login and stored in the session cookie: changes at the IdP apply at the next login or when the session expires (`OIDC_SESSION_TTL`, default 8 h). Session cookies issued by 0.3.3 carry no organizations and resolve as personal until the user logs in again. Very large organization claims enlarge the cookie accordingly.
913
+
914
+ **Token client** — `OidcTokenClient` (registered by `OidcModule`) wraps the token endpoint and returns `TokenSet` (`access_token`, `expires_at`, `refresh_token`, `scope`):
915
+
916
+ ```python
917
+ from minix.core.registry import Registry
918
+ from minix.core.modules.oidc import OidcTokenClient
919
+
920
+ client = Registry().get(OidcTokenClient)
921
+ svc = client.client_credentials(audience="billing-api")
922
+ fresh = client.refresh(refresh_token)
923
+ downstream = client.exchange(subject_token=access_token, audience="other-api") # RFC 8693
924
+ client.revoke(refresh_token)
925
+ ```
926
+
927
+ Errors: `OidcError` (base), `OidcTokenRevoked`, `OidcExchangeDenied`, `OidcUnavailable` (also raised for 5xx and unexpected 3xx responses).
928
+
929
+ `OidcTokenClient` is synchronous: each call blocks on an HTTP request (10 s timeout). From async code, run it in the threadpool:
930
+
931
+ ```python
932
+ from starlette.concurrency import run_in_threadpool
933
+
934
+ tokens = await run_in_threadpool(client.exchange, access_token, "other-api")
935
+ ```
936
+
937
+ **Login hook** — implement `OidcLoginHook.on_login(claims, token_response)` (sync or `async def`) and register it with `Registry().register(OidcLoginHook, instance)`. It runs once per successful login, before the session cookie is issued; an async hook is awaited. If it raises, the login fails with HTTP 500 and no session is set. minix never stores the token response: the hook owns it.
938
+
939
+ **Schema ownership** — apps that manage their schema with Alembic set `OIDC_AUTO_CREATE_TABLE=false` and include the exported table in their migrations:
940
+
941
+ ```python
942
+ from minix.core.modules.oidc import OIDC_USERS_TABLE # SQLAlchemy Table, usable in env.py / autogenerate
943
+ ```
944
+
945
+ **Security notes** — login/logout `redirect` accepts relative paths only (absolute URLs only for `OIDC_ALLOWED_REDIRECT_HOSTS`; userinfo and percent-encoded authority are rejected). JWT verification and the user upsert run in a threadpool; the upsert is skipped when nothing changed (300 s cache).
946
+
947
+ ---
948
+
828
949
  ## Configuration
829
950
 
830
951
  Minix uses a **pydantic-settings** config module (`config.py`).
@@ -940,6 +1061,12 @@ pip install "minix[ai]"
940
1061
  pip install "minix[vdb]"
941
1062
  ```
942
1063
 
1064
+ ### Vector DB (pgvector)
1065
+
1066
+ ```bash
1067
+ pip install "minix[pgvector]"
1068
+ ```
1069
+
943
1070
  ### ClickHouse Support
944
1071
 
945
1072
  ```bash
@@ -958,7 +1085,7 @@ pip install "minix[rag]"
958
1085
  ### Install All Extras
959
1086
 
960
1087
  ```bash
961
- pip install "minix[postgresql,mysql,ai,vdb,clickhouse,rag]"
1088
+ pip install "minix[postgresql,pgvector,mysql,ai,vdb,clickhouse,rag]"
962
1089
  ```
963
1090
 
964
1091
  ---
@@ -1003,8 +1130,13 @@ minix add module --help
1003
1130
  | New project in cwd | `minix init APP_NAME` |
1004
1131
  | New project with RAG | `minix init APP_NAME --rag` |
1005
1132
  | Enable built-in RAG in an existing project | `minix add rag` |
1133
+ | Set up migrations (once per project) | `minix db init` |
1134
+ | Generate a migration from entity changes | `minix db makemigrations -m "message"` |
1135
+ | Apply / revert migrations | `minix db migrate` / `minix db downgrade -1` |
1136
+ | Inspect migrations | `minix db current` / `minix db history` |
1006
1137
  | New feature module | `minix add module MODULE_NAME` |
1007
1138
  | Add to existing module | `minix add controller\|task\|periodic\|helper\|consumer\|binding [NAME] --module=MODULE` |
1139
+ | Refresh coding-agent guidance | `minix sync agents` (`--check` to verify) |
1008
1140
  | Version | `minix -v` / `minix --version` |
1009
1141
 
1010
1142
  ### Global options
@@ -1069,8 +1201,11 @@ installs the engines you selected.
1069
1201
  | `Dockerfile` | App image (`pip install "minix~=X.Y.Z"` / extras from PyPI) |
1070
1202
  | `docker-compose.yml` | PostgreSQL or MySQL, Redis, MinIO, API, Celery; optional Qdrant / ClickHouse / MLflow |
1071
1203
  | `.dockerignore` | Build context excludes |
1072
- | `AGENTS.md` | CLI guide for AI coding agents (prefer `minix` over hand-scaffolding) |
1204
+ | `AGENTS.md` | Rules for AI coding agents (CLI, decision flow, upstream-first) inside a Minix-managed block |
1205
+ | `CLAUDE.md` | Imports `AGENTS.md` for Claude Code; add project rules below the managed block |
1206
+ | `.claude/skills/minix/` | Claude Code skill: concept map, patterns, upstream workflow |
1073
1207
  | `entries/` | `api.py`, `worker.py`, `beat.py` process entrypoints |
1208
+ | `migrations/<connection>/` | Alembic setup per SQL connection, driven by [`minix db`](#minix-db) |
1074
1209
 
1075
1210
  **App wiring after init** (settings, not legacy `app_connectors.py` / `app_modules.py`):
1076
1211
 
@@ -1114,6 +1249,192 @@ pip install "minix[mysql]"
1114
1249
  pip install "minix[postgresql,mysql]"
1115
1250
  ```
1116
1251
 
1252
+ ### `minix db`
1253
+
1254
+ Database migrations for your SQL entities, built on
1255
+ [Alembic](https://alembic.sqlalchemy.org/). If you know Django, the commands
1256
+ will feel familiar: change an entity, run `makemigrations`, review the file,
1257
+ then run `migrate`.
1258
+
1259
+ Minix compares the database with the SQL entities of the modules in
1260
+ `INSTALLED_MODULES`, so you never list tables by hand. Alembic ships with the
1261
+ `postgresql`, `mysql` and `rag` extras.
1262
+
1263
+ #### Migration workflow
1264
+
1265
+ `minix init` already sets up migrations. For a project created another way,
1266
+ run `minix db init` once.
1267
+
1268
+ ```bash
1269
+ # 1. Change an entity (or add a module with `minix add module orders`)
1270
+ # 2. Generate a migration; the database must be running
1271
+ minix db makemigrations -m "add orders"
1272
+ # → default: wrote migrations/default/versions/3f2a9c1b7d4e_add_orders.py
1273
+
1274
+ # 3. Read the generated file and fix anything autogenerate got wrong
1275
+ # 4. Apply it
1276
+ minix db migrate
1277
+ # → default: migrated to head
1278
+
1279
+ # 5. Commit the file in migrations/<connection>/versions/ with the entity change
1280
+ ```
1281
+
1282
+ On every other machine, including CI, staging and production, only run
1283
+ `minix db migrate`.
1284
+
1285
+ Autogenerate is a draft, not a guarantee. Always read the file before you
1286
+ apply it. In particular, a renamed column or table shows up as a drop plus an
1287
+ add, which loses data. Change it to `op.alter_column(..., new_column_name=...)`
1288
+ or `op.rename_table(...)`.
1289
+
1290
+ #### Migration commands
1291
+
1292
+ These commands do more than Alembic's equivalents:
1293
+
1294
+ | Command | What it does | Options |
1295
+ |---------|--------------|---------|
1296
+ | `minix db init` | Creates `migrations/<connection>/` for each PostgreSQL / MySQL connection. Existing files are kept. | `--database/-d NAME` (repeatable; default: every PostgreSQL / MySQL connection) |
1297
+ | `minix db makemigrations` | Compares the entities with the live database and writes a migration. Writes nothing when there are no changes. | `-m/--message`, `--database/-d`, `--empty` (blank migration to write by hand) |
1298
+ | `minix db migrate [REVISION]` | Applies migrations, up to `head` by default. | `--database/-d` |
1299
+ | `minix db downgrade REVISION` | Reverts migrations. | `--database/-d` |
1300
+
1301
+ These run the Alembic command of the same name. Minix picks the connection and
1302
+ loads `config.py` and `.env`; every other argument goes to Alembic unchanged,
1303
+ and `minix db <command> --help` shows Alembic's own help:
1304
+
1305
+ | Command | What it does | Example |
1306
+ |---------|--------------|---------|
1307
+ | `current` | Shows the revision the database is at | `minix db current` |
1308
+ | `history` | Lists migrations, newest first | `minix db history -v`, `minix db history -r-3:current` (no space after `-r`) |
1309
+ | `heads` | Shows the latest revision(s); more than one means history has split | `minix db heads` |
1310
+ | `branches` | Shows where history splits | `minix db branches` |
1311
+ | `show` | Shows one migration | `minix db show 3f2a` |
1312
+ | `check` | Exits non-zero when entities have changes without a migration | `minix db check` |
1313
+ | `stamp` | Records a revision in the database without running anything | `minix db stamp head` |
1314
+ | `merge` | Writes a migration that joins two heads | `minix db merge -m "merge" heads` |
1315
+ | `edit` | Opens a migration in `$EDITOR` | `minix db edit head` |
1316
+
1317
+ All commands accept `--database/-d NAME` (repeatable). Without it, they run for
1318
+ every connection that has a `migrations/` directory, with an `== name ==`
1319
+ header per connection when there are several.
1320
+
1321
+ #### Revision targets
1322
+
1323
+ `migrate`, `downgrade`, `stamp` and `show` take a revision:
1324
+
1325
+ | Target | Meaning |
1326
+ |--------|---------|
1327
+ | `head` | The latest migration |
1328
+ | `heads` | Every head, when history has split |
1329
+ | `base` | Before the first migration (`downgrade base` reverts everything) |
1330
+ | `3f2a9c1b7d4e` or `3f2a` | A revision id, or any unique prefix of one |
1331
+ | `-1`, `-2` | Steps back from the current revision (`downgrade`) |
1332
+ | `+1`, `+2` | Steps forward from the current revision (`migrate`) |
1333
+
1334
+ #### Migration recipes
1335
+
1336
+ **Write a data migration.** Generate an empty migration and fill in
1337
+ `upgrade()` and `downgrade()`:
1338
+
1339
+ ```bash
1340
+ minix db makemigrations --empty -m "backfill order status"
1341
+ ```
1342
+
1343
+ ```python
1344
+ def upgrade() -> None:
1345
+ op.execute("UPDATE orders SET status = 'NEW' WHERE status IS NULL")
1346
+
1347
+
1348
+ def downgrade() -> None:
1349
+ pass
1350
+ ```
1351
+
1352
+ **Catch missing migrations in CI.** With the database migrated to head, this
1353
+ fails when someone changed an entity without running `makemigrations`:
1354
+
1355
+ ```bash
1356
+ minix db migrate && minix db check
1357
+ ```
1358
+
1359
+ **Adopt migrations on a database that already has its tables.**
1360
+ `makemigrations` compares with the live database, so against a database that
1361
+ already has the tables it finds nothing to write. Generate the first migration
1362
+ against an empty database, then mark existing databases as up to date:
1363
+
1364
+ ```bash
1365
+ # Against an empty local database
1366
+ minix db makemigrations -m "initial"
1367
+ minix db migrate
1368
+
1369
+ # Against each database that already has the tables (staging, production)
1370
+ minix db stamp head
1371
+ ```
1372
+
1373
+ **Resolve two migrations from parallel branches.** When two branches each add a
1374
+ migration, `migrate` and `makemigrations` fail with a "multiple heads" error.
1375
+ Join them, then migrate:
1376
+
1377
+ ```bash
1378
+ minix db heads # shows both
1379
+ minix db merge -m "merge" heads
1380
+ minix db migrate
1381
+ ```
1382
+
1383
+ **Remove a module.** Its tables stay in the database, because Minix never drops
1384
+ tables that no installed module owns. To drop them, write the drop in an empty
1385
+ migration (`makemigrations --empty`, then `op.drop_table("orders")`).
1386
+
1387
+ **Use several databases.** Each `settings.DATABASES` connection gets its own
1388
+ `migrations/<connection>/` and only manages the tables of entities bound to it
1389
+ with `add_binding(..., connection="analytics")`:
1390
+
1391
+ ```bash
1392
+ minix db init -d analytics
1393
+ minix db makemigrations -m "add events" -d analytics
1394
+ minix db migrate # every connection
1395
+ minix db migrate -d analytics # one connection
1396
+ ```
1397
+
1398
+ **Preview the SQL instead of running it.** Use Alembic directly with `--sql`:
1399
+
1400
+ ```bash
1401
+ alembic -c migrations/default/alembic.ini upgrade head --sql
1402
+ ```
1403
+
1404
+ **Run in Docker.** Migrate before the new app version starts serving:
1405
+
1406
+ ```bash
1407
+ docker compose run --rm app minix db migrate
1408
+ ```
1409
+
1410
+ #### How migrations work
1411
+
1412
+ - `migrations/<connection>/` holds `alembic.ini`, `env.py`, `script.py.mako`
1413
+ and `versions/`. `env.py` calls `minix.core.migrations.run_migrations`, which
1414
+ loads `.env` and `config.py`, so plain `alembic -c migrations/<connection>/alembic.ini …`
1415
+ works on the same files.
1416
+ - Each connection compares only the tables of the entities bound to it. Tables
1417
+ that no installed module owns, including other connections' tables, are never
1418
+ touched.
1419
+ - The `default` connection records its revision in `alembic_version`; others use
1420
+ `alembic_version_<connection>`, so two connections can share one database.
1421
+ - On PostgreSQL, generated downgrades also drop the enum types of the tables
1422
+ they drop, so a downgrade followed by `migrate` works.
1423
+ - ClickHouse connections are skipped, because Alembic does not support them.
1424
+
1425
+ #### Migration troubleshooting
1426
+
1427
+ | Message | Fix |
1428
+ |---------|-----|
1429
+ | `No config.py found` | Run the command in the project root. |
1430
+ | `Alembic is not installed` | `pip install "minix[postgresql]"` (or `mysql`). |
1431
+ | `No migrations set up` / `No migrations for 'x'` | `minix db init`, or `minix db init -d x`. |
1432
+ | `Target database is not up to date` | `minix db migrate`, then run `makemigrations` again. |
1433
+ | `Multiple head revisions are present` / `Multiple heads are present` | `minix db merge -m "merge" heads`, then `minix db migrate`. |
1434
+ | Connection refused | Start the database (`docker compose up -d`) and check `DB_*` in `.env`. |
1435
+ | `type "…" already exists` on PostgreSQL | An enum type was left behind by a downgrade. Drop it in the migration (`op.execute('DROP TYPE IF EXISTS "name"')`), or by hand. |
1436
+ | `type "…" does not exist` after adding an enum column | Alembic creates enum types with new tables but not with new columns. Add `sa.Enum(..., name="name").create(op.get_bind(), checkfirst=True)` before `op.add_column(...)`. |
1437
+
1117
1438
  ### `minix add module`
1118
1439
 
1119
1440
  Scaffold a feature module under `src/modules/<name>/`.
@@ -1211,7 +1532,7 @@ src/modules/<name>/
1211
1532
  #### After scaffolding
1212
1533
 
1213
1534
  1. Confirm `INSTALLED_MODULES` contains e.g. `"src.modules.orders.OrdersModule"`.
1214
- 2. Implement fields on the entity; add an Alembic migration if the app uses one.
1535
+ 2. Implement fields on the entity, then `minix db makemigrations -m "add orders" && minix db migrate`.
1215
1536
  3. Expand service / controller as needed.
1216
1537
  4. Restart API / worker.
1217
1538
 
@@ -1257,6 +1578,22 @@ minix add task ShipOrder -m orders # ShipOrderTask
1257
1578
  minix add binding -m payments --entity=Payment
1258
1579
  ```
1259
1580
 
1581
+ ### Coding agents
1582
+
1583
+ `minix init` writes guidance for AI coding agents: `AGENTS.md`, `CLAUDE.md` and the
1584
+ Claude Code skill in `.claude/skills/minix/`. Minix owns the text between the
1585
+ `<!-- BEGIN MINIX -->` / `<!-- END MINIX -->` markers and the skill directory; anything
1586
+ you write outside the markers is kept. The guidance tells agents to build with the CLI
1587
+ and Minix's base classes, and to add missing generic capabilities to Minix instead of
1588
+ the project.
1589
+
1590
+ After upgrading Minix, refresh it so the guidance matches the installed version:
1591
+
1592
+ ```bash
1593
+ minix sync agents # write
1594
+ minix sync agents --check # exit 1 if stale (for CI)
1595
+ ```
1596
+
1260
1597
  ---
1261
1598
 
1262
1599
  ## License