diff --git a/.github/CI_SECURITY.md b/.github/CI_SECURITY.md
index a8ab2ce..50670d0 100644
--- a/.github/CI_SECURITY.md
+++ b/.github/CI_SECURITY.md
@@ -73,6 +73,11 @@ Dependabot checks all library POMs, the parent and optional app weekly, with
separate Maven and SHA-pinned Actions groups and grouped Maven security updates.
Normal review and complete CI apply to automated PRs; no automatic merging is
configured. Review new action source and transitive downloads as well as pins.
+Baseline-sensitive API, JSP-engine and build-plugin dependencies are excluded only
+from the broad Maven **version-update group**, so their proposals receive individual
+review. They remain eligible for updates; the security-update group is unchanged.
+See [dependency decisions](DEPENDENCY_DECISIONS.md) for the current contracts,
+PR dispositions and conditions for reconsideration.
The nonstandard XML files under `compatibility/dependencies` remain explicit
manual compatibility fixtures. In particular Felix 5.6.12 is an intentional
OSGi R6/Java 8 baseline, not a production dependency; the Maven ignore prevents
diff --git a/.github/DEPENDENCY_DECISIONS.md b/.github/DEPENDENCY_DECISIONS.md
new file mode 100644
index 0000000..8b3e113
--- /dev/null
+++ b/.github/DEPENDENCY_DECISIONS.md
@@ -0,0 +1,66 @@
+# Dependency proposal decisions — 2026-09-26
+
+PRs [#176](https://github.com/OWASP/owasp-java-encoder/pull/176) and
+[#188](https://github.com/OWASP/owasp-java-encoder/pull/188) mixed ordinary build
+maintenance with changes to intentional tool/API/engine baselines. These decisions
+apply to the reviewed proposals, not to every future version or security advisory.
+The [1.x compatibility record](../docs/compatibility-decisions.md) and
+[build policy](../BUILDING.md) define the contracts being preserved.
+
+## Accepted build update
+
+Use Maven Bundle Plugin **6.2.0** in place of 6.1.2. Its bnd library moves from
+7.3.0 to 7.4.0; the [Felix release notes](https://felix.apache.org/documentation/news.html)
+include a fix for dependency resources entering JARs when a module descriptor is
+present. This is a packaging tool update, not a reason to change bundle identities,
+OSGi import floors, JPMS names, library dependencies or Java 8 runtime support.
+Validate generated JAR entries/manifests, original-JAR consumers and deterministic
+payloads after the change. Felix's **Maven plugin** is distinct from the deliberately
+old **OSGi framework** compatibility fixture.
+
+## Deferred proposals and reconsideration conditions
+
+| Proposal | Disposition and required evidence before reconsideration |
+| --- | --- |
+| Checkstyle 12.3.1 → 14.1.0 | Keep 12.3.1 for the JDK 17 build. PR #188 fails with Java 21 classfile version 65 on Java 17. Reconsider with a separately reviewed build/release-JDK migration and source-policy validation; this is not a claim that the old engine has upstream support. |
+| Plexus Utils 3.6.2 → 4.1.0 in GPG/Central plugin dependencies | Keep the reviewed 3.6.2 mitigation. The [upstream 4.x migration](https://github.com/codehaus-plexus/plexus-utils) moves XML utilities to a separate artifact; 4.1 also changes DirectoryScanner default exclusions. A newer major is not a drop-in plugin-realm security fix. Reconsider with actual plugin linkage, isolated signing/bundle/rehearsal evidence, transitive-advisory review and repeatable payloads. |
+| javax JSP 2.2.1 → 2.3.3 | Keep the published provided API and minimum fixture. A changed consumer POM dependency is observable even if no new API method is called. Reconsider only with explicit compatibility policy and old-container/OSGi/JPMS evidence. |
+| javax Servlet 3.0.1 → 4.0.1; EL 2.2.5 → 3.0.0 | Keep the test-only minimum API fixtures. These are not bundled production container implementations. Modern engine coverage is separate; replacing the minimum tests would remove evidence for existing consumers. |
+| Jakarta Pages 3.0.0 → 4.0.0 | Keep the published provided Pages 3 API and existing `[3.0,4)` package ranges. Reconsider only with a reviewed minimum-runtime/API migration, public POM implications and compatibility evidence. |
+| Jakarta Servlet 6.0.0 → 6.1.0; EL 4.0.0 → 6.0.1 | Keep the deliberate test API set. Reconsider test-baseline changes with explicit coverage goals and minimum-consumer evidence, rather than automatically matching the newest application container. |
+| Jasper/annotations 9.0.122 or 10.1.60 → 11.0.26 in the isolated tag fixtures | Keep coherent Tomcat 9 (`javax`) and 10.1 (`jakarta`) engines. PR #188 fails the javax engine with missing `javax.servlet.jsp.tagext.SimpleTagSupport` after the Tomcat 11 switch. The optional Boot/browser WAR already exercises Tomcat 11. Patch updates within each intended engine line remain reviewable; cross-line migration needs a separate coverage decision. |
+
+A dependency's test/build scope does not dismiss an advisory. Check each finding's
+actual affected versions, executed path and proposed remedy; use a supported fix
+or document a specific mitigation/decision. Security alerts remain visible. These
+proposals do not authorize raising a library or release baseline, and a future
+security fix may require revisiting a decision above.
+
+## Older PR #176
+
+Its GPG 3.2.8, Central 0.11.0, versions-maven-plugin 2.22.0, Boot 4.1.1 and
+optional-app API modernization were already delivered by #180/#185; #187 supplied
+the reviewed publisher-plugin mitigations. Site is deliberately disabled with an
+explicit lifecycle version. Doxia/Reflow and dormant project-info/FindBugs/PMD/JXR
+report tooling were retired in #185, so their old update proposals are obsolete.
+The versions plugin pin remains; only its old reporting execution was retired. The remaining Felix change is
+accepted above, and the library API proposals have explicit dispositions above.
+Close #176 as superseded, without restoring removed tooling or bypassing its
+failed tests. Replace #188's mixed group with the focused accepted change and this
+record; a grouped PR closure is not proof that every proposed upgrade was applied.
+
+## Future Dependabot proposals
+
+The [configuration](dependabot.yml) excludes the eleven baseline-sensitive
+coordinates above from the broad Maven **version-update group**, not from update
+eligibility. They therefore receive individual proposals and compatibility review;
+ordinary Maven changes can proceed separately. This follows GitHub's
+[group matching rules](https://docs.github.com/en/code-security/reference/supply-chain-security/dependabot-options-reference#groups).
+All original directories remain monitored. The Maven security-update group is
+unchanged, and no new `ignore` rules, security-alert dismissals or automatic merges
+are introduced. The pre-existing Felix framework fixture exception remains scoped
+and documented in [CI/security operations](CI_SECURITY.md).
+
+When a new proposal repeats a deferred baseline change, compare it with this dated
+record and any new advisory or upstream evidence. Do not automatically close a
+security proposal or infer permanent rejection from an older version decision.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 09ac4cf..ed10655 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -18,6 +18,21 @@ updates:
maven-dependencies:
applies-to: version-updates
patterns: ['*']
+ # These need individual compatibility review, not a mixed version PR.
+ # Group exclusions do not ignore updates or suppress security proposals.
+ # Rationale and revisit conditions: DEPENDENCY_DECISIONS.md.
+ exclude-patterns:
+ - org.apache.felix:maven-bundle-plugin
+ - com.puppycrawl.tools:checkstyle
+ - org.codehaus.plexus:plexus-utils
+ - javax.servlet.jsp:javax.servlet.jsp-api
+ - javax.servlet:javax.servlet-api
+ - javax.el:javax.el-api
+ - jakarta.servlet.jsp:jakarta.servlet.jsp-api
+ - jakarta.servlet:jakarta.servlet-api
+ - jakarta.el:jakarta.el-api
+ - org.apache.tomcat.embed:tomcat-embed-jasper
+ - org.apache.tomcat:tomcat-annotations-api
maven-security:
applies-to: security-updates
patterns: ['*']
diff --git a/pom.xml b/pom.xml
index ad9bf5d..0a11004 100644
--- a/pom.xml
+++ b/pom.xml
@@ -283,7 +283,7 @@
org.apache.felix
maven-bundle-plugin
- 6.1.2
+ 6.2.0
org.codehaus.mojo
diff --git a/releases/pr-queue-validation.md b/releases/pr-queue-validation.md
new file mode 100644
index 0000000..2c1fc05
--- /dev/null
+++ b/releases/pr-queue-validation.md
@@ -0,0 +1,77 @@
+# PR queue cleanup validation — 2026-09-26
+
+## Reviewed changes and preserved contracts
+
+PR #175 updates verified artifact-action pins together, retains named same-run ZIP
+transfer and makes download digest failures explicit. Local actionlint and all
+14 policy/verification tests passed. Sol and then Astra found no actionable issues
+on `9fafc772b8e7f55d44417a8b1f59b2ea69de2568`; all 28 checks passed before merge
+as `011734abc029726a115811b53228cdaa789e7232`. Post-merge workflow evidence is in #169.
+
+The focused Maven change replaces Bundle Plugin 6.1.2 with 6.2.0, which uses bnd
+7.4.0. The [dependency decision record](../.github/DEPENDENCY_DECISIONS.md) accounts
+for every proposal in #176/#188 and its reconsideration conditions. Eleven exact
+coordinates are excluded only from the broad version-update group. Parsed YAML
+comparison confirms all directories, schedules, existing ignores and the separate
+security-update group are unchanged. Exclusion from a group is not an update ignore.
+Sol corrected the attribution of the already delivered versions-maven-plugin
+2.22.0 upgrade; only its former reporting execution was retired.
+
+## Local build and packaged consumers
+
+A new isolated Maven repository/wrapper cache with reference Temurin 17.0.20.1+1
+and Maven 3.9.16 passed `./mvnw -B -ntp clean verify`: 2,178 unit tests, eight
+integration tests, API/Java 8 signature checks, coverage and both forked packaged
+JSP engines. All 17 artifact guards, 14 policy/verification tests and 34-file
+JSP/Jakarta parity passed. Original-JAR consumers passed locally on Java 17 across
+classpath, explicit/automatic JPMS and Felix R6/R8, including old-core rejection.
+Docker/browser and other runtime JVMs are checked by required PR CI, not claimed
+as locally executed. Final Sol/Astra review and exact-head CI evidence go in #169.
+
+Resolved the actual Bundle Plugin dependency closure before and after the change
+with dependency-plugin 3.11.0 `resolve-plugins`: both contain 61 distinct coordinates.
+The only replacements are the plugin 6.1.2 → 6.2.0, bndlib 7.3.0 → 7.4.0 and
+bnd.util 7.3.0 → 7.4.0. An OSV query on 2026-09-26 returned no matches for those
+three newly selected coordinates. This is a delta audit, not a claim that the
+58 unchanged plugin dependencies or the full build/runtime graphs are advisory-free.
+Existing alerts are not dismissed by this check, nor by test/build scope.
+
+## Reproducibility and artifact differences
+
+Two fresh `git archive` exports of implementation commit
+`d9d157d917c4b21208edcd52bdab5515e86a0a52` used separate empty Maven repositories
+and wrapper caches, reference Eclipse Temurin 17.0.20.1+1, Maven 3.9.16, macOS
+27.0 aarch64, UTC/C locale and explicit UTF-8/en-US JVM properties. The official
+Temurin archive matched its published SHA-256
+`196d13ba5f10414bef7f6a05a9b3f00edacb18ebacef2b99485db9e2ee18f0e8`.
+Both clean builds produced identical copies of all **17 payloads**. Subsequent
+workflow/documentation-only commits do not change artifact inputs. No cross-OS
+comparison, production signing, Portal upload or release/tag operation is claimed.
+
+Compared with the retained batch 05 reference payloads, all eight source/Javadoc
+JARs and four module POMs remain byte-identical. The parent POM changes only the
+Bundle Plugin version. Each of the four binary JARs has the same entry set and
+identical entry contents except `META-INF/MANIFEST.MF`, whose sole content change
+is `Created-By: Apache Maven Bundle Plugin 6.1.2` → `6.2.0`. No class/resource is
+added or removed; public identities, API ranges, bytecode and metadata are unchanged.
+Both copies and compact comparison/dependency evidence are retained locally.
+
+| Payload | SHA-256 (both builds) |
+| --- | --- |
+| `encoder-1.5.0-SNAPSHOT-javadoc.jar` | `a756dd361b2d6296fb2cb94f7f0c20c0a470d6dfaab7518832ca83b26641e7ca` |
+| `encoder-1.5.0-SNAPSHOT-sources.jar` | `0cd1292c1e03b9554be4f5c0d92ad4702f3a53da20e1c52b5f4423726370541a` |
+| `encoder-1.5.0-SNAPSHOT.jar` | `99749a02ade17e470dae672f8b4b0853f4dd6658b35dce5c9d07b9236e3c4cfb` |
+| `encoder-1.5.0-SNAPSHOT.pom` | `2c7a39dfb2b04ae75b2b8bda5695a2f3dee373ad0d7f36a55f1010aabe463afe` |
+| `encoder-esapi-1.5.0-SNAPSHOT-javadoc.jar` | `cd16a149a0c8aed8d1e244e88f7cde1f6ae482e212dc2377afdb05f63549874b` |
+| `encoder-esapi-1.5.0-SNAPSHOT-sources.jar` | `de93cb5d0d4233263f9ed175406fb93215611bc108507a4d31f2b7e3bb21e8c4` |
+| `encoder-esapi-1.5.0-SNAPSHOT.jar` | `e16e812e6efe844bb8f09630162714b86fda8e647fc5c7331eac431c7e951288` |
+| `encoder-esapi-1.5.0-SNAPSHOT.pom` | `8876d4eac1ad4f23117e0e27a9d184fbdbf20ab35e57bb8a88c2451a750c0e03` |
+| `encoder-jakarta-jsp-1.5.0-SNAPSHOT-javadoc.jar` | `494b1e428320798d2678eaf1e0d9f42efc45926b70b0065d8198d74ff7ea53c8` |
+| `encoder-jakarta-jsp-1.5.0-SNAPSHOT-sources.jar` | `b8743c89d737a415fc571f8e31cb8d6a11c1a113841bd4bea8ba771eed8bb533` |
+| `encoder-jakarta-jsp-1.5.0-SNAPSHOT.jar` | `e010c046b84d27b8852a89fc989199e4989063ae430c10f08d4c643a58e52234` |
+| `encoder-jakarta-jsp-1.5.0-SNAPSHOT.pom` | `df4eece564afbb1aeecda9b05d0f8b190a1bc7d1e92f1bf4829a6c4df78847f4` |
+| `encoder-jsp-1.5.0-SNAPSHOT-javadoc.jar` | `5dcbfc0e53938e69dae6345e43ba310f7d0e3bc2e67b4c105c85a9601aac2fb2` |
+| `encoder-jsp-1.5.0-SNAPSHOT-sources.jar` | `81b201dd6965a8add5726198665d65cf6f258da8e3986a670c4f976ca63f8e7f` |
+| `encoder-jsp-1.5.0-SNAPSHOT.jar` | `58cac1f9cd50ca012e5d161edbce8cebd4da392da04d8530269fbb051145545d` |
+| `encoder-jsp-1.5.0-SNAPSHOT.pom` | `c2e21aa5107fc215a6cae907776b4c2ee889376b226ae948f1ad841c4910d5ca` |
+| `encoder-parent-1.5.0-SNAPSHOT.pom` | `7fbb00ce7f35849eb1476c060ac70207b65f0a69d603252cdadc44aa91bc201d` |