|
| 1 | +# Contributing to AI-Factory |
| 2 | + |
| 3 | +Thanks for helping improve AI-Factory v2.1. This document is the entry point for contributors; deeper operator and security detail lives under [`docs/`](docs/README.md). |
| 4 | + |
| 5 | +## What you are working on |
| 6 | + |
| 7 | +- **Backend:** FastAPI (`web/backend/`), pipeline worker (`pipeline_worker.py`), agents (`agents/`), orchestrator (`orchestrator/`). |
| 8 | +- **Frontend:** Next.js admin + storefront (`web/frontend/`). |
| 9 | +- **Config:** Layered YAML in `config/fragments/` with an optional overlay in [`config.yaml`](config.yaml) (intentionally empty in git — Admin → Settings persists overrides there). |
| 10 | +- **Data:** Runtime state under `data/` (bind-mounted in Docker). **Do not commit** `data/users.json`, secrets, orders, or local methodology case dumps. |
| 11 | + |
| 12 | +## Prerequisites |
| 13 | + |
| 14 | +- **Python 3.12+** |
| 15 | +- **Node.js 20+** (frontend) |
| 16 | +- **Docker Compose V2** (recommended for full-stack dev and sandbox previews) |
| 17 | +- At least one **LLM API key** (e.g. `DEEPSEEK_API_KEY` in `.env`) |
| 18 | + |
| 19 | +## Local setup |
| 20 | + |
| 21 | +```bash |
| 22 | +git clone <your-fork-url> |
| 23 | +cd aicom |
| 24 | +cp -n .env.example .env # add API keys; never commit .env |
| 25 | + |
| 26 | +python3 -m venv .venv |
| 27 | +source .venv/bin/activate |
| 28 | +pip install -r requirements.txt |
| 29 | +python -m playwright install chromium # E2E / visual tests |
| 30 | + |
| 31 | +cd web/frontend && npm ci && cd ../.. |
| 32 | +``` |
| 33 | + |
| 34 | +**Docker (closest to production):** |
| 35 | + |
| 36 | +```bash |
| 37 | +./scripts/deploy.sh --public-url http://localhost:9080 |
| 38 | +# Frontend http://localhost:9080 · API http://localhost:9081/api/health |
| 39 | +``` |
| 40 | + |
| 41 | +First admin password: interactive TTY (`docker compose run --rm -it app`) or one-time file `data/secrets/bootstrap_admin.txt` on headless `up -d`. See [`docs/security.md`](docs/security.md). |
| 42 | + |
| 43 | +## Development workflow |
| 44 | + |
| 45 | +1. Fork the repo and branch from `main` (`feat/…`, `fix/…`). |
| 46 | +2. Keep pull requests **focused** — one behavioral change per PR when possible. |
| 47 | +3. Change **code, tests, and docs** together when behavior or env vars change. |
| 48 | +4. Run the relevant checks locally (below) before opening a PR. |
| 49 | +5. Do **not** commit secrets, wallet keys, or production hostnames unless they are public examples. |
| 50 | + |
| 51 | +## Local checks |
| 52 | + |
| 53 | +> **Read [`docs/testing-rules.md`](docs/testing-rules.md) first** — codebase-specific testing rules |
| 54 | +> (SQLite field-persistence trap, end-to-end loop tracing, the ruff gate, cold-start tests). Each |
| 55 | +> comes from a bug that passed unit tests and still broke production. |
| 56 | +
|
| 57 | +Run what your change touches; CI will run the rest on `main` / PRs. |
| 58 | + |
| 59 | +| Check | Command | |
| 60 | +|--------|---------| |
| 61 | +| **Full backend tests** | `USE_SQLITE=true .venv/bin/pytest -q` | |
| 62 | +| **Security benchmark** | `bash scripts/run_security_benchmark.sh` | |
| 63 | +| **Single test file** | `.venv/bin/pytest tests/test_<name>.py -q` | |
| 64 | +| **Python syntax (touched files)** | `python3 -m py_compile path/to/file.py` | |
| 65 | +| **Frontend build** | `cd web/frontend && npm run build` | |
| 66 | +| **OpenAPI schema** | `.venv/bin/python -c "from web.backend.main import app; app.openapi()"` | |
| 67 | + |
| 68 | +**Playwright:** required for browser/E2E jobs (`python -m playwright install chromium --with-deps` on Linux CI). |
| 69 | + |
| 70 | +**Pipeline worker locally:** `USE_SQLITE=true .venv/bin/python pipeline_worker.py` (needs configured providers and `data/state/`). The worker uses **event-driven wake** (`signal_new_work()`) with adaptive idle polling — see `AIFACTORY_PIPELINE_*_POLL_SEC` in [`docs/configuration.md`](docs/configuration.md). |
| 71 | + |
| 72 | +## Continuous integration |
| 73 | + |
| 74 | +GitHub Actions workflow [`.github/workflows/ci.yml`](.github/workflows/ci.yml): |
| 75 | + |
| 76 | +| Job | Purpose | |
| 77 | +|-----|---------| |
| 78 | +| `backend-tests` | Full `pytest -q` with SQLite | |
| 79 | +| `security-benchmark` | CSRF, firewall, audit chain, sandbox hardening, LLM usage guard, admin auth, WebAuthn helpers | |
| 80 | +| `visual-standards-e2e` | Playwright visual standards | |
| 81 | +| `browser-login-e2e` | FastAPI preview + declarative login crawl | |
| 82 | +| `customer-api-smoke` | Uvicorn + `scripts/customer_journey_e2e.py` | |
| 83 | +| `frontend-build` | `npm ci` + `npm run build` | |
| 84 | + |
| 85 | +## Security-related contributions |
| 86 | + |
| 87 | +Read [`docs/security.md`](docs/security.md) before changing auth, sandbox, firewall, or audit code. |
| 88 | + |
| 89 | +| Area | Notes | |
| 90 | +|------|--------| |
| 91 | +| **Admin auth** | JWT in `data/secrets/jwt_secret.key`; CSRF on cookie sessions; TOTP or **WebAuthn passkeys** (`mfa_method`). | |
| 92 | +| **Sandbox** | Prefer **container** mode in production (`AIFACTORY_SANDBOX_REQUIRE_CONTAINER=1`). Process fallback is dev-only. | |
| 93 | +| **Audit** | Tamper-evident hash chain under `data/logs/audit/`; pipeline **agent handoffs** use action `agent_handoff`. | |
| 94 | +| **LLM caps** | `LLMUsageGuard` is cross-worker (file lock on `llm_usage_guard.json`). | |
| 95 | + |
| 96 | +Add or extend tests under `tests/test_security*.py`, `tests/test_csrf_middleware.py`, `tests/test_firewall_*.py`, `tests/test_sandbox_*.py`, `tests/test_agent_handoff_audit.py`. |
| 97 | + |
| 98 | +## Configuration and migrations |
| 99 | + |
| 100 | +- **Env vars:** document new keys in [`.env.example`](.env.example) and [`docs/configuration.md`](docs/configuration.md). |
| 101 | +- **LLM provider IDs:** canonical names live in [`llm/provider_ids.py`](llm/provider_ids.py). Legacy ids (`deep-seek` → `deepseek_api`) are auto-migrated on API startup when `AIFACTORY_AUTO_MIGRATE_PROVIDER_IDS=1` (default). Manual run: `python scripts/migrate_llm_calls_provider_ids.py`. |
| 102 | +- **Deploy helper:** [`scripts/fill_production_env.py`](scripts/fill_production_env.py) appends **missing** production keys only (never overwrites your `.env`). |
| 103 | + |
| 104 | +## API documentation |
| 105 | + |
| 106 | +- Swagger UI: `/api/docs` (proxied via frontend at `http://localhost:9080/api/docs` in Compose). |
| 107 | +- Hand-crafted OpenAPI metadata: [`web/backend/openapi_meta.py`](web/backend/openapi_meta.py). Prefer adding `summary` / `description` on new FastAPI routes. |
| 108 | +- Integration guide: [`docs/api-integration-guide.md`](docs/api-integration-guide.md). |
| 109 | + |
| 110 | +## Pull request checklist |
| 111 | + |
| 112 | +- [ ] **Why** — problem and intended outcome in the PR description. |
| 113 | +- [ ] **Test plan** — commands run and observed results (copy-paste friendly). |
| 114 | +- [ ] **Config/env** — new variables listed in `.env.example` + `docs/configuration.md` if applicable. |
| 115 | +- [ ] **Secrets** — none in diff; no accidental `data/` commits. |
| 116 | +- [ ] **Compatibility** — note API, pipeline state, or admin UI breaking changes. |
| 117 | +- [ ] **Security** — if touching auth/sandbox/audit, mention threat model and link tests added. |
| 118 | + |
| 119 | +## Commit messages |
| 120 | + |
| 121 | +- Imperative, concise subject (≤72 chars when possible). |
| 122 | +- Body explains **why**, not only what. |
| 123 | +- Examples: |
| 124 | + - `Harden sandbox Docker defaults when container mode is required` |
| 125 | + - `Validate store orders with Pydantic before revenue aggregation` |
| 126 | + |
| 127 | +## Code style |
| 128 | + |
| 129 | +- Match surrounding modules (naming, imports, logging). |
| 130 | +- Prefer extending existing helpers over duplicating logic. |
| 131 | +- New Python modules: add **type hints** on public functions; agents are being migrated incrementally — add hints when you touch a file. |
| 132 | +- Keep diffs focused; avoid drive-by refactors unrelated to the PR. |
| 133 | + |
| 134 | +## Reporting bugs and proposing features |
| 135 | + |
| 136 | +Open an issue with: |
| 137 | + |
| 138 | +1. **Expected** vs **actual** behavior |
| 139 | +2. **Reproduction steps** (commands, env, product id if pipeline-related) |
| 140 | +3. **Logs** or screenshots (redact secrets) |
| 141 | +4. **Version** — commit hash or image tag |
| 142 | + |
| 143 | +## Good first contributions |
| 144 | + |
| 145 | +- Clarify docs ([`docs/README.md`](docs/README.md) index). |
| 146 | +- Add focused tests for pipeline state transitions, quality gates, or finance aggregation. |
| 147 | +- Improve admin UI filters, error messages, or observability panels. |
| 148 | +- Per-route OpenAPI `summary` / `description` on heavily used admin endpoints. |
| 149 | + |
| 150 | +Use the **good first issue** template when opening starter tasks. Audit follow-ups (no grants): [`docs/audit-remediation.md`](docs/audit-remediation.md). |
| 151 | + |
| 152 | +## Security scans (before PR) |
| 153 | + |
| 154 | +```bash |
| 155 | +./scripts/run_security_benchmark.sh # pytest security subset |
| 156 | +./scripts/run_dependency_audit.sh # bandit + pip-audit + npm audit |
| 157 | +``` |
| 158 | +- Type hints on a single agent module you are already modifying. |
| 159 | + |
| 160 | +## Where to read more |
| 161 | + |
| 162 | +| Topic | Doc | |
| 163 | +|--------|-----| |
| 164 | +| Security | [`docs/security.md`](docs/security.md) | |
| 165 | +| Configuration | [`docs/configuration.md`](docs/configuration.md) | |
| 166 | +| Pipeline ops | [`docs/pipeline-operations.md`](docs/pipeline-operations.md) | |
| 167 | +| Admin UI | [`docs/admin-guide.md`](docs/admin-guide.md) | |
| 168 | +| Agents | [`docs/agents.md`](docs/agents.md) | |
| 169 | +| Architecture | [`docs/architecture-orchestrator.md`](docs/architecture-orchestrator.md) | |
| 170 | + |
| 171 | +Questions about scope? Open an issue before a large refactor. For production deployments, see [`docs/production-domain.md`](docs/production-domain.md) and [`README.md`](README.md). |
0 commit comments