nova-arsenal 2.0.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 (279) hide show
  1. nova_arsenal-2.0.0/.devcontainer/devcontainer.json +5 -0
  2. nova_arsenal-2.0.0/.github/CODEOWNERS +21 -0
  3. nova_arsenal-2.0.0/.github/dependabot.yml +45 -0
  4. nova_arsenal-2.0.0/.github/workflows/ci.yml +118 -0
  5. nova_arsenal-2.0.0/.github/workflows/release.yml +180 -0
  6. nova_arsenal-2.0.0/.github/workflows/security.yml +54 -0
  7. nova_arsenal-2.0.0/.gitignore +114 -0
  8. nova_arsenal-2.0.0/.pre-commit-config.yaml +28 -0
  9. nova_arsenal-2.0.0/CHANGELOG.md +110 -0
  10. nova_arsenal-2.0.0/CONTRIBUTING.md +178 -0
  11. nova_arsenal-2.0.0/LICENSE +190 -0
  12. nova_arsenal-2.0.0/Makefile +69 -0
  13. nova_arsenal-2.0.0/PKG-INFO +759 -0
  14. nova_arsenal-2.0.0/README.md +708 -0
  15. nova_arsenal-2.0.0/SECURITY.md +90 -0
  16. nova_arsenal-2.0.0/alembic/README +1 -0
  17. nova_arsenal-2.0.0/alembic/env.py +47 -0
  18. nova_arsenal-2.0.0/alembic/script.py.mako +28 -0
  19. nova_arsenal-2.0.0/alembic/versions/82cbcd264eab_initial_models.py +216 -0
  20. nova_arsenal-2.0.0/alembic.ini +149 -0
  21. nova_arsenal-2.0.0/clients/vscode/.vscodeignore +7 -0
  22. nova_arsenal-2.0.0/clients/vscode/out/api.js +125 -0
  23. nova_arsenal-2.0.0/clients/vscode/out/api.js.map +1 -0
  24. nova_arsenal-2.0.0/clients/vscode/out/extension.js +246 -0
  25. nova_arsenal-2.0.0/clients/vscode/out/extension.js.map +1 -0
  26. nova_arsenal-2.0.0/clients/vscode/out/panel.js +217 -0
  27. nova_arsenal-2.0.0/clients/vscode/out/panel.js.map +1 -0
  28. nova_arsenal-2.0.0/clients/vscode/package-lock.json +59 -0
  29. nova_arsenal-2.0.0/clients/vscode/package.json +126 -0
  30. nova_arsenal-2.0.0/clients/vscode/src/api.ts +89 -0
  31. nova_arsenal-2.0.0/clients/vscode/src/extension.ts +259 -0
  32. nova_arsenal-2.0.0/clients/vscode/src/panel.ts +197 -0
  33. nova_arsenal-2.0.0/clients/vscode/tsconfig.json +18 -0
  34. nova_arsenal-2.0.0/clients/web/app/agents/page.tsx +5 -0
  35. nova_arsenal-2.0.0/clients/web/app/api/auth/login/route.ts +54 -0
  36. nova_arsenal-2.0.0/clients/web/app/api/auth/logout/route.ts +13 -0
  37. nova_arsenal-2.0.0/clients/web/app/api/health/route.ts +9 -0
  38. nova_arsenal-2.0.0/clients/web/app/api/nova/[...path]/route.ts +157 -0
  39. nova_arsenal-2.0.0/clients/web/app/chat/page.tsx +445 -0
  40. nova_arsenal-2.0.0/clients/web/app/findings/page.tsx +5 -0
  41. nova_arsenal-2.0.0/clients/web/app/globals.css +145 -0
  42. nova_arsenal-2.0.0/clients/web/app/layout.tsx +26 -0
  43. nova_arsenal-2.0.0/clients/web/app/login/page.tsx +163 -0
  44. nova_arsenal-2.0.0/clients/web/app/page.tsx +198 -0
  45. nova_arsenal-2.0.0/clients/web/app/scope/page.tsx +5 -0
  46. nova_arsenal-2.0.0/clients/web/app/sessions/[sessionId]/page.tsx +334 -0
  47. nova_arsenal-2.0.0/clients/web/app/sessions/page.tsx +133 -0
  48. nova_arsenal-2.0.0/clients/web/app/settings/page.tsx +408 -0
  49. nova_arsenal-2.0.0/clients/web/components/app-shell.tsx +114 -0
  50. nova_arsenal-2.0.0/clients/web/middleware.ts +18 -0
  51. nova_arsenal-2.0.0/clients/web/next.config.js +35 -0
  52. nova_arsenal-2.0.0/clients/web/package.json +34 -0
  53. nova_arsenal-2.0.0/clients/web/postcss.config.js +6 -0
  54. nova_arsenal-2.0.0/clients/web/tailwind.config.js +28 -0
  55. nova_arsenal-2.0.0/clients/web/tsconfig.json +27 -0
  56. nova_arsenal-2.0.0/config/.env.example +88 -0
  57. nova_arsenal-2.0.0/config/litellm.yaml +61 -0
  58. nova_arsenal-2.0.0/config/settings.example.yaml +132 -0
  59. nova_arsenal-2.0.0/containers/Dockerfile.agent +28 -0
  60. nova_arsenal-2.0.0/containers/Dockerfile.kali +37 -0
  61. nova_arsenal-2.0.0/containers/Dockerfile.web +33 -0
  62. nova_arsenal-2.0.0/docker-compose.prod.yml +151 -0
  63. nova_arsenal-2.0.0/docker-compose.yml +127 -0
  64. nova_arsenal-2.0.0/docs/FEATURES.md +1053 -0
  65. nova_arsenal-2.0.0/docs/RELEASING.md +44 -0
  66. nova_arsenal-2.0.0/docs/adr/0001-record-architecture-decisions.md +37 -0
  67. nova_arsenal-2.0.0/docs/adr/0002-multi-llm-strategy.md +62 -0
  68. nova_arsenal-2.0.0/docs/adr/0003-database-choice.md +62 -0
  69. nova_arsenal-2.0.0/docs/adr/0004-authentication-approach.md +65 -0
  70. nova_arsenal-2.0.0/docs/adr/0005-web-ui-framework.md +60 -0
  71. nova_arsenal-2.0.0/docs/adr/0006-container-architecture.md +57 -0
  72. nova_arsenal-2.0.0/docs/api-reference.md +345 -0
  73. nova_arsenal-2.0.0/docs/architecture.md +126 -0
  74. nova_arsenal-2.0.0/docs/configuration.md +205 -0
  75. nova_arsenal-2.0.0/docs/deployment.md +259 -0
  76. nova_arsenal-2.0.0/docs/getting-started.md +199 -0
  77. nova_arsenal-2.0.0/docs/yarn-context-scaling.md +135 -0
  78. nova_arsenal-2.0.0/k8s/configmap.yaml +8 -0
  79. nova_arsenal-2.0.0/k8s/deployments/agent.yaml +68 -0
  80. nova_arsenal-2.0.0/k8s/deployments/llm.yaml +49 -0
  81. nova_arsenal-2.0.0/k8s/deployments/web.yaml +64 -0
  82. nova_arsenal-2.0.0/k8s/ingress.yaml +43 -0
  83. nova_arsenal-2.0.0/k8s/namespace.yaml +7 -0
  84. nova_arsenal-2.0.0/k8s/network-policies/agent.yaml +41 -0
  85. nova_arsenal-2.0.0/k8s/pvc/ollama-data.yaml +11 -0
  86. nova_arsenal-2.0.0/k8s/pvc/web-data.yaml +11 -0
  87. nova_arsenal-2.0.0/k8s/pvc/workspace.yaml +11 -0
  88. nova_arsenal-2.0.0/k8s/services/agent.yaml +16 -0
  89. nova_arsenal-2.0.0/k8s/services/llm.yaml +16 -0
  90. nova_arsenal-2.0.0/k8s/services/web.yaml +16 -0
  91. nova_arsenal-2.0.0/nova_agent_core.py +168 -0
  92. nova_arsenal-2.0.0/nova_arsenal/__init__.py +181 -0
  93. nova_arsenal-2.0.0/nova_arsenal/agent_runner.py +1868 -0
  94. nova_arsenal-2.0.0/nova_arsenal/agents/__init__.py +1 -0
  95. nova_arsenal-2.0.0/nova_arsenal/agents/coordinator.py +358 -0
  96. nova_arsenal-2.0.0/nova_arsenal/api/__init__.py +5 -0
  97. nova_arsenal-2.0.0/nova_arsenal/api/__main__.py +28 -0
  98. nova_arsenal-2.0.0/nova_arsenal/api/app.py +148 -0
  99. nova_arsenal-2.0.0/nova_arsenal/api/routes.py +1031 -0
  100. nova_arsenal-2.0.0/nova_arsenal/api/routes_chat.py +675 -0
  101. nova_arsenal-2.0.0/nova_arsenal/api/websocket/__init__.py +5 -0
  102. nova_arsenal-2.0.0/nova_arsenal/api/websocket/events.py +138 -0
  103. nova_arsenal-2.0.0/nova_arsenal/arch/__init__.py +24 -0
  104. nova_arsenal-2.0.0/nova_arsenal/arch/mhc.py +277 -0
  105. nova_arsenal-2.0.0/nova_arsenal/async_utils.py +254 -0
  106. nova_arsenal-2.0.0/nova_arsenal/auth/__init__.py +22 -0
  107. nova_arsenal-2.0.0/nova_arsenal/auth/audit.py +119 -0
  108. nova_arsenal-2.0.0/nova_arsenal/auth/bootstrap.py +74 -0
  109. nova_arsenal-2.0.0/nova_arsenal/auth/cleanup.py +47 -0
  110. nova_arsenal-2.0.0/nova_arsenal/auth/middleware.py +224 -0
  111. nova_arsenal-2.0.0/nova_arsenal/auth/models.py +159 -0
  112. nova_arsenal-2.0.0/nova_arsenal/auth/oauth.py +317 -0
  113. nova_arsenal-2.0.0/nova_arsenal/auth/passwords.py +36 -0
  114. nova_arsenal-2.0.0/nova_arsenal/auth/rate_limit.py +108 -0
  115. nova_arsenal-2.0.0/nova_arsenal/auth/routes.py +662 -0
  116. nova_arsenal-2.0.0/nova_arsenal/cli.py +526 -0
  117. nova_arsenal-2.0.0/nova_arsenal/code_generator.py +410 -0
  118. nova_arsenal-2.0.0/nova_arsenal/compliance/__init__.py +13 -0
  119. nova_arsenal-2.0.0/nova_arsenal/compliance/mapper.py +387 -0
  120. nova_arsenal-2.0.0/nova_arsenal/config.py +497 -0
  121. nova_arsenal-2.0.0/nova_arsenal/context/__init__.py +24 -0
  122. nova_arsenal-2.0.0/nova_arsenal/context/compression.py +384 -0
  123. nova_arsenal-2.0.0/nova_arsenal/correlation/__init__.py +11 -0
  124. nova_arsenal-2.0.0/nova_arsenal/correlation/correlator.py +525 -0
  125. nova_arsenal-2.0.0/nova_arsenal/credentials/__init__.py +1 -0
  126. nova_arsenal-2.0.0/nova_arsenal/credentials/harvester.py +515 -0
  127. nova_arsenal-2.0.0/nova_arsenal/crypto/__init__.py +11 -0
  128. nova_arsenal-2.0.0/nova_arsenal/crypto/cipher.py +136 -0
  129. nova_arsenal-2.0.0/nova_arsenal/crypto/key_manager.py +150 -0
  130. nova_arsenal-2.0.0/nova_arsenal/ctf_solver.py +345 -0
  131. nova_arsenal-2.0.0/nova_arsenal/data_generation/__init__.py +61 -0
  132. nova_arsenal-2.0.0/nova_arsenal/data_generation/core.py +763 -0
  133. nova_arsenal-2.0.0/nova_arsenal/data_generation/dedup.py +132 -0
  134. nova_arsenal-2.0.0/nova_arsenal/db/__init__.py +36 -0
  135. nova_arsenal-2.0.0/nova_arsenal/db/crud.py +362 -0
  136. nova_arsenal-2.0.0/nova_arsenal/db/models.py +352 -0
  137. nova_arsenal-2.0.0/nova_arsenal/db/session.py +80 -0
  138. nova_arsenal-2.0.0/nova_arsenal/exploitation/__init__.py +1 -0
  139. nova_arsenal-2.0.0/nova_arsenal/exploitation/attack_chaining.py +536 -0
  140. nova_arsenal-2.0.0/nova_arsenal/exploitation/safe_engine.py +508 -0
  141. nova_arsenal-2.0.0/nova_arsenal/fix_verification/__init__.py +1 -0
  142. nova_arsenal-2.0.0/nova_arsenal/fix_verification/verifier.py +271 -0
  143. nova_arsenal-2.0.0/nova_arsenal/incremental/__init__.py +1 -0
  144. nova_arsenal-2.0.0/nova_arsenal/incremental/engine.py +394 -0
  145. nova_arsenal-2.0.0/nova_arsenal/integrations/__init__.py +16 -0
  146. nova_arsenal-2.0.0/nova_arsenal/integrations/burp_api.py +283 -0
  147. nova_arsenal-2.0.0/nova_arsenal/integrations/msf_rpc.py +309 -0
  148. nova_arsenal-2.0.0/nova_arsenal/integrations/nmap_parser.py +351 -0
  149. nova_arsenal-2.0.0/nova_arsenal/integrations/sqlmap_api.py +360 -0
  150. nova_arsenal-2.0.0/nova_arsenal/intelligence/__init__.py +25 -0
  151. nova_arsenal-2.0.0/nova_arsenal/intelligence/cve_research.py +322 -0
  152. nova_arsenal-2.0.0/nova_arsenal/intelligence/osint_chain.py +383 -0
  153. nova_arsenal-2.0.0/nova_arsenal/intelligence/self_optimizer.py +117 -0
  154. nova_arsenal-2.0.0/nova_arsenal/intelligence/tool_selector.py +677 -0
  155. nova_arsenal-2.0.0/nova_arsenal/kali_blueprint.py +769 -0
  156. nova_arsenal-2.0.0/nova_arsenal/kali_tools_data.py +2707 -0
  157. nova_arsenal-2.0.0/nova_arsenal/kali_tools_extended.py +1974 -0
  158. nova_arsenal-2.0.0/nova_arsenal/llm/__init__.py +27 -0
  159. nova_arsenal-2.0.0/nova_arsenal/llm/account_auth.py +1058 -0
  160. nova_arsenal-2.0.0/nova_arsenal/llm/anthropic.py +131 -0
  161. nova_arsenal-2.0.0/nova_arsenal/llm/base.py +101 -0
  162. nova_arsenal-2.0.0/nova_arsenal/llm/deepseek.py +109 -0
  163. nova_arsenal-2.0.0/nova_arsenal/llm/gemini.py +136 -0
  164. nova_arsenal-2.0.0/nova_arsenal/llm/huggingface.py +113 -0
  165. nova_arsenal-2.0.0/nova_arsenal/llm/keys.py +317 -0
  166. nova_arsenal-2.0.0/nova_arsenal/llm/local_llm.py +182 -0
  167. nova_arsenal-2.0.0/nova_arsenal/llm/multi_router.py +696 -0
  168. nova_arsenal-2.0.0/nova_arsenal/llm/ollama.py +117 -0
  169. nova_arsenal-2.0.0/nova_arsenal/llm/openai.py +220 -0
  170. nova_arsenal-2.0.0/nova_arsenal/llm/opencode.py +111 -0
  171. nova_arsenal-2.0.0/nova_arsenal/llm/openrouter.py +207 -0
  172. nova_arsenal-2.0.0/nova_arsenal/llm/qwen.py +109 -0
  173. nova_arsenal-2.0.0/nova_arsenal/llm/router.py +475 -0
  174. nova_arsenal-2.0.0/nova_arsenal/mcp/__init__.py +3 -0
  175. nova_arsenal-2.0.0/nova_arsenal/mcp/server.py +661 -0
  176. nova_arsenal-2.0.0/nova_arsenal/mitre/__init__.py +1 -0
  177. nova_arsenal-2.0.0/nova_arsenal/mitre/mapper.py +528 -0
  178. nova_arsenal-2.0.0/nova_arsenal/optimizers/__init__.py +14 -0
  179. nova_arsenal-2.0.0/nova_arsenal/optimizers/muon.py +244 -0
  180. nova_arsenal-2.0.0/nova_arsenal/payload_generator.py +244 -0
  181. nova_arsenal-2.0.0/nova_arsenal/persona_manager.py +132 -0
  182. nova_arsenal-2.0.0/nova_arsenal/prompt_builder.py +743 -0
  183. nova_arsenal-2.0.0/nova_arsenal/ransomware/__init__.py +1 -0
  184. nova_arsenal-2.0.0/nova_arsenal/ransomware/emulator.py +401 -0
  185. nova_arsenal-2.0.0/nova_arsenal/resilient_agent_core.py +193 -0
  186. nova_arsenal-2.0.0/nova_arsenal/safety/__init__.py +1 -0
  187. nova_arsenal-2.0.0/nova_arsenal/safety/controller.py +299 -0
  188. nova_arsenal-2.0.0/nova_arsenal/sandbox_executor.py +374 -0
  189. nova_arsenal-2.0.0/nova_arsenal/scheduler.py +297 -0
  190. nova_arsenal-2.0.0/nova_arsenal/secure_executor.py +265 -0
  191. nova_arsenal-2.0.0/nova_arsenal/sessions/__init__.py +30 -0
  192. nova_arsenal-2.0.0/nova_arsenal/sessions/api_routes.py +186 -0
  193. nova_arsenal-2.0.0/nova_arsenal/sessions/models.py +181 -0
  194. nova_arsenal-2.0.0/nova_arsenal/sessions/runtime.py +618 -0
  195. nova_arsenal-2.0.0/nova_arsenal/skills/__init__.py +0 -0
  196. nova_arsenal-2.0.0/nova_arsenal/skills/api_routes.py +212 -0
  197. nova_arsenal-2.0.0/nova_arsenal/skills/memory_api_routes.py +144 -0
  198. nova_arsenal-2.0.0/nova_arsenal/skills/platform_connector.py +171 -0
  199. nova_arsenal-2.0.0/nova_arsenal/skills/session_memory.py +393 -0
  200. nova_arsenal-2.0.0/nova_arsenal/skills/skill_author.py +219 -0
  201. nova_arsenal-2.0.0/nova_arsenal/skills/skill_manifest.py +219 -0
  202. nova_arsenal-2.0.0/nova_arsenal/streaming/__init__.py +1 -0
  203. nova_arsenal-2.0.0/nova_arsenal/streaming/realtime.py +387 -0
  204. nova_arsenal-2.0.0/nova_arsenal/swarm.py +522 -0
  205. nova_arsenal-2.0.0/nova_arsenal/tool_definitions.py +818 -0
  206. nova_arsenal-2.0.0/nova_arsenal/training/__init__.py +57 -0
  207. nova_arsenal-2.0.0/nova_arsenal/training/config.py +97 -0
  208. nova_arsenal-2.0.0/nova_arsenal/training/cross_stage_distillation.py +448 -0
  209. nova_arsenal-2.0.0/nova_arsenal/training/glm_agentic_rl.py +970 -0
  210. nova_arsenal-2.0.0/nova_arsenal/training/grpo_trainer.py +397 -0
  211. nova_arsenal-2.0.0/nova_arsenal/training/trajectory_pool.py +119 -0
  212. nova_arsenal-2.0.0/nova_arsenal/validation/__init__.py +1 -0
  213. nova_arsenal-2.0.0/nova_arsenal/validation/engine.py +583 -0
  214. nova_arsenal-2.0.0/nova_arsenal/zeroday/__init__.py +54 -0
  215. nova_arsenal-2.0.0/nova_arsenal/zeroday/crash_triage.py +216 -0
  216. nova_arsenal-2.0.0/nova_arsenal/zeroday/fuzz_orchestrator.py +387 -0
  217. nova_arsenal-2.0.0/nova_arsenal/zeroday/fuzz_worker.py +578 -0
  218. nova_arsenal-2.0.0/nova_arsenal/zeroday/http_mutator.py +158 -0
  219. nova_arsenal-2.0.0/nova_arsenal/zeroday/novelty.py +127 -0
  220. nova_arsenal-2.0.0/nova_arsenal/zeroday/pipeline.py +551 -0
  221. nova_arsenal-2.0.0/nova_arsenal/zeroday/recon_bridge.py +153 -0
  222. nova_arsenal-2.0.0/nova_arsenal/zeroday/static_scanner.py +276 -0
  223. nova_arsenal-2.0.0/nova_arsenal/zeroday/surface.py +407 -0
  224. nova_arsenal-2.0.0/nova_arsenal/zeroday/variant.py +243 -0
  225. nova_arsenal-2.0.0/nova_skills.py +191 -0
  226. nova_arsenal-2.0.0/nova_swarm.py +151 -0
  227. nova_arsenal-2.0.0/nova_tool_kit.py +241 -0
  228. nova_arsenal-2.0.0/nova_toolbox.py +377 -0
  229. nova_arsenal-2.0.0/pyproject.toml +111 -0
  230. nova_arsenal-2.0.0/skills/SKILL_AUTHORING_GUIDE.md +99 -0
  231. nova_arsenal-2.0.0/skills/bugcrowd-connector/connector.py +146 -0
  232. nova_arsenal-2.0.0/skills/bugcrowd-connector/skill.json +13 -0
  233. nova_arsenal-2.0.0/skills/hackerone-connector/connector.py +146 -0
  234. nova_arsenal-2.0.0/skills/hackerone-connector/skill.json +13 -0
  235. nova_arsenal-2.0.0/skills/hackthebox-connector/connector.py +143 -0
  236. nova_arsenal-2.0.0/skills/hackthebox-connector/skill.json +13 -0
  237. nova_arsenal-2.0.0/skills/tryhackme-connector/connector.py +158 -0
  238. nova_arsenal-2.0.0/skills/tryhackme-connector/skill.json +13 -0
  239. nova_arsenal-2.0.0/test_nova.py +109 -0
  240. nova_arsenal-2.0.0/tests/conftest.py +50 -0
  241. nova_arsenal-2.0.0/tests/fixtures/sample_targets.json +16 -0
  242. nova_arsenal-2.0.0/tests/integration/__init__.py +7 -0
  243. nova_arsenal-2.0.0/tests/integration/test_agent_core.py +42 -0
  244. nova_arsenal-2.0.0/tests/integration/test_agent_resilience.py +135 -0
  245. nova_arsenal-2.0.0/tests/integration/test_full_cycle.py +43 -0
  246. nova_arsenal-2.0.0/tests/integration/test_swarm.py +53 -0
  247. nova_arsenal-2.0.0/tests/unit/__init__.py +7 -0
  248. nova_arsenal-2.0.0/tests/unit/test_account_auth.py +108 -0
  249. nova_arsenal-2.0.0/tests/unit/test_agentic.py +416 -0
  250. nova_arsenal-2.0.0/tests/unit/test_agents.py +115 -0
  251. nova_arsenal-2.0.0/tests/unit/test_async_utils.py +269 -0
  252. nova_arsenal-2.0.0/tests/unit/test_auth.py +373 -0
  253. nova_arsenal-2.0.0/tests/unit/test_byok.py +126 -0
  254. nova_arsenal-2.0.0/tests/unit/test_chat_context.py +67 -0
  255. nova_arsenal-2.0.0/tests/unit/test_chat_crud.py +69 -0
  256. nova_arsenal-2.0.0/tests/unit/test_context.py +125 -0
  257. nova_arsenal-2.0.0/tests/unit/test_crypto.py +167 -0
  258. nova_arsenal-2.0.0/tests/unit/test_ctf_solver.py +103 -0
  259. nova_arsenal-2.0.0/tests/unit/test_exploitation.py +189 -0
  260. nova_arsenal-2.0.0/tests/unit/test_local_llm.py +58 -0
  261. nova_arsenal-2.0.0/tests/unit/test_mcp.py +216 -0
  262. nova_arsenal-2.0.0/tests/unit/test_modules.py +314 -0
  263. nova_arsenal-2.0.0/tests/unit/test_multi_provider.py +202 -0
  264. nova_arsenal-2.0.0/tests/unit/test_nova_agent_core_enhanced.py +173 -0
  265. nova_arsenal-2.0.0/tests/unit/test_nova_skills.py +133 -0
  266. nova_arsenal-2.0.0/tests/unit/test_nova_tool_kit.py +151 -0
  267. nova_arsenal-2.0.0/tests/unit/test_nova_toolbox.py +115 -0
  268. nova_arsenal-2.0.0/tests/unit/test_openai_provider.py +62 -0
  269. nova_arsenal-2.0.0/tests/unit/test_optimizers_arch.py +163 -0
  270. nova_arsenal-2.0.0/tests/unit/test_ownership.py +60 -0
  271. nova_arsenal-2.0.0/tests/unit/test_privileged_routes.py +71 -0
  272. nova_arsenal-2.0.0/tests/unit/test_prompt_builder.py +336 -0
  273. nova_arsenal-2.0.0/tests/unit/test_release_metadata.py +46 -0
  274. nova_arsenal-2.0.0/tests/unit/test_resilient_agent_core.py +123 -0
  275. nova_arsenal-2.0.0/tests/unit/test_sessions.py +65 -0
  276. nova_arsenal-2.0.0/tests/unit/test_swarm_zeroday.py +87 -0
  277. nova_arsenal-2.0.0/tests/unit/test_training.py +174 -0
  278. nova_arsenal-2.0.0/tests/unit/test_validation_safety.py +218 -0
  279. nova_arsenal-2.0.0/tests/unit/test_zeroday.py +276 -0
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "Ollama Dev",
3
+ "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
4
+ "postCreateCommand": "curl -fsSL https://ollama.com/install.sh | sh"
5
+ }
@@ -0,0 +1,21 @@
1
+ # Nova-Arsenal Code Owners
2
+
3
+ # Default owner for everything
4
+ * @Informant254
5
+
6
+ # Core agent system
7
+ /nova_arsenal/ @Informant254
8
+
9
+ # Web client
10
+ /clients/web/ @Informant254
11
+
12
+ # Infrastructure
13
+ /containers/ @Informant254
14
+ /k8s/ @Informant254
15
+ /.github/ @Informant254
16
+
17
+ # Configuration
18
+ /config/ @Informant254
19
+
20
+ # Documentation
21
+ /docs/ @Informant254
@@ -0,0 +1,45 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ open-pull-requests-limit: 10
8
+ labels:
9
+ - "dependencies"
10
+ - "python"
11
+ commit-message:
12
+ prefix: "deps"
13
+
14
+ - package-ecosystem: "npm"
15
+ directory: "/clients/web"
16
+ schedule:
17
+ interval: "weekly"
18
+ open-pull-requests-limit: 5
19
+ labels:
20
+ - "dependencies"
21
+ - "javascript"
22
+ commit-message:
23
+ prefix: "deps"
24
+
25
+ - package-ecosystem: "docker"
26
+ directory: "/"
27
+ schedule:
28
+ interval: "weekly"
29
+ open-pull-requests-limit: 5
30
+ labels:
31
+ - "dependencies"
32
+ - "docker"
33
+ commit-message:
34
+ prefix: "deps"
35
+
36
+ - package-ecosystem: "github-actions"
37
+ directory: "/"
38
+ schedule:
39
+ interval: "weekly"
40
+ open-pull-requests-limit: 5
41
+ labels:
42
+ - "dependencies"
43
+ - "ci"
44
+ commit-message:
45
+ prefix: "deps"
@@ -0,0 +1,118 @@
1
+ # Revival baseline: lint, formatting, typing, tests, client builds, and container builds are blocking gates.
2
+ name: CI
3
+
4
+ on:
5
+ workflow_dispatch:
6
+ push:
7
+ branches: [main, develop, "revive/**", "revival/**"]
8
+ pull_request:
9
+ branches: [main, "revival/**"]
10
+
11
+ jobs:
12
+ lint:
13
+ name: Python Lint & Format
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v7
17
+ - uses: actions/setup-python@v7
18
+ with:
19
+ python-version: "3.11"
20
+ cache: pip
21
+ - name: Install package and lint tools
22
+ run: pip install -e ".[dev]"
23
+ - name: Check Python linting
24
+ run: ruff check .
25
+ - name: Check Python formatting
26
+ run: ruff format --check .
27
+
28
+ typecheck:
29
+ name: Python Type Check
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v7
33
+ - uses: actions/setup-python@v7
34
+ with:
35
+ python-version: "3.11"
36
+ cache: pip
37
+ - name: Install package and type checker
38
+ run: pip install -e ".[dev]"
39
+ - name: Run type checking
40
+ run: basedpyright nova_arsenal/
41
+
42
+ test:
43
+ name: Test (Python ${{ matrix.python-version }})
44
+ runs-on: ubuntu-latest
45
+ strategy:
46
+ fail-fast: false
47
+ matrix:
48
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
49
+ steps:
50
+ - uses: actions/checkout@v7
51
+ - uses: actions/setup-python@v7
52
+ with:
53
+ python-version: ${{ matrix.python-version }}
54
+ cache: pip
55
+ - name: Install dependencies
56
+ run: pip install -e ".[dev]"
57
+ - name: Run tests
58
+ run: pytest tests/ -v --tb=short
59
+
60
+ web-build:
61
+ name: Web Client Build
62
+ runs-on: ubuntu-latest
63
+ steps:
64
+ - uses: actions/checkout@v7
65
+ - uses: actions/setup-node@v7
66
+ with:
67
+ node-version: "22"
68
+ - name: Install dependencies
69
+ working-directory: clients/web
70
+ run: npm install --no-audit --no-fund
71
+ - name: Build
72
+ working-directory: clients/web
73
+ run: npm run build
74
+
75
+ vscode-build:
76
+ name: VS Code Extension Build
77
+ runs-on: ubuntu-latest
78
+ steps:
79
+ - uses: actions/checkout@v7
80
+ - uses: actions/setup-node@v7
81
+ with:
82
+ node-version: "22"
83
+ cache: npm
84
+ cache-dependency-path: clients/vscode/package-lock.json
85
+ - name: Install dependencies
86
+ working-directory: clients/vscode
87
+ run: npm ci
88
+ - name: Compile extension
89
+ working-directory: clients/vscode
90
+ run: npm run compile
91
+
92
+ docker-build:
93
+ name: Docker Build (${{ matrix.image }})
94
+ runs-on: ubuntu-latest
95
+ strategy:
96
+ fail-fast: false
97
+ matrix:
98
+ image: [agent, web, kali]
99
+ steps:
100
+ - uses: actions/checkout@v7
101
+ - uses: docker/setup-buildx-action@v3
102
+ - name: Build ${{ matrix.image }} image
103
+ uses: docker/build-push-action@v6
104
+ with:
105
+ context: .
106
+ file: containers/Dockerfile.${{ matrix.image }}
107
+ push: false
108
+ tags: nova-${{ matrix.image }}:test
109
+ cache-from: type=gha
110
+ cache-to: type=gha,mode=max
111
+
112
+ ci-ok:
113
+ name: CI OK
114
+ runs-on: ubuntu-latest
115
+ needs: [lint, typecheck, test, web-build, vscode-build, docker-build]
116
+ steps:
117
+ - name: Required checks passed
118
+ run: echo "Required CI checks passed"
@@ -0,0 +1,180 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ env:
9
+ REGISTRY_GHCR: ghcr.io
10
+ REGISTRY_DOCKERHUB: docker.io
11
+
12
+ jobs:
13
+ validate:
14
+ name: Validate release
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v7
18
+
19
+ - uses: actions/setup-python@v7
20
+ with:
21
+ python-version: "3.13"
22
+ cache: pip
23
+
24
+ - name: Verify tag matches package version
25
+ run: |
26
+ python - <<'PY'
27
+ import os
28
+ import tomllib
29
+ from pathlib import Path
30
+
31
+ version = tomllib.loads(Path("pyproject.toml").read_text())["project"]["version"]
32
+ tag = os.environ["GITHUB_REF_NAME"]
33
+ expected = f"v{version}"
34
+ if tag != expected:
35
+ raise SystemExit(f"Release tag {tag!r} does not match package version {version!r}; expected {expected!r}")
36
+ print(f"Release version validated: {tag}")
37
+ PY
38
+
39
+ - name: Install package and release tools
40
+ run: pip install -e ".[dev]" build twine
41
+
42
+ - name: Lint and format
43
+ run: |
44
+ ruff check .
45
+ ruff format --check .
46
+
47
+ - name: Type check
48
+ run: basedpyright nova_arsenal/
49
+
50
+ - name: Test
51
+ run: pytest tests/ -q
52
+
53
+ - name: Build package
54
+ run: python -m build
55
+
56
+ - name: Validate distributions
57
+ run: twine check dist/*
58
+
59
+ pypi:
60
+ name: Publish to PyPI
61
+ runs-on: ubuntu-latest
62
+ needs: validate
63
+ permissions:
64
+ id-token: write
65
+ steps:
66
+ - uses: actions/checkout@v7
67
+
68
+ - uses: actions/setup-python@v7
69
+ with:
70
+ python-version: "3.13"
71
+
72
+ - name: Install build tools
73
+ run: pip install build
74
+
75
+ - name: Build package
76
+ run: python -m build
77
+
78
+ - name: Publish to PyPI
79
+ uses: pypa/gh-action-pypi-publish@release/v1
80
+ with:
81
+ # Using Trusted Publishing (OIDC). Configure this on PyPI before tagging.
82
+ skip-existing: true
83
+
84
+ docker-ghcr:
85
+ name: Publish to GHCR (${{ matrix.image }})
86
+ runs-on: ubuntu-latest
87
+ needs: validate
88
+ permissions:
89
+ contents: read
90
+ packages: write
91
+ strategy:
92
+ matrix:
93
+ image: [agent, web, kali]
94
+ steps:
95
+ - uses: actions/checkout@v7
96
+
97
+ - uses: docker/setup-buildx-action@v3
98
+
99
+ - name: Login to GHCR
100
+ uses: docker/login-action@v3
101
+ with:
102
+ registry: ${{ env.REGISTRY_GHCR }}
103
+ username: ${{ github.actor }}
104
+ password: ${{ secrets.GITHUB_TOKEN }}
105
+
106
+ - name: Extract metadata
107
+ id: meta
108
+ uses: docker/metadata-action@v5
109
+ with:
110
+ images: ${{ env.REGISTRY_GHCR }}/informant254/nova-${{ matrix.image }}
111
+ tags: |
112
+ type=semver,pattern={{version}}
113
+ type=semver,pattern={{major}}.{{minor}}
114
+ type=sha
115
+
116
+ - name: Build and push
117
+ uses: docker/build-push-action@v6
118
+ with:
119
+ context: .
120
+ file: containers/Dockerfile.${{ matrix.image }}
121
+ push: true
122
+ tags: ${{ steps.meta.outputs.tags }}
123
+ labels: ${{ steps.meta.outputs.labels }}
124
+ cache-from: type=gha
125
+ cache-to: type=gha,mode=max
126
+
127
+ docker-dockerhub:
128
+ name: Publish to Docker Hub (${{ matrix.image }})
129
+ runs-on: ubuntu-latest
130
+ needs: validate
131
+ strategy:
132
+ matrix:
133
+ image: [agent, web, kali]
134
+ steps:
135
+ - uses: actions/checkout@v7
136
+
137
+ - uses: docker/setup-buildx-action@v3
138
+
139
+ - name: Login to Docker Hub
140
+ uses: docker/login-action@v3
141
+ with:
142
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
143
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
144
+
145
+ - name: Extract metadata
146
+ id: meta
147
+ uses: docker/metadata-action@v5
148
+ with:
149
+ images: informant254/nova-${{ matrix.image }}
150
+ tags: |
151
+ type=semver,pattern={{version}}
152
+ type=semver,pattern={{major}}.{{minor}}
153
+ type=sha
154
+
155
+ - name: Build and push
156
+ uses: docker/build-push-action@v6
157
+ with:
158
+ context: .
159
+ file: containers/Dockerfile.${{ matrix.image }}
160
+ push: true
161
+ tags: ${{ steps.meta.outputs.tags }}
162
+ labels: ${{ steps.meta.outputs.labels }}
163
+ cache-from: type=gha
164
+ cache-to: type=gha,mode=max
165
+
166
+ github-release:
167
+ name: Create GitHub Release
168
+ runs-on: ubuntu-latest
169
+ needs: [pypi, docker-ghcr, docker-dockerhub]
170
+ permissions:
171
+ contents: write
172
+ steps:
173
+ - uses: actions/checkout@v7
174
+
175
+ - name: Create release
176
+ uses: softprops/action-gh-release@v1
177
+ with:
178
+ generate_release_notes: true
179
+ draft: false
180
+ prerelease: ${{ contains(github.ref, '-') }}
@@ -0,0 +1,54 @@
1
+ name: Security
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ schedule:
9
+ - cron: "0 0 * * 0"
10
+
11
+ jobs:
12
+ codeql:
13
+ name: CodeQL Analysis
14
+ runs-on: ubuntu-latest
15
+ permissions:
16
+ actions: read
17
+ contents: read
18
+ security-events: write
19
+ steps:
20
+ - uses: actions/checkout@v7
21
+ - uses: github/codeql-action/init@v4
22
+ with:
23
+ languages: python
24
+ - uses: github/codeql-action/analyze@v4
25
+
26
+ trivy:
27
+ name: Trivy Secret Scan
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@v7
31
+ - name: Scan repository for secrets
32
+ uses: aquasecurity/trivy-action@v0.36.0
33
+ with:
34
+ scan-type: fs
35
+ scan-ref: .
36
+ scanners: secret
37
+ exit-code: 1
38
+
39
+ pip-audit:
40
+ name: Python Dependency Audit
41
+ runs-on: ubuntu-latest
42
+ steps:
43
+ - uses: actions/checkout@v7
44
+ - uses: actions/setup-python@v7
45
+ with:
46
+ python-version: "3.11"
47
+ cache: pip
48
+ - name: Install Nova-Arsenal runtime dependencies and audit tool
49
+ run: |
50
+ python -m pip install --upgrade pip "setuptools>=83" wheel
51
+ python -m pip install -e .
52
+ python -m pip install pip-audit
53
+ - name: Audit installed Python dependencies
54
+ run: pip-audit
@@ -0,0 +1,114 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ .venv/
25
+ venv/
26
+ ENV/
27
+ env/
28
+
29
+ # IDE
30
+ .vscode/
31
+ .idea/
32
+ *.swp
33
+ *.swo
34
+ *~
35
+ .project
36
+ .settings/
37
+
38
+ # Testing
39
+ .pytest_cache/
40
+ .coverage
41
+ .coverage.*
42
+ htmlcov/
43
+ *.cover
44
+
45
+ # Type checking
46
+ .mypy_cache/
47
+ .pytype/
48
+ basedpyright/
49
+
50
+ # Ruff
51
+ .ruff_cache/
52
+
53
+ # Environment variables
54
+ .env
55
+ .env.local
56
+ .env.production
57
+
58
+ # Database
59
+ *.db
60
+ *.sqlite
61
+ *.sqlite3
62
+
63
+ # Docker
64
+ docker-compose.override.yml
65
+
66
+ # Node.js (web client)
67
+ clients/web/node_modules/
68
+ clients/web/.next/
69
+ clients/web/out/
70
+ clients/web/.env.local
71
+
72
+ # Nova workspace
73
+ nova_workspace/
74
+ nova_workspace/**
75
+
76
+ # Logs
77
+ *.log
78
+ logs/
79
+
80
+ # OS
81
+ .DS_Store
82
+ Thumbs.db
83
+
84
+ # Jupyter Notebook
85
+ .ipynb_checkpoints
86
+
87
+ # pyenv
88
+ .python-version
89
+
90
+ # pipenv
91
+ Pipfile.lock
92
+
93
+ # poetry
94
+ poetry.lock
95
+
96
+ # conda
97
+ environment.yml
98
+
99
+ # pre-commit
100
+ .pre-commit-cache/
101
+
102
+ # Kubernetes secrets (never commit)
103
+ k8s/secrets.yaml
104
+ node_modules/
105
+ clients/vscode/node_modules/
106
+ *.vsix
107
+ .env
108
+ config/.env
109
+ __pycache__/
110
+ *.pyc
111
+ .pytest_cache/
112
+ venv/
113
+ .venv/
114
+ fuzz_out/
@@ -0,0 +1,28 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.4.4
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+
9
+ - repo: https://github.com/gitleaks/gitleaks
10
+ rev: v8.18.2
11
+ hooks:
12
+ - id: gitleaks
13
+
14
+ - repo: https://github.com/pre-commit/pre-commit-hooks
15
+ rev: v4.6.0
16
+ hooks:
17
+ - id: trailing-whitespace
18
+ - id: end-of-file-fixer
19
+ - id: check-yaml
20
+ - id: check-json
21
+ - id: check-added-large-files
22
+ - id: check-merge-conflict
23
+
24
+ - repo: https://github.com/koalaman/shellcheck-precommit
25
+ rev: v0.10.0
26
+ hooks:
27
+ - id: shellcheck
28
+ args: [-e, SC1091]
@@ -0,0 +1,110 @@
1
+ # Changelog
2
+
3
+ All notable changes to Nova-Arsenal will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ No unreleased changes yet.
11
+
12
+ ---
13
+
14
+ ## [2.0.0] - 2026-10-01
15
+
16
+ ### Added
17
+ - **Concurrent work sessions + sub-agents** — `SessionManager` runs recon/web/osint/researcher/exploit/validator/reporter **in parallel** under one session; API `/api/work-sessions`, CLI `nova-agent session`, consensus aggregation, event stream, disk persistence
18
+ - **Natural multi-turn chat** — conversation-first system prompts, full history, fixed SSE streaming via LLMRouter (not broken `active_providers`), offline fallback that still talks; web UI welcome copy for “chat like ChatGPT”
19
+ - **ChatGPT / Codex subscription OAuth** — `nova-agent login --provider openai --oauth` (PKCE browser) and `--device-code` for headless; token refresh; preferred primary when signed in
20
+ - **Local LLM first-class** — Ollama auto-discovery, `nova-agent login --provider ollama`, LM Studio/OpenAI-compatible local servers; `GET /api/llm/local`
21
+ - **Account-style AI login (Codex / Claude Code)** — `nova-agent login`, import local Claude/Codex sessions, `CLAUDE_CODE_OAUTH_TOKEN`, Google OAuth for Gemini; tokens in `~/.nova/accounts.json`; API `/api/llm/accounts/*`
22
+ - **VS Code extension fixed** — compiles to `out/`, correct chat endpoint, Sign In / Import sessions / Ollama commands, host-mediated API calls, Output channel
23
+ - **BYOK (bring-your-own-key) LLM wiring** — auto-detect OpenAI/Anthropic/Gemini/OpenRouter/DeepSeek/Qwen/HF keys from `.env`; honor `LLM_PROVIDER` + `LLM_MODEL`; `GET /api/llm/status` + `POST /api/llm/reload`; Settings UI shows live key status (no secrets leaked)
24
+ - **Zero-Day Candidate Pipeline (`nova_arsenal.zeroday`)** — high-speed research stack:
25
+ - Parallel attack-surface ranking (`AttackSurfaceMapper`)
26
+ - CVE variant / patch-gap analysis (`VariantAnalyzer`)
27
+ - Static bug-class heuristics (`StaticBugScanner`)
28
+ - Multi-engine fuzz campaign orchestration (`FuzzOrchestrator`)
29
+ - **Live fuzz worker** (`LiveFuzzWorker`) — detects/runs ffuf, AFL++, honggfuzz, radamsa, HTTP mutator
30
+ - Crash triage & dedup (`CrashTriageEngine`)
31
+ - Novelty scoring vs known CVE fingerprints (`NoveltyScorer`)
32
+ - Recon→services bridge (`findings_to_services`)
33
+ - Unified hunter (`ZeroDayHunter`) with authorization gate
34
+ - **Swarm phase wiring:** recon → `researcher_zeroday` (auto ZeroDayHunter) → web/exploit/validator
35
+ - CLI: `--zeroday`, `--swarm`, `--live-fuzz`, `--authorized`, `--auth-ref`
36
+ - MCP: `zeroday_hunt`; `swarm_scan` returns phases + zeroday candidate count
37
+ - Tool schema + tool-selector rules for zeroday research
38
+ - Unit tests: `tests/unit/test_zeroday.py`, `tests/unit/test_swarm_zeroday.py`
39
+
40
+ ### Notes
41
+ - Pipeline optimizes *seconds-scale prioritization and planning*. Live fuzz uses short
42
+ job timeouts by default. It does **not** guarantee confirmed zero-day discovery;
43
+ candidates require human validation and responsible disclosure. Authorized testing only.
44
+
45
+ ### Previous
46
+ - Initial release of Nova-Arsenal platform
47
+ - 70+ security modules (recon, attack, analysis, reporting)
48
+ - Multi-LLM support (Ollama, OpenAI, Anthropic, Gemini)
49
+ - Web dashboard with real-time monitoring
50
+ - Docker-based deployment
51
+ - Multi-user authentication with JWT
52
+ - SQLite database for findings storage
53
+ - Kubernetes deployment manifests
54
+ - GitHub Actions CI/CD pipeline
55
+ - Security scanning (CodeQL, Trivy, TruffleHog)
56
+
57
+ ### Changed
58
+ - N/A (initial release)
59
+
60
+ ### Deprecated
61
+ - N/A (initial release)
62
+
63
+ ### Removed
64
+ - N/A (initial release)
65
+
66
+ ### Fixed
67
+ - N/A (initial release)
68
+
69
+ ### Security
70
+ - Privileged MCP and shared LLM-management APIs require analyst/admin authentication
71
+ - Nmap MCP execution uses validated argument-vector subprocesses instead of shell interpolation
72
+ - Credentialed CORS rejects wildcard origins and production Compose requires explicit secrets/origins
73
+ - Authentication uses PyJWT + Argon2 with transparent legacy bcrypt migration
74
+ - Internal provider/MCP exceptions are logged server-side and redacted from client responses
75
+ - CI enforces Ruff formatting/linting, BasedPyright, Python 3.10–3.13 tests, web/VS Code builds, and Docker builds
76
+ - Security CI runs dependency audit, Trivy secret scanning, and CodeQL
77
+ - Capability dropping in all containers
78
+ - Network isolation for sandbox
79
+ - Secret redaction in logs
80
+ - Tool governance and rate limiting
81
+
82
+ ---
83
+
84
+ ## Pre-2.0 development history
85
+
86
+ ### Added
87
+ - Core agent system with autonomous reasoning
88
+ - Skills library with prompt templates
89
+ - Governed tool kit with scope enforcement
90
+ - Multi-agent swarm architecture
91
+ - Web UI dashboard
92
+ - REST API with FastAPI
93
+ - WebSocket real-time updates
94
+ - Docker deployment
95
+ - Kubernetes manifests
96
+ - CI/CD pipeline
97
+ - Comprehensive documentation
98
+
99
+ ---
100
+
101
+ ## Versioning
102
+
103
+ We use [SemVer](https://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/Informant254/Nova-arsenal/tags).
104
+
105
+ ## Release Process
106
+
107
+ See [`docs/RELEASING.md`](docs/RELEASING.md). The tag must exactly match the package version
108
+ (for example, package `2.0.0` requires tag `v2.0.0`). The release workflow validates the
109
+ tag/version pair and full Python quality gate before publishing to PyPI, GHCR, Docker Hub,
110
+ and GitHub Releases.