1 line
9.4 KiB
JSON
1 line
9.4 KiB
JSON
{"repo": "aminueza/cloudlens", "files": {"agents.md": {"e4a5e98a231ba12149e9555e0f25be877115da8d": {"t": 1785596410.0798852, "n": 8822, "h": "b3f9ebd5fa1aaf8d", "c": "# AI Agent Rules — CloudLens\n\n> Read this FIRST before touching any code. These rules prevent the mistakes that matter.\n\n---\n\n## Core Principles\n\n- **Simplicity First** — Make every change as simple as possible. Minimal code impact.\n- **No Laziness** — Find root causes. No temporary fixes. Senior developer standards.\n- **Minimal Impact** — Only touch what's necessary. Don't introduce bugs.\n- **Prove It Works** — Never say \"done\" without running tests or showing evidence.\n\n---\n\n## The Project\n\nAI-powered multi-cloud network intelligence platform for SREs — monitors topology across AWS, Azure, and GCP, detects changes, evaluates compliance, analyzes blast radius, manages incidents, and provides AI-powered insights via Claude API. Not a dashboard — a network operations copilot.\n\n**Stack:** Python 3.12 · FastAPI · D3.js · boto3 (AWS) · Azure Resource Graph (Azure) · GCP Compute (stub) · aiosqlite · Anthropic Claude · Pydantic · Prometheus · SlowAPI · Black (formatter)\n\n**Architecture:** `config/ → providers/ → graph/ → api/ → frontend` + `db/` (persistence) + `engine/` (analysis) + `ai/` (intelligence)\n\n---\n\n## Hard Rules (Break These = Break the Project)\n\n| Rule | Why |\n|---|---|\n| Never import cloud SDKs outside `providers/` | One coupling point per provider. Core logic is cloud-agnostic. |\n| Provider modules implement `ProviderInterface` | Swap or add providers without touching core code. |\n| Never return raw dicts from API routes | Pydantic response models on every endpoint. |\n| Never duplicate resource-mapping logic | It lives once in `graph/helpers.py`. |\n| Never duplicate constants | Icons, colors, labels → `graph/constants.py`. |\n| Never hardcode config | All settings via `pydantic-settings` from env vars. |\n| Range-pin every dependency | `>=X,<Y` in `pyproject.toml`. Cloud SDKs are optional extras. |\n| Python ≥ 3.12 | Use `X | Y` unions, f-strings, type hints everywhere. |\n| Async-first | Blocking cloud SDK calls go through `asyncio.to_thread`. |\n| Ruff target py312, line length 120 | `ruff check .` must pass clean. |\n| Black for formatting | `black --check .` must pass clean. |\n| Never block startup on auth | Provider clients init without validating credentials. |\n| Never swallow auth errors silently | Auth failures propagate to frontend via provider error state. |\n| Single uvicorn worker | BackgroundFetcher + SQLite are not multi-process safe. |\n| AI reads settings, not os.environ | Use `settings.ANTHROPIC_API_KEY` and `settings.AI_MODEL`. |\n\n---\n\n## Project Layout\n\n```\nconfig/ Settings (pydantic-settings), structured logging\nproviders/ Cloud provider abstraction layer\n base.py ProviderInterface ABC + NetworkResource/NetworkPeering dataclasses\n registry.py Auto-discovers and loads enabled providers\n fetcher.py BackgroundFetcher — polls, caches, persists, runs analysis, SSE\n aws/client.py AWS EC2/VPC API queries → normalized NetworkResource\n azure/client.py Azure Resource Graph KQL → normalized NetworkResource\n azure/queries.py KQL strings + AZURE_TYPE_MAP\n gcp/client.py GCP stub (returns empty lists when SDK not installed)\ngraph/ Cloud-agnostic graph builders, constants, helpers\n builder.py build_graph() [flat] + build_structured_graph() [hierarchical]\n constants.py TYPE_LABELS, TYPE_ICONS, TYPE_COLORS, PROVIDER_COLORS, ENV_COLORS\n helpers.py safe_id, find_network_for_resource, build_resource_index\ndb/ SQLite persistence via aiosqlite\n session.py Schema (7 tables), connection management, default compliance rules\n repository.py CRUD for snapshots, changes, incidents, compliance, health, AI\nengine/ Cloud-agnostic analysis engines\n diff.py Topology diff — compares snapshots, detects changes with severity\n health.py 10 health checks + A-F scoring\n compliance.py Configurable rules engine (6 rule types)\n blast_radius.py Impact analysis + Tarjan's algorithm for critical nodes\nai/ Claude API integration\n analyzer.py NL queries, change analysis, anomaly detection, incident RCA, compliance recs\napi/ FastAPI app, routes, middleware, models\n app.py Lifespan (DB init, provider registry, fetcher), middleware stack\n auth.py Pluggable auth middleware (API key / disabled for dev)\n errors.py CloudLensError + exception handlers\n models.py Pydantic response models\n ratelimit.py slowapi limiter\n routes/ accounts, topology, export, changes, health_checks, compliance, incidents, ai_routes\nexporters/ SVG diagram renderer\ntemplates/ index.html — Jinja2 SPA\nstatic/css/ dashboard.css (dark/light, 14px base)\nstatic/js/ graph.js — D3.js viz, provider badges, AI chat, incidents\ntests/ pytest — 32 tests across 7 files\n```\n\n---\n\n## Key Data Flow\n\n```\nSettings (pydantic-settings, env vars)\n ↓\nProviderRegistry (loads enabled providers: aws, azure, gcp)\n ↓\nAuto-discovery (Azure subscriptions, AWS regions/account, GCP projects)\n ↓\nBackgroundFetcher._poll_loop()\n ↓\n┌─────────────┬───────────────────┬──────────────┐\n│ AWS EC2 API │ Azure Resource │ GCP Compute │\n│ (boto3) │ Graph (KQL) │ (stub) │\n└──────┬──────┴────────┬──────────┴──────┬───────┘\n └───────────────┼─────────────────┘\n ↓\n Normalizer (NetworkResource dataclass)\n ↓\n ┌───────────────┼───────────────┐\n ↓ ↓\nGraph Builders Analysis Engine\n(D3.js hierarchical) (diff, health, compliance, blast radius)\n ↓ ↓\n └──────── FastAPI Routes ───────┘\n ↓\n SQLite (snapshots, changes, incidents, compliance, health)\n ↓\n D3.js Frontend (SSE auto-refresh, AI chat panel)\n ↓\n Claude AI (NL queries, change analysis, RCA, anomaly detection)\n```\n\n---\n\n## Environment Variables\n\n| Variable | Default | Purpose |\n|---|---|---|\n| `ENABLED_PROVIDERS` | `azure` | Comma-separated: aws, azure, gcp |\n| `CLOUDLENS_POLL_INTERVAL` | `300` | Background fetch interval (seconds) |\n| `CLOUDLENS_AUTH_DISABLED` | `false` | Skip auth (for local dev) |\n| `CLOUDLENS_AUTH_PUBLIC_PATHS` | `/health,/metrics,/static,...,/api/events,/api/auth/status` | Auth-exempt paths |\n| `CLOUDLENS_CORS_ORIGINS` | `*` | Allowed CORS origins |\n| `ANTHROPIC_API_KEY` | `\"\"` | Claude API key (optional) |\n| `AI_MODEL` | `claude-sonnet-4-20250514` | Claude model |\n| `DB_PATH` | `data/cloudlens.db` | SQLite database path |\n| `SNAPSHOT_RETENTION` | `100` | Max snapshots per scope |\n\n## Commands\n\n```bash\nCLOUDLENS_AUTH_DISABLED=true python3 main.py # Run locally\nANTHROPIC_API_KEY=sk-... CLOUDLENS_AUTH_DISABLED=true python3 main.py # With AI\npytest tests/ -v # Tests\nruff check . # Lint\nblack --check . # Format check\nmypy config graph db engine ai api providers exporters # Type check\ndocker build -t cloudlens . # Build container\n```\n\n---\n\n## Playbooks\n\n### Add a New Cloud Provider\n1. Create `providers/{name}/client.py` implementing `ProviderInterface`\n2. Add optional dep in `pyproject.toml`: `[project.optional-dependencies.{name}]`\n3. Register in `providers/registry.py`\n4. Implement `get_discovered_accounts()` to return discovered accounts\n5. No changes needed in graph/, engine/, ai/, api/ — they're cloud-agnostic\n\n### Add a New Resource Type\n1. `graph/constants.py` — add to TYPE_LABELS, TYPE_ICONS, TYPE_COLORS\n2. `providers/{cloud}/client.py` — normalize to existing or new type in fetch methods\n3. `graph/builder.py` — already handles any type via constants lookup\n\n### Add a Compliance Rule Type\n1. `engine/compliance.py` — add handler function + register in `_RULE_HANDLERS`\n2. `db/session.py` — optionally add a default rule in `DEFAULT_RULES`\n\n### Add a Health Check\n1. `engine/health.py` — add `_check_*` function + call from `run_health_checks`\n\n---\n\n## Gotchas\n\n- `graph.js` is ~400 lines — search within it, don't read fully\n- Accounts are auto-discovered at runtime — no static config needed\n- BackgroundFetcher pauses per-provider on auth failure (60s retry)\n- Cloud SDKs are optional: `pip install cloudlens[aws]`, `cloudlens[azure]`, `cloudlens[all-providers]`\n- GCP is a stub — returns empty lists, no actual API calls\n- AI degrades gracefully without ANTHROPIC_API_KEY\n- `data/cloudlens.db` is gitignored — created at runtime\n- Provider-specific code NEVER leaks into graph/, engine/, ai/, or api/\n"}}}} |