Skip to content

Commit ef02d02

Browse files
committed
Move Quality Gates guidelines from AGENTS.md to TESTING.md
1 parent 91a9048 commit ef02d02

2 files changed

Lines changed: 48 additions & 63 deletions

File tree

‎AGENTS.md‎

Lines changed: 4 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ koog/
7070
- Document public APIs with KDoc comments
7171
- NEVER suppress compiler warnings without a good reason
7272

73+
## Quality Gates
74+
Read and follow the Quality Gates section in /TESTING.md before considering any code change complete.
75+
7376
## Architecture
7477

7578
### Core Framework Components
@@ -104,67 +107,6 @@ Features have unique storage keys and can intercept agent lifecycle events.
104107
- **Type Safety**: Generics ensure compile-time correctness for tool arguments/results
105108
- **Builder Patterns**: Fluent APIs for configuration throughout the framework
106109

107-
## Quality Gates (MANDATORY)
108-
109-
These rules are non-negotiable and apply to **every** change that touches production code.
110-
Claude MUST enforce them automatically without being asked.
111-
112-
### Definition of Done for any code change
113-
114-
A change is NOT done until ALL of the following are true:
115-
116-
1. **Tests exist for every newly added or modified code path.**
117-
- New public function/class → new unit test covering happy path + at least one edge case.
118-
- Bug fix → a regression test that fails WITHOUT the fix and passes WITH it.
119-
- Behavior change → existing tests updated to reflect the new contract.
120-
2. **Tests actually run and pass locally** via `./gradlew jvmTest` (and `jsTest` if the module has a JS target).
121-
Do NOT report a task as complete based on "it compiles". Compilation ≠ tests pass.
122-
3. **`./gradlew build` succeeds** for the affected modules before the change is handed back to the user.
123-
4. **No suppressed warnings, no `@Ignore`, no `@Disabled`, no commented-out assertions** were introduced to make tests pass.
124-
5. **Public API changes** (new/removed/renamed public symbols) are documented with KDoc.
125-
126-
If any gate fails, fix the underlying issue. Do NOT weaken the test, disable it, or mark
127-
the task complete with a caveat. If the gate genuinely cannot be satisfied, stop and ask the user.
128-
129-
### Automatic workflow triggers
130-
131-
Claude MUST follow this workflow without waiting for the user to ask:
132-
133-
| Trigger | Required action |
134-
|--------------------------------------------------------------|---------------------------------------------------------------------------------|
135-
| User asks for a non-trivial feature / refactor (>1 file) | Invoke the `create_plan` skill BEFORE writing code |
136-
| User asks for a bug fix | First write a failing regression test, then fix, then confirm test passes |
137-
| Any edit under `src/commonMain`, `src/jvmMain`, `src/jsMain` | Add/update tests in the corresponding `src/*Test` source set in the SAME change |
138-
| Before reporting task complete | Run `./gradlew <affectedModule>:jvmTest` and paste the result summary |
139-
| After finishing implementation | Invoke the `simplify` skill to review the diff for quality issues |
140-
| Touching code shared between JVM and non-JVM targets | Consider the `split-jvm-nonjvm` skill if platform-specific code is needed |
141-
142-
These triggers are **defaults**, not suggestions. Skip one only if the user explicitly says so
143-
in the current conversation.
144-
145-
### Test planning checklist (use before writing any test)
146-
147-
Before writing a test, Claude must answer in 1–2 lines each:
148-
149-
1. **What behavior is under test?** (not "what function" — what observable behavior)
150-
2. **What are the inputs / preconditions?** Include the boundary and error cases.
151-
3. **What is the expected observable outcome?** Return value, thrown exception, state change, emitted event.
152-
4. **What is the minimal test double setup?** Prefer the framework's `getMockExecutor` / `mockTool` over hand-rolled
153-
mocks.
154-
5. **Which source set does the test belong in?** (`commonTest` when platform-agnostic, else `jvmTest` / `jsTest`.)
155-
156-
If any of these is unclear, the implementation itself is probably under-specified — pause and clarify.
157-
158-
### Self-verification before handing back
159-
160-
Before telling the user "done", Claude MUST explicitly confirm, in the final message:
161-
162-
- [ ] Which tests were added or modified (file paths + test names).
163-
- [ ] The exact Gradle command that was run and its result (pass/fail count).
164-
- [ ] Whether any Quality Gate was skipped, and why.
165-
166-
If this checklist cannot be filled in truthfully, the task is not done.
167-
168110
## Testing
169111

170112
The framework provides comprehensive testing utilities in `agents-test` module:
@@ -298,9 +240,8 @@ export OPEN_ROUTER_API_TEST_KEY=your_key_here
298240
- **ALWAYS** run `./gradlew build` before submitting PRs
299241
- Ensure all tests pass on JVM, JS, WASM targets
300242
- Follow established patterns in existing code
301-
- Add tests for new functionality — see the **Quality Gates** section above; it is mandatory, not advisory
243+
- Add tests for new functionality
302244
- Update documentation for API changes
303-
- Run the `simplify` skill on your diff before opening a PR
304245

305246
### Commit Guidelines
306247

‎TESTING.md‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,50 @@
22

33
When making changes in the project, please make sure that the corresponding tests are not failing.
44

5+
## Quality Gates
6+
7+
These rules are non-negotiable and apply to **every** change that touches production code.
8+
9+
### Definition of Done for any code change
10+
11+
A change is NOT done until ALL of the following are true:
12+
13+
1. **Tests exist for every newly added or modified code path.**
14+
- New public function/class → new unit test covering happy path + at least one edge case.
15+
- Bug fix → a regression test that fails WITHOUT the fix and passes WITH it.
16+
- Behavior change → existing tests updated to reflect the new contract.
17+
2. **Tests actually run and pass locally** via `./gradlew jvmTest` (and `jsTest` if the module has a JS target).
18+
Do NOT report a task as complete based on "it compiles". Compilation ≠ tests pass.
19+
3. **`./gradlew build` succeeds** for the affected modules before the change is handed back to the user.
20+
4. **No suppressed warnings, no `@Ignore`, no `@Disabled`, no commented-out assertions** were introduced to make tests pass.
21+
5. **Public API changes** (new/removed/renamed public symbols) are documented with KDoc.
22+
23+
If any gate fails, fix the underlying issue. Do NOT weaken the test, disable it, or mark
24+
the task complete with a caveat. If the gate genuinely cannot be satisfied, stop and ask the user.
25+
26+
### Test planning checklist (use before writing any test)
27+
28+
Before writing a test, make sure these points are clear:
29+
30+
1. **What behavior is under test?** (not "what function" — what observable behavior)
31+
2. **What are the inputs / preconditions?** Include the boundary and error cases.
32+
3. **What is the expected observable outcome?** Return value, thrown exception, state change, emitted event.
33+
4. **What is the minimal test double setup?** Prefer the framework's `getMockExecutor` / `mockTool` over hand-rolled
34+
mocks.
35+
5. **Which source set does the test belong in?** (`commonTest` when platform-agnostic, else `jvmTest` / `jsTest`.)
36+
37+
If any of these is unclear, the implementation itself is probably under-specified — pause and clarify.
38+
39+
### Verification checklist
40+
41+
Before considering the change complete, confirm:
42+
43+
- [ ] Which tests were added or modified (file paths + test names).
44+
- [ ] The exact Gradle command that was run and its result (pass/fail count).
45+
- [ ] Whether any Quality Gate was skipped, and why.
46+
47+
If this checklist cannot be filled in truthfully, the task is not done.
48+
549
## Running unit tests
650

751
This project uses Kotlin Multiplatform with JVM tests located in the `jvmTest` source sets.

0 commit comments

Comments
 (0)