# werkcrappit — Agent Instructions This file holds the shared, tool-agnostic instructions for all AI coding agents. Claude Code imports it from `CLAUDE.md` via `@AGENTS.md`. ## Specification The specification is [docs/pitest-mutation-crap-coding-agent-auftrag.md](docs/pitest-mutation-crap-coding-agent-auftrag.md) (in German). IMPORTANT: Read it before designing or changing anything. Do not change its metric formula, its status policy `strict-v1` or its binding constraints without a documented decision. The default status policy is `timeouts-killed-v1`, a documented deviation (ADR 0006); `strict-v1` is unchanged and selectable. ## Build and Test Commands ```bash ./gradlew build # compile + unit tests + functional tests ./gradlew :werkcrappit-pit:test --tests "de.javagil.werkcrappit.pit.SomeTest" # a single test class ./gradlew :werkcrappit-pit:functionalTest # real PIT runs on fixture projects via Gradle TestKit ./gradlew :werkcrappit-gradle-plugin:functionalTest # the gate in real builds, incl. multi-project ``` ## Module Structure - `werkcrappit-pit` (`de.javagil.werkcrappit.pit`) — the PIT plugin JAR: metric core, JaCoCo adapter, PIT result listener, reports. - `werkcrappit-gradle-plugin` (`de.javagil.werkcrappit.gradle`) — the Gradle plugin `de.javagil.werkcrappit`: wiring into `info.solidsoft.pitest` and the gate task over the finished report; the gate logic itself is `de.javagil.werkcrappit.pit.gate` in `werkcrappit-pit`. Tests mirror this structure under `src/test/java`. Functional tests live in the source set `functionalTest` of each module; their fixture projects consume the plugins as published into the root's `build/functional-test-repo`, never the classes of the build. ## Hard Invariants - Mutation results come from the PIT listener interface, never from importing `mutations.xml`. - Complexity comes from JaCoCo Core analysing the original, unmutated class files — no JaCoCo agent, no `.exec` file, no extra test run. - The metric core knows neither PIT nor JaCoCo nor Gradle types; `CoreIndependenceTest` checks it. - A Mutation-CRAP value is compared as an exact fraction (`MutationCrap.exceeds`), never as a rounded or floating-point number. - The Gradle plugin holds no second implementation of the formula; it evaluates the report contract. - The plugin only observes: it never filters mutants, changes their status or alters PIT's configuration. ## Code and Tests - Production code in Java 21; build scripts in Gradle Kotlin DSL. - Use `var` or `final var` where it keeps the code readable. - Tests with JUnit Jupiter and AssertJ; Mockito only where a test double beats a small real fixture. ## File-Formatting Write documentation in English in Markdown files. The one exception are the Gherkin features under `docs/features/`: German, as the specification has them (`# language: de`, IDs `@MC-…`). In Markdown, use a single line per sentence. Keep sentences short. ## Documentation - `docs/adr/` — architecture decisions, starting with `0001-pit-integration.md`. - `docs/compatibility.md` — the version combinations a functional test actually ran. - `docs/guides/` — integration guides for real projects, starting with the pilot hsadmin-ng. - `docs/features/` — the acceptance scenarios of the specification as Gherkin (German); `docs/acceptance-test-map.md` maps each `@MC-…` ID to the JUnit tests that verify it. - `docs/rfcs/` — proposals larger than one PR and not yet a decision. - `docs/prs/` — one document per pull request. - `docs/werkcrappit.werkbaum` — the plan; each PR updates the status of its nodes. ## Working Mode The specification's section 8.3 has eight steps; each is one pull request with green CI on werkator.javagil.de and its own PR-doc. The pilot project is hsadmin-ng (Java); Kotlin stays the specification's optional goal. Releases go to the Gitea Maven package registry on git.javagil.de. ## Workflow Follow [docs/agentic-workflow.md](docs/agentic-workflow.md), the workflow of all werk repositories: roles, steps of a PR, review rounds, PR documents, versions and the writing style. In addition, for werkcrappit: - A version is published once and never replaced: the Gitea registry refuses a second upload. - The build derives the version from the PR documents, from the base version 0.26.14 on; for it, each Gradle run needs the full history and `origin/main`. - The release notes stand in the section "Release Notes" of the PR document; a change that users do not notice starts with "Internal:". `./gradlew changelog` writes them into `build/changelog/CHANGELOG.md`, followed by `CHANGELOG.md`, which ends with 0.26.14. - The acceptance scenarios of the specification stay in `docs/features/` (German, IDs `@MC-…`); `docs/acceptance-test-map.md` maps each ID to the tests that verify it.