<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.agentclientprotocol</groupId>
    <artifactId>acp-java-sdk</artifactId>
    <version>0.80.0</version>
    <packaging>pom</packaging>

    <name>ACP Java SDK</name>
    <description>Java implementation of the Agent Client Protocol (ACP) specification - enables building and connecting to ACP-compliant coding agents</description>
    <url>https://github.com/agentclientprotocol/java-sdk</url>

    <modules>
        <module>acp-annotations</module>
        <module>acp-core</module>
        <module>acp-json-jackson2</module>
        <module>acp-json-jackson3</module>
        <module>acp-agent-support</module>
        <module>acp-http-core</module>
        <module>acp-test</module>
        <module>acp-http-servlet</module>
        <module>acp-http-webflux</module>
        <module>acp-streamable-http-jetty</module>
        <module>acp-integration</module>
        <module>acp-spring-boot-autoconfigure</module>
        <module>acp-spring-boot-starter</module>
        <module>acp-micronaut</module>
        <module>acp-micronaut-sample</module>
        <module>acp-quarkus</module>
        <module>acp-quarkus-deployment</module>
        <module>acp-quarkus-integration-tests</module>
    </modules>

    <licenses>
        <license>
            <name>Apache License, Version 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0</url>
        </license>
    </licenses>

    <scm>
        <url>https://github.com/agentclientprotocol/java-sdk</url>
        <connection>scm:git:git://github.com/agentclientprotocol/java-sdk.git</connection>
        <developerConnection>scm:git:git@github.com:agentclientprotocol/java-sdk.git</developerConnection>
    </scm>

    <developers>
        <developer>
            <id>markpollack</id>
            <name>Mark Pollack</name>
            <email>mark@springframework.org</email>
            <roles>
                <role>lead</role>
            </roles>
        </developer>
        <developer>
            <id>tzolov</id>
            <name>Christian Tzolov</name>
            <email>christian@springframework.org</email>
            <roles>
                <role>developer</role>
            </roles>
        </developer>
    </developers>

    <properties>
        <java.version>17</java.version>
        <!-- release, not source/target: compiles against the Java 17 API even when the build
             runs on a newer JDK (the errorprone profile below runs only on JDK 21+). -->
        <maven.compiler.release>${java.version}</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- Dependency versions -->
        <reactor.version>2025.0.7</reactor.version>
        <jackson.version>2.22.3</jackson.version>
        <!-- Jackson 3 for acp-json-jackson3: the version Spring Boot 4.1 manages. It reads
             the jackson-annotations 2.x that jackson.version manages. -->
        <jackson3.version>3.1.7</jackson3.version>

        <slf4j.version>2.0.18</slf4j.version>
        <jspecify.version>1.0.0</jspecify.version>
        <jetty.version>12.1.12</jetty.version>
        <!-- The servlet host's APIs, the minimum it compiles against (the container provides
             them; not managed here, so a framework's BOM keeps its own), and the Tomcat its tests
             run on, the version Spring Boot 4.1 manages. -->
        <jakarta-servlet.version>6.0.0</jakarta-servlet.version>
        <jakarta-websocket.version>2.1.1</jakarta-websocket.version>
        <!-- The Jakarta WebSocket API the SDK's listener ships with: 2.2, which Jetty 12.1 runs on
             and Tomcat 11 implements (acp-streamable-http-jetty). -->
        <jakarta-websocket-runtime.version>2.2.0</jakarta-websocket-runtime.version>
        <tomcat.version>11.0.22</tomcat.version>
        <!-- Micronaut 4 (Java 17) for acp-micronaut and its sample only: its platform BOM is
             imported in those modules' own dependencyManagement, never here. The core version
             is the one the platform manages, for the annotation processor path. -->
        <micronaut.platform.version>4.10.20</micronaut.platform.version>
        <micronaut.core.version>4.10.30</micronaut.core.version>

        <!-- Test dependency versions -->
        <junit.version>5.14.4</junit.version>
        <assertj.version>3.27.7</assertj.version>
        <archunit.version>1.4.1</archunit.version>
        <mockito.version>5.23.0</mockito.version>
        <logback.version>1.6.3</logback.version>
        <lincheck.version>3.7</lincheck.version>

        <!-- Quarkus extension (acp-quarkus*). Its BOM is imported only in those modules'
             own dependencyManagement, never here. -->
        <quarkus.version>3.40.1</quarkus.version>

        <!-- Plugin versions -->
        <maven-compiler-plugin.version>3.15.0</maven-compiler-plugin.version>
        <maven-surefire-plugin.version>3.5.6</maven-surefire-plugin.version>
        <maven-failsafe-plugin.version>3.5.6</maven-failsafe-plugin.version>
        <maven-source-plugin.version>3.4.0</maven-source-plugin.version>
        <maven-javadoc-plugin.version>3.12.0</maven-javadoc-plugin.version>
        <maven-gpg-plugin.version>3.2.8</maven-gpg-plugin.version>
        <central-publishing-maven-plugin.version>0.11.0</central-publishing-maven-plugin.version>
        <jacoco-maven-plugin.version>0.8.15</jacoco-maven-plugin.version>
        <!-- Coverage floors; each module overrides them with its own (see the JaCoCo plugin) -->
        <jacoco.minimum.line>1.00</jacoco.minimum.line>
        <jacoco.minimum.branch>1.00</jacoco.minimum.branch>
        <!-- A module whose JDK 21 build runs code JDK 17 cannot (virtual threads) declares
             higher floors for it; otherwise JDK 21 checks the same floors. -->
        <jacoco.jdk21.minimum.line>${jacoco.minimum.line}</jacoco.jdk21.minimum.line>
        <jacoco.jdk21.minimum.branch>${jacoco.minimum.branch}</jacoco.jdk21.minimum.branch>
        <!-- The floors the gate checks on this JDK (the coverage-jdk21 profile switches them) -->
        <jacoco.gate.line>${jacoco.minimum.line}</jacoco.gate.line>
        <jacoco.gate.branch>${jacoco.minimum.branch}</jacoco.gate.branch>
        <owasp.version>13.0.0</owasp.version>
        <cyclonedx-maven-plugin.version>2.9.3</cyclonedx-maven-plugin.version>
        <maven-pmd-plugin.version>3.28.0</maven-pmd-plugin.version>
        <pmd.version>7.28.0</pmd.version>
        <cpd.minimumTokens>100</cpd.minimumTokens>
        <!-- spotbugs-maven-plugin 4.10.x requires Maven 3.8.9+, and the wrapper is 3.8.6; the
             4.9.8.x plugin runs the current SpotBugs engine below. -->
        <spotbugs-maven-plugin.version>4.9.8.5</spotbugs-maven-plugin.version>
        <spotbugs.version>4.10.4</spotbugs.version>

        <!-- Error Prone and NullAway (errorprone profile, JDK 21+ only) -->
        <errorprone.version>2.50.0</errorprone.version>
        <nullaway.version>0.13.8</nullaway.version>
        <!-- Surefire's own default, declared so the coverage gate can skip with the tests. -->
        <skipTests>false</skipTests>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Reactor BOM -->
            <dependency>
                <groupId>io.projectreactor</groupId>
                <artifactId>reactor-bom</artifactId>
                <version>${reactor.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Jackson BOM -->
            <dependency>
                <groupId>com.fasterxml.jackson</groupId>
                <artifactId>jackson-bom</artifactId>
                <version>${jackson.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Jackson 3 BOM. Imported after the Jackson 2 BOM, so jackson-annotations
                 (managed by both) comes from jackson.version. -->
            <dependency>
                <groupId>tools.jackson</groupId>
                <artifactId>jackson-bom</artifactId>
                <version>${jackson3.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- ACP modules -->
            <dependency>
                <groupId>com.agentclientprotocol</groupId>
                <artifactId>acp-core</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.agentclientprotocol</groupId>
                <artifactId>acp-json-jackson2</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.agentclientprotocol</groupId>
                <artifactId>acp-json-jackson3</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.agentclientprotocol</groupId>
                <artifactId>acp-test</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.agentclientprotocol</groupId>
                <artifactId>acp-http-core</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.agentclientprotocol</groupId>
                <artifactId>acp-http-servlet</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.agentclientprotocol</groupId>
                <artifactId>acp-http-webflux</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.agentclientprotocol</groupId>
                <artifactId>acp-streamable-http-jetty</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-core</artifactId>
                <version>${tomcat.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-websocket</artifactId>
                <version>${tomcat.version}</version>
            </dependency>
            <dependency>
                <groupId>org.eclipse.jetty.ee10.websocket</groupId>
                <artifactId>jetty-ee10-websocket-jakarta-server</artifactId>
                <version>${jetty.version}</version>
            </dependency>
            <dependency>
                <groupId>com.agentclientprotocol</groupId>
                <artifactId>acp-integration</artifactId>
                <version>${project.version}</version>
            </dependency>

            <!-- Null-marking annotations (@NullMarked, @Nullable). Annotations only; NullAway
                 enforces them in the errorprone profile. -->
            <dependency>
                <groupId>org.jspecify</groupId>
                <artifactId>jspecify</artifactId>
                <version>${jspecify.version}</version>
            </dependency>

            <!-- Logging -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>

            <!-- Jetty WebSocket -->
            <dependency>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-server</artifactId>
                <version>${jetty.version}</version>
            </dependency>
            <dependency>
                <groupId>org.eclipse.jetty.ee10</groupId>
                <artifactId>jetty-ee10-servlet</artifactId>
                <version>${jetty.version}</version>
            </dependency>
            <dependency>
                <groupId>org.eclipse.jetty.http2</groupId>
                <artifactId>jetty-http2-server</artifactId>
                <version>${jetty.version}</version>
            </dependency>

            <!-- Test dependencies -->
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <dependency>
                <groupId>org.assertj</groupId>
                <artifactId>assertj-core</artifactId>
                <version>${assertj.version}</version>
            </dependency>
            <dependency>
                <groupId>com.tngtech.archunit</groupId>
                <artifactId>archunit-junit5</artifactId>
                <version>${archunit.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-core</artifactId>
                <version>${mockito.version}</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>${logback.version}</version>
            </dependency>
            <!-- Model checker for the concurrent state machines (test scope, acp-core and
                 acp-streamable-http-jetty) -->
            <dependency>
                <groupId>org.jetbrains.lincheck</groupId>
                <artifactId>lincheck</artifactId>
                <version>${lincheck.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <resources>
            <!-- Module's own resources -->
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <!-- Ship LICENSE and NOTICE inside every artifact (Apache-2.0 section 4) -->
            <resource>
                <directory>${maven.multiModuleProjectDirectory}</directory>
                <targetPath>META-INF</targetPath>
                <includes>
                    <include>LICENSE</include>
                    <include>NOTICE</include>
                </includes>
            </resource>
        </resources>

        <plugins>
            <!-- Attach one module-rooted SBOM to every artifact. The release-manager
                 independently checks it against a clean external consumer. -->
            <plugin>
                <groupId>org.cyclonedx</groupId>
                <artifactId>cyclonedx-maven-plugin</artifactId>
                <version>${cyclonedx-maven-plugin.version}</version>
                <executions>
                    <execution>
                        <id>consumer-cyclonedx-sbom</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>makeBom</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <skipNotDeployed>false</skipNotDeployed>
                    <projectType>library</projectType>
                    <schemaVersion>1.6</schemaVersion>
                    <includeBomSerialNumber>true</includeBomSerialNumber>
                    <includeCompileScope>true</includeCompileScope>
                    <includeRuntimeScope>true</includeRuntimeScope>
                    <includeProvidedScope>false</includeProvidedScope>
                    <includeSystemScope>false</includeSystemScope>
                    <includeTestScope>false</includeTestScope>
                    <includeLicenseText>false</includeLicenseText>
                    <outputFormat>json</outputFormat>
                    <outputName>${project.artifactId}-${project.version}-cyclonedx</outputName>
                    <classifier>cyclonedx</classifier>
                </configuration>
            </plugin>

            <!-- Java compiler -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-compiler-plugin.version}</version>
                <configuration>
                    <release>${java.version}</release>
                </configuration>
            </plugin>

            <!-- Surefire for tests -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven-surefire-plugin.version}</version>
            </plugin>

            <!-- Integration tests (*IT). Surefire's defaults do not match *IT, so
                 without this plugin those classes are silently never executed. -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${maven-failsafe-plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- Attach sources -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>${maven-source-plugin.version}</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- Attach javadocs -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>${maven-javadoc-plugin.version}</version>
                <configuration>
                    <doclint>none</doclint>
                    <quiet>true</quiet>
                    <!-- The JDK's own block tags (JDK-8068562); javadoc drops an unregistered tag's
                         text from the page. -->
                    <tags>
                        <tag>
                            <name>apiNote</name>
                            <placement>a</placement>
                            <head>API Note:</head>
                        </tag>
                        <tag>
                            <name>implSpec</name>
                            <placement>a</placement>
                            <head>Implementation Requirements:</head>
                        </tag>
                        <tag>
                            <name>implNote</name>
                            <placement>a</placement>
                            <head>Implementation Note:</head>
                        </tag>
                    </tags>
                </configuration>
                <executions>
                    <execution>
                        <id>attach-javadocs</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- PMD size, complexity and duplication gate: pmd:check and pmd:cpd-check fail
                 verify on any violation. Rules and thresholds, each with its reason, are in
                 config/pmd/ruleset.xml; CPD's token threshold is cpd.minimumTokens above. Main
                 sources only. Fix a violation in the code: there is no baseline. -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-pmd-plugin</artifactId>
                <version>${maven-pmd-plugin.version}</version>
                <dependencies>
                    <dependency>
                        <groupId>net.sourceforge.pmd</groupId>
                        <artifactId>pmd-core</artifactId>
                        <version>${pmd.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>net.sourceforge.pmd</groupId>
                        <artifactId>pmd-java</artifactId>
                        <version>${pmd.version}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <rulesets>
                        <ruleset>${maven.multiModuleProjectDirectory}/config/pmd/ruleset.xml</ruleset>
                    </rulesets>
                    <targetJdk>${java.version}</targetJdk>
                    <includeTests>false</includeTests>
                    <minimumTokens>${cpd.minimumTokens}</minimumTokens>
                    <printFailingErrors>true</printFailingErrors>
                    <failOnViolation>true</failOnViolation>
                    <linkXRef>false</linkXRef>
                </configuration>
                <executions>
                    <execution>
                        <id>pmd-gate</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>check</goal>
                            <goal>cpd-check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- SpotBugs gate: spotbugs:check fails verify on main sources, in every module and
                 on every JDK the build runs on (17 and 21; unlike the errorprone profile it does
                 not need JDK 21). The analysis reports findings up to rank 20; the include filter
                 config/spotbugs/spotbugs-include.xml keeps the ones that fail the build:
                 - every pattern of rank 9 or less (SpotBugs' "scariest" 1-4 and "scary" 5-9
                   bands). Rank, not confidence, is the gate: rank combines the pattern's severity
                   with its confidence, so it keeps the bugs and drops the long tail (exposed
                   arrays, missing static on inner classes, serialization advice) that a
                   confidence threshold alone would keep;
                 - a listed set of multithreaded-correctness patterns at any rank (inconsistent
                   synchronization, wait/notify and lock misuse, wrong lock objects), which
                   SpotBugs ranks 14 to 17 and the rank gate alone would miss.
                 One analysis and one filter, not two check executions: check forks the
                 spotbugs goal with the plugin-level configuration only, so a second check
                 execution with its own filter would analyse with the first one's settings and
                 then pass silently on a report that was never written.
                 threshold Medium (the default) also drops low-confidence findings; effort Max
                 runs the interprocedural detectors. find-sec-bugs is not used: on this code base
                 it adds no finding at rank 9 or less, and its findings below that are the
                 library's purpose (spawning the configured agent process, writing JSON-RPC
                 responses). A false positive is excluded narrowly (class, method, pattern), with
                 its reason, in config/spotbugs/spotbugs-exclude.xml. -->
            <plugin>
                <groupId>com.github.spotbugs</groupId>
                <artifactId>spotbugs-maven-plugin</artifactId>
                <version>${spotbugs-maven-plugin.version}</version>
                <dependencies>
                    <dependency>
                        <groupId>com.github.spotbugs</groupId>
                        <artifactId>spotbugs</artifactId>
                        <version>${spotbugs.version}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <effort>Max</effort>
                    <threshold>Medium</threshold>
                    <maxRank>20</maxRank>
                    <includeFilterFile>${maven.multiModuleProjectDirectory}/config/spotbugs/spotbugs-include.xml</includeFilterFile>
                    <includeTests>false</includeTests>
                    <excludeFilterFile>${maven.multiModuleProjectDirectory}/config/spotbugs/spotbugs-exclude.xml</excludeFilterFile>
                    <failOnError>true</failOnError>
                </configuration>
                <executions>
                    <execution>
                        <id>spotbugs-gate</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- JaCoCo code coverage. Each module's report (target/site/jacoco/index.html) and
                 gate count that module's own classes, exercised by that module's own tests:
                 acp-core code reached only from another module's tests is not counted, and the
                 JSON modules, which run acp-core's contract suite against their mapper, count
                 only their mapper classes. Nothing is excluded. The integration harness
                 (integration-testing/) is outside the Maven build and is not counted.

                 The gate (check, in verify) fails when a module's LINE or BRANCH covered ratio
                 falls below its floor. CI builds on JDK 17 and on JDK 21, and a module may cover
                 more on JDK 21, where its virtual-thread code runs: such a module also declares
                 jacoco.jdk21.minimum.line and jacoco.jdk21.minimum.branch, which the JDK 21
                 build checks instead (the coverage-jdk21 profile); without them JDK 21 checks
                 the same floors. Measure a floor on both JDKs: the JDK 17 one from the JDK 17
                 build, the JDK 21 one from the JDK 21 build, and a shared floor from the lower. Every module declares jacoco.minimum.line and
                 jacoco.minimum.branch; the default below is full coverage, so a new module
                 fails until it declares measured floors. A floor is the coverage measured from a clean verify less a margin of
                 2 points, rounded down to a whole percent: enough for the run-to-run variation
                 of the concurrent tests (a branch or two), too little to lose a test class
                 unnoticed. Raise a floor when coverage rises; lower one only with a reason in
                 the commit.

                 A floor counts a whole module, so it cannot see the few lines that choose
                 between virtual threads (JDK 21 and later) and platform threads (JDK 17): CI
                 builds on both JDKs, and each JDK runs only its own side of every such choice.
                 The second rule names the classes that make those choices and requires every
                 branch of them covered on whichever JDK builds. Each takes the choice as an
                 argument (whether the JDK has virtual threads, or the virtual-thread executor
                 or handles), so its tests make both choices on both JDKs. A class that makes a
                 new such choice belongs on the list. -->
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco-maven-plugin.version}</version>
                <executions>
                    <execution>
                        <id>prepare-agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <!-- In verify, after the integration tests (failsafe appends to the same
                         execution data) and before the gate, so the report shows what the
                         gate checks. -->
                    <execution>
                        <id>report</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>coverage-gate</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>check</goal>
                        </goals>
                        <configuration>
                            <!-- No gate without tests: with -DskipTests the check would read
                                 whatever execution data an earlier run left in target (a
                                 -Dtest run's partial coverage, for one) and fail the build. -->
                            <skip>${skipTests}</skip>
                            <rules>
                                <rule>
                                    <element>BUNDLE</element>
                                    <limits>
                                        <limit>
                                            <counter>LINE</counter>
                                            <value>COVEREDRATIO</value>
                                            <minimum>${jacoco.gate.line}</minimum>
                                        </limit>
                                        <limit>
                                            <counter>BRANCH</counter>
                                            <value>COVEREDRATIO</value>
                                            <minimum>${jacoco.gate.branch}</minimum>
                                        </limit>
                                    </limits>
                                </rule>
                                <rule>
                                    <element>CLASS</element>
                                    <includes>
                                        <include>com.agentclientprotocol.sdk.util.VirtualThreads</include>
                                        <include>com.agentclientprotocol.sdk.util.AcpSchedulers*</include>
                                        <include>com.agentclientprotocol.sdk.agent.SyncHandlerScheduler</include>
                                        <include>com.agentclientprotocol.sdk.client.SyncHandlerScheduler</include>
                                        <include>com.agentclientprotocol.sdk.quarkus.runtime.AcpExecutors</include>
                                        <include>com.agentclientprotocol.sdk.spring.boot.autoconfigure.agent.HandlerExecutors*</include>
                                    </includes>
                                    <limits>
                                        <limit>
                                            <counter>BRANCH</counter>
                                            <value>COVEREDRATIO</value>
                                            <minimum>1.00</minimum>
                                        </limit>
                                    </limits>
                                </rule>
                            </rules>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <!-- The coverage gate's JDK 21 floors (see the JaCoCo plugin). -->
        <profile>
            <id>coverage-jdk21</id>
            <activation>
                <jdk>[21,)</jdk>
            </activation>
            <properties>
                <jacoco.gate.line>${jacoco.jdk21.minimum.line}</jacoco.gate.line>
                <jacoco.gate.branch>${jacoco.jdk21.minimum.branch}</jacoco.gate.branch>
            </properties>
        </profile>
        <!-- Error Prone: Error Prone's own bug checks and NullAway, at ERROR, on main sources.
             Error Prone 2.50 runs only on JDK 21+, while the SDK targets Java 17 and its
             release build runs on JDK 17, so the profile activates by JDK: every build on
             JDK 21+ (including the CI job that exists for it) is checked, and a JDK 17
             build compiles exactly as before. The javac internals Error Prone needs are
             opened in .mvn/jvm.config. Scope:
             - Error Prone's default-enabled checks, and failOnWarning (javac -Werror), so a
               check whose default severity is WARNING fails the build like an ERROR one.
               -Werror also fails on javac's own default warnings (removal, for one), which
               are worth failing on too; suggestions stay notes. A new Error Prone version
               brings its new checks in at ERROR: triage them on upgrade.
             - Checks that are pure style for this code base are disabled by name below,
               each with its reason. A real exception is a @SuppressWarnings with a reason.
             - Beyond the defaults, two bug finders that fit this code base:
               CheckReturnValue over reactor.core.publisher: a Mono or Flux operator whose
               result is dropped never runs. Results that are fine to drop (subscribe's
               Disposable, a terminal tryEmit*, fluent sink callbacks) are listed with
               reasons in config/errorprone/reactor-ignorable-results.txt.
               SystemOut: the stdio transport owns System.out, and anything else printed
               there corrupts the JSON-RPC stream.
             - NullAway: only @NullMarked packages (OnlyNullMarked), in JSpecify mode.
             - only default-compile: test sources are deliberately unchecked;
             - never fork the compiler (compiler-plugin then hides every diagnostic). -->
        <profile>
            <id>errorprone</id>
            <activation>
                <jdk>[21,)</jdk>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>default-compile</id>
                                <configuration>
                                    <failOnWarning>true</failOnWarning>
                                    <compilerArgs>
                                        <arg>-XDcompilePolicy=simple</arg>
                                        <arg>--should-stop=ifError=FLOW</arg>
                                        <arg>-XDaddTypeAnnotationsToSymbol=true</arg>
                                        <!-- Disabled, as style for this code base:
                                             StatementSwitchToExpressionSwitch: arrow or colon switch is a style choice. -->
                                        <arg>-Xplugin:ErrorProne -Xep:StatementSwitchToExpressionSwitch:OFF -Xep:SystemOut:ERROR -XepOpt:CheckReturnValue:Packages=reactor.core.publisher -XepOpt:CheckReturnValue:ApiExclusionList=${maven.multiModuleProjectDirectory}/config/errorprone/reactor-ignorable-results.txt -Xep:NullAway:ERROR -XepOpt:NullAway:JSpecifyMode=true -XepOpt:NullAway:OnlyNullMarked=true</arg>
                                    </compilerArgs>
                                    <annotationProcessorPaths>
                                        <path>
                                            <groupId>com.google.errorprone</groupId>
                                            <artifactId>error_prone_core</artifactId>
                                            <version>${errorprone.version}</version>
                                        </path>
                                        <path>
                                            <groupId>com.uber.nullaway</groupId>
                                            <artifactId>nullaway</artifactId>
                                            <version>${nullaway.version}</version>
                                        </path>
                                    </annotationProcessorPaths>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <!-- Release profile for Maven Central Portal publishing -->
        <profile>
            <id>release</id>
            <build>
                <plugins>
                    <!-- Maven Central Portal publishing plugin -->
                    <plugin>
                        <groupId>org.sonatype.central</groupId>
                        <artifactId>central-publishing-maven-plugin</artifactId>
                        <version>${central-publishing-maven-plugin.version}</version>
                        <extensions>true</extensions>
                        <configuration>
                            <publishingServerId>central</publishingServerId>
                            <autoPublish>true</autoPublish>
                            <!-- Modules that are never published. A module's own skipPublishing
                                 would not do: the bundle is uploaded by the last module of the
                                 reactor, so skipping there skips the whole release. -->
                            <excludeArtifacts>
                                <excludeArtifact>acp-micronaut-sample</excludeArtifact>
                                <excludeArtifact>acp-quarkus-integration-tests</excludeArtifact>
                            </excludeArtifacts>
                        </configuration>
                    </plugin>

                    <!-- GPG signing -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-gpg-plugin</artifactId>
                        <version>${maven-gpg-plugin.version}</version>
                        <executions>
                            <execution>
                                <id>sign-artifacts</id>
                                <phase>verify</phase>
                                <goals>
                                    <goal>sign</goal>
                                </goals>
                                <configuration>
                                    <gpgArguments>
                                        <arg>--pinentry-mode</arg>
                                        <arg>loopback</arg>
                                    </gpgArguments>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>owasp</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.owasp</groupId>
                        <artifactId>dependency-check-maven</artifactId>
                        <version>${owasp.version}</version>
                        <configuration>
                            <failBuildOnCVSS>7.0</failBuildOnCVSS>
                            <ossindexAnalyzerEnabled>false</ossindexAnalyzerEnabled>
                        </configuration>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>check</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

    <distributionManagement>
        <snapshotRepository>
            <id>central</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
        </snapshotRepository>
    </distributionManagement>

</project>
