|
1 | | -# AGENTS.md |
| 1 | +# Compliance Rules |
2 | 2 |
|
3 | | -This file provides guidance to AI assistants when working with this repository. |
| 3 | +This file contains the compliance and code quality rules for this repository. |
4 | 4 |
|
5 | | -## Project Overview |
| 5 | +## 1. All Python Source Files Must Import Future Annotations |
6 | 6 |
|
7 | | -Prefect is a workflow orchestration platform that coordinates and observes any data pipeline. It provides an SDK for building workflows and a server/cloud backend for orchestration. |
| 7 | +**Objective:** Enable forward reference resolution and improve type checking performance by requiring `from __future__ import annotations` at the top of all Python files that use type hints |
8 | 8 |
|
9 | | -Components: |
| 9 | +**Success Criteria:** Every Python file in src/ that contains type annotations includes `from __future__ import annotations` as the first import statement |
10 | 10 |
|
11 | | -- `src/prefect/` (@src/prefect/, @tests/): Core SDK - flows, tasks, states, deployments |
12 | | -- `src/prefect/engine.py` (@src/prefect/engine.py): Engine - orchestration entrypoint |
13 | | -- `src/prefect/client/` (@src/prefect/client/, @tests/client/): Client SDK - client, schemas, utilities |
14 | | -- `src/prefect/server/` (@src/prefect/server/, @tests/server/): Orchestration server - API, database, scheduling |
15 | | -- `src/integrations/` (@src/integrations/: External service integrations |
| 11 | +**Failure Criteria:** Python files with type annotations lack the `from __future__ import annotations` import statement |
16 | 12 |
|
17 | | -## Essential Commands |
| 13 | +--- |
18 | 14 |
|
19 | | -```bash |
20 | | -uv sync # Install dependencies |
21 | | -uv run --extra aws repros/1234.py # Run repro related to prefect-aws |
22 | | -uv run pytest tests/ # Run tests |
23 | | -uv run pytest -n4 # Run tests in parallel |
24 | | -uv run pytest tests/some_file.py -k test_name # Run specific test |
25 | | -prefect server start # Start local server |
26 | | -prefect config view # Inspect configuration |
27 | | -``` |
| 15 | +## 2. Type-Only Imports Must Use TYPE_CHECKING Guards |
28 | 16 |
|
29 | | -## Tech Stack |
| 17 | +**Objective:** Prevent circular import errors and reduce runtime overhead by requiring type-only imports to be placed within TYPE_CHECKING conditional blocks |
30 | 18 |
|
31 | | -- **FastAPI** for REST APIs |
32 | | -- **Pydantic v2** for validation |
33 | | -- **SQLAlchemy 2.0** async ORM |
34 | | -- **Alembic** for migrations |
35 | | -- **PostgreSQL/SQLite** databases |
| 19 | +**Success Criteria:** All imports used exclusively for type hints are placed within `if TYPE_CHECKING:` blocks, and the imported types are quoted in annotations |
36 | 20 |
|
37 | | -## Development Guidelines |
| 21 | +**Failure Criteria:** Type-only imports are imported at module level instead of within TYPE_CHECKING guards, or unquoted in annotations |
38 | 22 |
|
39 | | -### Make sure you have a Prefect server or Prefect Cloud |
40 | | -- use `prefect config view` to check your current profile |
41 | | -- run `prefect server start` in the background if needed |
| 23 | +--- |
42 | 24 |
|
| 25 | +## 3. Logger Instances Must Follow Standard Initialization Pattern |
43 | 26 |
|
44 | | -### Code Conventions |
| 27 | +**Objective:** Ensure consistent logging configuration and type safety across the codebase by standardizing logger instantiation |
45 | 28 |
|
46 | | -- Python 3.10+ with modern typing (`list[int]`, `T | None`) |
47 | | -- Private implementation details (`_private_method`) |
48 | | -- No public API changes without approval |
49 | | -- Use `uv` for dependency management, not `pip` |
| 29 | +**Success Criteria:** All logger instances are created using the pattern `logger: "logging.Logger" = get_logger("module_name")` where module_name describes the logger's scope |
50 | 30 |
|
51 | | -### Testing |
| 31 | +**Failure Criteria:** Loggers are instantiated using direct logging.getLogger() calls, or lack proper type annotations, or use inconsistent naming patterns |
52 | 32 |
|
53 | | -- Directory structure mirrors source code |
54 | | -- Run affected tests after changes: `uv run pytest tests/module/` |
55 | | -- Tests require deterministic behavior |
56 | | -- Mock external dependencies |
| 33 | +--- |
57 | 34 |
|
58 | | -### Working on Issues |
| 35 | +## 4. Secret Values Must Use Pydantic Secret Types |
59 | 36 |
|
60 | | -- Create repros in `repros/` directory (gitignored) |
61 | | -- Name files by issue number: `repros/1234.py` (only create one file per issue) |
62 | | -- Reproduce before fixing |
63 | | -- Add unit tests for fixes |
64 | | -- DO NOT delete files from `repros/` directory after reproducing the issue unless asked |
| 37 | +**Objective:** Prevent accidental exposure of sensitive data in logs, error messages, and API responses by requiring proper secret field typing |
65 | 38 |
|
66 | | -### PR Style |
| 39 | +**Success Criteria:** All fields containing sensitive data (passwords, tokens, API keys, credentials) are typed as SecretStr, SecretBytes, or SecretDict from Pydantic |
67 | 40 |
|
68 | | -- Start with "closes #1234" if resolving issue |
69 | | -- Brief summary: "this PR {changes}" |
70 | | -- Details in `<details>` tag |
71 | | -- Include relevant links |
| 41 | +**Failure Criteria:** Sensitive credential fields are typed as plain str, bytes, or dict instead of using Pydantic's Secret types |
72 | 42 |
|
73 | | -## Project Practices |
| 43 | +--- |
74 | 44 |
|
75 | | -- GitHub issues are used for tracking issues (use the `gh` cli) |
76 | | -- Pre-commit hooks required (never use `--no-verify`) |
77 | | -- Dependencies: updates to client-side deps in `@pyproject.toml` require parallel changes ing `@client/pyproject.toml` |
78 | | -- AGENTS.md always symlinked to CLAUDE.md |
79 | | -- the redis lease storage lives in @src/integrations/prefect-redis/ |
| 45 | +## 5. FastAPI Router Endpoints Must Include Docstrings |
| 46 | + |
| 47 | +**Objective:** Ensure API documentation is automatically generated and endpoints are self-documenting by requiring docstrings on all route handlers |
| 48 | + |
| 49 | +**Success Criteria:** All functions decorated with @router.get, @router.post, @router.patch, @router.delete, etc. include docstrings describing the endpoint purpose and behavior |
| 50 | + |
| 51 | +**Failure Criteria:** Route handler functions lack docstrings or have only placeholder/empty docstrings |
| 52 | + |
| 53 | +--- |
| 54 | + |
| 55 | +## 6. Test Files Must Mirror Source Directory Structure |
| 56 | + |
| 57 | +**Objective:** Maintain test organization and discoverability by ensuring test files follow the same directory hierarchy as the source code they test |
| 58 | + |
| 59 | +**Success Criteria:** For every source file at src/prefect/module/file.py, a corresponding test file exists at tests/module/test_file.py with the same relative path structure |
| 60 | + |
| 61 | +**Failure Criteria:** Test files are placed in incorrect directories that don't mirror the source structure, or use different naming conventions |
| 62 | + |
| 63 | +--- |
| 64 | + |
| 65 | +## 7. Async Functions Must Have Sync Compatibility Wrappers Where Public |
| 66 | + |
| 67 | +**Objective:** Provide user-friendly API that works in both async and sync contexts by ensuring public async functions offer sync compatibility |
| 68 | + |
| 69 | +**Success Criteria:** Public async functions that are part of the user-facing API have corresponding sync wrappers using @sync_compatible or explicit sync versions |
| 70 | + |
| 71 | +**Failure Criteria:** User-facing async functions lack sync compatibility wrappers, forcing users to always use asyncio.run() or similar |
| 72 | + |
| 73 | +--- |
| 74 | + |
| 75 | +## 8. Pydantic Models Must Use model_validator for Cross-Field Validation |
| 76 | + |
| 77 | +**Objective:** Ensure data integrity and proper validation sequencing by using Pydantic's model_validator decorator for validations that depend on multiple fields |
| 78 | + |
| 79 | +**Success Criteria:** Validation logic that depends on multiple fields uses @model_validator decorator instead of individual field validators |
| 80 | + |
| 81 | +**Failure Criteria:** Cross-field validation is implemented using individual field validators, causing order-dependent validation issues or accessing unvalidated fields |
| 82 | + |
| 83 | +--- |
| 84 | + |
| 85 | +## 9. TypeScript Components Must Use Tab Indentation |
| 86 | + |
| 87 | +**Objective:** Maintain consistent code formatting across the frontend codebase as enforced by Biome configuration |
| 88 | + |
| 89 | +**Success Criteria:** All TypeScript and TSX files in ui-v2/ use tab characters for indentation as specified in biome.json |
| 90 | + |
| 91 | +**Failure Criteria:** TypeScript files use spaces for indentation instead of tabs |
| 92 | + |
| 93 | +--- |
| 94 | + |
| 95 | +## 10. React Component Test Files Must Be Co-Located |
| 96 | + |
| 97 | +**Objective:** Improve test discoverability and maintenance by placing test files alongside the components they test |
| 98 | + |
| 99 | +**Success Criteria:** For every React component file component.tsx, the test file component.test.tsx exists in the same directory |
| 100 | + |
| 101 | +**Failure Criteria:** Test files are separated from component files in different directories, making them harder to find and maintain |
| 102 | + |
| 103 | +--- |
| 104 | + |
| 105 | +## 11. TypeScript Must Enable Strict Type Checking |
| 106 | + |
| 107 | +**Objective:** Catch type errors at compile time and ensure type safety throughout the frontend codebase |
| 108 | + |
| 109 | +**Success Criteria:** TypeScript compiler is configured with strict mode enabled and no-emit flag for validation, as evidenced by validate:types script running tsc -b --noEmit |
| 110 | + |
| 111 | +**Failure Criteria:** TypeScript strict mode is disabled or type checking is not part of the validation pipeline |
| 112 | + |
| 113 | +--- |
| 114 | + |
| 115 | +## 12. Unused Imports Must Be Automatically Removed |
| 116 | + |
| 117 | +**Objective:** Keep the codebase clean and reduce bundle size by eliminating unused imports via automated linting |
| 118 | + |
| 119 | +**Success Criteria:** Biome and ESLint configurations enforce noUnusedImports as an error, and pre-commit hooks automatically remove unused imports |
| 120 | + |
| 121 | +**Failure Criteria:** Unused imports remain in the codebase after linting, or the linter is not configured to detect them as errors |
| 122 | + |
| 123 | +--- |
| 124 | + |
| 125 | +## 13. Pre-Commit Hooks Must Run Ruff for Python Code Quality |
| 126 | + |
| 127 | +**Objective:** Enforce code quality standards and catch common issues before code is committed by running Ruff linter and formatter |
| 128 | + |
| 129 | +**Success Criteria:** The .pre-commit-config.yaml includes ruff-check and ruff-format hooks that run automatically on Python files before commits |
| 130 | + |
| 131 | +**Failure Criteria:** Pre-commit configuration lacks Ruff hooks, or they are configured to not block commits on failures |
| 132 | + |
| 133 | +--- |
| 134 | + |
| 135 | +## 14. Database Session Management Must Use Context Managers |
| 136 | + |
| 137 | +**Objective:** Ensure proper resource cleanup and transaction handling by requiring database sessions to be managed via async context managers |
| 138 | + |
| 139 | +**Success Criteria:** All database operations use `async with db.session_context(begin_transaction=True) as session:` pattern for session management |
| 140 | + |
| 141 | +**Failure Criteria:** Database sessions are created and managed manually without context managers, or transactions are not properly scoped |
| 142 | + |
| 143 | +--- |
| 144 | + |
| 145 | +## 15. API Request Parameters Must Use Pydantic Schema Validation |
| 146 | + |
| 147 | +**Objective:** Ensure data validation and automatic OpenAPI schema generation by using Pydantic models for all API request/response bodies |
| 148 | + |
| 149 | +**Success Criteria:** FastAPI route handlers accept request bodies typed as Pydantic schema classes from prefect.server.schemas.actions or prefect.client.schemas |
| 150 | + |
| 151 | +**Failure Criteria:** Route handlers accept raw dictionaries or unvalidated data structures instead of Pydantic models for request bodies |
| 152 | + |
| 153 | +--- |
0 commit comments