-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathpyproject.toml
More file actions
133 lines (125 loc) · 5.74 KB
/
Copy pathpyproject.toml
File metadata and controls
133 lines (125 loc) · 5.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
[project]
name = "genesis-v3"
version = "3.0.0b17"
requires-python = ">=3.12"
dependencies = [
"aiosqlite",
"aiohttp>=3.14.1", # security floor — 3.14.1 fixes 11 advisories (cookie leak on redirect, several DoS,
# multipart header injection). Genesis is client-only; the aioresponses/ClientResponse
# stream_writer-kwarg mismatch is absorbed by the tests/test_observability/conftest.py shim.
"apscheduler>=3.11,<4",
"tzlocal>=5", # transitive dep of apscheduler (ego/cadence uses the local-timezone path); declare so a clean/cached install can't drop it
"python-telegram-bot>=21.0",
"litellm==1.78.7", # pinned — 1.82.7/1.82.8 contain malware. Its open advisories are all
# proxy-server / JWT / OIDC / UI vulns (see the ci.yml dependency-audit
# ignore-list); not reachable — Genesis uses acompletion/completion_cost only.
"qdrant-client",
"pyyaml",
"httpx",
"diskcache>=5.6",
"beautifulsoup4",
"html2text",
"lxml",
"flask>=3.0",
"flask-sock>=0.7",
"wsproto>=1.2", # transitive dep of flask-sock; pin to prevent silent uninstall
"fastmcp>=2.0,<3.0", # <3 for API stability (3.x breaks the API). Genesis uses fastmcp stdio
# transport only (no OpenAPIProvider/OAuthProxy), so its OpenAPI/OAuth CVEs
# (CVE-2026-32871/27124/2025-64340, unfixed pre-3.2.0) are not reachable.
"detect-secrets>=1.4", # Phase 6 contribution sanitizer — REQUIRED floor. sanitize.py fails closed if missing.
"pymupdf>=1.27", # PDF text extraction for knowledge ingestion pipeline
"scrapling>=0.4.7", # Web fetching with TLS fingerprint impersonation
"curl_cffi>=0.15.0", # curl_cffi backend for Scrapling's AsyncFetcher
"networkx>=3.0", # In-memory graph for memory_links traversal + algorithms
"wyoming>=1.5", # Wyoming protocol for HA voice satellite STT/TTS integration
# Transitive deps pinned to secure floors (audit #638) so a clean/cached install can't resolve a vulnerable version
"urllib3>=2.7.0", # via qdrant-client/requests — CVE-2026-44431/44432 (auth-header leak, decompression DoS)
"idna>=3.15", # via httpx/requests — CVE-2026-45409 (quadratic-processing DoS)
"certifi>=2026.5.20", # via httpx/curl_cffi — current CA bundle
]
[project.optional-dependencies]
test = [
"pytest>=8.0",
"pytest-asyncio",
"pytest-timeout",
"aioresponses>=0.7.7",
# tests/test_hooks/test_edit_verify_advisory.py executes the real hook,
# which shells out to the venv's ruff — CI's test job installs only this
# extra, so ruff must be here (the lint job installs its own copy).
"ruff>=0.5",
]
browser = [
"playwright>=1.40",
"camoufox>=0.4",
]
voice = [
"openai[realtime]>=2.20", # GPT-Realtime API for speech-to-speech voice sessions
]
distribution = [
"composio-client>=1.33.0",
]
documents = [
"pageindex>=0.2.8",
]
release = [] # detect-secrets is now a core dep (see dependencies above)
[build-system]
requires = ["setuptools>=64"]
build-backend = "setuptools.build_meta"
[tool.setuptools.packages.find]
where = ["src"]
[tool.ruff]
target-version = "py312"
line-length = 100
# Agentic-gauntlet fixtures are INTENTIONALLY broken Python projects (the model's
# job is to fix them) — never lint them, or CI would fail on the planted bugs.
extend-exclude = ["src/genesis/eval/gauntlet_fixtures"]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear (catches common gotchas)
"SIM", # flake8-simplify
"UP", # pyupgrade
"S", # flake8-bandit (security) — see the documented ignores below
]
ignore = [
"E501", # line length (handled by formatter)
# S603/S607 flag EVERY subprocess call regardless of safety; this codebase
# shells to git/gh/ruff by design. The real shell-risk rule, S602
# (shell=True), stays ENABLED.
"S603", "S607",
# S110/S112 (try-except-pass/continue): most hits implement the deliberate
# "hooks/best-effort telemetry never crash" convention. A linter cannot
# distinguish that from bad swallowing in data-returning code — the review
# protocol + CODE_AUDITOR taxonomy own that class with judgment. This is a
# documented trade, not noise cleanup (user-accepted 2026-07-10).
"S110", "S112",
# S311 (non-crypto random): all uses are timing jitter / sampling / backoff
# (browser stealth, retry spread). No token or secret generation uses
# `random` — re-grep before adding any such use; use `secrets` there.
"S311",
]
[tool.ruff.lint.per-file-ignores]
# Tests assert, use fake credentials, /tmp literals, chmod fixtures,
# subprocess/shell fixtures, and literal fixture SQL by nature.
"tests/**" = ["S101", "S105", "S106", "S108", "S103", "S324", "S602", "S608"]
# Parametrized dynamic-WHERE builder pattern: SQL fragments are literal
# strings assembled in code; user values are ALWAYS bound parameters. S608
# stays live outside these data-access layers.
"src/genesis/db/crud/*" = ["S608"]
"src/genesis/dashboard/routes/*" = ["S608"]
# Schema/data migrations assemble literal SQL fragments (often from module-level
# constants); they run at deploy against the schema and NEVER take runtime user
# input, so S608 is a false positive here — same data-access-layer rationale as
# db/crud/*. (0053's f-string UPDATE uses a trusted literal _WHERE constant.)
"src/genesis/db/migrations/*" = ["S608"]
# Type-narrowing asserts in MCP handlers (follow-up: convert to explicit raises).
"src/genesis/mcp/memory/*" = ["S101"]
[tool.ruff.format]
quote-style = "double"
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
timeout = 1800