# Contributor handoff — langgenius/dify

> Canonical page: https://codevetter.com/unpack/dify/agent-handoff

# Contributor handoff — langgenius/dify

Scanned commit 3a017e8cccb316f23f601af65d2e8ce92e68f788 (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

This repo is agent-aware: layered AGENTS.md files (root, api/, web/, cli/, e2e/, dify-agent/) define per-area rules that must be read before editing. Backend work runs through `uv run --project api` and root `make` targets; frontend through pnpm/vp; CLI through pnpm with generated artifacts. Generated files (docker-compose.yaml, tree.generated.ts, contracts/generated, openapi specs) must never be hand-edited. The dominant correctness disciplines are tenant scoping, explicit bounded transactions, SSRF-routed egress, Pydantic v2 contracts at controller boundaries, and idempotent Celery tasks.
- Read the nearest AGENTS.md before editing: root `AGENTS.md` (repo gotchas: `uv run --project api`, integration tests CI-only, docker env layering), `api/AGENTS.md` (layer boundaries + typing rules), `web/AGENTS.md` (contracts/i18n/dify-ui + 'this is NOT the Next.js you know' warning), `cli/AGENTS.md` + `cli/ARD.md` (command structure), `e2e/AGENTS.md` (runtime ownership). — [AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/AGENTS.md) [api/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/AGENTS.md) [web/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/web/AGENTS.md) [cli/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/cli/AGENTS.md) [e2e/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/e2e/AGENTS.md)
- Backend commands: `make lint` (ruff format+check --fix + `api-contract-lint` + `lint-imports` + `dotenv-linter`), `make type-check` (pyrefly + mypy), `make test` / `make test TARGET_TESTS=./api/tests/<path>`; direct Python via `uv run --project api`. — [Makefile#L68-120](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/Makefile#L68-L120) [api/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/AGENTS.md)
- Layer rule: transport parsing/serialization stays in controllers, orchestration in `services/`, domain policy in `core/` or its domain owner; `libs/` must stay business-agnostic. Pydantic v2 models for req/resp; domain exceptions are translated at the controller boundary (see `ChatApi.post`'s long except-chain). — [api/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/AGENTS.md) [api/controllers/web/completion.py#L219-263](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/controllers/web/completion.py#L219-L263)
- Never hand-edit generated artifacts: `docker/docker-compose.yaml` (edit `docker-compose-template.yaml`/`envs` + regenerate via `docker/generate_docker_compose`), `cli/src/commands/tree.generated.ts` (`pnpm tree:gen`), `packages/contracts/generated/*` (regen via `gen-api-contract`), and generated API specs. — [docker/docker-compose.yaml#L1-5](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/docker/docker-compose.yaml#L1-L5) [cli/src/commands/tree.generated.ts#L1-4](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/cli/src/commands/tree.generated.ts#L1-L4) [packages/contracts/package.json#L37-38](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/packages/contracts/package.json#L37-L38)
- Tenant safety is the #1 trap: scope every tenant-owned read/write by the complete owner chain, propagate `tenant_id` across layers, and rehydrate trusted entities from DB state after payload/async boundaries (pattern: `workflow_execute_task` reloads everything from `AppExecutionParams` ids). — [api/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/AGENTS.md) [api/tasks/app_generate/workflow_execute_task.py](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/tasks/app_generate/workflow_execute_task.py)
- Egress/storage/config discipline: read config only via `configs.dify_config`, storage only via `extensions.ext_storage.storage`, and outbound HTTP only via `core.helper.ssrf_proxy` (or `core.file.remote_fetcher` for remote files). — [api/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/AGENTS.md) [api/core/helper/ssrf_proxy.py#L1-13](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/core/helper/ssrf_proxy.py#L1-L13)
- Celery discipline: tasks that may retry must keep side effects idempotent and log affected resource ids; keep write transactions explicit/bounded and never do external I/O inside an open transaction unless a documented consistency contract requires it. — [api/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/AGENTS.md)
- Monkey-patching order is load-bearing: `app.py`'s `if __name__ == "__main__"` gevent patch must precede socket/lock imports; gunicorn (`gevent` worker class) and Celery (`celery_entrypoint.py`) do their own patching — adding imports above the patch block freezes the process. — [api/app.py#L3-21](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/app.py#L3-L21) [api/celery_entrypoint.py#L1-13](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/celery_entrypoint.py#L1-L13) [api/gunicorn.conf.py](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/gunicorn.conf.py)
- `/system-features` is a minimal unauthenticated bootstrap allowlist, not a config registry — before touching controller schemas or `SystemFeatureModel`, read `controllers/API_SCHEMA_GUIDE.md`. — [api/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/AGENTS.md) [api/controllers/API_SCHEMA_GUIDE.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/controllers/API_SCHEMA_GUIDE.md)
- Frontend: use generated `consoleQuery`/`consoleClient` from `@/service/console` for backend calls (no handwritten REST/DTO mirrors); user strings must add keys in `web/i18n/locales/en-US/` and update every locale; prefer `@langgenius/dify-ui/*` primitives per the linked contracts in `web/AGENTS.md`. — [web/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/web/AGENTS.md) [web/service/console/index.ts](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/web/service/console/index.ts)
- Version is unified at 1.17.1 across `api/pyproject.toml`, `web/package.json`, `cli/package.json`, `dify-agent/pyproject.toml` and the compose image tags (`langgenius/dify-api:1.17.1`, `dify-web:1.17.1`, `dify-agent-backend:1.17.1`) — bump coherently. — [api/pyproject.toml#L1-4](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/pyproject.toml#L1-L4) [web/package.json#L2-3](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/web/package.json#L2-L3) [docker/docker-compose.yaml#L229-388](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/docker/docker-compose.yaml#L229-L388)
- Tests an agent can actually run locally: `make test` (unit only), `pnpm -C web test`/`vp test`, `pnpm -C cli test`, `cd dify-agent && make test`, `go test ./...` in dify-agent-runtime. Docker-backed integration, VDB smoke, and e2e are CI-only/opt-in — do not start long-running services during routine work. — [Makefile#L104-153](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/Makefile#L104-L153) [api/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/AGENTS.md) [cli/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/cli/AGENTS.md) [dify-agent/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/dify-agent/AGENTS.md)
- Error-surface convention: each blueprint namespace maps domain errors to HTTP errors in `controllers/<surface>/error.py` (e.g. `web/error.py`, `console/error.py` with `UnauthorizedAndForceLogout`); reuse these instead of raising raw werkzeug exceptions from services. — [api/controllers/web/completion.py#L13-24](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/controllers/web/completion.py#L13-L24) [api/controllers/console/error.py](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/controllers/console/error.py)
- Files an agent must read first for backend changes: `api/app_factory.py` (ext order + license gate), `api/configs/app_config.py` (settings pipeline), `api/services/app_generate_service.py` (primary dispatch), the target module's docstrings ('local contracts' per AGENTS.md), and `controllers/API_SCHEMA_GUIDE.md` when touching response schemas. (inferred) — [api/AGENTS.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/AGENTS.md) [api/app_factory.py](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/app_factory.py) [api/controllers/API_SCHEMA_GUIDE.md](https://github.com/langgenius/dify/blob/3a017e8cccb316f23f601af65d2e8ce92e68f788/api/controllers/API_SCHEMA_GUIDE.md)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
