aetherius 0.2.0__tar.gz → 0.4.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 (261) hide show
  1. aetherius-0.4.0/.dockerignore +11 -0
  2. {aetherius-0.2.0 → aetherius-0.4.0}/.env.example +8 -0
  3. {aetherius-0.2.0 → aetherius-0.4.0}/.github/workflows/ci.yml +1 -1
  4. aetherius-0.4.0/.github/workflows/release.yml +92 -0
  5. aetherius-0.4.0/CHANGELOG.md +311 -0
  6. {aetherius-0.2.0 → aetherius-0.4.0}/CONTRIBUTING.md +5 -1
  7. {aetherius-0.2.0 → aetherius-0.4.0}/Makefile +1 -1
  8. {aetherius-0.2.0 → aetherius-0.4.0}/PKG-INFO +193 -27
  9. {aetherius-0.2.0 → aetherius-0.4.0}/README.md +181 -23
  10. aetherius-0.4.0/contracts/blueprint.schema.json +247 -0
  11. {aetherius-0.2.0 → aetherius-0.4.0}/contracts/events.schema.json +1 -1
  12. aetherius-0.4.0/contracts/openapi.yaml +345 -0
  13. aetherius-0.4.0/deploy/.env.example +17 -0
  14. aetherius-0.4.0/deploy/Dockerfile +63 -0
  15. aetherius-0.4.0/deploy/aetherius.service +29 -0
  16. aetherius-0.4.0/deploy/docker-compose.yml +28 -0
  17. {aetherius-0.2.0 → aetherius-0.4.0}/pyproject.toml +19 -10
  18. aetherius-0.4.0/src/aetherius/_contracts/blueprint.schema.json +247 -0
  19. aetherius-0.4.0/src/aetherius/acts/_cognition/__init__.py +12 -0
  20. aetherius-0.4.0/src/aetherius/acts/_cognition/claude.py +217 -0
  21. aetherius-0.4.0/src/aetherius/acts/_cognition/local.py +47 -0
  22. aetherius-0.4.0/src/aetherius/acts/_cognition/planning.py +240 -0
  23. aetherius-0.4.0/src/aetherius/acts/_cognition/provider.py +61 -0
  24. aetherius-0.4.0/src/aetherius/acts/_perception.py +48 -0
  25. aetherius-0.4.0/src/aetherius/acts/_shared.py +280 -0
  26. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/bridge.py +6 -3
  27. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/browser.py +103 -13
  28. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/driver.py +20 -0
  29. aetherius-0.4.0/src/aetherius/acts/oracle/driver.py +220 -0
  30. aetherius-0.4.0/src/aetherius/acts/oracle/locator.py +62 -0
  31. aetherius-0.4.0/src/aetherius/acts/oracle/model.py +7 -0
  32. aetherius-0.4.0/src/aetherius/acts/oracle/perception.py +6 -0
  33. aetherius-0.4.0/src/aetherius/acts/oracle/scan.py +98 -0
  34. aetherius-0.4.0/src/aetherius/acts/phantom/driver.py +92 -0
  35. aetherius-0.4.0/src/aetherius/acts/phantom/loop.py +145 -0
  36. aetherius-0.4.0/src/aetherius/acts/phantom/memory.py +70 -0
  37. aetherius-0.4.0/src/aetherius/acts/phantom/perception.py +21 -0
  38. aetherius-0.4.0/src/aetherius/acts/phantom/planner.py +47 -0
  39. aetherius-0.4.0/src/aetherius/acts/vector/client.py +216 -0
  40. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/vector/driver.py +56 -5
  41. aetherius-0.4.0/src/aetherius/acts/vector/impersonate.py +81 -0
  42. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/builder/catalog.py +4 -1
  43. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/builder/factory.py +6 -0
  44. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/builder/validation.py +25 -13
  45. aetherius-0.2.0/src/aetherius/cli.py → aetherius-0.4.0/src/aetherius/cli/__init__.py +38 -32
  46. aetherius-0.4.0/src/aetherius/cli/_shared.py +20 -0
  47. aetherius-0.4.0/src/aetherius/cli/approvals.py +51 -0
  48. aetherius-0.4.0/src/aetherius/cli/schedule.py +245 -0
  49. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/config/settings.py +17 -0
  50. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/app.py +2 -2
  51. aetherius-0.4.0/src/aetherius/console/approvals.py +56 -0
  52. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/console.tcss +40 -0
  53. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/options_editor.py +8 -0
  54. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/home.py +5 -0
  55. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/library.py +17 -0
  56. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/runs.py +13 -1
  57. aetherius-0.4.0/src/aetherius/console/screens/schedules/__init__.py +12 -0
  58. aetherius-0.4.0/src/aetherius/console/screens/schedules/_common.py +44 -0
  59. aetherius-0.4.0/src/aetherius/console/screens/schedules/detail.py +269 -0
  60. aetherius-0.4.0/src/aetherius/console/screens/schedules/form.py +350 -0
  61. aetherius-0.4.0/src/aetherius/console/screens/schedules/screen.py +182 -0
  62. aetherius-0.4.0/src/aetherius/console/screenshots.py +324 -0
  63. aetherius-0.4.0/src/aetherius/console/widgets/confirm.py +58 -0
  64. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/widgets/form.py +6 -2
  65. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/widgets/run_summary.py +2 -1
  66. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/base.py +42 -10
  67. aetherius-0.4.0/src/aetherius/core/actions/flow.py +95 -0
  68. aetherius-0.4.0/src/aetherius/core/actions/human.py +67 -0
  69. aetherius-0.4.0/src/aetherius/core/actions/notification.py +59 -0
  70. aetherius-0.4.0/src/aetherius/core/actions/registry.py +117 -0
  71. aetherius-0.4.0/src/aetherius/core/actions/vision.py +35 -0
  72. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/blueprint/models.py +26 -0
  73. aetherius-0.4.0/src/aetherius/core/blueprint/validator.py +130 -0
  74. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/errors.py +45 -0
  75. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/events/models.py +9 -1
  76. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/extraction/json_extractor.py +12 -0
  77. aetherius-0.4.0/src/aetherius/core/runtime/approvals.py +154 -0
  78. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/runtime/context.py +9 -0
  79. aetherius-0.4.0/src/aetherius/core/runtime/drivers.py +119 -0
  80. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/runtime/engine.py +31 -80
  81. aetherius-0.4.0/src/aetherius/core/runtime/flow.py +143 -0
  82. aetherius-0.4.0/src/aetherius/core/runtime/healing.py +246 -0
  83. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/runtime/result.py +5 -0
  84. aetherius-0.4.0/src/aetherius/core/runtime/selector.py +77 -0
  85. aetherius-0.4.0/src/aetherius/core/runtime/steps.py +240 -0
  86. aetherius-0.4.0/src/aetherius/models/registry.py +39 -0
  87. aetherius-0.4.0/src/aetherius/models/store/.gitkeep +0 -0
  88. aetherius-0.4.0/src/aetherius/network/__init__.py +35 -0
  89. aetherius-0.4.0/src/aetherius/network/geo.py +63 -0
  90. aetherius-0.4.0/src/aetherius/network/identity.py +104 -0
  91. aetherius-0.4.0/src/aetherius/network/pool.py +64 -0
  92. aetherius-0.4.0/src/aetherius/network/proxy.py +90 -0
  93. aetherius-0.4.0/src/aetherius/network/transport.py +33 -0
  94. aetherius-0.4.0/src/aetherius/notify/__init__.py +48 -0
  95. aetherius-0.4.0/src/aetherius/notify/base.py +18 -0
  96. aetherius-0.4.0/src/aetherius/notify/channels/__init__.py +19 -0
  97. aetherius-0.4.0/src/aetherius/notify/channels/_http.py +31 -0
  98. aetherius-0.4.0/src/aetherius/notify/channels/discord.py +52 -0
  99. aetherius-0.4.0/src/aetherius/notify/channels/ntfy.py +105 -0
  100. aetherius-0.4.0/src/aetherius/notify/channels/telegram.py +48 -0
  101. aetherius-0.4.0/src/aetherius/notify/channels/webhook.py +32 -0
  102. aetherius-0.4.0/src/aetherius/notify/message.py +26 -0
  103. aetherius-0.4.0/src/aetherius/notify/registry.py +98 -0
  104. aetherius-0.4.0/src/aetherius/notify/sink.py +51 -0
  105. aetherius-0.4.0/src/aetherius/plugins.py +88 -0
  106. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_transform.py +21 -1
  107. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/base.py +1 -1
  108. aetherius-0.4.0/src/aetherius/server/app.py +72 -0
  109. aetherius-0.4.0/src/aetherius/server/approvals.py +40 -0
  110. aetherius-0.4.0/src/aetherius/server/config.py +47 -0
  111. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/deps.py +14 -0
  112. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/jobs.py +109 -5
  113. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/routes/runs.py +24 -1
  114. aetherius-0.4.0/src/aetherius/server/routes/schedules.py +142 -0
  115. aetherius-0.4.0/src/aetherius/server/scheduler/__init__.py +32 -0
  116. aetherius-0.4.0/src/aetherius/server/scheduler/alerts.py +140 -0
  117. aetherius-0.4.0/src/aetherius/server/scheduler/manual.py +82 -0
  118. aetherius-0.4.0/src/aetherius/server/scheduler/misfire.py +71 -0
  119. aetherius-0.4.0/src/aetherius/server/scheduler/service.py +198 -0
  120. aetherius-0.4.0/src/aetherius/server/scheduler/triggers.py +115 -0
  121. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/schemas.py +55 -0
  122. aetherius-0.4.0/src/aetherius/stealth/fingerprint/hardening.py +193 -0
  123. aetherius-0.4.0/src/aetherius/stealth/fingerprint/headers.py +46 -0
  124. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/fingerprint/profile.py +48 -7
  125. aetherius-0.4.0/src/aetherius/stealth/fingerprint/webrtc.py +64 -0
  126. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/input.py +26 -0
  127. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/mouse.py +18 -3
  128. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/timing.py +15 -8
  129. aetherius-0.4.0/src/aetherius/store/__init__.py +30 -0
  130. aetherius-0.4.0/src/aetherius/store/approvals.py +48 -0
  131. aetherius-0.4.0/src/aetherius/store/engine.py +77 -0
  132. aetherius-0.4.0/src/aetherius/store/models.py +48 -0
  133. aetherius-0.4.0/src/aetherius/store/runs.py +91 -0
  134. aetherius-0.4.0/src/aetherius/store/schedules.py +118 -0
  135. aetherius-0.4.0/src/aetherius/store/schema.py +96 -0
  136. aetherius-0.4.0/src/aetherius/store/state.py +51 -0
  137. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/version.py +1 -1
  138. aetherius-0.2.0/CHANGELOG.md +0 -39
  139. aetherius-0.2.0/RELEASING.md +0 -49
  140. aetherius-0.2.0/contracts/blueprint.schema.json +0 -144
  141. aetherius-0.2.0/contracts/openapi.yaml +0 -152
  142. aetherius-0.2.0/src/aetherius/_contracts/blueprint.schema.json +0 -144
  143. aetherius-0.2.0/src/aetherius/acts/_shared.py +0 -61
  144. aetherius-0.2.0/src/aetherius/acts/oracle/driver.py +0 -1
  145. aetherius-0.2.0/src/aetherius/acts/oracle/locator.py +0 -1
  146. aetherius-0.2.0/src/aetherius/acts/oracle/model.py +0 -1
  147. aetherius-0.2.0/src/aetherius/acts/oracle/perception.py +0 -1
  148. aetherius-0.2.0/src/aetherius/acts/phantom/driver.py +0 -1
  149. aetherius-0.2.0/src/aetherius/acts/phantom/loop.py +0 -1
  150. aetherius-0.2.0/src/aetherius/acts/phantom/memory.py +0 -1
  151. aetherius-0.2.0/src/aetherius/acts/phantom/perception.py +0 -1
  152. aetherius-0.2.0/src/aetherius/acts/phantom/planner.py +0 -1
  153. aetherius-0.2.0/src/aetherius/acts/vector/client.py +0 -129
  154. aetherius-0.2.0/src/aetherius/console/screenshots.py +0 -173
  155. aetherius-0.2.0/src/aetherius/core/actions/flow.py +0 -76
  156. aetherius-0.2.0/src/aetherius/core/actions/registry.py +0 -70
  157. aetherius-0.2.0/src/aetherius/core/blueprint/validator.py +0 -45
  158. aetherius-0.2.0/src/aetherius/core/runtime/selector.py +0 -1
  159. aetherius-0.2.0/src/aetherius/models/registry.py +0 -1
  160. aetherius-0.2.0/src/aetherius/server/app.py +0 -37
  161. aetherius-0.2.0/src/aetherius/server/config.py +0 -25
  162. {aetherius-0.2.0 → aetherius-0.4.0}/.gitignore +0 -0
  163. {aetherius-0.2.0 → aetherius-0.4.0}/LICENSE +0 -0
  164. {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/UKIT.king.blueprint.json +0 -0
  165. {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/direct.linkaetherius.blueprint.json +0 -0
  166. {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/github.aetherius.blueprint.json +0 -0
  167. {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/github.github.blueprint.json +0 -0
  168. {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/github.zeb.blueprint.json +0 -0
  169. {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/licence.aetherius.blueprint.json +0 -0
  170. {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/record.aetherius.blueprint.json +0 -0
  171. {aetherius-0.2.0/src/aetherius/models/store → aetherius-0.4.0/deploy/blueprints}/.gitkeep +0 -0
  172. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/__init__.py +0 -0
  173. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/__main__.py +0 -0
  174. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/_contracts/__init__.py +0 -0
  175. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/__init__.py +0 -0
  176. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/__init__.py +0 -0
  177. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/actions.py +0 -0
  178. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/debug_overlay.py +0 -0
  179. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/human_actions.py +0 -0
  180. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/oracle/__init__.py +0 -0
  181. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/phantom/__init__.py +0 -0
  182. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/vector/__init__.py +0 -0
  183. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/vector/auth.py +0 -0
  184. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/builder/__init__.py +0 -0
  185. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/builder/templates.py +0 -0
  186. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/config/__init__.py +0 -0
  187. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/config/secrets.py +0 -0
  188. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/__init__.py +0 -0
  189. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/daemon_control.py +0 -0
  190. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/run_bridge.py +0 -0
  191. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/__init__.py +0 -0
  192. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/_pending.py +0 -0
  193. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/__init__.py +0 -0
  194. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/act_picker.py +0 -0
  195. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/io_editor.py +0 -0
  196. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/preview.py +0 -0
  197. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/screen.py +0 -0
  198. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/step_editor.py +0 -0
  199. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/catalog.py +0 -0
  200. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/library_scan.py +0 -0
  201. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/recorder.py +0 -0
  202. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/sessions.py +0 -0
  203. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/settings.py +0 -0
  204. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/theme.py +0 -0
  205. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/widgets/__init__.py +0 -0
  206. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/widgets/event_log.py +0 -0
  207. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/widgets/json_preview.py +0 -0
  208. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/__init__.py +0 -0
  209. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/__init__.py +0 -0
  210. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/data.py +0 -0
  211. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/interaction.py +0 -0
  212. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/navigation.py +0 -0
  213. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/spec.py +0 -0
  214. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/blueprint/__init__.py +0 -0
  215. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/blueprint/loader.py +0 -0
  216. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/blueprint/template.py +0 -0
  217. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/driver.py +0 -0
  218. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/events/__init__.py +0 -0
  219. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/events/bus.py +0 -0
  220. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/events/sinks.py +0 -0
  221. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/extraction/__init__.py +0 -0
  222. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/extraction/html_extractor.py +0 -0
  223. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/runtime/__init__.py +0 -0
  224. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/models/__init__.py +0 -0
  225. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/__init__.py +0 -0
  226. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_capture_js.py +0 -0
  227. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_gesture_js.py +0 -0
  228. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_names.py +0 -0
  229. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_overlay_js.py +0 -0
  230. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_playwright.py +0 -0
  231. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_selector_js.py +0 -0
  232. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_vector_js.py +0 -0
  233. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/blueprint_recorder.py +0 -0
  234. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/capture.py +0 -0
  235. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/continuum_backend.py +0 -0
  236. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/gesture_recorder.py +0 -0
  237. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/selector_synth.py +0 -0
  238. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/session.py +0 -0
  239. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/vector_backend.py +0 -0
  240. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/__init__.py +0 -0
  241. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/routes/__init__.py +0 -0
  242. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/routes/blueprints.py +0 -0
  243. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/routes/recorder.py +0 -0
  244. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/routes/stream.py +0 -0
  245. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/__init__.py +0 -0
  246. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/fingerprint/__init__.py +0 -0
  247. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/fingerprint/patch.py +0 -0
  248. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/gestures/__init__.py +0 -0
  249. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/gestures/data/human_library.json +0 -0
  250. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/gestures/library.py +0 -0
  251. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/gestures/seed.py +0 -0
  252. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/__init__.py +0 -0
  253. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/keyboard.py +0 -0
  254. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/scroll.py +0 -0
  255. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/ml/__init__.py +0 -0
  256. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/ml/fingerprint_model.py +0 -0
  257. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/ml/motion_model.py +0 -0
  258. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/policy.py +0 -0
  259. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/session/__init__.py +0 -0
  260. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/session/store.py +0 -0
  261. {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/session/warmup.py +0 -0
@@ -0,0 +1,11 @@
1
+ # Contexte de build Docker (deploy/Dockerfile, contexte = racine du depot).
2
+ # Allowlist : seul ce que le Dockerfile copie entre dans le contexte — le reste (dont .env et
3
+ # tout secret local) est exclu par construction.
4
+ *
5
+ !pyproject.toml
6
+ !README.md
7
+ !LICENSE
8
+ !src
9
+ !examples
10
+ **/__pycache__
11
+ **/*.pyc
@@ -18,3 +18,11 @@ AETHERIUS_SECRET_QUOTES_PASS=demo
18
18
  # Universite de Bordeaux ENT/CAS.
19
19
  AETHERIUS_SECRET_BORDEAUX_USER=your-username
20
20
  AETHERIUS_SECRET_BORDEAUX_PASS='your-password'
21
+
22
+ # Notification targets (see docs/notifications.md) — uncomment the channels you use.
23
+ # A channel address grants write (and for ntfy, read) access: keep them out of Blueprints.
24
+ # AETHERIUS_SECRET_WEBHOOK_URL=https://webhook.site/<your-uuid>
25
+ # AETHERIUS_SECRET_DISCORD_WEBHOOK=https://discord.com/api/webhooks/<id>/<token>
26
+ # AETHERIUS_SECRET_TELEGRAM_BOT_TOKEN=123456:bot-token
27
+ # AETHERIUS_SECRET_TELEGRAM_CHAT_ID=123456789
28
+ # AETHERIUS_SECRET_NTFY_TOPIC=my-private-topic
@@ -30,7 +30,7 @@ jobs:
30
30
  cache: pip
31
31
  cache-dependency-path: pyproject.toml
32
32
  # Base install stays light; heavy Act extras are not needed, tests marked
33
- # browser/vision/agent skip themselves when their dependency is absent.
33
+ # browser/cognition/vision skip themselves when their dependency is absent.
34
34
  - run: python -m pip install -e ".[dev]"
35
35
  - run: make lint
36
36
  - run: make typecheck
@@ -0,0 +1,92 @@
1
+ # Automated release. Publishing lives here (as infra), not in a doc to remember.
2
+ #
3
+ # To cut a release:
4
+ # 1. Bump the version in BOTH src/aetherius/version.py and sdks/typescript/package.json (same X.Y.Z).
5
+ # 2. Add a "## [X.Y.Z] - <date>" section at the top of CHANGELOG.md (becomes the release notes).
6
+ # 3. Commit, then: git tag vX.Y.Z && git push && git push --tags
7
+ #
8
+ # Pushing the tag triggers this workflow, which — after checking the tag matches the versions —
9
+ # publishes to PyPI and npm and creates the GitHub Release. Nothing else to run by hand.
10
+ #
11
+ # One-time setup (see the pinned note): a PyPI "trusted publisher" for this repo (no token), and an
12
+ # NPM_TOKEN repository secret (npm automation token).
13
+
14
+ name: Release
15
+
16
+ on:
17
+ push:
18
+ tags: ["v*"]
19
+
20
+ permissions:
21
+ contents: read
22
+
23
+ jobs:
24
+ check-version:
25
+ name: Tag matches package versions
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ - name: Verify tag == version.py == package.json
30
+ run: |
31
+ tag="${GITHUB_REF_NAME#v}"
32
+ py=$(python3 -c "import re,pathlib; print(re.search(r'__version__\s*=\s*\"([^\"]+)\"', pathlib.Path('src/aetherius/version.py').read_text()).group(1))")
33
+ ts=$(node -p "require('./sdks/typescript/package.json').version")
34
+ echo "tag=$tag python=$py npm=$ts"
35
+ test "$tag" = "$py" || { echo "::error::Tag $tag != Python version $py (bump src/aetherius/version.py)"; exit 1; }
36
+ test "$tag" = "$ts" || { echo "::error::Tag $tag != npm version $ts (bump sdks/typescript/package.json)"; exit 1; }
37
+
38
+ pypi:
39
+ name: Publish to PyPI
40
+ needs: check-version
41
+ runs-on: ubuntu-latest
42
+ permissions:
43
+ id-token: write # OIDC for PyPI trusted publishing (no token stored)
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+ - uses: actions/setup-python@v5
47
+ with:
48
+ python-version: "3.12"
49
+ - run: python3 -m pip install build
50
+ - run: python3 -m build
51
+ - uses: pypa/gh-action-pypi-publish@release/v1
52
+
53
+ npm:
54
+ name: Publish to npm
55
+ needs: check-version
56
+ runs-on: ubuntu-latest
57
+ steps:
58
+ - uses: actions/checkout@v4
59
+ - uses: actions/setup-node@v4
60
+ with:
61
+ node-version: "20"
62
+ registry-url: "https://registry.npmjs.org"
63
+ - run: npm install --no-audit --no-fund
64
+ working-directory: sdks/typescript
65
+ - run: npm run build
66
+ working-directory: sdks/typescript
67
+ - run: npm publish --access public
68
+ working-directory: sdks/typescript
69
+ env:
70
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
71
+
72
+ github-release:
73
+ name: GitHub Release
74
+ needs: [pypi, npm]
75
+ runs-on: ubuntu-latest
76
+ permissions:
77
+ contents: write
78
+ steps:
79
+ - uses: actions/checkout@v4
80
+ - name: Extract the CHANGELOG section for this version
81
+ run: |
82
+ version="${GITHUB_REF_NAME#v}"
83
+ awk -v ver="$version" '
84
+ $0 ~ "^## \\[" ver "\\]" { f=1; next }
85
+ /^## \[/ { if (f) exit }
86
+ f { print }
87
+ ' CHANGELOG.md > release-notes.md
88
+ [ -s release-notes.md ] || echo "Release ${GITHUB_REF_NAME}." > release-notes.md
89
+ - name: Create the release
90
+ env:
91
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
92
+ run: gh release create "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" --notes-file release-notes.md
@@ -0,0 +1,311 @@
1
+ # Changelog
2
+
3
+ Toutes les évolutions notables du projet sont consignées ici. Le format s'inspire de
4
+ [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/) et le versionnage suit
5
+ [SemVer](https://semver.org/lang/fr/). Tant que la version reste en `0.x`, l'API publique peut encore
6
+ évoluer entre deux versions mineures (durcissement de la Phase 1 en conditions réelles).
7
+
8
+ ## [Non publié]
9
+
10
+ ## [0.4.0] - 2026-07-20
11
+
12
+ Phase 2 — les Acts autonomes : **Oracle** (vision) et **Phantom** (agent) deviennent runnables, la
13
+ **composition multi-Act** et le **self-healing** lèvent la contrainte « un Act par Blueprint », et
14
+ l'**humain dans la boucle** (`confirm`) garde les actions sensibles. Phase 2 complète (A–E).
15
+
16
+ ### Ajouté
17
+ - **Jalon 2-E — Human-in-the-loop (`confirm`)** ([docs/human-in-the-loop.md](docs/human-in-the-loop.md)) :
18
+ une action **orthogonale aux Acts** (héritée par tous les drivers comme `notify`) qui **gare le
19
+ run** jusqu'à une décision humaine puis reprend. **Attente bloquante, pas suspend/resume** : le
20
+ worker parqué bloque sur un rendez-vous mémoire (`core/runtime/approvals.py`,
21
+ `ApprovalRegistry`/`Rendezvous`), le run — navigateur compris — reste vivant ; la boucle asyncio,
22
+ l'UI, ne gèlent jamais. Le **statut reste `running`** (deux nouveaux events
23
+ `input_requested`/`input_provided` au contrat `events.schema.json`, aucun nouveau statut). **Timeout
24
+ obligatoire** (`timeout_ms`, défaut 5 min) + `on_timeout` `approve`/`reject`/`fail:CODE` (défaut
25
+ **reject**, deny-by-default : le step sensible gardé par `when` se saute) ; un run non surveillé
26
+ (bibliothèque, sans surface) applique le timeout **immédiatement**. **Quatre surfaces, un seul
27
+ rendez-vous** : Console (`ConfirmModal` via `ConsoleApprovalSink` sur `input_requested`),
28
+ CLI/in-process (invite stdin `questionary`, sur un thread pour respecter le timeout, no-op sans
29
+ TTY), **API daemon** (`POST /v1/runs/{id}/decisions`, token opaque lié au `run_id`, 404 run inconnu
30
+ / 409 rien en attente ou token invalide), et **réponse de notification** (boutons ntfy
31
+ Approve/Reject POSTant la route, via `Notification.data["confirm"]` + `AETHERIUS_DAEMON_PUBLIC_URL`).
32
+ Piste d'audit `approvals` (migration store forward-only **v1→v2**) écrite par le daemon depuis le
33
+ flux d'événements (source unique, sans course). Nouveaux : `core/actions/human.py` (spec `confirm`),
34
+ `Capability.CONFIRM`, `RunContext.approvals` + `RunEngine.run(approvals=)`, `server/approvals.py`,
35
+ `console/approvals.py`, `cli/approvals.py`, `store/approvals.py`. Contrats : event enum + route
36
+ OpenAPI. Exemple zéro config : `examples/vector/confirm-before-post.blueprint.json`. **Phase 2
37
+ terminée (A–E).**
38
+ - **Jalon 2-D — Composition multi-Act & self-healing** ([docs/composition.md](docs/composition.md)) :
39
+ la contrainte « un Act par Blueprint » tombe. **`act` par step** — chaque step peut surcharger
40
+ l'act du run (hérité dans les branches `if`/`repeat`/`for_each`, validé contre l'act **effectif**) ;
41
+ les Acts navigateur (II/III/IV) partagent **un seul navigateur** : le moteur pré-scanne l'arbre
42
+ (surcharges + chaînes de fallback) et instancie une seule instance du plus haut Act atteignable,
43
+ par subsomption de la chaîne d'héritage des drivers (`core/runtime/drivers.py`, `DriverManager` à
44
+ démarrage paresseux, teardown groupé). **Self-healing** opt-in : sur échec d'un step navigateur,
45
+ la chaîne `options.fallback` (ou `fallback` par step, `[]` désactive) rejoue l'**intention** du
46
+ step (`describe`, jamais devinée) sur l'Act supérieur — escalade `oracle` = rejeu du même step en
47
+ ciblage vision (`fill` → `type`), escalade `phantom` = **micro-objectif** d'agent borné (6
48
+ actions, capable d'écarter un obstacle ; limité aux intentions exprimables par le planner).
49
+ L'escalade est ponctuelle (le step suivant repart sur son act) ; un step guéri est un succès
50
+ (`StepResult.healed_by`, durée cumulée), le récit passe par des événements `progress` de niveau
51
+ `warning` (aucun nouveau type d'événement) ; chaîne épuisée = l'erreur d'origine propagée
52
+ inchangée. Schéma : champs `step.act`/`step.describe`/`step.fallback` + `options.fallback`
53
+ (additifs). L'exécuteur est réorganisé (`core/runtime/steps.py` + `flow.py` extrait +
54
+ `healing.py`), zéro régression mono-Act. Exemples zéro config : `examples/composition/`
55
+ (run mixte Continuum→Oracle et sélecteur cassé rattrapé par vision, vérifiés en réel).
56
+ - **Jalon 2-C — Act IV Phantom** ([docs/acts/phantom.md](docs/acts/phantom.md)) : `act: "phantom"`
57
+ est **runnable**. Un Blueprint **sans `steps`** déclare un `goal` et des `constraints` ; le moteur
58
+ route vers `driver.run_goal` (seam goal-only dans `RunEngine.run`) qui lance la boucle
59
+ **percevoir → raisonner → agir**. Le **planner** (Claude par défaut, rôle `Planner` du substrat de
60
+ cognition, `acts/_cognition/planning.py`) choisit chaque action par **tool use forcé**
61
+ (`tool_choice: any`) sur un vocabulaire restreint — ciblage **vision uniquement**, plus les outils
62
+ terminaux `finish` (objectif atteint → sortie) et `abort` (impossible / contrainte violée → échec
63
+ propre). L'action est jouée par le ciblage vision d'Oracle à travers la discrétion.
64
+ `PhantomDriver` **étend** `OracleDriver` (un seul navigateur, une seule discrétion, provider et
65
+ dispatch hérités) — un Blueprint `phantom` avec `steps` tourne déjà en mode scripté (socle 2-D).
66
+ Garde-fou : budget `options.agent.max_steps` (défaut 40, nouveau modèle `AgentOptions` + schéma) ;
67
+ un échec d'action est une **observation** mémorisée (résilience), jamais fatal — seuls `abort`, une
68
+ réponse de planner inutilisable ou le budget épuisé arrêtent le run. Observabilité par réutilisation
69
+ de `progress`/`step_started`/`step_finished` (`step_id` `agent[N]`, un `StepResult` par action),
70
+ **aucun nouvel `EventType`**. Sorties : `finish` exposé sous `{{ steps.agent.* }}`, ou l'issue de
71
+ l'agent (`{result, steps_taken}`) renvoyée telle quelle sans `outputs` déclarés. Garde validator
72
+ « goal-only ⇒ act phantom ». Exemple zéro config :
73
+ `examples/phantom/quotes-find-author.blueprint.json`.
74
+ - **Jalon 2-B — Act III Oracle** ([docs/acts/oracle.md](docs/acts/oracle.md)) : `act: "oracle"` est
75
+ **runnable**. `OracleDriver` **étend** le driver Continuum (un seul navigateur, une seule
76
+ discrétion, steps à sélecteur inchangés) et route les cibles vision : `click`/`type`/`upload`/
77
+ `hover`/`wait_for` acceptent `target: {vision: "description"}` — capture en pixels CSS →
78
+ grounding (un appel par cible, seuil de confiance 0.5 ajustable par `min_confidence`) → action
79
+ par coordonnées off-center (bande 30–70 %) via la façade stealth (`HumanInput` gagne
80
+ `hover_at`). `wait_for` par vision sonde l'écran (un grounding par sonde, `on_timeout:
81
+ "fail:CODE"` honoré) ; `upload` alimente le file chooser ouvert par le clic. Nouvelle action
82
+ **`read`** (extraction sémantique, capability + spec `core/actions/vision.py`) : avec `schema`
83
+ les champs deviennent les sorties du step, sans schéma la valeur arrive sous `data`. Contrat
84
+ documenté sans changement structurel (`target`, `vision.provider`) ; le Studio accepte les steps
85
+ ciblés par vision. Exemple zéro config : `examples/oracle/quotes-vision-demo.blueprint.json`.
86
+ - **Action `wait` : plage aléatoire** — sans `ms`, `min_ms`/`max_ms` tirent une durée uniforme
87
+ dans l'intervalle (act-agnostique) ; le gabarit fondateur `tiktok-upload` devient exact.
88
+ - **Oracle : recherche par défilement (scan)** — une cible vision hors du viewport est trouvée en
89
+ défilant la page viewport par viewport (scroll humanisé sous discrétion, remontée en haut pour
90
+ un départ en milieu de page), à coût borné : 8 coups d'œil maximum, un appel de grounding
91
+ chacun ; `scan: false` épingle le step au viewport courant. Exemple zéro config :
92
+ `examples/oracle/books-scan-below-fold.blueprint.json`.
93
+ - **Contribution : sondes réalistes** — la « Définition de terminé » exige désormais, en plus du
94
+ flux nominal vérifié à la main, une ou deux sondes réalistes « dures » (dont un cas conçu pour
95
+ échouer), consignées dans la doc de la capacité ([docs/testing.md](docs/testing.md)).
96
+ - **Jalon 2-A — Substrat de perception & cognition** ([docs/cognition.md](docs/cognition.md)) : la
97
+ fondation partagée des Acts cognitifs. `ClaudeProvider` implémente le **grounding** (`locate` :
98
+ description → `Box` + confiance) et l'**extraction sémantique** (`read`, schéma optionnel) par
99
+ tool use forcé — réponse structurée, un appel par cible, modèle par défaut `claude-opus-4-8`
100
+ écrasé par `vision.model`, clé via `ANTHROPIC_API_KEY` (`.env` supporté) ; `resolve_provider`
101
+ résout `vision.provider` (`claude` défaut / `local`) ; `LocalGrounder` reste l'option locale
102
+ derrière la même interface (rôles non portés en `CognitionError` typée). Perception de page en
103
+ **pixels CSS** (`capture` : screenshot `scale="css"` + DOM optionnel, réduction 2576 px avec
104
+ remise à l'échelle des boîtes), cible unifiée `Target.from_step` (sélecteur ou
105
+ `target: {vision}`, ambiguïté rejetée), et **clic par coordonnées à travers le stealth**
106
+ (`HumanInput.click_at`/`type_at`, gestes rejoués + timing humain, intégration Chromium réelle).
107
+ Nouvelle erreur `CognitionError`. `import aetherius` reste léger (SDK importés paresseusement).
108
+ - **Phase 2 — Autonomie & Contrôle : cadrage + squelette.** Directives et **spécifications par jalon**
109
+ ([docs/phase-2/](docs/phase-2/README.md), jalons 2-A à 2-E), plus les **stubs d'interface** du
110
+ substrat de cognition ([`acts/_cognition/`](src/aetherius/acts/_cognition/),
111
+ [`acts/_perception.py`](src/aetherius/acts/_perception.py),
112
+ [`core/runtime/selector.py`](src/aetherius/core/runtime/selector.py),
113
+ [`models/registry.py`](src/aetherius/models/registry.py)) et des Acts cognitifs (Oracle/Phantom).
114
+ Les Acts II/III/IV deviennent trois stratégies au-dessus d'un même substrat navigateur + stealth +
115
+ perception + cognition. La phase couvre aussi la composition multi-Act par step, le self-healing
116
+ (fallback d'Act) et le human-in-the-loop (action `confirm`). Aucun comportement runtime modifié
117
+ (`make check` vert, `import aetherius` reste léger).
118
+
119
+ ### Modifié
120
+ - **Extras refondus (Jalon 2-A)** : nouvel extra `[cognition]` (`anthropic`, `pillow`) — le défaut
121
+ partagé Oracle+Phantom, qui **absorbe l'ancien `[agent]`** (supprimé) ; `[vision]` repositionné
122
+ en **grounder local optionnel** ; `[all]` et les markers pytest alignés (`cognition` remplace
123
+ `agent`).
124
+ - **Oracle (Act III) redéfini** : le ciblage se fait par **grounding VLM** (Claude par défaut, un
125
+ détecteur local restant une option branchable derrière la même interface) plutôt que par un modèle
126
+ ONNX entraîné par tâche ; l'entraînement local devient une piste **optionnelle/avancée**. Fiches
127
+ [docs/acts/oracle.md](docs/acts/oracle.md) et [docs/acts/phantom.md](docs/acts/phantom.md)
128
+ réécrites (définition cible), [training/README.md](training/README.md) requalifié, section
129
+ « Phase 2 » et descriptions Oracle du README harmonisées.
130
+
131
+ ## [0.3.0] - 2026-07-17
132
+
133
+ Phase 1.5 : le socle devient **opérationnel** (planification, alertes, réactivité, furtivité réseau
134
+ et empreinte), et durcissement du socle Phase 1 avant d'entamer la Phase 2 (audit croisé de la doc).
135
+
136
+ ### Ajouté
137
+ - **Durcissement de l'empreinte (Jalon 1.5-H)** — les signaux à forte valeur que le profil laissait à
138
+ découvert sont fermés **de façon cohérente avec le profil actif** (un signal masqué mais incohérent
139
+ est un tell pire que l'absence de masque). Côté navigateur,
140
+ [`stealth/fingerprint/hardening.py`](src/aetherius/stealth/fingerprint/hardening.py) injecte, après
141
+ le script de cohérence du profil, un init script masquant : **Canvas** (`toDataURL`/`toBlob`/
142
+ `getImageData`) et **AudioContext** avec un bruit **déterministe par profil** (seed calculé côté
143
+ Python, hachage JS — stable entre deux lectures d'un même run, différent d'un profil à l'autre, lu
144
+ depuis une copie offscreen pour ne pas s'accumuler), **polices** (`measureText`), **client hints**
145
+ (`navigator.userAgentData`), **écran** (`screen.*` + `devicePixelRatio`) et **WebGL2**
146
+ (`getParameter`). Côté **Vector** (Act I, sans discrétion jusqu'ici),
147
+ [`stealth/fingerprint/headers.py`](src/aetherius/stealth/fingerprint/headers.py) donne une identité
148
+ d'en-têtes par défaut (`User-Agent`, `Sec-CH-UA`/`-Mobile`/`-Platform`, `Accept`, `Accept-Language`
149
+ aligné sur la géo) supprimant la signature « client HTTP nu » — **opt-in** (injectée seulement quand
150
+ `options.stealth` nomme un profil, un run sans stealth reste inchangé), les en-têtes explicites du
151
+ Blueprint gardant la priorité (fusion insensible à la casse) ; l'impersonation TLS `curl_cffi` garde
152
+ ses propres en-têtes. Le `FingerprintProfile` gagne les champs `screen`/`device_pixel_ratio`/
153
+ `ua_platform`/`ua_full_version` et dérive `Sec-CH-UA` de sa propre version d'UA : la limite « UA-CH
154
+ drift » est **levée**. Exemples exécutables zéro config
155
+ `examples/continuum/fingerprint-hardening.blueprint.json` et
156
+ `examples/vector/http-headers-identity.blueprint.json`. Voir [docs/stealth.md](docs/stealth.md).
157
+ - **Identité réseau (Jalon 1.5-G)** — option `options.proxy` de premier niveau qui rend le bot
158
+ invisible **au niveau réseau**, pour les **deux** moteurs (la couche stealth ne touche que le
159
+ navigateur). Le module `aetherius.network` est activé : `parse_proxy`/`ProxySpec` (rendu httpx et
160
+ Playwright, credentials masqués dans les logs), `ProxyPool` (rotation `per_run`/`round_robin`/
161
+ `random`/`sticky` — l'IP change d'un run à l'autre, ou reste stable par clé), `geo_hint` (cohérence
162
+ timezone/locale/langues avec le pays de l'IP), `resolve_identity` (option du Blueprint > défaut
163
+ d'environnement `AETHERIUS_PROXY_*` > aucun). Vector route par `httpx.Client(proxy=...)`
164
+ (HTTP/HTTPS, plus SOCKS5 via l'extra `[network]` avec garde typée si absent) et peut imiter la
165
+ poignée de main TLS d'un vrai navigateur (JA3/JA4) via un transport `curl_cffi` isolé
166
+ (`acts/vector/impersonate.py`, extra `[network]`, `DependencyError` claire sinon). Continuum lie le
167
+ proxy au lancement du contexte, force l'anti-fuite WebRTC (flag Chromium `disable_non_proxied_udp`
168
+ + init-script filtrant les candidats ICE locaux — indispensable, sinon le proxy laisse fuir l'IP
169
+ réelle) et dérive le profil d'empreinte pour coller à la géo (timezone/locale/`navigator.languages`
170
+ alignés sur l'IP, vérifiés sur Chromium réel). Identifiants **jamais** stockés dans le Blueprint
171
+ (`{{ secrets.x }}`). Le Studio préserve `options.proxy` verbatim (aucune régression à l'édition).
172
+ Exemple exécutable `examples/vector/ip-echo-proxy.blueprint.json` (nécessite un proxy via `.env`).
173
+ Voir [docs/network.md](docs/network.md).
174
+ - **Déploiement always-on (Jalon 1.5-F)** — recette 24/7 vérifiée de bout en bout pour héberger le
175
+ daemon (et donc le scheduler) sur un hôte toujours allumé : VPS, Raspberry Pi, NAS. Les brouillons
176
+ `deploy/` sont finalisés : image Docker multi-stage (wheel construit à part, image finale sans
177
+ sources ni outils de build), utilisateur non-root, `HEALTHCHECK` sur `/health`, exemples embarqués
178
+ comme sondes zéro config, variante Act II exécutable (`--build-arg BROWSER=1` : extra `[browser]` +
179
+ Chromium sous `PLAYWRIGHT_BROWSERS_PATH` partagé) ; `docker-compose.yml` (volume persistant unique
180
+ `/data`, port publié sur la loopback de l'hôte, `env_file` + `.env.example`, montage lecture seule
181
+ `blueprints/` — les schedules résolvent des chemins côté conteneur) ; service systemd utilisateur
182
+ (`enable-linger`, `EnvironmentFile` optionnel, redémarrage automatique) ; `.dockerignore` racine en
183
+ allowlist (l'ancien `deploy/.dockerignore` était inopérant, le contexte de build étant la racine).
184
+ Durcissement afférent : un `AETHERIUS_DAEMON_TOKEN` vide vaut absence de token — l'interpolation
185
+ compose (`${VAR:-}`) n'active plus l'auth par accident (`server/config.py`, test miroir). Doc
186
+ complète (recettes, persistance, sauvegarde SQLite, sécurité : loopback par défaut, exposer =
187
+ token + reverse proxy TLS) : voir [docs/deployment.md](docs/deployment.md).
188
+ - **Actions custom / plugins (Jalon 1.5-E)** — points d'extension activés : un paquet tiers ajoute
189
+ des actions de Blueprint et des canaux de notification sans forker le cœur. Découverte par
190
+ entry-points (`aetherius.actions`, `aetherius.notify_channels`) dans le nouveau module
191
+ `aetherius.plugins` (`load_plugins()` idempotent, appelé au démarrage par la CLI, le lifespan du
192
+ daemon et `RunEngine.run` ; surface d'import unique pour les auteurs de plugins). Le registre
193
+ d'actions dormant est activé : une action plugin embarque son `ActionSpec` (visible du Studio et
194
+ des validators, invariant « registre = source, catalogue = projection » préservé), est
195
+ **act-agnostique** (hors capability-table, validée dynamiquement) et dispatchée par les drivers
196
+ en repli après leur `match` built-in. Gardes de collision sur les deux registres (les built-ins
197
+ restent prioritaires, un conflit est un échec de chargement explicite) et pannes isolées (un
198
+ plugin qui lève à l'import est loggé et sauté, jamais fatal). Plugin d'exemple exécutable
199
+ (`examples/plugins/` : action `demo.slugify` + canal `logfile` + Blueprint zéro réseau), chargé
200
+ par de vrais entry-points dans les tests. Voir [docs/plugins.md](docs/plugins.md).
201
+ - **Écran Console « Schedules »** — l'UI du scheduler (Jalon 1.5-D) dans la Console : liste des
202
+ schedules (trigger, politique d'alerte, statut, prochains/derniers tirs en heure locale, sonde
203
+ d'honnêteté « daemon actif ou non »), pause/reprise (`p`, la reprise recale la cadence),
204
+ suppression confirmée (`d`, nouveau `ConfirmModal` réutilisable), **détail** avec l'historique
205
+ des runs du schedule et un **tir manuel** aux événements streamés en direct (même brique
206
+ in-process que `aetherius schedule run`, extraite dans `server/scheduler/manual.py::fire_schedule`
207
+ et partagée CLI/Console), et **formulaire guidé** de création/édition (inputs du Blueprint en
208
+ champs, secrets jamais saisis — état `.env` affiché, trigger/misfire/notify validés à la
209
+ sauvegarde). Raccourci `s` dans Library pour planifier le Blueprint surligné. Captures SVG
210
+ déterministes (fuseau épinglé, store de démo figé) et neutralisation renforcée des chemins
211
+ (le home ne fuit plus, même tronqué dans une colonne). Voir [docs/console.md](docs/console.md).
212
+ - **Scheduler intégré au daemon (Jalon 1.5-D)** — rejeu persistant d'un Blueprint à heure fixe
213
+ (cron à 5 champs, évalué dans le fuseau local, DST gérés via `tzlocal`), par intervalle ou en tir
214
+ unique (`at`). Boucle de tick dans le lifespan du daemon (30 s, `AETHERIUS_DAEMON_SCHEDULER_TICK_SECONDS`) ;
215
+ un run planifié passe par `RunManager.submit` — mêmes événements, même historique, plus le lien
216
+ `schedule_id`. Rattrapage des tirs manqués par politique `misfire` (`skip`/`run_once`/`run_all`,
217
+ portée par le trigger, résolue par le tick au-delà d'une fenêtre de grâce) et politique d'alerte
218
+ par schedule (`failure`/`success`/`always`/`change` — la dédup au changement d'état s'appuie sur
219
+ `state.compare_and_set`, cibles `{{ secrets.x }}` rendues au tir, jamais persistées). CLI
220
+ `aetherius schedule add|list|rm|pause|resume|run` (écrit directement dans le store : marche daemon
221
+ éteint ; `cli.py` devient le package `cli/`) et API `/v1/schedules` (CRUD + tir immédiat,
222
+ contrat OpenAPI à jour). Exemple zéro config : `examples/vector/quotes-watch.blueprint.json`.
223
+ Dépendances : `croniter` (déjà déclarée) + `tzlocal`. Voir [docs/scheduler.md](docs/scheduler.md).
224
+ - **Notifications natives (Jalon 1.5-C)** — couche d'alerte sans dépendance nouvelle (`notify/`) :
225
+ quatre canaux built-in en un POST `httpx` chacun (webhook générique, Discord, Telegram, ntfy pour
226
+ la push téléphone, en mode JSON publishing), action `notify` Act-agnostique (handler partagé, se
227
+ combine à `when`), `NotifySink` de fin de run (`failure`/`success`/`always`) et registre de canaux
228
+ prêt pour les plugins (Jalon E). Échec d'envoi contenu : jamais fatal au run, `delivered` exposé
229
+ dans les outputs du step. Exemple zéro config :
230
+ `examples/vector/books-restock-notify.blueprint.json`. Voir
231
+ [docs/notifications.md](docs/notifications.md).
232
+ - **Réactivité et flux conditionnel (Jalon 1.5-B)** — garde d'étape `when` universelle (évaluée
233
+ avant dispatch, même règle de véracité que `assert` ; step sauté = statut `skipped` + événement
234
+ `step_skipped`, contrats et SDK TypeScript à jour) et actions `if`/`repeat`/`for_each` exécutées
235
+ par un **exécuteur récursif** dans le moteur (`core/runtime/steps.py`), en amont des drivers —
236
+ tous les Acts en héritent sans câblage, `repeat` rejoint les capacités Vector. Variable de boucle
237
+ `as` (défaut `item`) exposée au template le temps de l'itération, validation sémantique récursive
238
+ des branches, identifiants de steps imbriqués traçables (`loop[2].fetch`), schéma des steps
239
+ formalisé (`when`, `then`/`else`/`steps`). Deux exemples zéro config dans `examples/vector/`.
240
+ Voir [docs/blueprint-schema.md](docs/blueprint-schema.md).
241
+ - **Persistance durable (Jalon 1.5-A)** — socle de stockage SQLite (stdlib `sqlite3`, mode WAL, zéro
242
+ dépendance) sous `~/.aetherius/aetherius.db`, avec migrations versionnées (`PRAGMA user_version`) et
243
+ trois dépôts typés : schedules, historique des runs, état clé/valeur inter-run (`compare_and_set`
244
+ pour la déduplication d'alertes). Le daemon persiste désormais le résultat de ses runs dans le store
245
+ (migration douce, sans régression). Voir [docs/store.md](docs/store.md).
246
+ - **Cadrage Phase 1.5** — squelette (stubs, interfaces, contrats) et spécifications par jalon pour
247
+ rendre le socle **récurrent, réactif et furtif** : persistance SQLite (`store/`), notifications
248
+ natives (`notify/`), scheduler du daemon, flux conditionnel (`when`, `if`/`repeat`/`for_each`),
249
+ plugins, déploiement 24/7, **identité réseau** (`network/` : proxy, rotation d'IP, anti-fuite
250
+ WebRTC, cohérence géo, impersonation TLS) et **durcissement de l'empreinte**
251
+ (`stealth/fingerprint/` : canvas/audio/UA-CH/écran/WebGL2 + identité d'en-têtes pour Vector).
252
+ Aucune capacité n'est encore activée (jalons en attente : l'action `notify` est déclarée mais
253
+ marquée `PENDING`, les modules lèvent une erreur « jalon en attente ») ; `make check` reste vert.
254
+ Nouvel extra optionnel `[network]` (SOCKS5 + `curl_cffi`). Voir [docs/phase-1.5/](docs/phase-1.5/README.md).
255
+ - **Suivi des nouveaux onglets (Act II — Continuum)** : un clic ouvrant un onglet (`target="_blank"`,
256
+ `window.open`) rend la nouvelle page active pour les steps suivants, avec retombée sur une page
257
+ survivante si l'onglet actif se referme. Auparavant les steps restaient bloqués sur l'onglet initial.
258
+ - **Recorder « Make input »** : le `type`/`format` de l'input produit est inféré du type HTML du champ
259
+ (`number`, `date`+`format`, `email`/`url`, …) au lieu d'un `string` générique.
260
+
261
+ ### Sécurité
262
+ - **Évaluateur `where` (Act I — Vector)** : rejet explicite des attributs magiques (`__class__`,
263
+ `__globals__`, tout nom en `__`) dans l'AST-walk. L'allowlist de nœuds bloquait déjà l'exécution de
264
+ code, mais la traversée d'attributs dunder combinée à une comparaison restait un oracle booléen sur
265
+ le graphe d'objets Python — la garde ferme cette évasion de sandbox sans dépendre de l'absence
266
+ d'appels/indexation.
267
+
268
+ ### Corrigé
269
+ - **`precise_sleep` (stealth/humanizer)** : le busy-wait pur sous 20 ms saturait un cœur CPU à 100 %
270
+ (chaque point de geste souris), risque de privation de ressources sur le daemon en multi-run.
271
+ Désormais `time.sleep` cède le CPU pour le gros du délai et le busy-wait ne couvre que la queue
272
+ (~1,5 ms) — précision de timing inchangée, CPU au repos (~9 %).
273
+ - **Debug (Act II — Continuum)** : quand les entrées sont humanisées, `slow_mo` est à 0 et les actions
274
+ brutes (`select`, `upload`, `navigate`, …) défilaient instantanément, illisibles en debug. Elles
275
+ reçoivent maintenant un délai manuel équivalent.
276
+
277
+ ## [0.2.0] - 2026-07-10
278
+
279
+ Première release publique. Elle clôt la **Phase 1** : le socle d'Aetherius, utilisable comme
280
+ **bibliothèque** (in-process Python) et comme **service** (daemon local + SDK), avec sa Console.
281
+
282
+ ### Ajouté
283
+ - **Daemon local (FastAPI)** — passerelle HTTP + WebSocket exposant le moteur à tout langage
284
+ (`aetherius serve`, bind loopback, token bearer optionnel) : `POST /v1/runs`, `GET /v1/runs/{id}`,
285
+ `WS /v1/runs/{id}/events` (rejeu bufferisé + flux live jusqu'à `done`), `POST /v1/blueprints/validate`,
286
+ `GET /v1/schema`, `GET /health`. L'enregistrement reste host-local (`POST /v1/recorder/sessions` → 501).
287
+ Voir [docs/daemon.md](docs/daemon.md).
288
+ - **SDK TypeScript** `@aetherius/client` (Node 20+) — spawn du daemon (ou `baseUrl`),
289
+ `client.run(blueprint, { inputs, secrets, onEvent })`, streaming d'événements typé.
290
+ - **Console : écran Settings** — démarrer/arrêter le daemon et voir son statut, sans quitter le terminal.
291
+ - **Act I — Vector** : client HTTP/API (requêtes, retries/backoff, 5 stratégies d'auth, extraction
292
+ JSONPath et CSS/XPath, moteur de templates Jinja2).
293
+ - **Act II — Continuum** : automatisation d'un vrai navigateur (Playwright, extra `[browser]`) —
294
+ navigation, interactions, extraction DOM, `wait_for` avec échec nommé, sessions persistantes, debug.
295
+ - **Système de discrétion (stealth)** : couche transverse (`options.stealth`) — souris humaine par
296
+ rejeu géométrique de gestes, clavier/scroll/timing humains, fingerprint, warmup de profil.
297
+ - **Recorder** : création de Blueprint par démonstration (Continuum et Vector) + gesture recorder.
298
+ - **Builder headless + Blueprint Studio** : construction guidée de Blueprints sans JSON, avec aperçu
299
+ validé en direct, réutilisable par la Console, le daemon et les SDKs.
300
+ - **Console (Textual)** : Library, Runs, Catalog, Recorder, Blueprint Studio, Settings.
301
+ - **Contrats** langage-agnostiques (`contracts/`) : schéma Blueprint, OpenAPI du daemon, schéma
302
+ d'événements — source de vérité, gardés par des tests.
303
+
304
+ ### Notes
305
+ - SemVer `0.x` : l'API peut évoluer pendant le durcissement de la Phase 1.
306
+ - La **Phase 2** ajoutera Act III (Oracle, vision) et Act IV (Phantom, agent autonome).
307
+
308
+ [Non publié]: https://github.com/kln-mltre/Aetherius/compare/v0.4.0...HEAD
309
+ [0.4.0]: https://github.com/kln-mltre/Aetherius/releases/tag/v0.4.0
310
+ [0.3.0]: https://github.com/kln-mltre/Aetherius/releases/tag/v0.3.0
311
+ [0.2.0]: https://github.com/kln-mltre/Aetherius/releases/tag/v0.2.0
@@ -43,7 +43,11 @@ est vrai. On ne saute pas une étape en attendant qu'on la réclame :
43
43
  3. **Doc à jour** dans le même changement — voir [Documentation](#documentation).
44
44
  4. **`make check` vert.**
45
45
  5. **Flux vérifié à la main** au moins une fois : le vrai `run`, pas seulement les tests (chaque
46
- doc d'Act a une section « Tester … » pour ça).
46
+ doc d'Act a une section « Tester … » pour ça). En plus du chemin nominal, jouer **une ou deux
47
+ sondes réalistes « dures »** — un scénario réel plus exigeant que l'exemple zéro config, dont si
48
+ possible un cas conçu pour faire échouer la capacité. Un échec **propre et explicable** est un
49
+ résultat valide ; un comportement surprenant est un correctif ou une limite à documenter avant
50
+ de clore. Voir [docs/testing.md](docs/testing.md#sondes-réalistes).
47
51
  6. **Prise en main UI** pour une capacité **liée à l'UI et non triviale** (nouvel écran ou
48
52
  interaction non évidente de la Console) : un walkthrough orienté UI dans la doc **et** des captures
49
53
  SVG générées (`make screenshots`) — voir [Documentation](#documentation). Exception : une
@@ -31,7 +31,7 @@ test: ## Run the full Python test suite with coverage
31
31
  pytest --cov=aetherius --cov-report=term-missing
32
32
 
33
33
  test-fast: ## Run only the fast tests (skip heavy extras and slow tests)
34
- pytest -m "not browser and not vision and not agent and not slow"
34
+ pytest -m "not browser and not vision and not cognition and not slow"
35
35
 
36
36
  test-browser: ## Run the browser tests (Act II) against a real Chromium; needs the [browser] extra
37
37
  pytest -m browser