[build-system] requires = ["setuptools>=68.0", "wheel"] build-backend = "setuptools.build_meta" [project] name = "agent-bom" version = "0.114.0" description = "AI supply-chain BOM: every agent, MCP server and AI package, and what each one can reach." readme = "docs/registry/PYPI_README.md" license = "Apache-2.0" license-files = ["LICENSE"] requires-python = ">=3.11" authors = [ {name = "Wagdy Saad", email = "andwgdysaad@gmail.com"} ] keywords = ["ai-bom", "sbom", "mcp", "mcp-server", "mcp-security", "ai-agents", "ai-supply-chain", "supply-chain", "supply-chain-security", "vulnerability-scanner", "cve", "cyclonedx", "llm-security", "security"] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "Intended Audience :: System Administrators", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Environment :: Console", "Topic :: Security", "Topic :: System :: Monitoring", ] dependencies = [ "click>=8.0", "rich>=13.0", "httpx>=0.28.1", # core async HTTP client (CLI, TestClient, registry/OSV fetchers) "httpcore>=1.0.9,<2", # public network-backend API for connect-time gateway DNS pinning "pydantic>=2.0", "cyclonedx-python-lib>=11.6", # Updated for better CycloneDX 1.6 support "packageurl-python>=0.17", "packaging>=24.0", "pathspec>=1.1", "regex>=2026.9.10", # bounded runtime policy matching with engine-enforced timeouts "toml>=0.10", "pyyaml>=6.0", "defusedxml>=0.7.1", # XML manifests (pom.xml, .csproj) are untrusted input "jsonschema>=4.0", # Workstation preset process/listener inventory must work from the base # package. The collector reads names and local bind classes only; it never # captures process arguments, environment values, or remote addresses. "psutil>=5.9", # MCP is a first-class advertised entry point (`uvx agent-bom mcp server`) # and must work from the base package used by the official registry. # SDK 2 provides stateless 2026 MCP and legacy protocol negotiation. "mcp>=2.3,<3", # Transitive dep pins — fix known CVEs flagged by OpenSSF/OSV "certifi>=2026.10.19", # GHSA-6q48-6c7w-9gw2 (compromised emSign intermediate CA keys) "jinja2>=3.1.6", # GHSA-cpwx-vrp4-4pq7, GHSA-gmj6-6f8f-6699 (sandbox breakout) "requests>=2.33.0", # GHSA-9hjg-9r4m-mvj7, GHSA-j8r2-6x86-q33q (session cookie leak) "urllib3>=2.8.0", # CVE-2026-97687, CVE-2026-97689 (proxy TLS isolation and chunk parsing) # NOTE: nltk pin removed — safety (which pulled nltk) was replaced by pip-audit. # nltk is not imported by agent-bom. Keeping it added 3 CVEs to Docker images. "pyjwt>=2.15.0", # CVE-2026-101918 (nested JWT payload error handling) # NOTE: stale pyopenssl suppressions were retired after snowflake-connector-python moved to a compatible range. # Tracked: https://github.com/koda-ai-studio/agent-bom/issues/930 "cryptography>=50.0.0", # CVE-2026-69247; required by audit chain, proxy response signing, and OIDC. # JS/TS source analysis is part of the default scan path. Keep the parser # runtime in the base package so clean PyPI installs do not silently fall # back to regex-only coverage while advertising AST-backed findings. "tree-sitter>=0.26.0", "tree-sitter-javascript>=0.25.0", "tree-sitter-typescript>=0.23.2", "cvss>=3.6,<4", # Finding, job and hub payloads are stored zstd-compressed; `quickstart --run` # writes those rows from a base install. "zstandard>=0.23", ] [project.optional-dependencies] api = [ # API local-path scans use werkzeug.security.safe_join; preserve its security floor. "werkzeug>=3.1.9", # GHSA-g6x2-hccm-hh4m, GHSA-29vq-49wr-vm6x, GHSA-2g68-c3qc-8985, GHSA-87hc-h4r5-73f7, GHSA-f9vj-2wh5-fj8j, GHSA-hgf8-39gv-g3f2, GHSA-hrfv-mqp8-q5rw, GHSA-px8h-6qxv-m22q, GHSA-q34m-jh98-gwm2, GHSA-xg9f-g7g7-2323 "fastapi>=0.115,!=0.136.3", "uvicorn[standard]>=0.49.0", "sse-starlette>=2.1", "starlette>=1.4.1,<2", # GZipMiddleware compresses large bodies in a worker thread (1.4.0; default fixed in 1.4.1) ] otel = [ "opentelemetry-api>=1.45.1", "opentelemetry-sdk>=1.45.1", "opentelemetry-exporter-otlp-proto-http>=1.45.1", "protobuf>=6.33.5", # CVE-2022-1941, CVE-2026-0994 (ParseDict DoS) — transitive via otlp-proto-http ] ui = [ "agent-bom[api]", ] aws = ["boto3>=1.34"] azure = [ "azure-identity>=1.15", "azure-mgmt-resource>=23.0", "azure-mgmt-authorization>=4.0", "azure-mgmt-cognitiveservices>=13.5", "azure-mgmt-web>=7.2", "azure-mgmt-appcontainers>=3.0", "azure-mgmt-containerinstance>=10.1", "azure-mgmt-containerservice>=41.3.0", "azure-mgmt-machinelearningservices>=1.0", "azure-ai-ml>=1.34", # v2 control plane: online endpoints/deployments live here, not in the mgmt SDK "azure-ai-projects>=1.0", "azure-mgmt-compute>=30.0", "azure-mgmt-storage>=21.0", "azure-mgmt-network>=25.0", "azure-mgmt-msi>=7.0", "azure-mgmt-monitor>=6.0", "azure-mgmt-security>=7.0", "azure-mgmt-keyvault>=10.3", "azure-keyvault-keys>=4.8", "azure-keyvault-secrets>=4.7", "azure-mgmt-sql>=3.0", "azure-mgmt-rdbms>=10.1", "azure-mgmt-containerregistry>=15.0.0", "azure-containerregistry>=1.2", "azure-mgmt-cosmosdb>=9.5", "azure-mgmt-managementgroups>=1.0", "azure-mgmt-eventhub>=11.0", "azure-mgmt-servicebus>=8.2", "azure-mgmt-redis>=14.3", "azure-mgmt-frontdoor>=1.1", "azure-mgmt-apimanagement>=4.0", "azure-storage-queue>=12.9", # Scheduled findings export to an Azure Blob sink (#4040). "azure-storage-blob>=12.19", # msrest -> requests-oauthlib; exclude the vulnerable OAuthlib 3.x line. "oauthlib>=4.0.1", "six>=1.17.0", ] gcp = [ "google-cloud-aiplatform>=1.38", "google-cloud-asset>=3.30", "google-cloud-functions>=1.16", "google-cloud-container>=2.36", "google-cloud-run>=0.10", "google-cloud-resource-manager>=1.12", # Estate inventory imports these directly — without them GCP compute/firewall, # IAM service-account, storage, and log discovery silently return empty. "google-cloud-compute>=1.14", "google-cloud-iam>=2.19", "google-cloud-storage>=2.10", "google-cloud-logging>=3.5", "google-cloud-pubsub>=2.18", # The CIS benchmark builds service clients via the discovery API. "google-api-python-client>=2.100", # Scheduled findings export to a BigQuery table sink (#4040). "google-cloud-bigquery>=3.14", # These google.cloud modules are imported (guarded) by the GCP code but were # never declared here, so API Gateway / Artifact Registry / Org Policy # discovery silently no-op unless the package happens to arrive transitively: # apigateway_v1 -> gcp_inventory._discover_api_gateways # artifactregistry_v1 -> registry_sweep (GAR sweep) # orgpolicy_v2 -> gcp_organizations (org-policy constraints) "google-cloud-api-gateway>=1.9", "google-cloud-artifact-registry>=1.11", "google-cloud-org-policy>=1.11", ] coreweave = [] # kubectl only — no pip packages # CIS/control-plane discovery; scheduled warehouse exports use the HTTPS API. databricks = ["databricks-sdk>=0.20"] snowflake = ["snowflake-connector-python>=3.6"] nebius = ["requests>=2.33.0"] # GHSA-9hjg-9r4m-mvj7 (session cookie leak) huggingface = ["huggingface-hub>=0.20"] wandb = ["wandb>=0.16"] # Temporarily unbundled from agent-bom extras until upstream MLflow CVEs are fixed. # MLflow discovery still works if users install `mlflow` separately. openai = ["openai>=1.12"] ai-enrich = [ # 1.96.2 is clear of every litellm advisory on OSV as of 2026-10-24, including # CVE-2026-84377 (SSRF and provider-credential exfiltration). 1.107.0 wheels # were a compromised release (credential stealer, 2026-10-21) and are excluded. "litellm>=1.96.2,!=1.107.0", # Security floors mirrored from [tool.uv].override-dependencies so pip installs # cannot land vulnerable litellm transitives (Closes #3684). "python-dotenv>=1.2.2", "aiohttp>=3.13.4", "openai>=2.30.0", ] graph = [ "networkx>=3.0", "numpy>=1.26", "scipy>=1.13", ] pdf = [] postgres = [ "psycopg[binary]>=3.1", "psycopg-pool>=3.1", "alembic>=1.13", "sqlalchemy>=2.0", ] watch = ["watchdog>=4.0"] runtime = [ "cryptography>=50.0.0", # Proxy audit hash chain + response signing; CVE-2026-69247 floor. ] visual = [ # Visual-leak detection on MCP screenshot/image tool responses. # Opt-in because OCR is CPU-heavy — pilots without screen-capture MCPs # don't pay for pytesseract at runtime. See issue #1568. "Pillow>=13.0.0", # Decoder memory-safety fixes released in 13.0.0. "pytesseract>=0.3.10", ] # MCP ships in the base install; retain the extra for install-command compatibility. mcp-server = [] sigstore = ["sigstore>=4.5.1,<5"] # Optional offline keyless image-signature verification. lake = [ "pyarrow>=15.0", "pyiceberg>=0.11.1", ] sca-import = [] # Supported external scanner reports use base dependencies. snyk = [] # Deprecated packaging alias; retained through the next release for compatibility. interactive = ["prompt-toolkit>=3.0"] oidc = [ "PyJWT>=2.15.0", # CVE-2026-101918 "cryptography>=50.0.0", # CVE-2026-69247 and older non-contiguous-buffer advisories. ] saml = [ "python3-saml>=1.16.0", ] cloud = [ "agent-bom[aws]", "agent-bom[azure]", "agent-bom[gcp]", "agent-bom[databricks]", "agent-bom[snowflake]", "agent-bom[nebius]", "agent-bom[huggingface]", "agent-bom[wandb]", "agent-bom[openai]", ] all = [ # First-run product surfaces only. Dev/docs stay separate, and MLflow stays # intentionally unbundled until its upstream CVE backlog is fixed. "agent-bom[ai-enrich]", "agent-bom[cloud]", "agent-bom[graph]", "agent-bom[interactive]", "agent-bom[mcp-server]", "agent-bom[oidc]", "agent-bom[otel]", "agent-bom[postgres]", "agent-bom[runtime]", "agent-bom[saml]", "agent-bom[ui]", "agent-bom[visual]", "agent-bom[watch]", ] docs = [ "mkdocs-material>=9.5", "mkdocstrings[python]>=0.24", ] dev = [ "pytest>=7.0", "pytest-asyncio>=1.4.0", "ruff>=0.16.7", "mypy>=1.0", "types-PyYAML>=6.0", "types-requests>=2.31", "types-toml>=0.10.8.20260518", "bandit>=1.9", # Static security analysis "pytest-cov>=7.1.0", # Coverage reporting "pytest-benchmark>=5.2.3", # Performance benchmarking — see docs/PERFORMANCE_BENCHMARKS.md "pytest-xdist>=3.5", # Parallel test execution (-n auto) — cuts CI test wall time "pytest-randomly>=3.15", # Randomize test order to surface order-dependence early # API tests import the complete runtime, including the filesystem jail. # Reuse its dependency floors so a dev-only install can collect the suite. "agent-bom[api]", ] dev-all = [ "agent-bom[dev]", "agent-bom[ui]", "agent-bom[mcp-server]", "agent-bom[graph]", "agent-bom[postgres]", ] [project.scripts] agent-bom = "agent_bom.__main__:cli_main" agent-shield = "agent_bom.cli.shield:shield_main" agent-cloud = "agent_bom.cli.cloud:cloud_main" agent-iac = "agent_bom.cli.iac:iac_main" agent-claw = "agent_bom.cli.claw:claw_main" [project.entry-points."agent_bom.cloud_providers"] agent_bom_builtin = "agent_bom.cloud:builtin_provider_registrations" [project.entry-points."agent_bom.connectors"] agent_bom_builtin = "agent_bom.connectors:builtin_connector_registrations" [project.entry-points."agent_bom.inventory_parsers"] agent_bom_builtin = "agent_bom.parsers:builtin_inventory_parser_registrations" [project.urls] Homepage = "https://github.com/koda-ai-studio/agent-bom" Repository = "https://github.com/koda-ai-studio/agent-bom" Issues = "https://github.com/koda-ai-studio/agent-bom/issues" Changelog = "https://github.com/koda-ai-studio/agent-bom/releases" Documentation = "https://koda-ai-studio.github.io/agent-bom/" "Security Policy" = "https://github.com/koda-ai-studio/agent-bom/blob/main/SECURITY.md" "Trust & Permissions" = "https://github.com/koda-ai-studio/agent-bom/blob/main/docs/PERMISSIONS.md" [tool.uv] # Only install core deps by default — extras (cloud, dev) must be explicit. # Prevents `uv sync` from pulling heavy optional deps (azure, gcp, etc.) # which break on Python 3.14 and bloat CI/container builds. default-groups = [] # Override litellm's stale exact transitive pin to avoid CVE-2026-28684. override-dependencies = [ "python-dotenv>=1.2.2", "aiohttp>=3.13.4", "openai>=2.30.0", "gitpython>=3.1.54", # snowflake-connector-python 4.x caps filelock<4, and 5.x ships no musl # wheels for the Alpine image. Its FileLock, BaseFileLock and Timeout use is # unchanged in filelock 4, whose breaking changes are in SoftReadWriteLock. # GHSA-v4x8-3wr5-3wq8, GHSA-9vhv-jxww-xfm5, GHSA-567q-5qvw-pf92. "filelock>=4.2.1", ] [tool.setuptools.packages.find] where = ["src"] [tool.setuptools.package-data] agent_bom = ["mcp_registry.json", "cloud/benchmark_inventory.json", "ui_dist/**", "data/*.json", "demo_estate/data/*.jsonl", "output/vendor/*.js", "output/vendor/*.md"] [tool.smithery] server = "agent_bom.mcp_server:create_smithery_server" [tool.pytest.ini_options] asyncio_mode = "strict" pythonpath = ["src"] # pytest-randomly is ON by default: every run (local + CI — main matrix, # Alpine/musl, Postgres) shuffles test order to keep order-dependence from # creeping back in. Order-independence is enforced structurally by the autouse # reset_global_test_state fixture in tests/conftest.py, which snapshots and # restores every process-global store singleton (the ~35 set_*_store accessors), # the shared Rich output console, the proxy in-memory alert/metric buffers, and # the auth env/config — so a test that swaps a global and skips its own cleanup # cannot leak into the next test regardless of order. A failing run stays # reproducible: pytest-randomly prints "Using --randomly-seed=N"; re-run with # `--randomly-seed=N` to replay the exact order. To force deterministic order # for a one-off local run, pass `-p no:randomly`. addopts = "" # Starlette 1.x recommends an optional TestClient transport that our own # supply-chain scanner currently blocks. Keep the patched framework and its # supported httpx fallback while silencing only this exact upstream migration # warning; all other deprecations remain visible. filterwarnings = [ "ignore:Using `httpx` with `starlette\\.testclient` is deprecated; install `httpx2` instead\\.:DeprecationWarning", ] markers = [ "network: tests that require network access (OSV API)", "slow: slow tests (e.g. large-scale perf benchmarks) — opt-in only", "graph_performance: measured graph scale assertions — graph changes, main, and scheduled evidence only", "output_performance: measured export and API projection scale assertions — dedicated CI lane only", "scan_performance: measured image and manifest scan scale assertions — dedicated CI lane only", "live_cluster: tests that require a reachable local Kubernetes cluster (e.g. kind) — opt-in only", "real_vuln_db_sync: test drives sync_db itself; opts out of the autouse no-download patch", "graph_contract(mode): run the test under AGENT_BOM_GRAPH_CONTRACT=mode instead of strict", ] [tool.mypy] python_version = "3.11" warn_unused_configs = true disallow_untyped_defs = false # Phase 3: enable after remaining untyped modules are reduced check_untyped_defs = true # Phase 2: check bodies of existing untyped functions ignore_missing_imports = true # Third-party stubs (yaml, toml, requests) no_implicit_optional = true warn_redundant_casts = true show_error_codes = true # Phase 3 (per-module): strict typing for the enterprise/compliance surface. # New modules land here first; expand the glob as older modules are retyped. [[tool.mypy.overrides]] module = [ "agent_bom.api.access_review", "agent_bom.api.agent_identity_store", "agent_bom.api.identity_grants", "agent_bom.api.identity_policies", "agent_bom.api.delegation_token", "agent_bom.api.mcp_config_store", "agent_bom.api.postgres_mcp_config", "agent_bom.api.routes.mcp_config", "agent_bom.api.anomaly", "agent_bom.api.audit_log", "agent_bom.api.auth", "agent_bom.api.blueprint_store", "agent_bom.api.postgres_blueprint", "agent_bom.api.routes.blueprints", "agent_bom.api.compliance_hub_store", "agent_bom.api.compliance_signing", "agent_bom.api.connection_crypto", "agent_bom.api.connection_store", "agent_bom.api.cost_forecast", "agent_bom.api.credential_expiry", "agent_bom.api.credential_rotation", "agent_bom.api.credential_store", "agent_bom.api.dashboard_csp", "agent_bom.api.dataset_version_store", "agent_bom.api.drift_incident_store", "agent_bom.api.durable_store", "agent_bom.api.evaluation_store", "agent_bom.api.exception_store", "agent_bom.api.firewall_decision_store", "agent_bom.api.fleet_store", "agent_bom.api.governance_audit_log", "agent_bom.api.idempotency_store", "agent_bom.api.issue_mapping_store", "agent_bom.api.mcp_observation_store", "agent_bom.api.metrics", "agent_bom.api.models", "agent_bom.api.policy_store", "agent_bom.api.postgres_access", "agent_bom.api.postgres_access_review", "agent_bom.api.postgres_agent_identity", "agent_bom.api.postgres_audit", "agent_bom.api.postgres_common", "agent_bom.api.postgres_compliance_hub", "agent_bom.api.postgres_connection", "agent_bom.api.postgres_cost", "agent_bom.api.postgres_runtime_event", "agent_bom.api.postgres_scim", # Phase 1 (#1969): core store/pipeline surface brought under strict typing. # Phase 4 (#1969): findings-list pipeline, store accessors, background # workers, and tenant-retention surface brought under strict typing. "agent_bom.api.finding_cursor", "agent_bom.api.finding_lifecycle", "agent_bom.api.findings_count_cache", "agent_bom.api.versioning", "agent_bom.api.service_registry", "agent_bom.api.readiness", "agent_bom.api.hub_current_payload", "agent_bom.api.hub_reference_store", "agent_bom.api.cost_store", "agent_bom.api.stores", "agent_bom.api.scan_queue", "agent_bom.api.scheduler", "agent_bom.api.connection_scheduler", "agent_bom.api.partition_maintenance", "agent_bom.api.hub_observations_partition", "agent_bom.api.tenant_graph_retention", "agent_bom.api.tenant_graph_retention_store", "agent_bom.api.store", "agent_bom.api.pipeline", "agent_bom.api.hub_payload_codec", "agent_bom.api.hub_reference_payload", "agent_bom.api.credential_ref_validation", "agent_bom.api.shared_auth_state", "agent_bom.api.proxy_replay_store", "agent_bom.api.routes.agent_manifest", "agent_bom.api.routes.assets", "agent_bom.api.routes.cloud_connections", "agent_bom.api.routes.connectors", "agent_bom.api.routes.credentials", "agent_bom.api.routes.datasets", "agent_bom.api.routes.entitlements", "agent_bom.api.routes.evaluations", "agent_bom.api.routes.frameworks", "agent_bom.api.routes.intel", "agent_bom.api.routes.plugins", "agent_bom.api.routes.posture_streaming", "agent_bom.api.routes.privacy", "agent_bom.api.routes.runtime_blueprints", "agent_bom.api.runtime_event_store", "agent_bom.api.scan_batches", "agent_bom.api.scan_job_reconciliation", "agent_bom.api.schedule_store", "agent_bom.api.scim", "agent_bom.api.scim_store", "agent_bom.api.secret_lifecycle", "agent_bom.api.secret_rotation_adapters", "agent_bom.api.source_store", "agent_bom.api.storage.sql", "agent_bom.api.storage.jobs", "agent_bom.api.storage.jobs_schema", "agent_bom.api.storage.finding_reads", "agent_bom.api.storage.finding_ledger_writes", "agent_bom.api.storage.finding_current", "agent_bom.api.storage.finding_current_reads", "agent_bom.api.storage.finding_current_writes", "agent_bom.api.storage.finding_write_session", "agent_bom.api.storage.finding_payloads", "agent_bom.api.storage_schema", "agent_bom.api.tenancy", "agent_bom.api.tenant_quota", "agent_bom.api.tenant_quota_store", "agent_bom.api.tracing", "agent_bom.api.webhook_store", "agent_bom.models", "agent_bom.cloud.connection_broker", "agent_bom.backpressure", "agent_bom.proxy_sandbox", "agent_bom.capabilities", "agent_bom.routing", "agent_bom.orchestration", "agent_bom.components.base", "agent_bom.components.enricher_registry", "agent_bom.components.matcher_registry", # Phase 6 (#1969): remaining api/ surface — routes, stores, workers, # graph/inventory/report/gateway modules — brought under strict typing. "agent_bom.api", "agent_bom.api.browser_session", "agent_bom.api.campaign_store", "agent_bom.api.clickhouse_store", "agent_bom.api.exec_score_config", "agent_bom.api.export_destination_store", "agent_bom.api.export_schedule_store", "agent_bom.api.export_scheduler", "agent_bom.api.graph_store", "agent_bom.api.graph_store_base", "agent_bom.api.graph_store_correlation", "agent_bom.api.graph_store_pages", "agent_bom.api.graph_store_snapshots", "agent_bom.api.graph_store_support", "agent_bom.api.graph_store_traversal", "agent_bom.api.hitl_approval_queue", "agent_bom.api.hitl_approval_store", "agent_bom.api.hub_ingest", "agent_bom.api.hub_overview_cache", "agent_bom.api.inventory_service", "agent_bom.api.kspm_posture_store", "agent_bom.api.middleware", "agent_bom.api.model_key_broker", "agent_bom.api.neptune_graph", "agent_bom.api.oauth_as", "agent_bom.api.oidc_browser", "agent_bom.api.oidc_discovery_shim", "agent_bom.api.postgres_auth", "agent_bom.api.postgres_campaign", "agent_bom.api.postgres_governance_audit", "agent_bom.api.postgres_graph", "agent_bom.api.postgres_job_store", "agent_bom.api.postgres_model_key_broker", "agent_bom.api.postgres_policy", "agent_bom.api.postgres_scan_snapshot", "agent_bom.api.postgres_store", "agent_bom.api.postgres_tenant_score_config", "agent_bom.api.repo_tree_scan", "agent_bom.api.report_artifact_store", "agent_bom.api.report_job_store", "agent_bom.api.report_worker", "agent_bom.api.risk_campaigns", "agent_bom.api.routes", "agent_bom.api.routes.campaigns", "agent_bom.api.routes.cloud", "agent_bom.api.routes.compliance", "agent_bom.api.routes.discovery", "agent_bom.api.routes.enterprise", "agent_bom.api.routes.estate", "agent_bom.api.routes.exports", "agent_bom.api.routes.fleet", "agent_bom.api.routes.gateway", "agent_bom.api.routes.gateway_feed", "agent_bom.api.routes.governance", "agent_bom.api.routes.graph", "agent_bom.api.routes.identities", "agent_bom.api.routes.inventory_assets", "agent_bom.api.routes.kspm", "agent_bom.api.routes.mitre", "agent_bom.api.routes.model_keys", "agent_bom.api.routes.observability", "agent_bom.api.routes.overview", "agent_bom.api.routes.proxy", "agent_bom.api.routes.reports", "agent_bom.api.routes.scan", "agent_bom.api.routes.schedules", "agent_bom.api.routes.scim", "agent_bom.api.routes.self_posture", "agent_bom.api.routes.sources", "agent_bom.api.routes.ticketing", "agent_bom.api.routes.webhooks", "agent_bom.api.saml", "agent_bom.api.scan_snapshot", "agent_bom.api.scan_snapshot_store", "agent_bom.api.secret_source", "agent_bom.api.server", "agent_bom.api.snowflake_oauth", "agent_bom.api.snowflake_store", "agent_bom.api.tenant_score_config_store", "agent_bom.api.trace_explorer", ] disallow_untyped_defs = true disallow_incomplete_defs = true warn_return_any = true warn_unused_ignores = true # Phase 2+5 (#1969): modules brought under the stricter profile that also # bans implicit ``Any`` generics (``dict``/``list`` without parameters). # Applied module-by-module; expand this list as each module is de-genericized. # Not a global flip — the base [tool.mypy] settings stay unchanged. [[tool.mypy.overrides]] module = [ "agent_bom.models", "agent_bom.api.findings_current", "agent_bom.api.oidc", "agent_bom.api.postgres_fleet_store", "agent_bom.api.finding_list_envelope", "agent_bom.api.time_window", "agent_bom.api.cost_owner", "agent_bom.api.gateway_relay_admission", "agent_bom.api.gateway_relay_context", "agent_bom.api.gateway_relay_identity", "agent_bom.api.gateway_relay_pipeline", "agent_bom.api.gateway_relay_profile", "agent_bom.api.gateway_relay_reachability", "agent_bom.api.gateway_relay_tool_policy", ] disallow_untyped_defs = true disallow_incomplete_defs = true disallow_any_generics = true warn_return_any = true warn_unused_ignores = true [tool.ruff] line-length = 140 # Relaxed from 120 for CLI help strings target-version = "py311" [tool.ruff.lint] # T201 = `print` found: library code under src/agent_bom/ routes all # user-visible output through Rich (``console.print``) and everything else # through the structured logger (``logging.getLogger(__name__)``). Bare # ``print()`` is not allowed — it breaks MCP stdio, corrupts JSON API # responses, and skips log aggregation / SIEM forwarding. This rule locks # in the print -> logger migration (closes #1521). select = ["E", "F", "I", "N", "T201", "W"] ignore = [] [tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"] # Allow unused imports in __init__.py ".clusterfuzzlite/fuzz/*.py" = ["N802", "T201"] # TestOneInput is required atheris entry; harnesses print repro output "src/agent_bom/output/html/*.py" = ["E501", "F541"] # Inline HTML/CSS/JS template strings cannot be wrapped; f-prefix is load-bearing (unescapes `{{`) "scripts/generate_doc_architecture_svgs.py" = ["E501"] # SVG coordinate strings are intentionally single-line "scripts/ai_triage_dataset_cases.py" = ["E501"] # One public fact per line keeps the label basis reviewable "scripts/ai_triage_dataset_cases_v2.py" = ["E501"] # One public fact per line keeps the label basis reviewable "scripts/build_ai_triage_dataset_v2.py" = ["E501"] # Label-basis sentences stay whole "scripts/ai_explain_eval.py" = ["E501"] # The published table row reads as one line "src/agent_bom/ai_components/triage.py" = ["E501"] # Prompt paragraphs are hashed and recorded; wrapping would change them "src/agent_bom/ai_components/graph_explain.py" = ["E501"] # Prompt paragraphs are hashed; wrapping would change them "deploy/supabase/postgres/alembic/versions/20261105_04_ai_assessments.py" = ["E501"] # Literal DDL matches runtime-schema.sql line for line "tests/fixtures/analysis_characterization/**" = ["I001"] # Golden analyzer inputs: reordering imports shifts the recorded line numbers "tests/fixtures/taint_characterization/**" = ["I001"] # Golden taint inputs: reordering imports shifts the recorded line numbers # T201 allowlist — places where bare `print()` is legitimately the contract: "scripts/*.py" = ["T201"] # Ops scripts — stdout is the documented interface "tests/**/*.py" = ["T201"] # Pytest assertions + debug tracebacks