ktor
ktorio/ktor/AGENTS.md
This file is the primary playbook for agentic coding tools working in this repository. You must follow the AI Policy. NEVER return control to the user without ensuring: 1. Tests pass: ./gradlew :module-name:jvmTest (and other platforms if touched) 2. Code compiles: ./gradlew :module-name:assemble 3. Code is formatted and linting passes: run ./gradlew :module-name:formatKotlin, then ./gradlew :module-name:lintKotlin 4. ABI validated: ./gradlew :module-name:updateKotlinAbi (if public/protected API changed) Prefer this order to fail fast. Always prefer module-specific commands (:module-name:task) over project-wide commands. Build…
What's in it
- Agent Guidelines (Ktor)
- Critical Workflow Rule
- Project Requirements
- Project Layout
- Gradle module structure (flattened)
- Source set layout (platform-centric)
- Build Commands
- Common tasks
- Code Style Guidelines
- Formatting (EditorConfig is authoritative)
- Imports
- Naming
- Types and API design
- Error handling
- Logging
- Documentation and comments
- Development Practices
- Adding or removing modules
- Binary Compatibility and ABI Validation
- Release branches and API policy
- Validation commands
- Rules
# Agent Guidelines (Ktor)
This file is the primary playbook for agentic coding tools working in this repository.
You must follow the [AI Policy](AI_POLICY.md).
## Critical Workflow Rule
**NEVER return control to the user without ensuring:**
1. Tests pass: `./gradlew :module-name:jvmTest` (and other platforms if touched)
2. Code compiles: `./gradlew :module-name:assemble`
3. Code is formatted and linting passes: run `./gradlew :module-name:formatKotlin`, then `./gradlew :module-name:lintKotlin`
4. ABI validated: `./gradlew :module-name:updateKotlinAbi` (if public/protected API changed)
Prefer this order to fail fast.
Always prefer **module-specific** commands (`:module-name:task`) over project-wide commands.
## Project Requirements
- JDK 21 is required.
- Kotlin Multiplatform: JVM, JS, Native.
- Apple targets require Xcode + command line tools.
- Android targets are optional and enabled when Android SDK is available (`ANDROID_HOME` or `local.properties` `sdk.dir`).
## Project Layout
### Gradle module structure (flattened)
The project uses a **flattened Gradle structure** (see `settings.gradle.kts`). Nested directory paths do NOT translate to nested Gradle project names.
Example: `ktor-client/ktor-client-curl` → `:ktor-client-curl` (not `:ktor-client:ktor-client-curl`).
### Source set layout (platform-centric)
Kotlin Multiplatform sources use a flattened, platform-centric layout (do not re-introduce `src/<platform>Main/...`).
```text
common/src
jvm/src
jvm/resources
jvm/test
jvm/test-resources
...
```
Build logic enforces "no surprise source sets": manually registering extra source sets is rejected.
To add a new target/source set, add the directory or enable the target via `gradle.properties` (`target.<name>=true`).
## Build Commands
**Important**: Always prefer running tasks on the specific module you touched, not the entire project.
### Common tasks
```bash
./gradlew :module-name:assemble # Build the module
```
Run tests:
```bash
./gradlew :module-name:jvmTest # Run JVM tests for the module
./gradlew :module-name:allTests # Run tests across all platforms for the module
./gradlew :module-name:jvmTest --tests "fully.qualified.TestClassName" # Run a specific test
./gradlew :module-name:jvmTest --tests "fully.qualified.TestClassName.methodName" # Run a specific test method
```
Linting:
```bash
./gradlew :module-name:formatKotlin # Format the module
./gradlew :module-name:lintKotlin # Lint the module
```
## Code Style Guidelines
### Formatting (EditorConfig is authoritative)
- Kotlin style: IntelliJ + `KOTLIN_OFFICIAL` (`.editorconfig`).
- Indent: 4 spaces (JSON/YAML: 2); max line length: 120; end of line: LF.
- Use `./gradlew :module-name:formatKotlin` rather than manual formatting.
### Imports
- Star imports are preferred for `io.ktor.*` (configured in `.editorconfig`).
### Naming
- Follow Kotlin conventions unless the surrounding package has a strong established pattern.
- Tests: prefer descriptive test names in backticks: `describe what is being tested`.
### Types and API design
- Prefer `internal` by default; keep the public surface intentional.
- Public API requires KDoc (parameters, return, and notable exceptions).
- Public-but-not-for-users APIs that cannot be `internal` should use `@InternalAPI`.
- Keep `@OptIn(...)` scope minimal.
- All types used as receivers in DSL should be annotated with `@KtorDsl` (for example, all plugin configs).
### Error handling
- `require(...)` for argument validation, `check(...)` for state validation, `error("...")` for unreachable states.
- Throw specific exceptions appropriate to the layer (IO parsing: `IOException`/`EOFException`; validation: Ktor exceptions like `BadRequestException`).
- Make error messages actionable; include the problematic value/context.
### Logging
- Prefer Ktor log helpers where present.
- Avoid noisy logs in hot paths.
### Documentation and comments
- Avoid redundant comments; add them only for tricky invariants or platform-specific behavior.
- Keep KDoc correct when behavior/signatures change.
- New source files must include the repository copyright header.
## Development Practices
- Prefer TDD where feasible: add/adjust tests, then implement.
- For multiplatform changes: start JVM-first unless the task requires another platform.
- Keep local-only build knobs (for example, developer `gradle.properties` overrides) out of commits.
- If asked to create commits: use imperative mood and include `KTOR-<NUM>` when there is a related YouTrack issue.
### Adding or removing modules
- Module names must start with `ktor-`.
- The project uses a flattened Gradle structure with custom DSL in `settings.gradle.kts` (see Project Layout section).
- When modules are added/removed or new targets enabled, run `./update-artifact-dumps.sh` to update published artifact lists in `gradle/artifacts`.
Publishing will fail if these dumps are stale.
## Binary Compatibility and ABI Validation
Binary compatibility is **enforced** using Kotlin Gradle Plugin ABI validation.
All public API changes must be tracked in `/api/` directories within modules.
### Release branches and API policy
- Patch releases are maintained in `release/<major>.x` (for example, v3 uses `release/3.x`, v4 uses `release/4.x`).
- The next minor release is developed on `main`.
- Public API changes are allowed only for minor/major releases (typically on `main`), not for patch releases (on `release/<major>.x`).
- Breaking changes are **only allowed in major version releases**.
- The repo includes an interactive helper `./switch-base-branch.sh` for switching a feature branch base between `main` and `release/<major>.x`.
For agents: use `--dry-run` to print the git commands, then run them after user approval.
### Validation commands
```bash
./gradlew :module-name:checkKotlinAbi # Validate ABI compatibility
./gradlew :module-name:updateKotlinAbi # Update ABI signature files after changes
```
### Rules
- **All** `public`/`protected` API changes require updating `api/*.api` dumps.
- API changes must be **intentional and well-documented**.
More agent context in ktorio/ktor
2 other files this repository gives its agents.
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

