This is an automated email from the ASF dual-hosted git repository.

Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new aa8a0cca57 docs: define client boundaries, compatibility and server 
evolution (#7947)
aa8a0cca57 is described below

commit aa8a0cca5798a4bc7cd0b5020fd945d3a72a011e
Author: redyyang <[email protected]>
AuthorDate: Fri Oct 23 11:16:57 2026 +0800

    docs: define client boundaries, compatibility and server evolution (#7947)
    
    * docs: define client boundaries, compatibility and server evolution
    
    * docs: specify asynchronous registration field requirements
    
    * docs(client): date verification of pinned compatibility evidence
---
 docs/cross-repo-compatibility-testing.md    | 134 +++++++++++++
 docs/java-client-compatibility.md           | 121 ++++++++++++
 docs/java-client-repository-boundary.md     | 140 +++++++++++++
 docs/registration-protocol-compatibility.md | 224 +++++++++++++++++++++
 docs/server-jdk-upgrade.md                  | 205 +++++++++++++++++++
 docs/virtual-thread-design.md               | 297 ++++++++++++++++++++++++++++
 shenyu-dist/README.md                       |  13 ++
 7 files changed, 1134 insertions(+)

diff --git a/docs/cross-repo-compatibility-testing.md 
b/docs/cross-repo-compatibility-testing.md
new file mode 100644
index 0000000000..e10ff452c8
--- /dev/null
+++ b/docs/cross-repo-compatibility-testing.md
@@ -0,0 +1,134 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# Cross-repository registration compatibility testing
+
+Proposal for #6367. This specifies test ownership, artifacts and promotion 
gates;
+it does not claim that independent-client deployment jobs already exist.
+The main repository and shenyu-client-java keep independent JDK baselines and 
releases.
+
+## Scenarios and observable outcomes
+
+| Scenario | Exercise | Required evidence |
+| --- | --- | --- |
+| HTTP metadata | Start a minimal Spring MVC application using the selected 
client starter; authenticate and register a unique endpoint/namespace | One 
persisted selector/rule/metadata identity with the expected path, protocol and 
enablement; a success acknowledgement alone is insufficient |
+| Service address | Register the application's bound host/port, then send the 
same event again and concurrently through two Admin instances | Exactly one 
logical upstream and selector; no duplicate-key/TooManyResults failures |
+| Heartbeat | Send beats, restart one Admin, then stop beats | Persisted last 
heartbeat advances; configured timeout marks the instance offline; another 
Admin's missing local heartbeat does not overwrite valid persisted liveness |
+| Gateway | Start bootstrap with a real sync transport; wait for the unique 
route, then send a request through the gateway | Exact upstream 
response/status/body and route identity; no direct backend request counted as 
gateway success |
+| Offline/crash | Gracefully close one client, then forcibly stop a second 
upstream without an offline callback | Route removal after 
deregistration/active checks; healthy siblings remain usable; empty final 
snapshot removes stale gateway destinations |
+| Independent discovery | Register/discover/deregister with one real 
disposable provider | Provider key/serialization compatibility and expiry/watch 
removal; test each provider claimed by a release |
+| MCP | Register a known tool, list/invoke through bootstrap, restart 
bootstrap and repeat | Correct schema/result without manually toggling a rule; 
test rule-before-selector and selector-before-rule replay |
+| Version negotiation | Replay headerless v1, explicit v1, 
unsupported/multiple headers and additive unknown fields | Legacy behavior 
preserved; invalid versions rejected before enqueue; new optional fields do not 
break old receivers |
+| API documentation | Submit a serialized document and query its persisted 
detail | Body/schema and source code preserved, independently of deprecated 
viewers |
+
+Use a distinct test namespace, application name and port per run. Poll 
observable
+readiness with a deadline; do not use fixed sleep as success. On timeout retain
+redacted logs, current route/instance state and the last unsuccessful response.
+
+## Matrix and scheduling
+
+Resolve immutable client coordinates plus source ref and Admin/bootstrap image 
digest
+plus source ref. Record the actual application, build and runtime JDK 
vendor/patch.
+Never use an unpinned moving SNAPSHOT to certify a release.
+
+| Lane | Client | Admin/bootstrap | JDKs | Trigger / budget estimate |
+| --- | --- | --- | --- | --- |
+| Main PR contract | Serialized legacy and additive-field fixtures, no shared 
DTO dependency | Changed main code | Main baseline 17; Java 21 compatibility 
lane | Every registration/DTO/heartbeat/sync change; roughly 2-5 minutes warm |
+| Client PR contract | Candidate client plus serialized receiver fixtures | 
Pinned current stable Admin when the change touches wire semantics | Client 
baseline 8 and one 17/21 application lane; server 17 | Relevant client PRs; 
roughly 5-10 minutes warm |
+| Main PR deployed smoke | Pinned supported independent-client artifact | 
Candidate Admin/bootstrap | Application 8 or 17 according to starter; server 17 
| Registration/identity/sync changes; roughly 5-10 minutes warm |
+| Nightly | Oldest supported and latest released client, plus candidate client 
| Latest stable and candidate main | Client 8/17/21; main 17/21 | Sparse 
representative combinations; roughly 15-30 minutes with parallel jobs |
+| Release | Every pair claimed supported in the matrix | Candidate and oldest 
supported receiver, including upgrade/rollback | Include 23/25 only where 
explicitly claimed; incompatible baselines excluded | Before release promotion; 
roughly 30-60 minutes with provider lanes |
+
+These are planning budgets, not measured results. Measure cold image/artifact 
downloads
+separately and update budgets after the first ten CI runs. Do not multiply 
every
+framework, JDK and registry into every PR. Release scope must still cover all
+combinations advertised as supported. Keep runtime support, configured CI and 
passing
+deployment evidence distinct in [the matrix](java-client-compatibility.md).
+
+## Harness and artifact selection
+
+Implement a versioned external-process harness owned jointly by registration 
and
+client maintainers. Each repository invokes the same scenario protocol with 
inputs:
+
+- client repository ref or published Maven coordinates, client application JDK;
+- main repository ref or published Admin/bootstrap image digests, server JDK;
+- database image/digest, sync channel, optional registry image/digest;
+- unique namespace, startup/route/heartbeat deadlines and output directory.
+
+For a main PR, build candidate Admin/bootstrap with the repository Maven 
wrapper.
+Build the fixture application using a pinned released split-client starter 
from the
+artifact repository; inspect its dependency tree to reject accidental in-tree
+client/register DTO dependencies. A one-time candidate-client lane can accept a
+counterpart ref explicitly, recording both commit IDs.
+
+For a client PR, build/install only candidate client artifacts into an 
isolated Maven
+repository or publish an expiring CI artifact. Launch the fixture with those 
exact
+artifacts against pinned stable server images. Do not build server sources 
from the
+client checkout or silently substitute an in-tree client if artifact 
resolution fails.
+
+The minimum environment is H2 Admin, bootstrap with WebSocket sync and one 
independent
+Spring MVC fixture process. Use Docker Compose for process/network isolation or
+Testcontainers with a bounded shared network and dynamically mapped host ports.
+The fixture must announce its actual bound container address/port; localhost 
inside
+a container refers to that container. A local-process equivalent is useful for
+contributors without Docker, but must record different topology and cannot 
certify
+provider/image parity.
+
+Exercise one real registry in the first discovery lane (choose a provider 
supported
+by both selected artifacts). Add provider-specific Testcontainers/Compose 
services
+later. Registry mocks do not establish session expiry/watch compatibility. 
Separate
+MCP fixture dependencies from the small HTTP fixture so framework requirements 
do not
+raise the ordinary client's Java 8 baseline.
+
+## First implementation
+
+1. Land this contract, [protocol 
inventory](registration-protocol-compatibility.md)
+   and version matrix. Keep existing RegistrationProtocolCompatibilityTest as a
+   fast receiver gate.
+2. Add one minimal external Spring MVC fixture and a harness command accepting
+   explicit client coordinates and server images. Prove authentication, 
persistence,
+   heartbeat and proxying, then stop the backend and require route eviction.
+3. Add a single main-PR deployed smoke lane for registration-related paths and 
a
+   client-PR lane against stable Admin. Gate promotion only after establishing 
a
+   reliable baseline; fail visibly on unresolved dependencies rather than 
skipping.
+4. Add reverse skew, two Admins, independent discovery, MCP restart and 
database
+   upgrade/rollback to nightly/release lanes. Expand advertised support only 
when
+   corresponding evidence is retained.
+
+## Failure handling, cost and release evidence
+
+Set a job deadline, individual readiness deadlines and bounded retry/backoff.
+Distinguish artifact-download/setup failure from assertion failure, but 
neither is
+a passing compatibility result. Retry the environment at most once and 
preserve the
+first failure. Never retry only an assertion until it becomes green.
+
+Cache immutable Maven downloads and image layers; keep candidate artifacts 
isolated.
+Use changed-path selection for PR cost, explicit cancellation of superseded PR 
runs
+and bounded concurrency. Always close clients, gateways, Admins and registry 
services
+in finally/CI cleanup, including failed startups. Redact credentials and 
payload secrets.
+
+Persist a machine-readable result containing both refs/digests, Maven 
coordinates,
+actual JDKs, provider/database versions, enabled features, command, duration 
and each
+assertion outcome. Attach fixture dependency trees and redacted process logs.
+A release checklist must link this evidence and the matching 
compatibility-matrix
+row, identify reviewer ownership and document known exclusions. Block supported
+status when a required lane fails or was not run.
+
+This proposal adds no requirement for Java clients to upgrade JDK with the 
server.
+Build/release maintainers own CI/image integrity, Admin/runtime owners review 
routing
+and liveness assertions, and client owners review framework/wire fixtures.
+
diff --git a/docs/java-client-compatibility.md 
b/docs/java-client-compatibility.md
new file mode 100644
index 0000000000..ca6ed69315
--- /dev/null
+++ b/docs/java-client-compatibility.md
@@ -0,0 +1,121 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+# Java client and server compatibility
+
+Evidence last verified: 2026-10-22. The client CI run 35421426447 and server CI
+run 38836735672 below still refer to the pinned commits recorded in this 
matrix;
+this date does not certify newer commits or untested deployment combinations.
+
+This matrix describes business application registration through 
[shenyu-client-java](https://github.com/apache/shenyu-client-java) to ShenYu 
Admin, and the JDK requirements of Admin and bootstrap. It addresses [issue 
#6370](https://github.com/apache/shenyu/issues/6370).
+
+## Version dimensions and support levels
+
+Record these dimensions separately when selecting or verifying a deployment:
+
+| Dimension | What to record |
+| --- | --- |
+| Client | Exact Maven artifact versions and source tag or commit from 
`shenyu-client-java`, client starter, application framework version, and 
registration transport. Keep artifacts from the same client release together. |
+| Admin | Exact main repository release or commit, enabled registration 
endpoints, authentication settings, and registry implementation. |
+| Bootstrap | Exact main repository release or commit, gateway plugins, and 
Admin-to-gateway sync channel. Keep Admin and bootstrap on the same release by 
default; mixed server versions require separate sync and plugin verification. |
+| JDK | Build JDK and runtime JDK for the application, Admin, and bootstrap 
independently, including vendor and patch version when recording test results. |
+| Protocol | Registration wire format and capabilities, independently of the 
client artifact version. Non-HTTP registration also requires registry-specific 
verification. |
+
+The client runs in the business application's JVM. It can use JDK 8 while 
Admin and bootstrap use JDK 17 in separate JVMs. An independent client version 
need not equal the main repository version. Do not replace server-side 
dependencies with client artifacts to make their version numbers match.
+
+Support and test evidence have different meanings:
+
+| Level | Meaning |
+| --- | --- |
+| **Supported** | A declared JDK baseline, or an exact released 
client/Admin/bootstrap combination with recorded successful release 
verification. JDK support alone does not certify a client/server pair. |
+| **Best effort** | A plausible combination above the JDK baseline or within 
the shared registration contract, without complete verification for that 
combination. Verify it before deployment; optional features can require a newer 
server. |
+| **Unsupported** | A JDK below the component's baseline, an incompatible 
application framework or dependency, or a required protocol/capability absent 
from the receiver. Upgrade or select compatible artifacts. |
+
+The **runtime baseline** is the minimum declared Java level. The effective 
minimum also includes the selected starter, framework, plugins, and transitive 
dependencies. A compiler `source`/`target` setting alone does not prove that 
the resolved application can run on that JDK.
+
+**Verified** means a recorded successful test, with its scope stated. 
**Configured CI** means a workflow schedules tests; it does not establish that 
a run passed. Unit tests and controller fixtures do not establish full 
application startup, database persistence, registry behavior, or gateway 
routing. A release row must link passing results before claiming those scopes.
+
+## Version compatibility matrix
+
+The initial evidence snapshot uses split-client commit 
[`8b93088973bf`](https://github.com/apache/shenyu-client-java/tree/8b93088973bf9f8f50d614e708bb87f662b707d5)
 and main repository `2.7.2-SNAPSHOT` at 
[`297ac6f84985`](https://github.com/apache/shenyu/tree/297ac6f849857bd0c2ad368709013e98494b0330),
 checked on 2026-10-16. Historical source tags are listed explicitly. Snapshot 
coordinates are mutable: pin a commit when reproducing results.
+
+| `shenyu-client-java` version / source | Main repo Admin / bootstrap version 
| Client JDK baseline | Client JDK verified versions / scope | Admin / 
bootstrap JDK baseline | Registration protocol compatibility | Status / notes |
+| --- | --- | --- | --- | --- | --- | --- |
+| Tag `v2.7.0.1-jdk8`; POM declares `2.7.0.1-jdk8-SNAPSHOT` | `2.7.0.1` / 
`2.7.0.1` | 8 | No passing run recorded here; tag configures CI on 8, 11, 17 | 
17 | Legacy HTTP registration; exact pair not verified here | **Best effort**. 
A source tag alone does not establish a published non-SNAPSHOT artifact. |
+| `2.7.0.1-jdk8-SNAPSHOT` at `8b93088973bf` | `2.7.0.1` / `2.7.0.1` | 8 | 8, 
17, 21, 23, 25: passing client reactor CI on 2026-09-19; see evidence below | 
17 | Common legacy HTTP endpoints only; verify required capabilities on this 
Admin | **Best effort**. New client features are not implied by an older server 
version. |
+| `2.7.0.1-jdk8-SNAPSHOT` at `8b93088973bf` | `2.7.1` / `2.7.1` | 8 | 8, 17, 
21, 23, 25: passing client reactor CI on 2026-09-19 | 17 | Common legacy HTTP 
endpoints; exact pair not verified here | **Best effort**. Client-only tests do 
not certify this server pair. |
+| `2.7.0.1-jdk8-SNAPSHOT` at `8b93088973bf` | `2.7.2-SNAPSHOT` / 
`2.7.2-SNAPSHOT` | 8 | 8, 17, 21, 23, 25: passing client reactor CI on 
2026-09-19 | 17 | Admin HTTP v1 controller fixtures pass on JDK 17, including 
headerless requests; split-client end-to-end verification remains pending | 
**Best effort**, development combination. Main snapshot CI is not fully 
passing; verify heartbeat, discovery, MCP, persistence, sync, and routing 
before promotion. |
+
+No split-client/server pair above is advertised as fully verified or supported 
for production solely from these sources. Combinations not listed are best 
effort only when their JDKs, frameworks, and required wire contracts are 
compatible; otherwise they are unsupported. Add an exact release row with 
passing evidence to promote a pair to **Supported**. Older in-tree clients use 
their own main release's POM and documentation; the split client's JDK 8 
baseline does not apply to those artifacts.
+
+Evidence for the version rows:
+
+- Tagged split-client 
[POM](https://github.com/apache/shenyu-client-java/blob/22a3cca759b3592dc4a8c9fb45c144ec79d43146/pom.xml)
 and 
[CI](https://github.com/apache/shenyu-client-java/blob/22a3cca759b3592dc4a8c9fb45c144ec79d43146/.github/workflows/ci.yml):
 Java 8, Spring Boot 2.7.18, and the original CI matrix. Do not transfer later 
test results to this tag.
+- Current split-client 
[POM](https://github.com/apache/shenyu-client-java/blob/8b93088973bf9f8f50d614e708bb87f662b707d5/pom.xml)
 and 
[CI](https://github.com/apache/shenyu-client-java/blob/8b93088973bf9f8f50d614e708bb87f662b707d5/.github/workflows/ci.yml):
 Java 8 and Spring Boot 2.7.18. [CI run 
35421426447](https://github.com/apache/shenyu-client-java/actions/runs/35421426447)
 passed all five JDK reactor jobs on 2026-09-19 for this exact commit. The 
[migration verification record](https:/ [...]
+- Main release POMs for 
[2.7.0.1](https://github.com/apache/shenyu/blob/v2.7.0.1/pom.xml) and 
[2.7.1](https://github.com/apache/shenyu/blob/v2.7.1/pom.xml): Java 17 and 
Spring Boot 3.3.1. Their CI configurations are [2.7.0.1 
CI](https://github.com/apache/shenyu/blob/v2.7.0.1/.github/workflows/ci.yml) 
and [2.7.1 
CI](https://github.com/apache/shenyu/blob/v2.7.1/.github/workflows/ci.yml); 
configured jobs are not release verification evidence.
+- Current main [POM](../pom.xml), [CI](../.github/workflows/ci.yml), and 
[registration compatibility 
tests](../shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/RegistrationProtocolCompatibilityTest.java).
 For `297ac6f84985`, the [JDK 17 registration fixture 
job](https://github.com/apache/shenyu/actions/runs/38836735672/job/116767753175)
 passed on 2026-10-16. The [JDK 17 admin-sync 
group](https://github.com/apache/shenyu/actions/runs/38836735672/job/116769383235)
 and [Java 21 [...]
+
+## JDK support policy
+
+This table applies to the current source snapshot above. Historical tags 
retain their own dependencies and test evidence. Build with the repository's 
Maven wrapper and a JDK that meets its baseline; verify the packaged 
application on the intended runtime JDK separately.
+
+| JDK | Split client runtime policy | Client test evidence | Main Admin / 
bootstrap runtime policy | Main test evidence |
+| --- | --- | --- | --- | --- |
+| 8 | **Supported baseline** for the JDK 8 client line and compatible 
application dependencies | Passing client reactor CI on 2026-09-19 | 
**Unsupported**, below Java 17 baseline | No current Java 8 lane |
+| 11 | **Best effort**, above client baseline | Tagged source configures CI; 
no current passing result recorded here | **Unsupported**, below Java 17 
baseline | No current Java 11 lane |
+| 17 | **Supported** client JDK target, subject to application framework 
compatibility | Passing client reactor CI on 2026-09-19 | **Supported 
baseline** | Registration fixtures pass; admin-sync group fails in the recorded 
snapshot run |
+| 21 | **Supported** client JDK target, subject to application framework 
compatibility | Passing client reactor CI on 2026-09-19 | **Best effort** 
runtime beyond the baseline until passing checks and deployment smoke tests are 
recorded | `compat_java21` fails in the recorded snapshot run; no full runtime 
result recorded here |
+| 23 | **Best effort**; test success does not extend every framework's runtime 
support | Passing client reactor CI on 2026-09-19 | **Best effort**, 
unverified; check framework and plugin requirements | No current Java 23 lane |
+| 25 | **Best effort**; test success does not extend every framework's runtime 
support | Passing client reactor CI on 2026-09-19 | **Best effort**, 
unverified; check framework and plugin requirements | No current Java 25 lane |
+
+Keep the split client's Java 8 baseline unless a client release explicitly 
raises it. Its current Spring Boot 2.7 dependency line does not certify Spring 
Boot 3 applications simply because they run on JDK 17 or later. Select a 
compatible starter and framework together. Likewise, changing the server's 
compiler target to 8 cannot make its Spring Boot 3 dependencies run on JDK 8.
+
+## Registration and version skew
+
+For the current main source, the [HTTP v1 
contract](../shenyu-register-center/shenyu-register-protocol/src/main/java/org/apache/shenyu/register/common/protocol/RegistrationProtocol.java)
 is independent of Maven release numbers. Its [Admin 
interceptor](../shenyu-admin/src/main/java/org/apache/shenyu/admin/config/RegistrationProtocolInterceptor.java)
 treats a missing `X-Shenyu-Register-Protocol-Version` header as v1 and accepts 
an explicit value of `1`. It rejects other explicit values, in [...]
+
+The interceptor advertises `X-Shenyu-Register-Protocol-Version: 1` and 
`X-Shenyu-Register-Capabilities` on the covered POST endpoints. Capabilities 
are `metadata`, `uri`, `api-doc`, `discovery-config`, `mcp`, `offline`, and 
`heartbeat`. `X-Shenyu-Client-Version` identifies an implementation; it is not 
a protocol version or a compatibility guarantee. The inspected split client 
uses legacy requests without these negotiation headers; do not assume it 
already negotiates or downgrades capabil [...]
+
+| Direction / combination | Expectation and required action |
+| --- | --- |
+| Old client to new Admin | Preserve the legacy v1 paths, field meanings, 
defaults for missing optional fields, authentication, and response body. 
Current Admin fixtures cover headerless requests and optional fields. Verify a 
real old client before marking an exact release pair supported. |
+| New client to old Admin | Use only endpoints and field semantics understood 
by that Admin. Missing capability headers mean capabilities are unknown. Verify 
the required subset explicitly, disable optional features only when the client 
supports doing so, or upgrade Admin. Do not assume automatic fallback. |
+| Same protocol with additive optional fields | Current Admin fixtures check 
that unknown fields are tolerated and missing optional fields retain defaults. 
Check the older receiver independently; do not generalize current receiver 
behavior to historical releases. |
+| Required endpoint/capability absent, or explicit incompatible protocol 
version | **Unsupported** for that feature or protocol. A new client version 
cannot add an endpoint to an old Admin. Required field changes or changed 
meanings need an explicit protocol migration and new matrix evidence. |
+| Mixed Admin/bootstrap releases or registry transports | **Best effort** 
until the exact sync channel, registry versions, payloads, plugins, and routing 
behavior are tested. HTTP controller fixtures do not verify ZooKeeper, Nacos, 
etcd, or another registry transport. |
+
+The current controller fixtures cover metadata, URI registration (including 
heartbeat-enabled URI payloads), offline, API docs, discovery config, MCP, and 
heartbeat. They mock registration publishing and use standalone MVC 
controllers. Their scope ends before database persistence, live registry 
discovery, Admin-to-gateway synchronization, and gateway requests.
+
+Upgrade Admin and bootstrap as a verified server pair before enabling client 
features that require new capabilities. Existing clients can then be upgraded 
independently within the tested wire contract. Keep old capabilities available 
during a rolling upgrade, and test rollback with the old client payloads and 
server data before publishing a compatibility claim.
+
+## Updating the matrix
+
+Use the [release compatibility 
checklist](../shenyu-dist/README.md#release-compatibility-checklist) for every 
main or client release, and whenever the JDK baseline, application framework, 
registration contract, or registry transport changes. Update this document in 
the same change as the compatibility change. Preserve historical rows and their 
evidence; add rows for new releases instead of treating a newer snapshot as 
proof for an older tag.
+
+For each new row, record exact client artifact versions and source ref, Admin 
and bootstrap versions, client JDK baseline and successfully tested JDKs, 
server JDK baseline and successfully tested JDKs, transport, capabilities, 
support level, limitations, and dated links to results. Separate configured 
jobs, reported local results, passing CI, and full deployment verification. A 
failed required check prevents promotion; keep unverified combinations marked 
best effort and document known in [...]
+
+Release verification must exercise application startup with the selected 
client starter, authenticated registration, persisted metadata and service 
addresses, heartbeat and offline behavior, discovery, sync to bootstrap, and a 
request through the required gateway plugin. Include API docs and MCP when 
claimed by the row. Test an old client with the candidate Admin and the 
candidate client with the oldest Admin claimed by the row, including upgrade 
and rollback.
+
+The existing controller fixture suite can be replayed from the main repository 
with:
+
+```bash
+./mvnw -B -ntp -pl shenyu-admin -am test \
+  -Dtest=RegistrationProtocolCompatibilityTest \
+  -Dsurefire.failIfNoSpecifiedTests=false -Djacoco.skip=true
+```
+
+Run the independent client repository's `./mvnw -B clean test` with each 
claimed client JDK. Run the main repository's checks and deployment smoke tests 
with each claimed server runtime. Use `mvnw.cmd` on Windows. Attach the exact 
commands, JDK versions, source refs, and results to the release evidence; these 
commands alone do not certify a client/server pair.
diff --git a/docs/java-client-repository-boundary.md 
b/docs/java-client-repository-boundary.md
new file mode 100644
index 0000000000..5c19dce0c6
--- /dev/null
+++ b/docs/java-client-repository-boundary.md
@@ -0,0 +1,140 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+# Boundary between ShenYu and shenyu-client-java
+
+This document defines the responsibility boundary for [issue 
#6364](https://github.com/apache/shenyu/issues/6364). Use it when moving or 
changing Java registration clients, starters, registration payloads, heartbeat, 
discovery instance registration, or MCP registration. The [wire 
contract](registration-protocol-compatibility.md) and [cross-repository test 
strategy](cross-repo-compatibility-testing.md) define the shared behavior and 
verification.
+
+The main repository owns Admin and gateway behavior. 
[shenyu-client-java](https://github.com/apache/shenyu-client-java) owns the 
Java registration code embedded in business applications. They communicate 
through documented wire contracts and can release independently. The split 
client preserves its JDK 8 baseline; the main repository currently requires JDK 
17 and can evolve its server JDK and threading model independently.
+
+## Inventory and migration baseline
+
+Inventory checked on 2026-10-16 against main repository `2.7.2-SNAPSHOT` at 
[`297ac6f84985`](https://github.com/apache/shenyu/tree/297ac6f849857bd0c2ad368709013e98494b0330)
 and split-client commit 
[`8b93088973bf`](https://github.com/apache/shenyu-client-java/tree/8b93088973bf9f8f50d614e708bb87f662b707d5).
 The tables distinguish current source locations from the intended ownership. 
Client sources still present in the main reactor are migration work, not a 
second long-term implementation t [...]
+
+### Client-related code still in the main repository
+
+Paths below are relative to the main repository. The [root 
reactor](../pom.xml), [client reactor](../shenyu-client/pom.xml), [registration 
reactor](../shenyu-register-center/pom.xml), and [client starter 
reactor](../shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/pom.xml)
 provide the module inventory.
+
+| Current module or area | Contents | Ownership after separation |
+| --- | --- | --- |
+| `shenyu-client/shenyu-client-core` | Annotation scanning, registration 
lifecycle, API extraction, discovery instance registration, and client events | 
Split client |
+| `shenyu-client/shenyu-client-http/shenyu-client-springmvc` | Spring MVC 
endpoint registration | Split client |
+| 
`shenyu-client/shenyu-client-dubbo/{shenyu-client-dubbo-common,shenyu-client-apache-dubbo}`
 | Dubbo annotations, metadata extraction, and registration | Split client |
+| `shenyu-client/shenyu-client-{grpc,sofa,tars}` | Framework-specific client 
registration | Split client |
+| `shenyu-client/shenyu-client-websocket/shenyu-client-spring-websocket` | 
Spring WebSocket endpoint registration | Split client |
+| 
`shenyu-client/shenyu-client-mcp/{shenyu-client-mcp-common,shenyu-client-mcp-register}`
 | MCP annotations, tool extraction, and registration | Split client |
+| `shenyu-client/shenyu-client-{api-docs-annotations,autoconfig}` | API 
documentation annotations and client auto-configuration | Split client |
+| `shenyu-spring-boot-starter/shenyu-spring-boot-starter-client` | Child 
starters: `common`, `springmvc`, `apache-dubbo`, `grpc`, `sofa`, `tars`, 
`spring-websocket`, `mcp`, and `beat` (each prefixed 
`shenyu-spring-boot-starter-client-`) | Application starters belong to the 
split client; separate bootstrap heartbeat integration as described below |
+| 
`shenyu-register-center/shenyu-register-client/{shenyu-register-client-api,shenyu-register-client-http}`
 | Registration SDK, retry handling, and HTTP transport | Split client; 
equivalent code is currently inside its `shenyu-client-core` |
+| `shenyu-register-center/shenyu-register-client-beat` | Heartbeat sender, 
currently including bootstrap-specific configuration | Split client owns 
reusable sending support; main owns bootstrap configuration and lifecycle 
integration |
+| `shenyu-register-center/shenyu-register-protocol` | Registration DTOs, 
event/data types, registration paths, and HTTP version/capability constants | 
Main owns its receiver-side representations; the wire contract is reviewed 
across both repos |
+| `shenyu-register-center/shenyu-register-common` | Mixed registration 
configuration, queue subscribers, `RegisterUtils`, and `OkHttpTools` | Split by 
use: main keeps server configuration/consumption; client keeps its own 
configuration, HTTP, and retry implementation |
+| `shenyu-register-center/shenyu-register-mcp` | MCP models and tool 
generation also consumed by Admin's Swagger import | Main keeps Admin-side 
import/generation; split client owns application-side extraction/generation |
+| `shenyu-registry/shenyu-registry-api` | Registry SPI, instance entity, 
configuration, events, and path conventions used by discovery registration | 
Main keeps gateway/Admin registry APIs; split client has a local API subset. 
Review actual registry wire formats across both repos |
+| `shenyu-common` | Registration path aliases and discovery models/utilities 
used by in-tree clients, alongside server models | Main keeps server 
models/utilities; client uses minimal local equivalents rather than depending 
on the full module |
+
+Braces in paths abbreviate multiple modules. The registration client reactor 
currently contains API and HTTP modules. ZooKeeper, Nacos, etcd, and other 
instance registry implementations under `shenyu-registry` are a separate 
concern from HTTP metadata registration.
+
+### Modules restored in shenyu-client-java
+
+The pinned split-client [root 
POM](https://github.com/apache/shenyu-client-java/blob/8b93088973bf9f8f50d614e708bb87f662b707d5/pom.xml)
 and [migration 
record](https://github.com/apache/shenyu-client-java/blob/8b93088973bf9f8f50d614e708bb87f662b707d5/progress.md)
 establish the current inventory. Paths here are relative to that repository; 
it has no `shenyu-client/` parent directory.
+
+| Module or area | Current state |
+| --- | --- |
+| `shenyu-client-core` | Contains local DTOs, constants, configuration, 
utilities, registration interfaces, HTTP registration, retries, and discovery 
listeners under `org.apache.shenyu.client.core.*`. These replace dependencies 
on main-repo `common` and `register.common` sources |
+| `shenyu-client-http/shenyu-client-springmvc` | Present |
+| 
`shenyu-client-dubbo/{shenyu-client-dubbo-common,shenyu-client-apache-dubbo}` | 
Present |
+| `shenyu-client-{grpc,sofa,tars,motan}` | Present; `motan` is in the split 
reactor but absent from the inspected main client reactor |
+| `shenyu-client-websocket/shenyu-client-spring-websocket` | Present |
+| `shenyu-client-mcp/{shenyu-client-mcp-common,shenyu-client-mcp-register}` | 
Restored, including MCP registration payload and HTTP path support |
+| `shenyu-client-{api-docs-annotations,autoconfig}` | Present |
+| `shenyu-spring-boot-starter-client` | All nine child starters listed in the 
main inventory are present; Spring MVC, gRPC, and Spring WebSocket discovery 
auto-configuration has been restored |
+| `shenyu-register-client-beat` | Restored, with client-local 
configuration/DTO support |
+| `shenyu-registry-api` | Restored API needed by instance registration; 
concrete registry provider modules are not in this reactor |
+
+The split client's POM declares Java 8 and Spring Boot 2.7.18. Restored source 
and a compilable API do not establish a working registry provider or full 
interoperability with Admin/bootstrap. The migration record leaves live beat, 
discovery, and MCP verification pending. No additional registration transport 
or framework support is implied by this inventory.
+
+## Responsibilities
+
+| Area | Main ShenYu repository | shenyu-client-java |
+| --- | --- | --- |
+| Admin and management APIs | Registration receivers, 
authentication/authorization, validation, persistence, dashboard APIs, health 
decisions, and configuration publication | Authentication calls and payload 
submission needed by registration; no access to Admin's database |
+| Bootstrap and gateway runtime | Launcher, WebFlux/plugin execution, routing, 
upstream selection, gateway caches, gateway lifecycle, and server-specific 
concurrency changes | Application registration lifecycle; no gateway runtime or 
plugin execution |
+| Plugins and sync | All gateway plugins, Admin listeners, and 
Admin-to-gateway data sync channels and payloads | No dependency on gateway 
sync implementations |
+| Java registration client and starters | Temporary in-tree copies until 
explicitly migrated/deprecated | Java annotations, framework adapters, API/docs 
extraction, client auto-configuration, configuration binding, registration SDK, 
HTTP/authentication, retry, and shutdown/offline behavior |
+| Beat | Receive and interpret beat messages, maintain instance health, and 
integrate bootstrap's own reporter | Reusable beat sender and client starter 
support compatible with the application's JDK/framework |
+| Discovery registration | Admin discovery management, registry 
watching/consumption, gateway upstream updates, and server-side registry 
implementations | Publish application instances and discovery configuration; 
own client-side listeners and any compatible provider adapters shipped for 
applications |
+| MCP | Registration receiver, Admin Swagger import, persistence/rule 
generation, and MCP gateway/server plugins | Application annotations, 
method/tool/schema extraction, and MCP registration requests |
+| Build and release | Server dependency management, server JDK baseline, 
server distributions, and deployment tests | Client dependency management, JDK 
8 compatibility, client artifacts/starters, and application-side tests |
+
+Gateway, plugin, sync, registry, SDK, and Kubernetes starters outside the 
`shenyu-spring-boot-starter-client` subtree remain in main. The request/signing 
SDK under `shenyu-sdk` and its starters are outside this registration-client 
split; moving them needs a separate scope decision. Examples and integration 
suites belong with the behavior they exercise and may use released client 
artifacts.
+
+## Cross-repository protocol contracts
+
+Share field meanings and wire behavior, not Java source trees. Each repository 
may represent the same message using its own DTOs, enums, and utilities. 
Matching Java package names, inheritance, builders, or Maven versions are not 
interoperability requirements.
+
+The main receiver's 
[RegistrationProtocol](../shenyu-register-center/shenyu-register-protocol/src/main/java/org/apache/shenyu/register/common/protocol/RegistrationProtocol.java),
 
[DTOs](../shenyu-register-center/shenyu-register-protocol/src/main/java/org/apache/shenyu/register/common/dto),
 [registration 
controller](../shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ShenyuClientHttpRegistryController.java),
 and [instance controller](../shenyu-admin/src/main/java/org/apache/s [...]
+
+| Contract point | Boundary and compatibility surface | Review areas |
+| --- | --- | --- |
+| Metadata, URI, API docs, and offline registration | Client to Admin: POST 
`/shenyu-client/register-metadata`, `/shenyu-client/register-uri`, 
`/shenyu-client/register-apiDoc`, and `/shenyu-client/offline`. Preserve JSON 
field names/types, RPC identifiers, namespace handling, event meanings, 
authentication, and success/error behavior | Admin registration + Java client 
registration; affected RPC plugin area for metadata semantics |
+| Beat | Service URI heartbeat uses `/shenyu-client/register-uri` with 
`eventType: HEARTBEAT`; instance reporting uses POST `/instance/beat` with 
`instanceIp`, `instancePort`, `instanceType`, `instanceInfo`, and 
`namespaceId`. These are distinct messages. Review identity, interval/expiry 
expectations, retry behavior, and health/offline transitions | Admin 
instance/health + Java client beat; bootstrap area for gateway reporting |
+| Discovery configuration and instance registration | Client to Admin: POST 
`/shenyu-client/register-discoveryConfig` carries discovery type, server list, 
listener node, handler, plugin, properties, and namespace. Client to registry: 
instance identity/address, status, weight, registry keys/paths, serialization, 
lifecycle, and removal semantics consumed by Admin/gateway | Admin discovery + 
Java client discovery + affected registry provider area |
+| MCP registration | Client to Admin: POST `/shenyu-client/register-mcp` 
carries `metaDataRegisterDTO`, `namespaceId`, and `mcpConfig`. The JSON inside 
`mcpConfig`, including tool/request configuration and schemas, is part of the 
contract too | Admin MCP registration + Java MCP client + MCP plugin area |
+
+Additional contract rules:
+
+- Preserve metadata/URI identity and field meanings such as `appName`, 
`contextPath`, `rpcType`, `host`, `port`, and `namespaceId`. Current Admin 
defaults a missing namespace for metadata, URI, discovery config, MCP, and 
offline requests. Verify API-doc and beat behavior separately instead of 
applying that default to every DTO.
+- Wire-visible event values such as `REGISTER`, `UPDATED`, `DELETED`, 
`OFFLINE`, and `HEARTBEAT` require compatibility review. Local disruptor 
queues, subscriber classes, and Java dispatch types remain implementation 
details unless a transport actually serializes them.
+- Registration constants such as endpoint paths, header names, success 
markers, namespace defaults, and registry path conventions describe contract 
values. They may have separate local definitions. Thread factories, HTTP 
wrappers, caches, reflection utilities, and retry executors are implementation 
details owned by their repo.
+- The current main HTTP v1 interceptor accepts a missing version header as v1 
and an explicit `X-Shenyu-Register-Protocol-Version: 1`. It rejects unsupported 
explicit versions or multiple version headers. It advertises 
`X-Shenyu-Register-Capabilities`; successful covered registration requests 
retain the plain `success` body. See the 
[interceptor](../shenyu-admin/src/main/java/org/apache/shenyu/admin/config/RegistrationProtocolInterceptor.java).
 Existing authentication remains required.
+- `X-Shenyu-Client-Version` identifies the implementation and does not select 
the wire protocol. The inspected split client still uses legacy requests; do 
not assume it negotiates capabilities or falls back automatically. These 
headers describe HTTP registration and do not version external registry 
payloads.
+- Java `InstanceEntity` and `DiscoveryUpstreamData` are local representations. 
Only the fields actually published through a registry, together with 
provider-specific paths and encodings, form the instance contract. Admin 
database IDs/timestamps and gateway cache structures need not be copied into 
the client.
+
+Admin-to-gateway sync is owned entirely by main and follows registration 
acceptance/persistence. A client registration protocol change must not require 
the application to import gateway `PluginData`, `SelectorData`, or other 
runtime cache models.
+
+## Remaining coupling and migration actions
+
+The following dependencies exist in the inspected main source. Their presence 
must be accounted for before deleting or moving any client-related module.
+
+| Remaining dependency | Evidence | Required treatment |
+| --- | --- | --- |
+| Admin consumes registration DTOs and constants | [Admin 
POM](../shenyu-admin/pom.xml) depends on `shenyu-register-common`; controllers, 
services, transfer code, and subscribers use 
`org.apache.shenyu.register.common.dto.*`, `EventType`, `DataType`, and 
`RegistrationProtocol` from the main `shenyu-register-protocol` module | Keep 
receiver-side contract representations in main. Removing client senders must 
not remove the DTOs or force Admin to depend on the split client's 
`client.core` c [...]
+| Admin consumes mixed registration infrastructure | 
[RegisterCenterConfiguration](../shenyu-admin/src/main/java/org/apache/shenyu/admin/config/RegisterCenterConfiguration.java)
 uses `ShenyuRegisterCenterConfig`; 
[RegisterServerConsumerExecutor](../shenyu-admin/src/main/java/org/apache/shenyu/admin/disruptor/executor/RegisterServerConsumerExecutor.java)
 uses queue subscriber types from `shenyu-register-common` | Retain server 
configuration and consumers. Separate unused client configurat [...]
+| Admin uses MCP generation code | 
[SwaggerImportServiceImpl](../shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImpl.java)
 imports `ShenyuMcpRequestConfig`, `ShenyuMcpTool`, and 
`McpToolsRegisterDTOGenerator` from `shenyu-register-mcp` | Keep or relocate 
Admin's generator/models within main. Coordinate generated MCP JSON with the 
independent application-side generator; do not copy client scanning/runtime 
code into Admin |
+| Bootstrap depends on a client-named beat starter | [Bootstrap 
POM](../shenyu-bootstrap/pom.xml) includes 
`shenyu-spring-boot-starter-client-beat`; 
[HeartbeatListenerConfiguration](../shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-beat/src/main/java/org/apache/shenyu/register/client/beat/HeartbeatListenerConfiguration.java)
 and 
[HeartbeatListener](../shenyu-register-center/shenyu-register-client-beat/src/main/java/org/apache/shenyu/registe
 [...]
+| Main common constants alias registration paths | 
[Constants](../shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java)
 delegates registration/login/beat path values to `RegistrationProtocol` | 
Retain local aliases while main callers need them. Do not replace main 
`shenyu-common` with client-core constants or require the split client to 
import server common |
+| In-tree registration clients depend on server common/utilities and registry 
API | 
[HttpClientRegisterRepository](../shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/main/java/org/apache/shenyu/register/client/http/HttpClientRegisterRepository.java)
 uses `Constants`, `GsonUtils`, `AesUtils`, and `RegisterUtils`; 
[InstanceRegisterListener](../shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/InstanceRegisterListener.java)
 u [...]
+
+The split client's pinned [core 
POM](https://github.com/apache/shenyu-client-java/blob/8b93088973bf9f8f50d614e708bb87f662b707d5/shenyu-client-core/pom.xml)
 and [registry API 
POM](https://github.com/apache/shenyu-client-java/blob/8b93088973bf9f8f50d614e708bb87f662b707d5/shenyu-registry-api/pom.xml)
 still use released `shenyu-disruptor`/`shenyu-spi` artifacts at `2.6.1`. These 
are explicit binary dependencies, not permission to import the current main 
reactor or a newer server dependency s [...]
+
+Do not add cross-repository source directories, relative parent POMs, or 
snapshot dependencies merely to reuse a DTO or utility. Do not place in-tree 
and split variants of the same client artifacts/classes on one application 
classpath. Migration PRs must select one implementation, account for 
coordinate/package compatibility, and document any consumer changes.
+
+## Review ownership and rules for future changes
+
+The review areas in the contract table are responsibility assignments by 
subsystem, not a claim that a named person has approved a protocol. Protocol 
PRs must request review from both the main receiver area and the split-client 
producer area. Include discovery/registry or MCP/plugin reviewers when those 
semantics change. Main-only implementation changes can stay with the relevant 
main area when the observable contract is unchanged.
+
+For any future PR that moves or modifies client-related code:
+
+1. Link this document and identify the owning repo, affected modules, and 
whether the wire contract changes. Keep server JDK upgrades and virtual-thread 
work in main; preserve Java 8-compatible source, bytecode, APIs, and runtime 
dependencies in the client line unless a separate client baseline change is 
approved.
+2. For a protocol change, describe old and new request/response examples, 
field types/defaults, authentication, capability/version behavior, and registry 
encodings where relevant. Link counterpart issues/PRs and obtain review from 
both producer and receiver areas before merging a breaking change.
+3. Prefer additive optional fields with compatible defaults. Renaming/removing 
fields or endpoints, changing required fields/types or enum meanings, changing 
success/error behavior, or changing registry identity/path/serialization 
requires an explicit protocol migration, coexistence period, and rollback plan. 
Preserve legacy headerless HTTP v1 clients during that migration.
+4. Release Admin support before enabling a new client capability. Record the 
minimum compatible Admin version and required capabilities. Client Maven 
versions and server Maven versions are independent; matching version numbers do 
not prove compatibility. Document behavior when a required endpoint or 
capability is absent, including old Admins that advertise no capabilities.
+5. Validate an old client against the candidate Admin and the candidate client 
against the oldest Admin claimed as compatible. Cover 
registration/authentication, API docs, heartbeat/offline, discovery, and MCP as 
applicable. Run the split client on its supported JDK/framework combinations 
and server checks on the server baseline. For discovery, exercise an actual 
provider and its watch/removal behavior.
+6. Run the main [registration compatibility 
fixtures](../shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/RegistrationProtocolCompatibilityTest.java),
 and use serialized payload fixtures on both sides so compatibility does not 
depend on shared Java classes. Controller mocks establish receiver behavior 
only; separately verify persistence, health handling, Admin-to-gateway sync, 
and gateway routing for end-to-end claims.
+7. Before removing an in-tree module, check production, test, example, 
starter, distribution, and dependency-management references. Preserve Admin 
DTO/config/MCP consumers and bootstrap heartbeat integration. Document artifact 
relocation/deprecation and ensure consumers can build against released client 
artifacts without the other repository's checkout.
+8. Update this inventory, contract documentation, release compatibility 
evidence, and release notes in the corresponding change. Keep counterpart PRs 
linked so future migrations and fixes have an explicit owner and compatibility 
record.
diff --git a/docs/registration-protocol-compatibility.md 
b/docs/registration-protocol-compatibility.md
new file mode 100644
index 0000000000..f83bd0f12e
--- /dev/null
+++ b/docs/registration-protocol-compatibility.md
@@ -0,0 +1,224 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# Java client registration compatibility contract
+
+This document addresses #6365. It describes the receiver at main commit
+87c22dde7 (2.7.2-SNAPSHOT); it is a wire contract for independent 
implementations,
+not a requirement to share Java DTO classes. Read it alongside
+[java-client-repository-boundary.md](java-client-repository-boundary.md) and
+[java-client-compatibility.md](java-client-compatibility.md).
+
+## Version negotiation, authentication and acknowledgement
+
+The canonical paths and header names are defined by
+[RegistrationProtocol](../shenyu-register-center/shenyu-register-protocol/src/main/java/org/apache/shenyu/register/common/protocol/RegistrationProtocol.java).
+POST JSON with Content-Type application/json. Names and path capitalization are
+significant; register-apiDoc and register-discoveryConfig retain their 
historical case.
+
+- A missing X-Shenyu-Register-Protocol-Version header means legacy v1.
+  An explicit single value of 1 is accepted. Empty, unsupported or multiple
+  version headers return HTTP 400 with "Unsupported registration protocol 
version".
+- Responses advertise X-Shenyu-Register-Protocol-Version: 1 and
+  X-Shenyu-Register-Capabilities: 
metadata,uri,api-doc,discovery-config,mcp,offline,heartbeat.
+  These identify receiver capabilities, not a negotiated client artifact 
version.
+- X-Shenyu-Client-Version can identify the sender. It does not override the 
wire
+  version, authenticate the client or establish framework/JDK compatibility.
+- Preserve existing Admin authentication. The HTTP client authenticates through
+  POST /platform/login, extracts the returned token and uses the existing
+  X-Access-Token header on subsequent calls. Credentials, expiry and 
unauthorized
+  responses are deployment concerns; never hardcode the documentation's 
examples.
+- Successful calls below return the plain string success. Registration 
controllers
+  enqueue work through ShenyuClientServerRegisterPublisher before returning.
+  This acknowledges submission; it does not prove database persistence, sync 
delivery
+  or route availability. Observe those stages separately.
+- HTTP success alone is insufficient: inspect the response body. Admin 
exception
+  handling can return a JSON error envelope with HTTP 200. Retry boundedly on
+  transport/transient failures; report authentication, malformed payload and 
version
+  errors explicitly. Do not spin indefinitely on a permanent rejection.
+
+## HTTP endpoints
+
+| POST path | Request | Capability | Receiver behavior |
+| --- | --- | --- | --- |
+| /shenyu-client/register-metadata | MetaDataRegisterDTO object | metadata | 
Enqueue backend endpoint metadata; plugin-specific subscribers create/update 
selectors, rules and metadata |
+| /shenyu-client/register-uri | URIRegisterDTO object | uri | Enqueue an 
upstream registration/update for the application's selector |
+| /shenyu-client/register-apiDoc | ApiDocRegisterDTO object | api-doc | 
Enqueue persisted API documentation |
+| /shenyu-client/register-discoveryConfig | DiscoveryConfigRegisterDTO object 
| discovery-config | Enqueue discovery configuration and selector association |
+| /shenyu-client/register-mcp | McpToolsRegisterDTO object | mcp | Enqueue MCP 
tool registration with embedded endpoint metadata |
+| /shenyu-client/offline | URIRegisterDTO object | offline | Enqueue upstream 
removal; clients must supply the offline/deletion event type used by the 
consumer |
+| /instance/beat | InstanceBeatInfoDTO object | heartbeat | Pass the report to 
InstanceCheckService; return success |
+
+The receiver is
+[ShenyuClientHttpRegistryController](../shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ShenyuClientHttpRegistryController.java),
+with 
[InstanceController](../shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/InstanceController.java)
+for heartbeat. There is no single HTTP endpoint for all external registry 
instance
+providers; do not invent /register-instance.
+
+## Field semantics and defaults
+
+"Required" below means needed to carry out the operation, not necessarily a 
Jakarta
+@NotNull annotation or immediate HTTP rejection. Several controllers accept a 
DTO
+without @Valid and downstream failures can occur after acknowledgement.
+Send explicit values for operational fields; a deserialization default is not a
+promise that an omitted field creates a usable route.
+
+Metadata, URI, discovery-config, MCP and offline controllers replace a null 
namespaceId
+with the default namespace ID 649330b6-c2d7-4edc-be8e-8a54df9eb385. Empty 
strings
+are distinct from null at the controller; downstream services can normalize 
further.
+API-doc and heartbeat do not share that controller normalization. Always send 
an
+explicit valid namespace for nondefault deployments, including nested MCP 
metadata.
+
+### Metadata
+
+[MetaDataRegisterDTO](../shenyu-register-center/shenyu-register-protocol/src/main/java/org/apache/shenyu/register/common/dto/MetaDataRegisterDTO.java):
+
+| Fields | JSON type | Semantics |
+| --- | --- | --- |
+| appName, contextPath | string | Application/selector identity; a missing 
context path can fall back to appName in registration helpers |
+| path, rpcType | string | Endpoint and protocol/plugin identity; required by 
the selected registration consumer |
+| serviceName, methodName, parameterTypes, rpcExt | string | Protocol-specific 
invocation descriptor; required according to the RPC plugin. Keep rpcExt's 
embedded JSON schema compatible |
+| ruleName | string | Required nonblank by the asynchronous registration 
consumer |
+| pathDesc | string | Optional description |
+| host, port | string, integer | Backend address; supply a valid host/port for 
consumers that also register upstreams |
+| namespaceId | string | Tenant identity; null controller default as above |
+| enabled, registerMetaData, addPrefixed | boolean | Endpoint enablement, 
metadata persistence selection and path-prefix behavior. Java no-arg defaults 
are false; builders may choose other values, so send these explicitly |
+| pluginNames | array of strings | Optional plugin selection for registration |
+| timeMillis | integer | Sender event time in milliseconds; no-arg field 
default is 0; builder-generated values do not establish receiver clock ordering 
|
+
+Do not serialize service objects or Java class names as the contract itself.
+Keep parameterTypes/rpcExt formatting stable for the selected invocation 
plugin.
+The current consumer drops metadata events missing appName, path, ruleName,
+rpcType or namespaceId; the HTTP acknowledgement can already have been sent.
+URI events similarly require nonblank contextPath, rpcType and namespaceId 
before
+dispatch, in addition to the upstream address checks in the service.
+
+### URI registration and offline
+
+[URIRegisterDTO](../shenyu-register-center/shenyu-register-protocol/src/main/java/org/apache/shenyu/register/common/dto/URIRegisterDTO.java):
+
+| Fields | JSON type | Semantics |
+| --- | --- | --- |
+| appName, contextPath, rpcType | string | Locate the application selector and 
protocol/plugin |
+| host, port | string, integer | Backend identity; valid nonblank host and 
nonnull port are needed to update an upstream |
+| protocol | string | Upstream protocol, preserving the consumer's existing 
format |
+| eventType | string enum | REGISTER, UPDATED, DELETED, IGNORED, OFFLINE, 
HEARTBEAT retain their exact spellings. Offline path alone does not manufacture 
the deletion event |
+| namespaceId | string | Namespace identity |
+| instanceInfo | string | Optional serialized instance information, not a 
substitute for host/port |
+
+Registration can race ahead of metadata creation. Existing consumers retry 
when the
+selector does not yet exist. Preserve bounded sender retry and idempotent 
receiver
+identity; do not create a second selector to work around a temporarily missing 
route.
+Graceful shutdown sends offline; node death or forced pod termination may send 
nothing.
+Admin active upstream checks and registry expiration/watch events must remove 
those
+unreachable destinations. Gateway request retries are not a liveness protocol.
+
+### Heartbeat and instance lifecycle
+
+[InstanceBeatInfoDTO](../shenyu-register-center/shenyu-register-protocol/src/main/java/org/apache/shenyu/register/common/dto/InstanceBeatInfoDTO.java):
+
+| Field | JSON type | Meaning |
+| --- | --- | --- |
+| instanceIp | string | Instance address |
+| instancePort | string | Port is historically encoded as a string, unlike 
URIRegisterDTO.port |
+| instanceType | string | Preserve receiver-recognized instance type keys |
+| instanceInfo | string | Optional implementation details |
+| namespaceId | string | Namespace identity; send explicitly |
+
+The beat reports liveness of an Admin-visible instance, not every route's HTTP 
health.
+InstanceCheckService records last-heartbeat state and its checker decides when 
a
+missing report makes an instance offline. Use the configured check interval and
+timeout; there is no fixed heartbeat TTL negotiated by HTTP v1. Stop sending 
beats
+on shutdown, deregister where supported, and verify eventual removal 
separately.
+New clients must not label a gateway as a business backend or guess a port 
before
+the server has bound it.
+
+External discovery uses
+[InstanceEntity](../shenyu-registry/shenyu-registry-api/src/main/java/org/apache/shenyu/registry/api/entity/InstanceEntity.java)
+and ShenyuInstanceRegisterRepository. Instance fields are appName and host 
(strings),
+port (integer), uri (provider-serialized URI), status and weight (integers). 
The
+provider defines persisted identity, serialization, session/lease and watch 
behavior.
+The common register root is /shenyu/register/instance; verify each provider's 
exact
+child key and deletion semantics against its implementation before changing 
them.
+HTTP capability headers do not version ZooKeeper/Nacos/etcd/Apollo/Eureka data.
+A registry layout/serialization change needs its own coexistence and rollback 
plan.
+
+### Discovery configuration
+
+[DiscoveryConfigRegisterDTO](../shenyu-register-center/shenyu-register-protocol/src/main/java/org/apache/shenyu/register/common/dto/DiscoveryConfigRegisterDTO.java)
+has string fields selectorName, name, discoveryType, serverList, listenerNode,
+handler, pluginName and namespaceId, plus props (JSON object mapping property 
names
+to values). Supply selectorName/pluginName/namespaceId to identify ownership 
and the
+provider-required connection/listener properties. Provider secrets must be 
redacted
+from diagnostics. Handler and props formats are provider contracts, not 
arbitrary
+cross-provider equivalents.
+
+### API documents
+
+[ApiDocRegisterDTO](../shenyu-register-center/shenyu-register-protocol/src/main/java/org/apache/shenyu/register/common/dto/ApiDocRegisterDTO.java)
+has contextPath, apiPath, consume, produce, version, rpcType, ext, apiOwner, 
apiDesc
+and document (strings); httpMethod, state and apiSource (integers); eventType 
(enum);
+and tags (array of strings). apiPath/contextPath and rpcType identify the 
described
+endpoint. Preserve numeric method/state/source codes and the existing 
document/ext
+format. This DTO does not contain namespaceId; adding it is a protocol change 
to
+review with API ownership, not an assumed existing capability. An import source
+label does not imply the receiver implements that importer.
+
+### MCP registration
+
+[McpToolsRegisterDTO](../shenyu-register-center/shenyu-register-protocol/src/main/java/org/apache/shenyu/register/common/dto/McpToolsRegisterDTO.java)
+contains metaDataRegisterDTO (the metadata object above), namespaceId (string) 
and
+mcpConfig (string containing serialized MCP configuration/tool definitions).
+The outer namespace is controller-defaulted; send a consistent explicit 
namespace
+in both the outer object and embedded metadata. Consumers require usable 
embedded
+metadata and MCP configuration. The mcp capability indicates registration 
support,
+not arbitrary MCP schema/protocol-version support or that the gateway plugin 
is enabled.
+Verify tool discovery and invocation after configuration reaches bootstrap, 
including restart.
+
+## Evolution and version skew
+
+No existing field above is declared deprecated by this contract. Track a future
+deprecation with the introducing/deprecating release, replacement and removal 
gate.
+
+1. Add optional fields with documented omission/default behavior. Both sides 
must
+   tolerate unknown optional fields in compatibility fixtures; this is a tested
+   requirement, not an assumption about every historical JSON mapper.
+2. Never silently rename/remove a field, change its JSON type, reuse an enum 
code,
+   tighten validation of formerly valid input or change a default inside v1.
+   Use a new capability/version with an explicit migration when semantics 
change.
+3. Deploy receiver support before requiring the capability from senders. A new
+   client talking to old Admin must treat missing capability headers as 
unknown,
+   probe only documented endpoints, and fail clearly if its required feature 
is absent.
+   Do not silently drop an essential MCP/discovery registration after a 404.
+4. Old headerless clients retain v1 behavior against new Admin. Authentication,
+   namespaces and feature-specific minimum versions still apply.
+5. An additive field may be omitted only when the requested operation remains
+   meaningful. Do not downgrade authorization or tenant identity as a 
compatibility fallback.
+6. Reconcile idempotent register/retry/offline behavior across multiple Admins 
and
+   transports; duplicate event delivery must not duplicate logical identities.
+7. Review changes with both the Admin registration/registry area and the 
affected
+   client/framework owners. Update serialized fixtures in both repositories, 
the
+   compatibility matrix, release notes and rollback guidance.
+
+## Verification
+
+[RegistrationProtocolCompatibilityTest](../shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/RegistrationProtocolCompatibilityTest.java)
+and RegistrationProtocolTest exercise receiver/header and serialized DTO 
contracts.
+They are not end-to-end client/server certification. Use the
+[cross-repo test strategy](cross-repo-compatibility-testing.md) for 
authentication,
+persistence, heartbeat, external discovery, gateway sync/proxy and MCP 
coverage.
+
diff --git a/docs/server-jdk-upgrade.md b/docs/server-jdk-upgrade.md
new file mode 100644
index 0000000000..605002b152
--- /dev/null
+++ b/docs/server-jdk-upgrade.md
@@ -0,0 +1,205 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+# Main repository JDK upgrade proposal
+
+Design deliverable for [#6368](https://github.com/apache/shenyu/issues/6368).
+Status: proposed migration plan; no compiler target, supported-runtime policy,
+dependency, image, or CI configuration is changed by this document.
+Source inventory: `2.7.2-SNAPSHOT`, commit `87c22dde7`, reviewed on 2026-10-21.
+Future implementation PRs must refresh the inventory and attach their own 
results.
+
+## Decision and compatibility boundary
+
+Adopt Java 21 as the next server baseline through separate runtime-validation
+and bytecode-baseline stages. First run Java 17 artifacts on Java 21 with the
+existing thread model. Keep virtual threads opt-in and assess them through the
+[virtual thread design](virtual-thread-design.md); they are not an upgrade gate
+for every plugin.
+
+The Java registration client has an independent Java 8 compatibility boundary.
+The pinned [split-client 
POM](https://github.com/apache/shenyu-client-java/blob/8b93088973bf9f8f50d614e708bb87f662b707d5/pom.xml)
+declares `java.version=1.8`. Server upgrades must not raise that repository's
+compiler target or require client applications to adopt a new JDK.
+Preserve the [registration v1 wire 
contract](../shenyu-register-center/shenyu-register-protocol/README.md)
+and test released clients against the candidate Admin. Sharing JSON fields and
+endpoint semantics does not require sharing server bytecode.
+
+Java 21 is a concrete migration target, not a claim that it is the newest JDK.
+Java 23 and 25 can be separate compatibility lanes; they do not become 
supported
+through a Java 21 test result. A Java 25 proposal must revalidate the selected
+framework, bytecode tools, drivers, and extensions before changing policy.
+
+## Current constraints
+
+| Area | Evidence in the inspected source | Consequence |
+| --- | --- | --- |
+| Main compilation | [root POM](../pom.xml): Java 17, compiler plugin 3.7.0, 
explicit `source`/`target`; no repository toolchain configuration found | 
Building with a newer JDK does not currently restrict API usage to Java 17. 
Introduce `release=17` before claiming that newer-JDK builds retain Java 17 
compatibility |
+| Build entry point | [wrapper 
configuration](../.mvn/wrapper/maven-wrapper.properties): Maven 3.6.3; root 
Maven Enforcer requires Maven 3.6.3+ and Java 17+ | Use `./mvnw` or `mvnw.cmd`; 
preserve the implemented validation when changing the baseline |
+| Framework and tooling | Root POM: Spring Boot 3.3.1, Surefire 3.0.0-M4, 
JaCoCo 0.8.12, Byte Buddy 1.14.11 | Treat resolved dependencies and agent/test 
support as migration inputs; a source-level change alone is insufficient |
+| Server CI | [ci.yml](../.github/workflows/ci.yml) uses Java 17 for normal 
builds/tests; `compat_java21` runs on upstream push with code changes | A 
configured compatibility job is not passing evidence, and it currently does not 
gate a PR before merge |
+| Independent E2E reactor | [E2E POM](../shenyu-e2e/pom.xml) has its own 
Apache parent and Java 17 property | Updating the main property will not update 
this reactor |
+| Independent examples reactor | [examples POM](../shenyu-examples/pom.xml) 
has a Spring Boot 3.3.1 parent and compiler configuration | Audit it 
independently; the `example` profile does not make it inherit the main parent |
+| Lower-target declarations | Examples `shenyu-examples-common`, 
`shenyu-examples-springmvc`, and `shenyu-examples-springmvc-tomcat` declare 
Java 8 compiler properties; client beat starter declares 17 | Inspect effective 
POMs and dependency bytecode. These properties are not proof that Boot 3 
examples run on Java 8 |
+| Distribution images | [Admin 
Dockerfile](../shenyu-dist/shenyu-admin-dist/docker/Dockerfile): Corretto 17 on 
Alpine; [Bootstrap 
Dockerfile](../shenyu-dist/shenyu-bootstrap-dist/docker/Dockerfile): Temurin 17 
on CentOS 7 | Both runtime and base-OS changes require explicit image testing. 
Do not infer runtime JDK from the CI build JDK |
+| Other runtime images | Dockerfiles under `shenyu-examples` and 
`shenyu-integrated-test` also select Java 17 | Test backend containers and 
gateway containers are independent; upgrade each intentionally |
+
+The server family includes Admin, Bootstrap, WebFlux runtime, gateway plugins,
+data sync, registry implementations, distribution launchers, and Kubernetes
+controller. No inspected server module has an established Java 8 support
+obligation. Existing Java 8-looking example settings are an inconsistency to
+resolve, not a reason to retarget the server dependency graph to Java 8.
+
+## Module migration units
+
+| Unit | Proposed handling | Gate before Java 21 bytecode |
+| --- | --- | --- |
+| `shenyu-admin`, Admin listeners and server registration receivers | First 
Java 21 runtime canaries, then server baseline | MVC/MyBatis, all claimed DB 
drivers, authenticated registration, import, config publication, cluster and 
shutdown tests |
+| `shenyu-bootstrap`, `shenyu-web`, gateway starters and server plugins | 
Upgrade as a compatible server set | WebFlux routing/streaming, protocol 
plugins, extension loading, cancellation, TLS, and packaged launcher tests |
+| Sync, registry, infrastructure, Disruptor and load balancer modules | Follow 
the server set; retain ordering and lifecycle contracts | Actual registry 
transports, reconnect/failover, config updates, node recovery and shutdown |
+| `shenyu-common`, `shenyu-spi`, plugin APIs and `shenyu-register-protocol` | 
Keep Java 17 output during staging; inventory external consumers before raising 
their floor | No retained lower-JDK consumer may depend on Java 21 classes. 
Publish and review the public plugin/API compatibility change |
+| In-tree `shenyu-client`, registration senders, client starters | Complete 
the split or explicitly isolate a lower-baseline artifact graph before the root 
target changes | No hidden main-repo parent/dependency forces the split 
client's Java 8 build to consume server classes |
+| `shenyu-sdk` and SDK starters | Separate consumer-JDK decision; they are 
outside the registration-client split | Inventory applications and transitive 
dependencies. Preserve an explicit Java 17 build if promised; otherwise 
announce the Java 21 requirement |
+| Examples and integration/E2E engines | Upgrade server fixtures with the 
server; keep a separate released Java 8 client fixture | Standalone reactors 
compile, images start, and the old-client/new-server scenario runs |
+
+A parent-property override cannot preserve a lower-JDK library if that library
+depends on Java 21 server classes. Split such dependencies, keep the necessary
+shared artifacts at Java 17, or announce the consumer baseline increase.
+Do not solve the registration-client boundary with duplicate server source.
+
+## Build and dependency preparation
+
+In an independent preparation PR, replace the root compiler's `source` and
+`target` entries with `release` while preserving the value 17. Preserve
+`-parameters`, encoding, generated-source configuration and annotation 
processing.
+The [Maven compiler 
documentation](https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-release.html)
+explains that `--release` also checks the chosen Java SE API surface.
+This protects JDK APIs, not the Java baseline of third-party dependencies.
+
+Choose and pin compatible compiler/Surefire/bytecode-analysis versions based on
+a clean Java 17/21 build, separately from the eventual target increase. 
Preserve
+the existing Maven Enforcer rules for wrapper-compatible Maven 3.6.3+ and 
update
+the minimum JDK only at the announced baseline stage. If toolchains are 
introduced, configure compiler and test JVM selection
+explicitly and record `java -version`, `./mvnw -v`, and the forked test JDK.
+Selecting a compiler toolchain alone does not prove tests run on that JDK.
+
+| Dependency or feature | Risk to verify | Evidence required |
+| --- | --- | --- |
+| Spring Boot 3.3.1, Spring Framework and Spring Cloud | Exact resolved 
version support; servlet/reactive adapters and auto-configuration | Effective 
POM/dependency tree plus startup, routing and config-binding results on the 
candidate JDK. Do not substitute a newer Boot maintenance page for 3.3.1 
evidence |
+| Netty 4.1.139.Final, Reactor from the Boot BOM, gRPC 1.65.1 | Native 
transport, TLS/ALPN, DNS and event-loop behavior | HTTP/HTTPS, gRPC 
streaming/cancellation, architecture-specific image tests, and reactor version 
recorded from the resolved tree |
+| Dubbo 3.2.14 and other RPC adapters | Reflection/proxy generation, 
serialization, context propagation and third-party worker assumptions | 
Provider calls, errors, concurrency and extension loading; preserve explicit 
attachment cleanup |
+| Byte Buddy 1.14.11, Mockito and JaCoCo 0.8.12 | Instrumentation/attach, 
generated bytecode and coverage execution | Agent-enabled tests and the 
memory-limited queue option in `ShenyuThreadPoolConfiguration`; test both with 
and without attach permissions |
+| Chicory 1.7.3 | Interpreter/compiler paths and host calls | WASM fixture, 
concurrent instance-pool, traps, callbacks and gateway tests |
+| JDBC drivers, MyBatis, Gson, protobuf and registry SDKs | Reflection, 
generated code, native binaries and access restrictions | Each supported 
DB/registry matrix and generated-code compilation. Resolve failures 
individually rather than adding broad `--add-opens` flags |
+| External plugins | API linkage and dependency conflicts after a target 
change | Load an old plugin on the new server and a rebuilt plugin; document 
that Java 21 plugin classes cannot load on a Java 17 server |
+
+## Phases and release gates
+
+| Phase | Change | Exit evidence / owner area |
+| --- | --- | --- |
+| 0: inventory and boundary | Record effective compiler/dependency graphs, API 
consumers, distribution JDKs and current failures; align with 
[#6364](https://github.com/apache/shenyu/issues/6364) and 
[#6370](https://github.com/apache/shenyu/issues/6370) | Build/release and 
client maintainers review the artifact boundary; failures have named follow-up 
issues |
+| 1: Java 17 artifacts on Java 21 | Add a PR-gating Java 21 job, enforce 
`release=17`, keep Java 17 primary and virtual threads disabled | Same source 
passes clean compilation/unit tests on 17 and 21; Java 17-built distribution 
starts and passes deployment tests on both |
+| 2: Java 21 runtime canary | Publish an explicitly identified Java 21 image 
variant; retain the Java 17 image and configuration | Real DB/registry and 
HTTP/RPC/streaming tests, resource measurements, restart/rollback drill and 
platform image checks pass |
+| 3: announced server baseline | In a separately reviewed release, raise the 
selected server artifact set to `release=21`, update minimum-JDK checks, normal 
CI, images and release notes together | Client/SDK boundary gates satisfied, 
required tests green, release manager and affected maintainers approve support 
policy |
+| 4: optional execution changes | Introduce narrowly scoped virtual-thread 
adapters and benchmarks | Gates in [#6369's design](virtual-thread-design.md), 
with platform execution still selectable on Java 21 |
+
+Every phase can ship independently. Phase 1 is the minimal first 
implementation:
+it adds verification and API-target protection without requiring a new client 
JDK
+or a server bytecode-baseline change. Do not backport a Java 21 bytecode target
+into an existing Java 17 compatibility line.
+
+## Images, launchers and CI
+
+Update both distribution Dockerfiles, their build/publish workflows, and each
+claimed architecture together. Select an available maintained OS/JDK image and
+pin its tested version/digest in implementation; do not mechanically replace
+`17` with `21` in a vendor tag that may not exist. Preserve non-root behavior,
+certificates, timezone handling, health checks, mounts and signal delivery.
+
+Audit `start.sh`, `start.bat`, and Docker `entrypoint.sh` for both 
distributions.
+They contain JDK-specific branches, heap/stack defaults and 
`ADMIN_JVM`/`BOOT_JVM`
+overrides. Test defaults and operator-supplied options, startup rejection below
+the supported JDK, Windows launchers, graceful stop and restart. A legacy JDK 8
+GC branch in a launcher does not establish JDK 8 server support.
+
+Required workflow inventory:
+
+- `ci.yml`: normal build, release local-repository artifact, unit-test groups,
+  `compat_java21`, Checkstyle and RAT. Namespace caches/artifacts by build JDK 
and
+  target; never reuse `target/` across compiler-baseline comparisons.
+- `docker-publish.yml` and `docker-publish-dockerhub.yml`: build JDK and actual
+  Admin/Bootstrap runtime-image JDK.
+- `integrated-test.yml`, both `integrated-test-k8s-*` workflows,
+  `e2e-k8s.yml`, and `k8s-examples-http.yml`: server, example and runner images
+  and startup scripts, including rolling updates.
+- `codeql-analysis.yml`, `wasm-fixtures.yml` and `native-sql-matrix.yml`:
+  analysis/build runtime; preserve their specialized verification.
+
+Retain the Java 17 required lane until Phase 3. Then require Java 21 for the
+new server line, while testing the previous Java 17 release for migration and
+rollback. Higher-JDK exploratory lanes do not replace baseline tests.
+
+## Reproducible validation and promotion
+
+These are required future validation commands, not results reported by this
+design-only change. Run in fresh checkouts on each claimed JDK; use
+`mvnw.cmd` on Windows.
+
+```bash
+java -version
+./mvnw -v
+./mvnw -B -ntp -N help:effective-pom -Doutput=target/effective-pom.xml
+./mvnw -B -ntp clean install -Dmaven.javadoc.skip=true
+./mvnw -B -ntp -Prelease clean package -DskipTests -Dmaven.javadoc.skip=true
+./mvnw -B -ntp -f shenyu-examples/pom.xml -Pexample clean install -DskipTests
+./mvnw -B -ntp -f shenyu-e2e/pom.xml clean test-compile
+```
+
+Do not equate `-DskipTests` packaging or E2E test compilation with deployment
+verification. Run the existing Docker/Kubernetes suites for the support claims.
+At minimum exercise authenticated client registration and heartbeat/offline,
+persisted routes, Admin-to-Bootstrap updates/deletions, a proxied request,
+streaming and cancellation, upstream recovery, registry failover and shutdown.
+Include every claimed DB dialect, RPC protocol and sync channel before release.
+
+For Phase 1, inspect packaged class files (major version 61 for Java 17) and
+test the packaged distribution under both JDKs. At Phase 3, expect major 65
+for Java 21 artifacts and update the minimum-runtime diagnostics. Archive 
source
+SHA, exact JDK/vendor, OS/architecture, image digest, effective POM, dependency
+tree, unit/integration reports, startup logs and benchmark results. No passing
+full-build, deployment or performance evidence is claimed by this document.
+
+## Rollback and ownership
+
+During Phases 1 and 2, roll back the image/JVM and matching launch options to 
the
+tested Java 17 combination; artifacts remain Java 17 compatible. Rehearse this
+against the same persisted configuration before rollout.
+
+After Phase 3, Java 21 class files cannot be made Java 17 compatible by setting
+a flag. Restore the previous complete Java 17 distribution/image and its plugin
+set. Preserve DB/config wire compatibility, keep unrelated schema migrations 
out
+of the JDK change, and test that old Admin/gateways can consume any intervening
+configuration. If that cannot be shown, block promotion until a migration and
+rollback procedure is agreed.
+
+Build/release maintainers own compiler, CI, images and support announcements;
+Admin/runtime maintainers own server behavior; plugin and registry maintainers
+own their integration evidence; client maintainers own independent Java 8
+fixtures. Changes to shared DTO semantics or public plugin APIs require both
+the receiving server area and the relevant client/plugin reviewers. Update the
+compatibility matrix and release checklist with verified versions when each
+phase is implemented.
diff --git a/docs/virtual-thread-design.md b/docs/virtual-thread-design.md
new file mode 100644
index 0000000000..9c3374c7c3
--- /dev/null
+++ b/docs/virtual-thread-design.md
@@ -0,0 +1,297 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+# Virtual thread execution proposal
+
+Design deliverable for [#6369](https://github.com/apache/shenyu/issues/6369).
+Status: proposal; the configuration and Java types below do not exist yet.
+Inventory: `2.7.2-SNAPSHOT` at `297ac6f84`, reviewed on 2026-10-21.
+This proposal complements the [server JDK migration 
plan](server-jdk-upgrade.md)
+and keeps the independent Java registration client compatible with Java 8.
+
+## Decision
+
+Keep Reactor Netty and the reactive plugin chain. Introduce an opt-in executor
+for identified blocking operations, with the same capacity, deadline,
+cancellation and context rules for platform and virtual execution. Do not 
switch
+all gateway work or every `boundedElastic()` caller to virtual threads.
+
+Java 21 finalized virtual threads in [JEP 444](https://openjdk.org/jeps/444).
+They help scale work that waits on blocking I/O; they do not make CPU work
+faster. Use a thread per admitted task rather than pooling virtual threads.
+The [JDK 21 
guide](https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html)
+also describes pinning, thread-local overhead and diagnostics. The choices 
below
+are ShenYu design decisions; performance improvements remain to be measured.
+
+## Current execution inventory
+
+Paths are relative to the repository. These are application-owned execution
+domains, not an inventory of every internal thread in third-party libraries.
+
+| Source / domain | Current behavior | Proposed disposition |
+| --- | --- | --- |
+| 
[ShenyuWebHandler](../shenyu-web/src/main/java/org/apache/shenyu/web/handler/ShenyuWebHandler.java)
 and 
[ShenyuConfig.Scheduler](../shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java)
 | Scheduler defaults disabled; enabled `fixed` selects `newParallel`, other 
values select shared `boundedElastic`; scheduling uses `subscribeOn` | Preserve 
current chain scheduling. A whole-chain switch does not control later async 
callbacks or make CPU work suitable for virtual [...]
+| 
[ShenyuThreadPoolConfiguration](../shenyu-web/src/main/java/org/apache/shenyu/web/configuration/ShenyuThreadPoolConfiguration.java),
 
[ShenyuThreadPoolExecutor](../shenyu-common/src/main/java/org/apache/shenyu/common/concurrent/ShenyuThreadPoolExecutor.java)
 and `TaskQueue` | Shared platform executor with queue/memory controls and 
explicit rejection; optional queue sizing uses Byte Buddy instrumentation | 
Preserve concrete bean/API and memory protections. Add a separate execution 
servic [...]
+| 
[ApacheDubboProxyService](../shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-dubbo/shenyu-plugin-apache-dubbo/src/main/java/org/apache/shenyu/plugin/apache/dubbo/proxy/ApacheDubboProxyService.java)
 | Deferred reference resolution/invocation on `boundedElastic`; explicitly 
snapshots/restores `RpcContext` attachments; response uses a future | First 
request-path candidate for the synchronous reference/invocation portion. Keep 
the asynchronous RPC future reactive and test [...]
+| [HTTP sync 
service](../shenyu-sync-data-center/shenyu-sync-data-http/src/main/java/org/apache/shenyu/sync/data/http/HttpSyncDataService.java),
 `AccessTokenManager`, WebSocket `ShenyuWebsocketClient` | One long-polling 
worker per configured Admin; separate token-refresh scheduler and bounded 
reconnect executor | Possible later blocking long-poll task candidate. Preserve 
per-server sequencing, reconnect limits and refresh timers; keep a separate 
budget from request plugins |
+| 
[ShenyuLoaderService](../shenyu-web/src/main/java/org/apache/shenyu/web/loader/ShenyuLoaderService.java)
 | Scheduled plugin-directory scanning | Keep periodic trigger on a platform 
scheduler; consider file/jar I/O offload only after measuring it |
+| 
[AbstractLogCollector](../shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/collector/AbstractLogCollector.java)
 and log consumers | Platform executor drains buffered logs with batch/capacity 
semantics; client shutdown owns additional lifecycle work | Later candidate for 
blocking sink sends, not a task per log. Preserve buffer bounds, batch order, 
drop policy and draining |
+| 
[OrderlyExecutor](../shenyu-disruptor/src/main/java/org/apache/shenyu/disruptor/thread/OrderlyExecutor.java),
 `SingletonExecutor`, Disruptor factories | Hash-selected serial lanes and 
dedicated threads | Keep ordering. The field named `virtualExecutors` 
represents hash-ring lanes, not JDK virtual threads |
+| 
[HierarchicalWheelTimer](../shenyu-common/src/main/java/org/apache/shenyu/common/timer/HierarchicalWheelTimer.java),
 memory calculator, registry watchers and heartbeat | Dedicated timer/periodic 
workers | Keep timer/ordering semantics. Offload selected blocking callbacks 
independently; do not create a virtual thread as a repeating timer |
+| 
[ManagedRemoteMcpCatalog](../shenyu-plugin/shenyu-plugin-agent-gateway/src/main/java/org/apache/shenyu/plugin/agent/gateway/remote/ManagedRemoteMcpCatalog.java)
 | Dedicated `newBoundedElastic(1, 16, ...)`, version checks and serialized 
reload lifecycle; bounded blocking during startup/close | Preserve 
single-writer reload ordering and lifecycle timeouts; changing its executor 
requires separate evidence |
+| Cache plugins and AI sensitive-word plugin | Memory-cache 
operations/cache-body handling and automaton work use `boundedElastic` or 
`publishOn` | Review operation type first. Memory access, parsing and automaton 
construction are not blocking-I/O candidates merely because they use this 
scheduler |
+| WASM API/base plugins | Synchronous guest exports, instance-pool contention 
and host callbacks | CPU/guest-budget isolation is a separate problem. Virtual 
threads cannot stop an infinite loop or enforce guest memory/deadline budgets |
+| Admin health checks, cluster election, HTTP/WebSocket publication, AI-key 
resolver and alert dispatch | Separate scheduled/worker pools, with DB/network 
work and task bounds | Separate Admin workstream; preserve transactions, 
publication ordering and existing limits before considering any migration |
+
+Netty event loops, nonblocking HTTP/gRPC/WebSocket/AI streams, selector/rule
+matching, hashing, serialization, compression, cryptography and WASM guest
+computation remain on their existing or explicitly bounded CPU execution paths.
+Retain protocol-client callback executors until their thread-affinity contract
+has been reviewed.
+
+## Execution abstraction
+
+Add a main-owned `shenyu-executor` module with a Java 17-compatible, JDK-only 
API.
+Keep Reactor adaptation in `shenyu-plugin-base` and wiring in the appropriate
+starter, so plugins do not depend on `shenyu-web` and the dependency graph has
+no runtime-to-plugin cycle. Proposed API shape:
+
+```java
+interface BlockingTaskExecutor {
+    <T> TaskHandle<T> submit(String domain, Callable<T> task, Duration 
timeout);
+}
+
+interface TaskHandle<T> {
+    CompletionStage<T> completion();
+    void cancel();
+}
+```
+
+These names are illustrative API contracts, not implemented source. A domain
+is a bounded registered value, such as `dubbo` or `http-sync`, never a
+request ID, selector ID or user-controlled label. The implementation owns task
+admission, queueing, timeout, context decoration and lifecycle. Plugins receive
+the service by injection; they do not construct executors per request.
+
+Provide a platform backend and a Java 21 capability adapter. While main 
artifacts
+remain Java 17-compatible, the adapter may resolve stable public JDK APIs
+reflectively only after checking runtime capability: `Thread.ofVirtual()`,
+the public `Thread.Builder` interfaces for naming/factory settings, and
+`Executors.newThreadPerTaskExecutor(ThreadFactory)`. Cache resolved handles;
+do not reflect on a non-public builder implementation. Keep Java 21 types out
+of signatures, constant-pool class references and eagerly initialized classes
+loaded on Java 17. Verify this with Java 17 startup/linkage tests.
+
+This allows opt-in Java 21 runtime testing without raising every artifact's
+compiler baseline or distributing mixed-baseline providers through automatic
+service loading. After the separately announced server baseline becomes 21,
+a direct-API adapter can replace the reflective adapter in its own change.
+Java 21-compiled server artifacts themselves cannot fall back to a Java 17 JVM.
+
+The Reactor adapter must submit lazily on subscription and connect cancellation
+to `TaskHandle.cancel()`. Never call `Future.get()`, `join()`, semaphore
+`acquire()` or a blocking queue `put()` on a Netty event loop. Adapt an
+asynchronous result without blocking a virtual worker for the entire response
+stream. Preserve downstream demand and buffer ownership. Do not silently change
+the public `ShenyuPlugin.execute/before/after` contracts.
+
+## Proposed configuration and fallback
+
+The following is a future configuration contract, not a runnable setting in the
+current release. Initial defaults are deliberately explicit and must be tested
+before implementation is enabled:
+
+```yaml
+shenyu:
+  execution:
+    blocking:
+      mode: platform                 # platform | virtual
+      fallback: platform             # platform | fail
+      plugins: []                    # empty means no request plugin is 
migrated
+      max-concurrency: 64
+      max-pending-tasks: 128
+      task-timeout: 3s
+      shutdown-grace-period: 30s
+```
+
+Capacity/deadline values apply to the new service's first request domain and
+are proposed defaults, not replacements for current shared-pool settings.
+Validate positive concurrency/timeouts, nonnegative pending capacity and known
+plugin/domain names. `max-pending-tasks=0` means immediate rejection when all
+execution slots are occupied. Add independently bounded configuration for each
+later control-plane domain; one global queue must not let slow RPC calls starve
+config sync or heartbeat.
+
+| Condition | Required behavior |
+| --- | --- |
+| Default mode or plugin absent from the allowlist | Existing execution path 
remains unchanged; the new service's opt-in adapters are not invoked |
+| Virtual requested, Java 21 capability available | Use named per-task virtual 
threads behind admission limits; log the resolved mode once at startup |
+| Virtual unavailable and `fallback=platform` | Warn once with a reason and 
use the bounded platform backend with identical task semantics |
+| Virtual unavailable and `fallback=fail` | Fail configuration/startup before 
accepting traffic |
+| Invalid configuration | Fail binding/startup; do not conceal it as a 
capability fallback |
+| Runtime saturation, task error or timeout | Apply the task's normal 
rejection/error semantics. Never retry the same call on another backend as a 
fallback |
+
+Mode is resolved at startup. Rollback changes configuration and restarts/drains
+the instance; live backend replacement is out of scope. Keep
+`shenyu.scheduler.*` and `shenyu.shared-pool.*` unchanged. Do not enable
+`spring.threads.virtual.enabled` as a substitute for controlling plugin work.
+
+Reactor 3.6 exposes a [global virtual bounded-elastic 
option](https://projectreactor.io/docs/core/3.6.7/api/reactor/core/scheduler/Schedulers.html)
+on Java 21. That is an alternative experiment, not this rollout mechanism:
+the global switch affects multiple shared callers and provides no per-plugin
+admission contract. Do not set it globally in the default distribution. Record
+the resolved Reactor version and property values in every experiment.
+
+## Admission, timeout and cancellation semantics
+
+Bound active physical tasks to `max-concurrency` and queued task records to
+`max-pending-tasks`. Include task context/retained payload in memory 
accounting;
+do not remove existing memory protections or accept arbitrarily large captured
+request bodies. Both backends use the same admission state machine:
+
+1. On subscription, capture the allowed request context and a monotonic 
deadline.
+   Admit immediately into an execution slot or a bounded FIFO pending queue.
+   If neither has capacity, reject immediately. No `CallerRunsPolicy`.
+2. Before starting queued work, check cancellation/deadline again. Account for
+   queue wait in the task timeout and discard expired/cancelled queued work.
+   A single platform timer schedules deadlines; its thread never runs user 
work.
+3. Run an admitted task once. Complete its result with the original 
value/error,
+   unless its downstream result has already timed out or been cancelled.
+4. For an active cancellation/timeout, cancel the underlying future with
+   interruption and invoke transport cancellation where supported. A terminal
+   downstream result does not prove that the blocking call physically stopped.
+5. Release the active permit only in the running task's actual `finally`.
+   Pending cancellation removes its queue record once. Handle cancellation
+   racing with submission/start without a leaked or double-released permit.
+   Do not rely on `Future.isDone()` after cancellation as proof of task exit.
+
+For a task ignoring interruption, retain its capacity charge until it exits,
+record it as still running after cancellation, and reject excess work within
+the configured limits. No unsafe thread stop and no replacement task beyond the
+budget. This containment does not solve WASM execution deadlines or native
+calls that never return.
+
+For opted-in request plugins, map capacity rejection to the gateway's 503 error
+path and deadline expiration to its 504 path, preserving tracing/error format.
+If headers/body have already been committed, cancel/terminate through the
+existing response error handling instead of writing a second response.
+Subscriber cancellation writes no response. Preserve plugin/business errors
+and existing retry policy; the executor introduces no automatic retries or
+duplicate side effects.
+
+On shutdown, stop admission, cancel queued work and allow active work up to the
+configured grace period, then request interruption/cancellation and report
+remaining tasks. Do not wait forever on `ExecutorService.close()` from an event
+loop. Integrate with Spring lifecycle; thread daemon/liveness behavior must not
+replace lifecycle ownership.
+
+## Context, pinning and observability
+
+Capture Reactor context and the intended tracing/security/MDC fields at the
+subscription boundary. Install only those fields in a worker and restore/clear
+them in `finally`; do not blindly inherit thread-local state. Preserve the
+Dubbo attachment snapshot and cleanup around invocation/future lookup. Test two
+overlapping requests with distinct identities and traces, plus failure,
+cancellation and a reused platform worker. Spring transaction context is
+thread-bound; moving Admin work across threads requires an explicit transaction
+boundary and is outside the first gateway change.
+
+For Java 21, inspect blocking while holding monitors and native/foreign calls
+with JFR, rather than assuming every `synchronized` statement causes a problem.
+The [JDK guide's 
diagnostics](https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html)
+cover `jdk.VirtualThreadPinned` and thread dumps.
+[JDK 24's release 
notes](https://www.oracle.com/java/technologies/javase/24-relnote-issues.html)
+describe JEP 491's monitor-pinning improvement; do not assume this improvement
+exists on Java 21 or that it removes every native-call limitation.
+
+Name workers `shenyu-blocking-<domain>-<sequence>`. Expose requested/resolved
+mode, runtime capability and fallback reason in startup logs and diagnostics.
+Use bounded domain/mode/outcome labels, never request IDs or credentials.
+Measure submitted, active, pending, completed, rejected, timed-out and 
cancelled
+tasks; actual running-after-cancellation count; queue wait and execution
+duration; and shutdown drain duration. Preserve trace parentage across the
+handoff, with queue wait and execution observable separately. Use JFR to 
inspect
+carrier/platform thread counts, pinning, allocation and parked tasks; OS thread
+counts alone do not measure virtual-thread concurrency.
+
+## Benchmark and verification gates
+
+All rows below are planned experiments. No throughput, latency or memory
+improvement is claimed by this document.
+
+Compare (A) unchanged Java 17/platform, (B) unchanged Java 21/platform,
+(C) Java 21/new service/platform and (D) Java 21/new service/virtual.
+C versus D isolates backend effects from a JDK upgrade or a new admission 
policy.
+Use equal active/pending limits and downstream connection pools for C/D;
+report baseline differences for A/B rather than masking them.
+
+| Scenario | Workload / assertions |
+| --- | --- |
+| Blocking RPC adapter | Disposable provider with fixed 10/100/1000 ms delays; 
concurrency 1/64/256/1024; verify response values, attachments, trace IDs and 
provider invocation count |
+| Nonblocking HTTP control | Same payloads/rates through normal HTTP routing, 
including SSE and a slow consumer; verify the untouched path does not gain 
queueing or buffers |
+| Overload and cancellation | Downstream stalls, refused connection and 
interruption-ignoring test task; cancel while queued/running; verify bounded 
active/pending memory and no duplicate invocation |
+| CPU control | Rule matching/serialization or a bounded CPU fixture; confirm 
it remains outside the virtual executor |
+| Config/order and shutdown | Apply ordered updates during traffic, 
restart/drain, and exercise platform fallback; verify route state, no 
lost/reordered callbacks and no leaked owned executors |
+
+Use an external fixed-rate load generator, a controlled backend and fresh
+processes with equal heap/CPU/container limits. Record source SHA, JDK/vendor,
+OS/architecture, flags, config, payload, provider/connection limits and actual
+offered/achieved load. Warm up for 2 minutes, measure for 5, repeat at least
+5 times, and report all runs plus median/spread. Count rejects/timeouts/errors
+in achieved-load and latency reports so fast rejection cannot look like 
success.
+Collect p50/p95/p99 end-to-end latency, throughput, CPU, RSS/heap, 
allocation/GC,
+active/pending tasks, platform/carrier counts and pinned duration/stacks.
+
+Proposed promotion gates, agreed before measuring:
+
+- Correctness: zero duplicate invocations/context leakage, bounded buffers and
+  exact permit cleanup across success/failure/queue cancellation/start races.
+  Reactive cancellation and result propagation pass deterministic tests.
+- Overload: active and pending counts never exceed limits, including calls that
+  ignore interruption; drain completes within grace or reports retained tasks.
+- Nonblocking control: no more than 5% p99 or throughput regression versus B
+  under matched load; investigate regressions outside run-to-run variability.
+- Blocking benefit: versus C, demonstrate at least 15% throughput improvement
+  at the same p99 budget, or 15% lower RSS at the same successful throughput
+  with no more than 5% p99 regression. Publish confidence/spread and resource
+  limits; do not promote from a single favorable run.
+
+## Implementation sequence and rollback
+
+1. Add the service API, bounded platform backend, context/cancellation adapter,
+   metrics and race tests without migrating callers. Java 17/21 startup tests
+   and capability/fallback tests are required.
+2. Add the Java 21 capability adapter and opt-in Dubbo synchronous-call 
adapter.
+   Keep RPC-future handling reactive and preserve attachment cleanup. Test the
+   existing plugin suite on both backends plus a real disposable provider.
+3. Publish C/D measurements and a canary recipe; enable only an explicit
+   `plugins: [dubbo]` configuration after the correctness gates pass.
+4. Review long-polling, log sinks and Admin candidates separately. Require
+   ordering, independent budgets, lifecycle and integration evidence for each.
+
+Set `mode: platform` to retain the new service's admission/deadline contract
+while changing backend; remove the plugin from the allowlist to restore its
+original execution path. Restart and drain rather than replaying active calls.
+The server JDK rollback rules remain those in the JDK proposal. No registration
+payload, split-client dependency or Java 8 target changes are needed.
+
+Runtime maintainers own admission/lifecycle and the Reactor adapter; plugin
+maintainers own invocation/cancellation/context semantics; build/release
+maintainers own the JDK capability matrix; observability maintainers review
+metrics/tracing cardinality. Review this proposal and benchmark thresholds
+before enabling a default. Structured concurrency and preview APIs are outside
+this design.
diff --git a/shenyu-dist/README.md b/shenyu-dist/README.md
index 6777a16342..7505c624eb 100644
--- a/shenyu-dist/README.md
+++ b/shenyu-dist/README.md
@@ -2,6 +2,19 @@
 
 The `shenyu-dist` module is used to build packages and releases.
 
+### Release compatibility checklist
+
+Complete this checklist for every main repository or `shenyu-client-java` 
release. Record results in the [Java client and server compatibility 
matrix](../docs/java-client-compatibility.md#updating-the-matrix).
+
+- [ ] Record exact client artifact versions and source tag/commit, Admin and 
bootstrap versions, application framework, registration transport, and sync 
channel.
+- [ ] Confirm client and server JDK baselines from the release POMs and 
resolved dependencies; record build and runtime JDK vendors and versions 
separately.
+- [ ] Run client tests on each claimed JDK, considering 8, 17, 21, 23, and 25; 
keep configured CI and passing results separate. Record exclusions and 
unsupported combinations.
+- [ ] Run server checks and Admin/bootstrap startup and routing smoke tests on 
every claimed server JDK. A client test on JDK 8 does not qualify the server 
for JDK 8.
+- [ ] Test the old client with the candidate Admin and the candidate client 
with the oldest claimed Admin. Verify authentication, persisted metadata/URIs, 
heartbeat, offline, discovery, gateway sync and routing, plus API docs/MCP when 
claimed.
+- [ ] Replay registration contract fixtures and verify the selected registry 
transport. Record protocol/capability changes, rolling upgrade behavior, and 
rollback results.
+- [ ] Add or update exact version rows with dated, passing test evidence and 
supported, best-effort, or unsupported status. Preserve historical evidence and 
document remaining limitations.
+- [ ] Link the updated matrix and any incompatible changes from the release 
notes before publishing the release.
+
 ### Quickstart
 
 * git clone https://github.com/apache/shenyu.git

Reply via email to