baobab-auth-core 0.1.0__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 (206) hide show
  1. baobab_auth_core-0.1.0/.codex/rules/default.rules +92 -0
  2. baobab_auth_core-0.1.0/.cursor/rules/00-global-workflow.mdc +45 -0
  3. baobab_auth_core-0.1.0/.cursor/rules/000-core.mdc +41 -0
  4. baobab_auth_core-0.1.0/.cursor/rules/10-python-oop.mdc +48 -0
  5. baobab_auth_core-0.1.0/.cursor/rules/20-tests-coverage.mdc +40 -0
  6. baobab_auth_core-0.1.0/.cursor/rules/30-documentation-rst.mdc +54 -0
  7. baobab_auth_core-0.1.0/.cursor/rules/40-git-workflow.mdc +59 -0
  8. baobab_auth_core-0.1.0/.cursor/rules/50-no-ai-attribution.mdc +52 -0
  9. baobab_auth_core-0.1.0/.editorconfig +18 -0
  10. baobab_auth_core-0.1.0/.env.example +9 -0
  11. baobab_auth_core-0.1.0/.gitattributes +18 -0
  12. baobab_auth_core-0.1.0/.github/ISSUE_TEMPLATE/01-user-story.yml +32 -0
  13. baobab_auth_core-0.1.0/.github/ISSUE_TEMPLATE/02-feature.yml +32 -0
  14. baobab_auth_core-0.1.0/.github/ISSUE_TEMPLATE/03-task.yml +34 -0
  15. baobab_auth_core-0.1.0/.github/ISSUE_TEMPLATE/config.yml +1 -0
  16. baobab_auth_core-0.1.0/.github/dependabot.yml +20 -0
  17. baobab_auth_core-0.1.0/.github/pull_request_template.md +52 -0
  18. baobab_auth_core-0.1.0/.github/workflows/ci.yml +110 -0
  19. baobab_auth_core-0.1.0/.github/workflows/integration.yml +74 -0
  20. baobab_auth_core-0.1.0/.github/workflows/release.yml +110 -0
  21. baobab_auth_core-0.1.0/.gitignore +52 -0
  22. baobab_auth_core-0.1.0/.pre-commit-config.yaml +58 -0
  23. baobab_auth_core-0.1.0/.python-version +1 -0
  24. baobab_auth_core-0.1.0/AGENTS.md +294 -0
  25. baobab_auth_core-0.1.0/CHANGELOG.md +136 -0
  26. baobab_auth_core-0.1.0/CLAUDE.md +16 -0
  27. baobab_auth_core-0.1.0/CONTRIBUTING.md +53 -0
  28. baobab_auth_core-0.1.0/LICENSE +21 -0
  29. baobab_auth_core-0.1.0/Makefile +30 -0
  30. baobab_auth_core-0.1.0/PKG-INFO +206 -0
  31. baobab_auth_core-0.1.0/README.md +186 -0
  32. baobab_auth_core-0.1.0/SECURITY.md +27 -0
  33. baobab_auth_core-0.1.0/docs/_static/.gitkeep +0 -0
  34. baobab_auth_core-0.1.0/docs/ai_workflow/priorities/.gitkeep +0 -0
  35. baobab_auth_core-0.1.0/docs/ai_workflow/roles/.gitkeep +0 -0
  36. baobab_auth_core-0.1.0/docs/ai_workflow/runs/.gitkeep +0 -0
  37. baobab_auth_core-0.1.0/docs/ai_workflow/runs/BL-010-001/status.yaml +8 -0
  38. baobab_auth_core-0.1.0/docs/ai_workflow/state/dependency_graph.yaml +66 -0
  39. baobab_auth_core-0.1.0/docs/ai_workflow/state/lock.yaml +20 -0
  40. baobab_auth_core-0.1.0/docs/ai_workflow/state/queue.yaml +68 -0
  41. baobab_auth_core-0.1.0/docs/ai_workflow/versions/.gitkeep +0 -0
  42. baobab_auth_core-0.1.0/docs/ai_workflow/versions/v0.1.0/version.yaml +38 -0
  43. baobab_auth_core-0.1.0/docs/ai_workflow/workflow.md +103 -0
  44. baobab_auth_core-0.1.0/docs/api/index.rst +10 -0
  45. baobab_auth_core-0.1.0/docs/architecture/adr/.gitkeep +0 -0
  46. baobab_auth_core-0.1.0/docs/backlog/backlogs/.gitkeep +0 -0
  47. baobab_auth_core-0.1.0/docs/backlog/features/.gitkeep +0 -0
  48. baobab_auth_core-0.1.0/docs/backlog/user_stories/.gitkeep +0 -0
  49. baobab_auth_core-0.1.0/docs/conf.py +30 -0
  50. baobab_auth_core-0.1.0/docs/contracts/compatibility.md +22 -0
  51. baobab_auth_core-0.1.0/docs/contracts/exceptions.md +15 -0
  52. baobab_auth_core-0.1.0/docs/contracts/imports.md +16 -0
  53. baobab_auth_core-0.1.0/docs/contracts/models.md +7 -0
  54. baobab_auth_core-0.1.0/docs/contracts/public_api.md +21 -0
  55. baobab_auth_core-0.1.0/docs/contracts/services.md +8 -0
  56. baobab_auth_core-0.1.0/docs/guides/domain_model.rst +168 -0
  57. baobab_auth_core-0.1.0/docs/guides/how-to/ajouter-une-classe.rst +25 -0
  58. baobab_auth_core-0.1.0/docs/guides/index.rst +19 -0
  59. baobab_auth_core-0.1.0/docs/guides/ports.rst +136 -0
  60. baobab_auth_core-0.1.0/docs/guides/testing.rst +158 -0
  61. baobab_auth_core-0.1.0/docs/guides/tutorials/premiers-pas.rst +26 -0
  62. baobab_auth_core-0.1.0/docs/index.rst +23 -0
  63. baobab_auth_core-0.1.0/docs/integrations/compatibility_matrix.yaml +35 -0
  64. baobab_auth_core-0.1.0/docs/integrations/reports/.gitkeep +0 -0
  65. baobab_auth_core-0.1.0/docs/specifications/cahier-des-charges/README.md +13 -0
  66. baobab_auth_core-0.1.0/docs/specifications/glossary.rst +16 -0
  67. baobab_auth_core-0.1.0/docs/specifications/index.rst +36 -0
  68. baobab_auth_core-0.1.0/docs/specifications/us/US-001-exemple/FEAT-001.1-salutations.rst +25 -0
  69. baobab_auth_core-0.1.0/docs/specifications/us/US-001-exemple/index.rst +29 -0
  70. baobab_auth_core-0.1.0/docs/specifications/us/index.rst +7 -0
  71. baobab_auth_core-0.1.0/docs/workflow/README.md +66 -0
  72. baobab_auth_core-0.1.0/docs/workflow/SETUP.md +112 -0
  73. baobab_auth_core-0.1.0/docs/workflow/gates.md +38 -0
  74. baobab_auth_core-0.1.0/docs/workflow/handoff.md +53 -0
  75. baobab_auth_core-0.1.0/docs/workflow/prompts/init.md +42 -0
  76. baobab_auth_core-0.1.0/docs/workflow/prompts/orchestration.md +25 -0
  77. baobab_auth_core-0.1.0/docs/workflow/roles/00-orchestrateur.md +24 -0
  78. baobab_auth_core-0.1.0/docs/workflow/roles/01-product-owner.md +22 -0
  79. baobab_auth_core-0.1.0/docs/workflow/roles/02-architecte.md +22 -0
  80. baobab_auth_core-0.1.0/docs/workflow/roles/03-developpeur.md +23 -0
  81. baobab_auth_core-0.1.0/docs/workflow/roles/04-relecteur.md +24 -0
  82. baobab_auth_core-0.1.0/docs/workflow/roles/05-securite.md +26 -0
  83. baobab_auth_core-0.1.0/docs/workflow/roles/06-release-manager.md +27 -0
  84. baobab_auth_core-0.1.0/docs/workflow/roles/07-support.md +22 -0
  85. baobab_auth_core-0.1.0/noxfile.py +45 -0
  86. baobab_auth_core-0.1.0/pyproject.toml +116 -0
  87. baobab_auth_core-0.1.0/scripts/check_no_ai_attribution.py +57 -0
  88. baobab_auth_core-0.1.0/scripts/setup_github.sh +58 -0
  89. baobab_auth_core-0.1.0/src/baobab_auth_core/__init__.py +13 -0
  90. baobab_auth_core-0.1.0/src/baobab_auth_core/application/__init__.py +6 -0
  91. baobab_auth_core-0.1.0/src/baobab_auth_core/application/commands/__init__.py +6 -0
  92. baobab_auth_core-0.1.0/src/baobab_auth_core/application/results/__init__.py +6 -0
  93. baobab_auth_core-0.1.0/src/baobab_auth_core/application/use_cases/__init__.py +6 -0
  94. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/__init__.py +6 -0
  95. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/entities/__init__.py +20 -0
  96. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/entities/audit_event.py +46 -0
  97. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/entities/permission.py +32 -0
  98. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/entities/role.py +33 -0
  99. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/entities/session.py +42 -0
  100. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/entities/user.py +157 -0
  101. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/entities/user_profile.py +34 -0
  102. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/enums/__init__.py +18 -0
  103. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/enums/audit_event_type.py +37 -0
  104. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/enums/audit_severity.py +19 -0
  105. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/enums/session_status.py +20 -0
  106. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/enums/user_status.py +23 -0
  107. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/policies/__init__.py +18 -0
  108. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/policies/password_policy.py +80 -0
  109. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/policies/role_policy.py +30 -0
  110. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/policies/session_policy.py +33 -0
  111. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/services/__init__.py +6 -0
  112. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/__init__.py +44 -0
  113. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/audit_event_id.py +43 -0
  114. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/auth_subject.py +44 -0
  115. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/email.py +46 -0
  116. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/password_hash.py +44 -0
  117. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/permission_id.py +43 -0
  118. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/permission_name.py +49 -0
  119. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/plain_password.py +44 -0
  120. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/role_id.py +43 -0
  121. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/role_name.py +49 -0
  122. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/session_id.py +43 -0
  123. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/token_id.py +43 -0
  124. baobab_auth_core-0.1.0/src/baobab_auth_core/domain/value_objects/user_id.py +43 -0
  125. baobab_auth_core-0.1.0/src/baobab_auth_core/exceptions/__init__.py +98 -0
  126. baobab_auth_core-0.1.0/src/baobab_auth_core/exceptions/auth.py +29 -0
  127. baobab_auth_core-0.1.0/src/baobab_auth_core/exceptions/authorization.py +27 -0
  128. baobab_auth_core-0.1.0/src/baobab_auth_core/exceptions/base.py +22 -0
  129. baobab_auth_core-0.1.0/src/baobab_auth_core/exceptions/role.py +29 -0
  130. baobab_auth_core-0.1.0/src/baobab_auth_core/exceptions/session.py +27 -0
  131. baobab_auth_core-0.1.0/src/baobab_auth_core/exceptions/user.py +41 -0
  132. baobab_auth_core-0.1.0/src/baobab_auth_core/exceptions/validation.py +43 -0
  133. baobab_auth_core-0.1.0/src/baobab_auth_core/ports/__init__.py +32 -0
  134. baobab_auth_core-0.1.0/src/baobab_auth_core/ports/audit_repository.py +33 -0
  135. baobab_auth_core-0.1.0/src/baobab_auth_core/ports/clock.py +22 -0
  136. baobab_auth_core-0.1.0/src/baobab_auth_core/ports/id_generator.py +21 -0
  137. baobab_auth_core-0.1.0/src/baobab_auth_core/ports/password_hasher.py +35 -0
  138. baobab_auth_core-0.1.0/src/baobab_auth_core/ports/permission_repository.py +45 -0
  139. baobab_auth_core-0.1.0/src/baobab_auth_core/ports/role_repository.py +45 -0
  140. baobab_auth_core-0.1.0/src/baobab_auth_core/ports/session_repository.py +45 -0
  141. baobab_auth_core-0.1.0/src/baobab_auth_core/ports/token_provider.py +49 -0
  142. baobab_auth_core-0.1.0/src/baobab_auth_core/ports/unit_of_work.py +58 -0
  143. baobab_auth_core-0.1.0/src/baobab_auth_core/ports/user_repository.py +65 -0
  144. baobab_auth_core-0.1.0/src/baobab_auth_core/py.typed +0 -0
  145. baobab_auth_core-0.1.0/src/baobab_auth_core/testing/__init__.py +46 -0
  146. baobab_auth_core-0.1.0/src/baobab_auth_core/testing/fake_clock.py +45 -0
  147. baobab_auth_core-0.1.0/src/baobab_auth_core/testing/fake_id_generator.py +36 -0
  148. baobab_auth_core-0.1.0/src/baobab_auth_core/testing/fake_password_hasher.py +34 -0
  149. baobab_auth_core-0.1.0/src/baobab_auth_core/testing/fake_token_provider.py +66 -0
  150. baobab_auth_core-0.1.0/src/baobab_auth_core/testing/in_memory_audit_repository.py +42 -0
  151. baobab_auth_core-0.1.0/src/baobab_auth_core/testing/in_memory_permission_repository.py +53 -0
  152. baobab_auth_core-0.1.0/src/baobab_auth_core/testing/in_memory_role_repository.py +53 -0
  153. baobab_auth_core-0.1.0/src/baobab_auth_core/testing/in_memory_session_repository.py +55 -0
  154. baobab_auth_core-0.1.0/src/baobab_auth_core/testing/in_memory_unit_of_work.py +68 -0
  155. baobab_auth_core-0.1.0/src/baobab_auth_core/testing/in_memory_user_repository.py +76 -0
  156. baobab_auth_core-0.1.0/tests/__init__.py +0 -0
  157. baobab_auth_core-0.1.0/tests/contracts/.gitkeep +0 -0
  158. baobab_auth_core-0.1.0/tests/fixtures/.gitkeep +0 -0
  159. baobab_auth_core-0.1.0/tests/fixtures/__init__.py +0 -0
  160. baobab_auth_core-0.1.0/tests/fixtures/builders.py +119 -0
  161. baobab_auth_core-0.1.0/tests/integration/.gitkeep +0 -0
  162. baobab_auth_core-0.1.0/tests/unit/__init__.py +0 -0
  163. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/__init__.py +0 -0
  164. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/__init__.py +0 -0
  165. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/entities/__init__.py +0 -0
  166. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/entities/test_audit_event.py +53 -0
  167. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/entities/test_permission.py +38 -0
  168. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/entities/test_role.py +39 -0
  169. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/entities/test_session.py +46 -0
  170. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/entities/test_user.py +128 -0
  171. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/entities/test_user_profile.py +45 -0
  172. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/enums/__init__.py +0 -0
  173. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/enums/test_audit_event_type.py +30 -0
  174. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/enums/test_audit_severity.py +15 -0
  175. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/enums/test_session_status.py +15 -0
  176. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/enums/test_user_status.py +25 -0
  177. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/policies/__init__.py +0 -0
  178. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/policies/test_password_policy.py +71 -0
  179. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/policies/test_role_policy.py +30 -0
  180. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/policies/test_session_policy.py +32 -0
  181. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/value_objects/__init__.py +0 -0
  182. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/value_objects/test_auth_subject.py +37 -0
  183. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/value_objects/test_email.py +48 -0
  184. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/value_objects/test_ids.py +117 -0
  185. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/value_objects/test_password_hash.py +37 -0
  186. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/value_objects/test_permission_name.py +38 -0
  187. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/value_objects/test_plain_password.py +37 -0
  188. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/domain/value_objects/test_role_name.py +44 -0
  189. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/exceptions/__init__.py +0 -0
  190. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/exceptions/test_auth.py +28 -0
  191. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/exceptions/test_authorization.py +33 -0
  192. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/exceptions/test_base.py +24 -0
  193. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/exceptions/test_role.py +32 -0
  194. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/exceptions/test_session.py +28 -0
  195. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/exceptions/test_user.py +44 -0
  196. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/exceptions/test_validation.py +49 -0
  197. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/ports/__init__.py +0 -0
  198. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/ports/test_ports_protocol.py +65 -0
  199. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/testing/__init__.py +0 -0
  200. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/testing/test_fake_clock.py +34 -0
  201. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/testing/test_fake_id_generator.py +27 -0
  202. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/testing/test_fake_password_hasher.py +30 -0
  203. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/testing/test_fake_token_provider.py +45 -0
  204. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/testing/test_in_memory_repositories.py +268 -0
  205. baobab_auth_core-0.1.0/tests/unit/baobab_auth_core/testing/test_in_memory_unit_of_work.py +52 -0
  206. baobab_auth_core-0.1.0/uv.lock +1337 -0
@@ -0,0 +1,92 @@
1
+ # Règles Codex — baobab-python-template
2
+ # Ce fichier encadre les commandes autorisées, à confirmer ou interdites.
3
+
4
+ prefix_rule(
5
+ pattern = ["uv", "run", "pytest"],
6
+ decision = "allow",
7
+ justification = "Les tests doivent pouvoir être exécutés."
8
+ )
9
+
10
+ prefix_rule(
11
+ pattern = ["uv", "run", "black"],
12
+ decision = "allow",
13
+ justification = "Le formatage est autorisé."
14
+ )
15
+
16
+ prefix_rule(
17
+ pattern = ["uv", "run", "ruff"],
18
+ decision = "allow",
19
+ justification = "Le lint est autorisé."
20
+ )
21
+
22
+ prefix_rule(
23
+ pattern = ["uv", "run", "mypy"],
24
+ decision = "allow",
25
+ justification = "Le typage doit être contrôlé."
26
+ )
27
+
28
+ prefix_rule(
29
+ pattern = ["uv", "run", "bandit"],
30
+ decision = "allow",
31
+ justification = "L'analyse sécurité est obligatoire."
32
+ )
33
+
34
+ prefix_rule(
35
+ pattern = ["uv", "build"],
36
+ decision = "allow",
37
+ justification = "La construction du package est autorisée."
38
+ )
39
+
40
+ prefix_rule(
41
+ pattern = ["uv", "run", "twine", "check"],
42
+ decision = "allow",
43
+ justification = "La vérification de la distribution est autorisée."
44
+ )
45
+
46
+ prefix_rule(
47
+ pattern = ["uv", "sync"],
48
+ decision = "allow",
49
+ justification = "La synchronisation de l'environnement est autorisée."
50
+ )
51
+
52
+ prefix_rule(
53
+ pattern = ["uv", "add"],
54
+ decision = "confirm",
55
+ justification = "L'ajout d'une dépendance nécessite une confirmation explicite."
56
+ )
57
+
58
+ prefix_rule(
59
+ pattern = ["uv", "remove"],
60
+ decision = "confirm",
61
+ justification = "La suppression d'une dépendance nécessite une confirmation explicite."
62
+ )
63
+
64
+ prefix_rule(
65
+ pattern = ["git", "push"],
66
+ decision = "confirm",
67
+ justification = "Un push vers le dépôt distant doit être confirmé."
68
+ )
69
+
70
+ prefix_rule(
71
+ pattern = ["git", "tag"],
72
+ decision = "confirm",
73
+ justification = "La création d'un tag de release doit être confirmée."
74
+ )
75
+
76
+ prefix_rule(
77
+ pattern = ["rm", "-rf"],
78
+ decision = "forbidden",
79
+ justification = "Suppression récursive interdite sans validation explicite."
80
+ )
81
+
82
+ prefix_rule(
83
+ pattern = ["git", "push", "--force"],
84
+ decision = "forbidden",
85
+ justification = "Force push interdit sur ce dépôt."
86
+ )
87
+
88
+ prefix_rule(
89
+ pattern = ["git", "commit", "--amend"],
90
+ decision = "confirm",
91
+ justification = "L'amendement d'un commit nécessite une confirmation (risque de perte)."
92
+ )
@@ -0,0 +1,45 @@
1
+ ---
2
+ description: Workflow IA multi-outils, verrou, handoff, recovery, runs
3
+ globs:
4
+ - "docs/ai_workflow/**"
5
+ - "docs/backlog/**"
6
+ alwaysApply: false
7
+ ---
8
+
9
+ # Workflow global
10
+
11
+ Source unique : [`AGENTS.md`](../../AGENTS.md) — section « Workflow ».
12
+
13
+ ## Principe fondamental
14
+
15
+ Un seul outil actif à la fois. Avant toute modification, lire
16
+ `docs/ai_workflow/state/lock.yaml` :
17
+
18
+ - `locked: false` → tu peux démarrer, créer le verrou.
19
+ - `locked: true` + `expires_at` futur → **STOP**, un autre outil est actif.
20
+ - `locked: true` + `expires_at` dépassé → verrou orphelin → procédure de recovery.
21
+
22
+ ## Rôles disponibles
23
+
24
+ Orchestrateur · Analyste fonctionnel · Architecte Python · Découpeur backlog ·
25
+ Développeur Python · Ingénieur QA · Reviewer technique · Release manager.
26
+
27
+ Un outil endosse **un seul rôle** par session.
28
+
29
+ ## Structure d'un run (`docs/ai_workflow/runs/BL-XXX/`)
30
+
31
+ ```
32
+ 00_assignment.md 01_context.md 02_role_prompt.md 03_expected_outputs.md
33
+ 04_worklog.md 05_tests_report.md 06_review.md 07_handoff.md
34
+ 08_recovery.md status.yaml
35
+ ```
36
+
37
+ Mettre à jour `status.yaml` à chaque transition d'état.
38
+
39
+ ## Recovery
40
+
41
+ En cas de verrou orphelin :
42
+ 1. Lire `status.yaml` + `git status` + `git diff`.
43
+ 2. Exécuter `make all`.
44
+ 3. Produire `08_recovery.md`.
45
+ 4. Recréer le verrou.
@@ -0,0 +1,41 @@
1
+ ---
2
+ description: Point d'entrée des règles — référence vers AGENTS.md et les règles spécialisées
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Règles de développement
8
+
9
+ La **source unique de vérité** est [`AGENTS.md`](../../AGENTS.md) à la racine.
10
+ **Lis-le intégralement avant toute action.** Ne duplique pas son contenu ici.
11
+
12
+ Règles spécialisées Cursor (pour le contexte automatique) :
13
+
14
+ | Fichier | Domaine |
15
+ |---------|---------|
16
+ | `00-global-workflow.mdc` | Workflow IA, verrou, handoff, recovery |
17
+ | `10-python-oop.mdc` | Python OOP, type hints, docstrings RST |
18
+ | `20-tests-coverage.mdc` | Tests pytest, couverture ≥ 95 %, miroir |
19
+ | `30-documentation-rst.mdc` | Sphinx, RST, Diátaxis |
20
+ | `40-git-workflow.mdc` | Modèle Git 3 niveaux, commits BL-XXX |
21
+ | `50-no-ai-attribution.mdc` | Interdiction attribution IA (appliquée toujours) |
22
+
23
+ Rappels prioritaires (le détail complet est dans `AGENTS.md`) :
24
+
25
+ - **Python ≥ 3.13, orienté objet.** 1 classe = 1 fichier (module nommé d'après la classe).
26
+ - **PEP 8** + **PEP 20** ; en cas de conflit, **PEP 8 prime**.
27
+ - **Type hints obligatoires** ; `black` (format) + `ruff` (lint) ; `mypy` strict.
28
+ - **Docstrings en reStructuredText**, avec `:spec: <ID>`.
29
+ - **Tests `pytest` en arborescence miroir** (`tests/unit/<pkg>/`) ; 1 classe testée = 1 classe
30
+ de test ; classe abstraite testée via une classe concrète de test ; **couverture ≥ 95 %**.
31
+ - Doc **Sphinx/RST** ; dossier `docs/guides/` obligatoire.
32
+ - Gestion des dépendances via **`uv`** ; lockfile **`uv.lock`** versionné.
33
+ - Aucun secret en clair (`.env` gitignoré + `.env.example`).
34
+ - **Modèle Git 3 niveaux** : `main` → `version/vX.Y.Z` → `bl/XXX-description`.
35
+ Une seule branche `bl/` active à la fois.
36
+ - **Messages de commit** : `BL-XXX: action courte`. Jamais de mention d'outil.
37
+ Le hook `no-ai-attribution` rejette tout commit avec attribution interdite.
38
+ - **Verrou** `docs/ai_workflow/state/lock.yaml` : ne pas modifier le projet si le
39
+ verrou est actif et non expiré.
40
+ - **Aucun outil ne doit apparaître comme contributeur, auteur, co-auteur ou mainteneur**
41
+ dans le moindre fichier versionné.
@@ -0,0 +1,48 @@
1
+ ---
2
+ description: Règles Python orienté objet, typage, docstrings
3
+ globs:
4
+ - "src/**/*.py"
5
+ alwaysApply: false
6
+ ---
7
+
8
+ # Python orienté objet
9
+
10
+ Source unique : [`AGENTS.md`](../../AGENTS.md) — sections « Langage & conception »,
11
+ « Typage & style ».
12
+
13
+ ## Règles absolues
14
+
15
+ - **1 classe = 1 fichier.** `class MonService` → `mon_service.py`.
16
+ Dérogation : hiérarchie d'exceptions → `exceptions/<catégorie>.py`.
17
+ - Python ≥ 3.13. SOLID. Composition > héritage.
18
+ - **Type hints obligatoires** sur toutes les signatures (paramètres et retours).
19
+ - Format : `black` (line-length 88). Lint : `ruff`. Types : `mypy --strict`.
20
+ - Pas de logique exécutable au niveau module.
21
+
22
+ ## Docstrings (reStructuredText)
23
+
24
+ ```python
25
+ class MonService:
26
+ """Description courte.
27
+
28
+ :param dep: Dépendance injectée.
29
+ :type dep: MonRepository
30
+ :spec: FEAT-001.1
31
+ """
32
+
33
+ def faire(self, valeur: str) -> str:
34
+ """Fait quelque chose.
35
+
36
+ :param valeur: La valeur d'entrée.
37
+ :returns: Le résultat.
38
+ :raises ValueError: Si valeur est vide.
39
+ """
40
+ ```
41
+
42
+ - Tout élément **public** doit avoir une docstring RST avec `:spec: <ID>`.
43
+ - `:spec:` lie le code à l'exigence fonctionnelle (traçabilité).
44
+
45
+ ## Contrat d'API
46
+
47
+ Ce qui est dans `__all__` est un contrat SemVer.
48
+ Rupture → MAJOR bump + entrée BREAKING dans `CHANGELOG.md`.
@@ -0,0 +1,40 @@
1
+ ---
2
+ description: Tests pytest, couverture ≥ 95 %, arborescence miroir
3
+ globs:
4
+ - "tests/**/*.py"
5
+ alwaysApply: false
6
+ ---
7
+
8
+ # Tests & couverture
9
+
10
+ Source unique : [`AGENTS.md`](../../AGENTS.md) — section « Tests ».
11
+
12
+ ## Arborescence miroir
13
+
14
+ ```
15
+ src/<pkg>/a/b/c.py → tests/unit/<pkg>/a/b/test_c.py
16
+ ```
17
+
18
+ Autres dossiers :
19
+ - `tests/integration/` — tests inter-librairies.
20
+ - `tests/contracts/` — tests de contrat des API publiques.
21
+ - `tests/fixtures/` — fixtures partagées.
22
+
23
+ ## Conventions
24
+
25
+ - **1 classe testée = 1 classe de test** : `class MonService` → `class TestMonService`.
26
+ - **Classe abstraite** : tester via une classe concrète définie dans le fichier de test.
27
+ - Structure **AAA** : Arrange / Act / Assert.
28
+ - Noms porteurs de l'ID spec : `def test_FEAT_001_1_cas_nominal(...)`.
29
+ - **Couverture ≥ 95 %** — imposée par `--cov-fail-under=95`.
30
+ - Aucun `# pragma: no cover` sans justification documentée.
31
+ - Aucun `@pytest.mark.skip` sans justification documentée.
32
+ - Zéro warning pytest accepté.
33
+
34
+ ## Lancer les tests
35
+
36
+ ```bash
37
+ uv run pytest --cov=src --cov-report=term-missing --cov-fail-under=95
38
+ # ou :
39
+ make test
40
+ ```
@@ -0,0 +1,54 @@
1
+ ---
2
+ description: Documentation Sphinx, docstrings reStructuredText, Diátaxis
3
+ globs:
4
+ - "docs/**/*.rst"
5
+ - "src/**/*.py"
6
+ alwaysApply: false
7
+ ---
8
+
9
+ # Documentation reStructuredText
10
+
11
+ Source unique : [`AGENTS.md`](../../AGENTS.md) — section « Documentation ».
12
+
13
+ ## Docstrings publiques (RST obligatoire)
14
+
15
+ Format reStructuredText sur tout élément public (classe, méthode, propriété) :
16
+
17
+ ```python
18
+ def calculer(self, valeur: float) -> float:
19
+ """Calcule le résultat.
20
+
21
+ :param valeur: La valeur d'entrée (doit être positive).
22
+ :type valeur: float
23
+ :returns: Le résultat du calcul.
24
+ :rtype: float
25
+ :raises ValueError: Si ``valeur`` est négative.
26
+ :spec: FEAT-002.3
27
+ """
28
+ ```
29
+
30
+ Champs obligatoires : `:param:`, `:returns:`, `:raises:` (si applicable), `:spec:`.
31
+
32
+ ## Structure docs/
33
+
34
+ ```
35
+ docs/
36
+ ├── specifications/ # US / FEAT en RST (source stable)
37
+ ├── ai_workflow/ # workflow IA, state, runs (Markdown opérationnel)
38
+ ├── api/ # autodoc Sphinx (généré)
39
+ ├── guides/
40
+ │ ├── tutorials/ # apprendre (Diátaxis)
41
+ │ └── how-to/ # résoudre un problème précis (Diátaxis)
42
+ ├── contracts/ # contrats publics de la librairie
43
+ └── integrations/ # matrices de compatibilité, rapports
44
+ ```
45
+
46
+ ## Générer la doc
47
+
48
+ ```bash
49
+ make docs
50
+ # ou :
51
+ sphinx-build -b html docs docs/_build/html
52
+ ```
53
+
54
+ La doc **ne doit pas** mentionner un outil comme auteur ou générateur.
@@ -0,0 +1,59 @@
1
+ ---
2
+ description: Modèle Git 3 niveaux, messages de commit, PR, SemVer
3
+ globs:
4
+ - ".github/**"
5
+ alwaysApply: false
6
+ ---
7
+
8
+ # Workflow Git
9
+
10
+ Source unique : [`AGENTS.md`](../../AGENTS.md) — section « Git & traçabilité ».
11
+
12
+ ## Modèle de branches (3 niveaux)
13
+
14
+ ```
15
+ main
16
+ └── version/v0.1.0
17
+ └── bl/012-implement-user-repository
18
+ ```
19
+
20
+ - `main` — stable uniquement, porte les tags de release.
21
+ - `version/vX.Y.Z` — tout le travail d'une version.
22
+ - `bl/XXX-description` — implémentation atomique d'un backlog.
23
+ - **Une seule branche `bl/` active** (non mergée) à la fois.
24
+ - Merges toujours ascendants : `bl/` → `version/` → `main`.
25
+ - **Aucun commit direct sur `main`.**
26
+
27
+ ## Format de commit obligatoire
28
+
29
+ ```
30
+ BL-XXX: action courte et explicite
31
+ ```
32
+
33
+ Exemples :
34
+ ```
35
+ BL-012: implement user repository
36
+ BL-013: add user repository unit tests
37
+ ```
38
+
39
+ **Jamais** : mention d'un outil, `Co-authored-by:`, génération automatique.
40
+ Le hook `no-ai-attribution` bloque les commit non conformes.
41
+
42
+ ## Actions par backlog
43
+
44
+ ```
45
+ git checkout version/vX.Y.Z
46
+ git checkout -b bl/XXX-description
47
+ # ... implémenter, tester ...
48
+ make all
49
+ git commit -m "BL-XXX: ..."
50
+ # ouvrir PR vers version/vX.Y.Z, attendre CI verte
51
+ ```
52
+
53
+ ## Release
54
+
55
+ Tag créé sur `main` uniquement si la version est `RELEASE_READY` :
56
+ ```bash
57
+ git tag vX.Y.Z
58
+ git push origin vX.Y.Z
59
+ ```
@@ -0,0 +1,52 @@
1
+ ---
2
+ description: Interdiction absolue de mention contributive des outils IA
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Interdiction de mention contributive des outils
8
+
9
+ Source unique : [`AGENTS.md`](../../AGENTS.md) — section « Interdiction de mention
10
+ contributive des outils ».
11
+
12
+ ## Règle absolue
13
+
14
+ **Aucun outil de développement assisté (Cursor, Claude Code, Codex…) ne doit
15
+ apparaître comme contributeur, auteur, co-auteur, mainteneur ou générateur.**
16
+
17
+ Cette règle s'applique partout et sans exception.
18
+
19
+ ## Formulations interdites
20
+
21
+ ```
22
+ Generated by ...
23
+ Created by ...
24
+ Implemented by Cursor / Claude / Codex
25
+ Co-authored-by: ...
26
+ AI-generated contribution
27
+ Assistant contribution
28
+ ```
29
+
30
+ ## Périmètre de l'interdiction
31
+
32
+ - Messages de commit
33
+ - Descriptions de pull requests
34
+ - `README.md`, `CHANGELOG.md`, documentation projet
35
+ - Métadonnées `pyproject.toml`, `AUTHORS`, `CONTRIBUTORS`
36
+ - Commentaires de code et docstrings
37
+ - Rapports de revue, de release, de run
38
+ - Logs de workflow versionnés dans le dépôt
39
+
40
+ ## Contrôle automatique
41
+
42
+ Un hook `pre-commit` de type `commit-msg` (`no-ai-attribution`) et un job CI
43
+ (`commit-policy`) rejettent automatiquement tout commit contenant une formulation
44
+ interdite. Il n'est pas possible de contourner ce contrôle.
45
+
46
+ ## Format correct
47
+
48
+ ```
49
+ BL-012: implement user repository
50
+ ```
51
+
52
+ Décrire le **travail réalisé**, jamais l'outil qui l'a réalisé.
@@ -0,0 +1,18 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+ indent_style = space
9
+
10
+ [*.py]
11
+ indent_size = 4
12
+ max_line_length = 100
13
+
14
+ [*.{rst,md,yml,yaml,toml,cfg}]
15
+ indent_size = 2
16
+
17
+ [Makefile]
18
+ indent_style = tab
@@ -0,0 +1,9 @@
1
+ # Copiez ce fichier en `.env` et renseignez vos valeurs.
2
+ # `.env` est gitignoré : n'y mettez jamais de secret dans le dépôt.
3
+ # Chargé/validé via pydantic-settings (voir src/<package>/settings.py si présent).
4
+
5
+ APP_ENV=development
6
+ LOG_LEVEL=INFO
7
+
8
+ # Exemple de secret (ne jamais committer la vraie valeur)
9
+ # API_KEY=changeme
@@ -0,0 +1,18 @@
1
+ # Normalise les fins de ligne : LF dans le dépôt, quel que soit l'OS du dev.
2
+ * text=auto eol=lf
3
+
4
+ # Scripts Windows : conserver CRLF (requis par cmd.exe).
5
+ *.bat text eol=crlf
6
+ *.cmd text eol=crlf
7
+
8
+ # Fichiers binaires : aucune normalisation.
9
+ *.png binary
10
+ *.jpg binary
11
+ *.jpeg binary
12
+ *.gif binary
13
+ *.ico binary
14
+ *.pdf binary
15
+ *.zip binary
16
+ *.gz binary
17
+ *.woff binary
18
+ *.woff2 binary
@@ -0,0 +1,32 @@
1
+ name: "📘 User Story"
2
+ description: "Décrire un besoin utilisateur (US)"
3
+ title: "[US-XXX] "
4
+ labels: ["type:us"]
5
+ body:
6
+ - type: input
7
+ id: id
8
+ attributes:
9
+ label: Identifiant
10
+ placeholder: "US-001"
11
+ validations:
12
+ required: true
13
+ - type: textarea
14
+ id: story
15
+ attributes:
16
+ label: Récit
17
+ description: "En tant que… je veux… afin de…"
18
+ placeholder: "En tant qu'utilisateur, je veux …, afin de …"
19
+ validations:
20
+ required: true
21
+ - type: textarea
22
+ id: acceptance
23
+ attributes:
24
+ label: Critères d'acceptation
25
+ placeholder: "- [ ] …"
26
+ validations:
27
+ required: true
28
+ - type: input
29
+ id: spec
30
+ attributes:
31
+ label: Spécification (RST)
32
+ placeholder: "docs/specifications/us/US-001-.../index.rst"
@@ -0,0 +1,32 @@
1
+ name: "🧩 Feature"
2
+ description: "Découper une US en fonctionnalité (FEAT)"
3
+ title: "[FEAT-XXX.Y] "
4
+ labels: ["type:feat"]
5
+ body:
6
+ - type: input
7
+ id: id
8
+ attributes:
9
+ label: Identifiant
10
+ placeholder: "FEAT-001.1"
11
+ validations:
12
+ required: true
13
+ - type: input
14
+ id: parent
15
+ attributes:
16
+ label: US parente
17
+ placeholder: "US-001 (#numéro de l'issue)"
18
+ validations:
19
+ required: true
20
+ - type: textarea
21
+ id: description
22
+ attributes:
23
+ label: Description
24
+ validations:
25
+ required: true
26
+ - type: textarea
27
+ id: acceptance
28
+ attributes:
29
+ label: Critères d'acceptation
30
+ placeholder: "- [ ] …"
31
+ validations:
32
+ required: true
@@ -0,0 +1,34 @@
1
+ name: "🔧 Task (backlog)"
2
+ description: "Tâche concrète rattachée à une Feature"
3
+ title: "[TASK-XXX.Y.Z] "
4
+ labels: ["type:task"]
5
+ body:
6
+ - type: input
7
+ id: id
8
+ attributes:
9
+ label: Identifiant
10
+ placeholder: "TASK-001.1.1"
11
+ validations:
12
+ required: true
13
+ - type: input
14
+ id: parent
15
+ attributes:
16
+ label: Feature parente
17
+ placeholder: "FEAT-001.1 (#numéro de l'issue)"
18
+ validations:
19
+ required: true
20
+ - type: textarea
21
+ id: description
22
+ attributes:
23
+ label: Description / étapes
24
+ validations:
25
+ required: true
26
+ - type: checkboxes
27
+ id: dod
28
+ attributes:
29
+ label: Definition of Done
30
+ options:
31
+ - label: "Code POO, 1 classe/fichier, type hints complets"
32
+ - label: "ruff + mypy strict passent"
33
+ - label: "Test miroir présent, couverture ≥ 90 %"
34
+ - label: "Docstrings RST / guide à jour si besoin"
@@ -0,0 +1 @@
1
+ blank_issues_enabled: false
@@ -0,0 +1,20 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ open-pull-requests-limit: 5
8
+ commit-message:
9
+ prefix: "chore"
10
+ include: "scope"
11
+ labels:
12
+ - "type:task"
13
+ - "dependencies"
14
+
15
+ - package-ecosystem: "github-actions"
16
+ directory: "/"
17
+ schedule:
18
+ interval: "weekly"
19
+ commit-message:
20
+ prefix: "ci"
@@ -0,0 +1,52 @@
1
+ ## Objectif
2
+
3
+ <!-- Décrire le but de cette PR et le backlog implémenté. -->
4
+
5
+ ## Backlog lié
6
+
7
+ - Backlog : `BL-XXX`
8
+ - User Story : `US-XXX`
9
+ - Feature : `FEAT-XXX`
10
+ - Issue : Closes #
11
+
12
+ ## Changements
13
+
14
+ <!-- Lister les fichiers/classes modifiés et ce qui a changé. -->
15
+
16
+ ## Tests exécutés
17
+
18
+ ```
19
+ make all
20
+ ```
21
+
22
+ - [ ] `uv run black --check src tests` → vert
23
+ - [ ] `uv run ruff check src tests` → vert
24
+ - [ ] `uv run mypy src` → vert
25
+ - [ ] `uv run bandit -r src -c pyproject.toml` → vert
26
+ - [ ] `uv run pytest --cov=src --cov-fail-under=95` → vert
27
+
28
+ ## Résultats qualité
29
+
30
+ <!-- Coller le résumé de `make all` ou copier les sorties pertinentes. -->
31
+
32
+ ## Couverture
33
+
34
+ <!-- Indiquer le pourcentage de couverture obtenu (doit être ≥ 95 %). -->
35
+
36
+ Couverture : X %
37
+
38
+ ## Impact contrat public
39
+
40
+ - [ ] Aucun symbole public (`__all__`) modifié de façon incompatible.
41
+ - [ ] Si rupture de contrat : MAJOR bump + entrée BREAKING dans `CHANGELOG.md` + note de migration.
42
+
43
+ ## Impact intégration
44
+
45
+ - [ ] `integration_required: false` — aucune validation inter-librairie requise.
46
+ - [ ] `integration_required: true` — les tests d'intégration ont été exécutés et sont verts.
47
+
48
+ ## Décision attendue
49
+
50
+ - [ ] `QA_PASSED`
51
+ - [ ] `TECH_REVIEW_PASSED`
52
+ - [ ] Prêt à merger vers `version/vX.Y.Z`