# S8 — Palantir formatting for Java Status: IMPLEMENTED Agreed after the grill-me review; shared understanding confirmed. ## User story As a developer, I want maintained Java code formatted using Palantir Java Format through the Maven workflow, so that local development and CI use consistent, reproducible formatting without unnecessary build overhead. ## Scope ### In scope - Backend Java production code and Java tests. - Maintained Java CI/source-launcher helpers under `ci/`, despite those files being outside ordinary Maven source roots. - Integration with local Maven builds, CI checking and standalone format/check commands. - A separate initial formatting commit, performance measurements and README instructions. ### Out of scope - Generated code and build output. - Frontend formatting, which remains under Prettier. - Additional coding conventions, naming rules, structural checks or refactorings. Those belong in S7. ## Formatter and integration - Use the **actual Palantir Java Format engine** and its Palantir style. - OpenRewrite is the preferred integration route. S8 includes the custom Palantir adapter/recipe and bootstrap required to make that route work. - OpenRewrite's own `AutoFormat` is not an equivalent replacement for Palantir and must not be substituted silently. - Spotless is not the agreed default: the maintainer has experienced unacceptable slowness with it. Do not choose it merely because a native integration exists. - Pin the formatter, plugin and adapter dependencies to explicit versions in Maven configuration. Local development and CI use the same pinned engine. - Formatter/integration updates are reviewed through PRs and include any resulting formatting changes. Do not implicitly resolve the newest formatter at build time. - Include Palantir's import ordering and unused-import removal. Do not add separate import policies or unrelated code transformations. - Leave optional extra Javadoc reformatting disabled for the initial adoption. ## Maven behavior ### Local builds Local builds apply formatting before compilation, so the compiled and tested sources are the formatted sources. Early lifecycle integration means ordinary `mvn compile`, `mvn test`, `mvn verify` and `mvn install` may format maintained Java files. Binding only to `install` does not satisfy this specification: the existing CI verification uses `mvn clean verify` and would not reach that phase. Provide standalone commands to: - Apply formatting without performing the complete application build. - Check formatting without modifying maintained sources or performing the complete application build. The concrete commands/profile names are implementation work and must be documented. ### CI - CI runs the check-only mode before compilation and fails if formatting differs from the committed source. - CI must not repair or rewrite maintained Java source files automatically. - Use the same pinned Palantir engine, configuration and file scope locally and in CI; only apply versus check behavior differs. - Integrate the checking invocation into the existing Java-based CI orchestration. - Show actionable diagnostics identifying the files that need formatting and how to apply the formatter locally. - A formatting failure prevents successful verification and image publication. Demonstrate that the check leaves maintained source files unchanged on failure. ## Clean-checkout bootstrap Normal Maven commands from the repository root must work from a clean checkout without first requiring a developer to compile or install a custom recipe artifact by hand. The custom recipe/adapter must be available before it is needed to format the application sources. Placing it in ordinary backend source code and assuming that it has already been compiled is not a valid bootstrap solution. Prove bootstrap behavior with no previously installed project-specific recipe artifact. Normal dependency resolution is allowed; any extra tooling module or bootstrap must be included in the implementation and documentation. ## Correctness and Java 25 - Demonstrate support for every Java construct actually used in the maintained backend, tests and CI helpers on the project's JDK 25. - Running the formatter on JDK 25 is not, by itself, proof that its parser supports every possible Java 25 construct. Record relevant limitations of the chosen pinned version. - An unprocessable file or formatter error fails the operation/build with its path and a concrete cause. Do not silently skip it or exclude it merely to obtain a successful build or faster measurement. - The adapter must preserve source paths and encoding and avoid corrupting files. - Formatting is deterministic and idempotent: applying it again produces no further source differences. Check-only and apply mode agree on the result. - Application behavior remains unchanged; builds and tests must pass after the initial formatting and subsequent formatter changes. ## Initial adoption and commit separation Apply the chosen formatting to all existing maintained Java files in scope. Record this initial mass formatting in a separate **formatting-only commit**, without functional changes. Keep integration/configuration changes separate so reviewers can distinguish tooling changes from the mechanical source rewrite. Native import ordering/removal is part of that formatting commit. Do not combine it with unrelated cleanup or refactoring. ## Performance requirements The integration must be measured rather than selected on an unverified claim that one wrapper is faster than another. - A repeated ordinary build with no Java-source changes may incur at most **three seconds of additional formatting-related overhead**. - Include the required integration/recipe/bootstrap overhead in that comparison; do not report only time spent inside the Palantir formatting function. - Compare otherwise equivalent builds with and without the formatting integration under the same environment/cache conditions. - Also measure a build after changing a maintained Java file and a `clean verify` run. Record these timings; the agreed three-second threshold specifically applies to the repeated unchanged-build case. - Report one-time dependency downloads separately, rather than disguising ongoing overhead as first-time setup or counting downloads as formatter execution. - Record the machine, JDK/Maven/tool versions, commands, file scope, cache state and results with the implementation evidence. The time threshold is an acceptance criterion, not a hard interrupt that kills a formatter while it is writing source files. If the selected integration cannot meet the threshold, report the measurements and obtain agreement before choosing an alternative integration or relaxing the bound. Do not silently skip formatting, switch engines, choose Spotless or weaken the criterion. ## README and editor integration Explain in the root `README.md`: - The formatter, pinned versions/configuration and maintained file scope. - The standalone apply and check commands. - Which local Maven lifecycle commands can rewrite files and when that occurs. - The CI check-only invocation and how to reproduce and resolve a failure locally. - Clean-checkout bootstrap behavior and any included tooling artifact/module. - Available supported IDE integration and how to keep its result consistent with the project's pinned formatter. - The performance evidence and any relevant Java 25 syntax limitations. Maven is the authoritative formatting path regardless of editor. Do not require format-on-save or an IDE plugin. An IDE integration must not redefine the agreed style or silently take precedence over the Maven result. ## Acceptance criteria - [x] The actual Palantir engine formats all maintained backend Java sources, Java tests and `ci/*.java`; generated code is excluded. - [x] OpenRewrite integration, custom adapter/recipe and bootstrap are implemented and reproducible from a clean checkout without manual recipe installation. - [x] Plugin, formatter and adapter dependencies are pinned, with matching local and CI configuration. - [x] Local Maven builds apply formatting before compilation; `compile`, `test`, `verify` and `install` reach the intended integration. - [x] Standalone apply and check commands work without the full application build. - [x] CI checks only, leaves maintained sources unchanged, reports formatting differences and fails before image publication. - [x] Import ordering and unused-import removal follow Palantir; optional extra Javadoc reformatting remains disabled and no unrelated refactoring is added. - [x] All currently used Java 25 syntax is handled, or causes an explicit failure requiring resolution rather than silent exclusion. - [x] Apply/check results agree and a second apply produces no differences. - [x] Initial formatting is isolated in a formatting-only commit; application builds and tests remain green. - [x] Equivalent repeated unchanged-build measurements demonstrate at most three seconds of additional integration overhead. Changed-file and clean-build measurements and one-time downloads are reported separately. - [x] Failure to meet the performance bound is reported before changing the route or bound; a writing formatter is not killed to force compliance. - [x] README instructions cover local and CI commands, bootstrap, optional IDE use, authoritative Maven formatting and verification evidence. ## Implementation handoff This specification records agreed behavior. It does not install a formatter, create an adapter, change Maven/CI behavior or reformat source files. Recipe loading, Java 25 compatibility and performance must be demonstrated during implementation; there is no pre-existing project benchmark establishing the preferred route's performance. Implementation and measured acceptance evidence: [S8-formatting-evidence.md](http://192.168.2.28:3000/wanjakrah/agiledancers/src/branch/feature/S19_multi-project/docs/validation/S8-formatting-evidence.md). Affected repositories: `agiledancers`.