)]}'
{
  "log": [
    {
      "commit": "a87a3613f5ef1694f0624911002a821ab3587a45",
      "tree": "3d8f976628e785f3607355f6f29e7682042ca10f",
      "parents": [
        "4fc4d8eb1b31bfd5d9c491accad213729c4be960"
      ],
      "author": {
        "name": "hanzhe-one",
        "email": "200491821+hanzhe-one@users.noreply.github.com",
        "time": "Wed Oct 28 17:14:05 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 28 02:14:05 2026 -0700"
      },
      "message": "fix(admin): enforce metadata operation permissions (#8197)"
    },
    {
      "commit": "4fc4d8eb1b31bfd5d9c491accad213729c4be960",
      "tree": "f02473fbc115b3dcf81dd4ad4ea05edb0664c2b3",
      "parents": [
        "94be23fbc53e5ce7d3be3e8ba4628095e0679e3d"
      ],
      "author": {
        "name": "build",
        "email": "142670241+klT45@users.noreply.github.com",
        "time": "Wed Oct 28 17:12:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 28 02:12:39 2026 -0700"
      },
      "message": "fix(admin): enforce data scope on selector and rule detail reads (#8190)\n\n* fix(admin): enforce selector and rule data scope on detail reads (#8173)\n\nDetail endpoints resolved selectors and rules by id without applying the caller\u0027s data permission or namespace scope, so knowing a resource id was enough to read its configuration.\n\nResolve the persisted namespace of the resource and require both namespace membership and an explicit data_permission grant for non-admin callers. Administrators remain explicitly unrestricted, and the check runs before selector/rule conditions are loaded so a denial never returns configuration data.\n\n* fix(admin): harden selector and rule detail authorization (#8173)\n\nResolve the persisted namespace through a projection before the full selector/rule row is loaded, so a denied caller never causes configuration to be read. Also map a wrapped Shiro UnauthorizedException to the existing 601 permission response instead of the generic ShenyuException error."
    },
    {
      "commit": "94be23fbc53e5ce7d3be3e8ba4628095e0679e3d",
      "tree": "b8d3ec1c616ed51d24684221d81185081ec7beb8",
      "parents": [
        "1503d45ae77dcd473886285e300f373fa2fb56b7"
      ],
      "author": {
        "name": "build",
        "email": "142670241+klT45@users.noreply.github.com",
        "time": "Wed Oct 28 17:12:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 28 02:12:28 2026 -0700"
      },
      "message": "fix(admin): unify empty data-permission semantics across list queries (#8191)\n\n* fix(admin): unify empty data-permission scope across list queries (#8175)\n\nThe aspect-based legacy list path treated an empty grant set as no restriction, while the condition-based path treated it as no accessible resource. The same user could therefore see every selector or rule in a namespace through one path and none through the other.\n\nRepresent the effective scope explicitly as unrestricted, selected or none. Empty grants now set an empty filter which the SQL renders as match-nothing, global administrators are explicitly unrestricted, and both list paths share the same empty-grant semantics.\n\n* fix(admin): resolve data scope per resource type (#8175)\n\nFilter grants by the data type of the query so selector and rule permissions cannot leak into each other, and only treat the caller as an administrator when the requested user is the current session identity."
    },
    {
      "commit": "1503d45ae77dcd473886285e300f373fa2fb56b7",
      "tree": "70cf9e440669a7d09ebd0515217b851604a98b56",
      "parents": [
        "7ba0360dc284d0cfb865e768ca0fc32dd0251b83"
      ],
      "author": {
        "name": "hanzhe-one",
        "email": "200491821+hanzhe-one@users.noreply.github.com",
        "time": "Wed Oct 28 17:12:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 28 02:12:10 2026 -0700"
      },
      "message": "fix(admin): bind self-service password changes to the authenticated user id (#8198)\n\nmodifyPassword rejected a request only when the path id differed from the\nauthenticated user id *and* the body user name differed from the\nauthenticated user name. Because the body is caller-controlled, echoing\nthe caller\u0027s own user name let a request for another account\u0027s id through\nthe identity check, and the DTO id was then taken from the path.\n\nAuthorize on the authenticated user id alone. The body user name is no\nlonger consulted, so omitting, mismatching or supplying it cannot widen\nthe target. The @Existed lookup on the path id is dropped as well: it ran\nbefore the method body, so a foreign id still triggered a database read\nand revealed whether that account exists. Rejecting first also keeps\ndenied requests from loading the target account, verifying its old\npassword, writing credentials or publishing an update event.\n\nAdministrative resets are unaffected: they use PUT /dashboardUser/{id},\nwhich stays behind system:manager:edit."
    },
    {
      "commit": "7ba0360dc284d0cfb865e768ca0fc32dd0251b83",
      "tree": "c61e6c4fc89027742cae2f47507b0680072d7f03",
      "parents": [
        "750673e3f619e335333150ff1b2d14070d5d5c31"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Wed Oct 28 17:11:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 28 02:11:58 2026 -0700"
      },
      "message": "feat(divide): optional deterministic key selection for sticky configuration (#8037) (#8212)"
    },
    {
      "commit": "750673e3f619e335333150ff1b2d14070d5d5c31",
      "tree": "a55fdcb79584f45e7821712b32a4f92f2c18a70b",
      "parents": [
        "4a1a08b9ab4362ea47b4fe1f5d0a8d0cae2abfad"
      ],
      "author": {
        "name": "menggy2025swu",
        "email": "536528593@qq.com",
        "time": "Wed Oct 28 11:38:22 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:38:22 2026 -0700"
      },
      "message": "fix(admin): add local upstream probe mode (#8099)"
    },
    {
      "commit": "4a1a08b9ab4362ea47b4fe1f5d0a8d0cae2abfad",
      "tree": "6a860edc46cce7f105c19575df623c353f4389e0",
      "parents": [
        "79d827cce254df35cdc26a542bfc31c6c9f087df"
      ],
      "author": {
        "name": "Dr.Dread",
        "email": "135847306+DrDread746@users.noreply.github.com",
        "time": "Wed Oct 28 09:05:04 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:35:04 2026 -0700"
      },
      "message": "[ISSUE #7693] Fix false offline timeout during HTTP long-polling holds (#7727)\n\n* [ISSUE #7693] Fix false offline timeout during HTTP long-polling holds\n\n* [ISSUE #7693] Address review feedback: fix clientsMap leak, isolate scheduler, make interval configurable\n\n* [ISSUE #7693] Address review feedback and resolve rebase conflicts"
    },
    {
      "commit": "79d827cce254df35cdc26a542bfc31c6c9f087df",
      "tree": "bdafe0ab541ce773b7b07e570fa41369fbb6476f",
      "parents": [
        "ad813b7ff864999278510f5b0b2c5f91aed5834a"
      ],
      "author": {
        "name": "shown",
        "email": "yuluo08290126@gmail.com",
        "time": "Wed Oct 28 11:22:49 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:22:49 2026 -0700"
      },
      "message": "fix: correct release license inventories and exclude bundled CI actions (#8159)\n\n* fix: update release notices and license inventories\n\n* fix: synchronize release license inventories\n\n* fix: exclude bundled CI actions from source releases\n\n* fix: exclude downloaded wrapper binary from source archive\n\n---------\n\nCo-authored-by: Aias00 \u003c25810623+Aias00@users.noreply.github.com\u003e"
    },
    {
      "commit": "ad813b7ff864999278510f5b0b2c5f91aed5834a",
      "tree": "1323d0490c500d1173d0f06b7f3806d42e1e3beb",
      "parents": [
        "535c58877ac36f3dbe3d304a51df67c144f69908"
      ],
      "author": {
        "name": "SouthwestAsiaFloat",
        "email": "2034946972@qq.com",
        "time": "Wed Oct 28 11:00:06 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:00:06 2026 -0700"
      },
      "message": "OSPP docs(divide): document canary routing, migration and rollback (#8151)"
    },
    {
      "commit": "535c58877ac36f3dbe3d304a51df67c144f69908",
      "tree": "6652d6722b15a22fb21a6c81048678e2052e3cdb",
      "parents": [
        "44a7f7572dbc604931d322cd1266088bf0ed134d"
      ],
      "author": {
        "name": "redyyang",
        "email": "3202137046@qq.com",
        "time": "Wed Oct 28 10:59:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 19:59:54 2026 -0700"
      },
      "message": "[ISSUE #7649] Add an opt-in HTTP gateway assembly and benchmarks (#7665)\n\n* feat(bootstrap): add opt-in minimal HTTP distribution\n\n* ci: update license checker for Windows batch headers\n\n* test(sync): assert proxy selector deletion by ID\n\n* test(e2e): use local HTTP fixture for wait helper checks\n\n* fix(benchmark): reject invalid minimal HTTP load evidence\n\n* fix(ci): handle empty module arrays on Bash 3.2"
    },
    {
      "commit": "44a7f7572dbc604931d322cd1266088bf0ed134d",
      "tree": "1ff5d1e115d2c45c0afd618af0c2107fd0e0d370",
      "parents": [
        "3989503a58d303178289ed0c8278ae8d7f9e7978"
      ],
      "author": {
        "name": "BobSong",
        "email": "bobsongdev@gmail.com",
        "time": "Wed Oct 28 08:04:25 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 17:04:25 2026 -0700"
      },
      "message": "Fixes #8122: Make AI retries replay-safe and Retry-After aware (#8144)\n\n* feat(ai-proxy): make retries ambiguity and retry-after aware\n\n* fix(ai-proxy): apply replay policy to fallback failures"
    },
    {
      "commit": "3989503a58d303178289ed0c8278ae8d7f9e7978",
      "tree": "2bb7d88a0d2d269b4dc686de84e5f04a357285c6",
      "parents": [
        "c3045fc1ef238e29e2f81d7ba2951df5f3599b96"
      ],
      "author": {
        "name": "imDwAaY",
        "email": "wuwangyi000@gmail.com",
        "time": "Wed Oct 28 07:00:57 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 16:00:57 2026 -0700"
      },
      "message": "[type:bug] [ISSUE #8131] keep the local resource registry when binding HTTP tools (#8154)\n\nWhen a rule configured HTTP tools, AgentMcpDispatcher.dispatch rebuilt a nested\ndispatcher through the four-argument constructor to bind the request-local\nAgentHttpToolProvider instances. That constructor hardcodes an empty\nAgentResourceRegistry, while the nested execution context still carries the\nrule\u0027s resource grants. Resource validation therefore rejected every configured\nlocal resource as unregistered, and every method failed the validation that runs\nbefore routing: discovery, resource list/read and tool list/call all answered\nHTTP 500 with JSON-RPC code -32603 even though the local provider and its grants\nwere unchanged.\n\nThe dispatcher now keeps the AgentResourceRegistry it was constructed with and\npasses it to the nested dispatcher. The registry is immutable and request\nindependent, so sharing it preserves the local registrations, the request-local\nidentity, the cancellation and deadline of the nested context, and the remote\nsnapshot ownership unchanged.\n\nTests: AgentMcpResourceIntegrationTest gains a parameterized case (json and sse\nresponse modes) where the rule grants the HTTP tool \"lookup\" and the local\nresource \"status\" independently; server/discover, resources/list,\nresources/templates/list, resources/read and tools/list all answer 200 and the\nresource is readable while the HTTP tool is listed. The case fails on the\nprevious implementation with the reported HTTP 500."
    },
    {
      "commit": "c3045fc1ef238e29e2f81d7ba2951df5f3599b96",
      "tree": "280073483e47232b34fd46ba9be226987c175fea",
      "parents": [
        "bec0fbe144ce333fbccee5177822d084b0edba26"
      ],
      "author": {
        "name": "imDwAaY",
        "email": "wuwangyi000@gmail.com",
        "time": "Wed Oct 28 07:00:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 16:00:48 2026 -0700"
      },
      "message": "[type:bug] [ISSUE #8134] never decode a compressed request body as text (#8153)\n\nThe request path called the string based rewrite helper before looking at\nContent-Encoding. ServerWebExchangeUtils.rewriteRequestBody reads the raw wire\nbytes through bodyToMono(String.class) and writes the string back, so a gzip\npayload was re-encoded as UTF-8 text of the decoded characters: the forwarded\nbytes no longer formed a valid gzip stream while the Content-Encoding header\nstill claimed they did, even though the plugin only logged \"passed through\nunscanned\".\n\nThe plugin now decides on the content encoding first, for every path that would\notherwise decode the body: the request scan, and the fail closed mode precheck\nof a response only scope. A non identity encoding is an unsupported enforcement\nmode, handled like the response side already handles compressed responses:\n\n- fail open: the chain is invoked with the untouched exchange, so the original\n  wire bytes and the original Content-Encoding and framing headers are forwarded;\n- fail closed: the request is rejected before the backend is invoked, without\n  the body being consumed. Bounded decompression is deliberately not added in\n  this release, matching the documented response behaviour.\n\nAn identity encoding is still scanned, and a response only fail open scope still\nnever reads the request body, so neither path changes behaviour.\n\nTests: PiiDetectionRequestFlowTest gains five cases: a two chunk gzip request is\nforwarded byte for byte with its encoding header when fail open; a compressed\nrequest is rejected when fail closed, including through the response scope\nprecheck; a response only fail open rule still forwards it, and an identity\nencoding is still scanned and redacted. The byte for byte and the precheck\ncases fail against the previous implementation."
    },
    {
      "commit": "bec0fbe144ce333fbccee5177822d084b0edba26",
      "tree": "1dc40b1dbe324f932d8ee47d7d2666657328a2bf",
      "parents": [
        "1d0133477634f62a5093be10014c96f9f835c645"
      ],
      "author": {
        "name": "imDwAaY",
        "email": "wuwangyi000@gmail.com",
        "time": "Wed Oct 28 07:00:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 16:00:39 2026 -0700"
      },
      "message": "[type:bug] [ISSUE #8135] publish existing app parameters in the replacePaths update event (#8152)\n\nreplacePaths published an APP_AUTH UPDATE without paramDataList. The gateway\nSign subscriber replaces the whole cached auth with the payload\n(SignAuthDataCache.cacheAuthData uses AUTH_MAP.put), so a paths-only change\nsilently dropped the existing application parameters and the subsequent\nsigned requests could no longer read Constants.APP_PARAM.\n\nThe update event now carries a complete snapshot: the persisted parameters\nplus the replaced paths, which matches the subscriber semantics and needs no\npartial-update handling on the gateway side.\n\nRegression coverage:\n- AppAuthReplacePathsEventTest (runs with no external database): a paths-only\n  replacement, a full clear and a repeated replacement all carry the existing\n  appParam together with the unchanged appKey/appSecret/open/namespace.\n- AppAuthReplacePathsTest (isolated MySQL): the published event of a real\n  replacePaths transaction contains the persisted appParam and the new paths."
    },
    {
      "commit": "1d0133477634f62a5093be10014c96f9f835c645",
      "tree": "bad0bf274f3d81fd33644fbd3dad1c3613965518",
      "parents": [
        "485822951b5ebcd8e9fbf181e0ca6fba5d0b7052"
      ],
      "author": {
        "name": "Liming Deng",
        "email": "liming.d.pro@gmail.com",
        "time": "Tue Oct 27 21:01:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 21:01:39 2026 +0800"
      },
      "message": "fix(admin): preserve auth path application names (#7080)"
    },
    {
      "commit": "485822951b5ebcd8e9fbf181e0ca6fba5d0b7052",
      "tree": "305efa5615983fdab7cb8d4f96d80336cffdb225",
      "parents": [
        "7a2531d5b63777ac829ce1ddae458a99ba0d4580"
      ],
      "author": {
        "name": "Liming Deng",
        "email": "liming.d.pro@gmail.com",
        "time": "Tue Oct 27 21:01:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 21:01:18 2026 +0800"
      },
      "message": "fix(web): load plugin inner classes (#7091)\n\nCo-authored-by: aias00 \u003cliuhongyu@apache.org\u003e"
    },
    {
      "commit": "7a2531d5b63777ac829ce1ddae458a99ba0d4580",
      "tree": "c9189a2439053f41c6b270970d5fc7414c841849",
      "parents": [
        "4f6a1ce404b92d8a23eff51330a6e01eb616bf9b"
      ],
      "author": {
        "name": "Liming Deng",
        "email": "liming.d.pro@gmail.com",
        "time": "Tue Oct 27 21:01:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 21:01:03 2026 +0800"
      },
      "message": "fix(dubbo): default missing rule handles (#7113)\n\nCo-authored-by: aias00 \u003cliuhongyu@apache.org\u003e"
    },
    {
      "commit": "4f6a1ce404b92d8a23eff51330a6e01eb616bf9b",
      "tree": "e530399330c04a6bf0d7bd1a1ad18e3810f434db",
      "parents": [
        "2b9bbb160b65f1684cf91d0a53ae1b7d2418a83a"
      ],
      "author": {
        "name": "Liming Deng",
        "email": "liming.d.pro@gmail.com",
        "time": "Tue Oct 27 21:00:45 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 21:00:45 2026 +0800"
      },
      "message": "test(client): use an ephemeral registration port (#7184)"
    },
    {
      "commit": "2b9bbb160b65f1684cf91d0a53ae1b7d2418a83a",
      "tree": "6a9112dbc515ae16d85357ff855a9bc71150f353",
      "parents": [
        "4c886ba1e32175458d47005b41c3bfcd2c82b03b"
      ],
      "author": {
        "name": "Liming Deng",
        "email": "liming.d.pro@gmail.com",
        "time": "Tue Oct 27 21:00:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 21:00:28 2026 +0800"
      },
      "message": "fix(admin): map namespace plugin enabled state (#7188)"
    },
    {
      "commit": "4c886ba1e32175458d47005b41c3bfcd2c82b03b",
      "tree": "e03e1ef04c91dd397a1751f3e23d51e220362696",
      "parents": [
        "e76a5acd3cf9da6efa2a83398bfd4392c5cdf275"
      ],
      "author": {
        "name": "Liming Deng",
        "email": "liming.d.pro@gmail.com",
        "time": "Tue Oct 27 21:00:11 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 21:00:11 2026 +0800"
      },
      "message": "fix(admin): cascade role deletion safely (#7191)"
    },
    {
      "commit": "e76a5acd3cf9da6efa2a83398bfd4392c5cdf275",
      "tree": "827432d0173765aaf0c8c7aa6ca2c33bc4429f05",
      "parents": [
        "4449fa7f892f2eb612fdce3454f560492d748f6d"
      ],
      "author": {
        "name": "Southern",
        "email": "491852417@qq.com",
        "time": "Tue Oct 27 20:59:46 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:59:46 2026 +0800"
      },
      "message": "fix: make mock request record lookup deterministic (#7666)\n\nOrder mock request records by date_updated DESC and id DESC so queryByApiId consistently returns the most recently\n  updated record, using the primary key as a stable tie breaker.\n\n  Add H2 integration coverage for duplicate api_id values, timestamp ordering, ID tie breaking, and the service-level\n  queryByApiId selection."
    },
    {
      "commit": "4449fa7f892f2eb612fdce3454f560492d748f6d",
      "tree": "fd43b07349674499468434664cd851a46821a8be",
      "parents": [
        "ef68c80789d51294d9dd43576b3ac9d179f61ddf"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Tue Oct 27 20:59:31 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:59:31 2026 +0800"
      },
      "message": "fix(admin): ignore heartbeats with an incomplete instance identity (#7764) (#7776)\n\n* fix(admin): ignore heartbeats with an incomplete instance identity (#7764)\n\n* fix(admin): default blank namespace and signal rejected heartbeats (#7764)"
    },
    {
      "commit": "ef68c80789d51294d9dd43576b3ac9d179f61ddf",
      "tree": "d5cacd1be8cbd6fd4d7385b3ad6d9b70e33d699a",
      "parents": [
        "e1ffee30af403d2ce44b6485191f983756892b48"
      ],
      "author": {
        "name": "Joker",
        "email": "3014355539@stu.scau.edu.cn",
        "time": "Tue Oct 27 20:59:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:59:15 2026 +0800"
      },
      "message": "fix(register): refresh rejected heartbeat tokens with bounded backoff (#7879)\n\nCo-authored-by: Mrmr \u003c3014355539@qq.com\u003e"
    },
    {
      "commit": "e1ffee30af403d2ce44b6485191f983756892b48",
      "tree": "1e46c5ea9527479770ec221d2085c08dd8e12aaf",
      "parents": [
        "46dfda3fe4724904ca926f71302a4de95c206c20"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Tue Oct 27 20:58:55 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:58:55 2026 +0800"
      },
      "message": "fix(admin): back k8s client/scaler beans off their own types and guard the missing client (#7912) (#7917)\n\n* fix(admin): back k8s client/scaler beans off their own types and guard the missing client (#7912)\n\n* fix(admin): register k8s properties as a conditional bean and verify TLS against the CA (#7912)\n\n* fix(admin): keep the deployment properties prefix on the class only (#7912)"
    },
    {
      "commit": "46dfda3fe4724904ca926f71302a4de95c206c20",
      "tree": "824338d68194b354e6c275da4d58c94db745a92f",
      "parents": [
        "ede4d9add9904e15dafe2d7b2314a5ec10582b3d"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Tue Oct 27 20:58:31 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:58:31 2026 +0800"
      },
      "message": "fix(plugin): gate negative match cache entries by path-only operators (#7977) (#7984)"
    },
    {
      "commit": "ede4d9add9904e15dafe2d7b2314a5ec10582b3d",
      "tree": "2af5089b3e2dd7947280000839e1f70fdfcc82a8",
      "parents": [
        "9134bcdd0433cbb92749cbffc5520f7e5a6ed91a"
      ],
      "author": {
        "name": "Duansg",
        "email": "siguoduan@gmail.com",
        "time": "Tue Oct 27 20:58:11 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:58:11 2026 +0800"
      },
      "message": "fix(ratelimiter): clamp token bucket ttl to at least 1 second (#8115)"
    },
    {
      "commit": "9134bcdd0433cbb92749cbffc5520f7e5a6ed91a",
      "tree": "a8a3d23823afddb00825d49e6d022b818a5a64c5",
      "parents": [
        "bc6d64f5a3c58c1cb6f51dcf73b1b1b35aa2a416"
      ],
      "author": {
        "name": "Duansg",
        "email": "siguoduan@gmail.com",
        "time": "Tue Oct 27 20:57:55 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:57:55 2026 +0800"
      },
      "message": "fix(logging): round sample rate instead of truncating in CountSampler (#8118)"
    },
    {
      "commit": "bc6d64f5a3c58c1cb6f51dcf73b1b1b35aa2a416",
      "tree": "611e6169a0fe7c2e7def533b7ab104261c2a5da2",
      "parents": [
        "11453f607c947af82c1c778cf83b1f88194e62c1"
      ],
      "author": {
        "name": "build",
        "email": "142670241+klT45@users.noreply.github.com",
        "time": "Tue Oct 27 20:57:36 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:57:36 2026 +0800"
      },
      "message": "fix(divide): release pooled chunked request buffers on rejection (#8137) (#8142)"
    },
    {
      "commit": "11453f607c947af82c1c778cf83b1f88194e62c1",
      "tree": "fa98f423efa03488381ad419086e2c1cbe8e5ddc",
      "parents": [
        "c0bf67f074cd720840c2a5e4b22b36d18d4c509a"
      ],
      "author": {
        "name": "hanzhe-one",
        "email": "200491821+hanzhe-one@users.noreply.github.com",
        "time": "Tue Oct 27 20:57:17 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:57:17 2026 +0800"
      },
      "message": "fix(loadbalancer): isolate failed health-check futures per round (#8146)\n\nUpstreamCheckTask.waitFinish() awaited every probe with future.get() and\ncleared the shared futures list only after the whole loop succeeded. One\nexceptional probe (for example an unparsable upstream URL, which throws\nfrom Integer.parseInt inside UpstreamCheckUtils) skipped both the\nremaining health-pool updates and the clear, so later rounds re-awaited\nthe same failed future and kept rethrowing it. Removing the bad endpoint\ndid not recover the task without restarting Bootstrap.\n\n- Contain each probe in its own future: exceptional probes complete with\n  a null result and are logged, so they cannot abort the round.\n- Await each future independently in waitFinish(), skipping cancelled or\n  failed futures and keeping the rest of the results.\n- Always clear the round bookkeeping in a finally block, so an aborted\n  round (including an executor rejection) cannot leak futures forward.\n- Treat a throwing probe as a failed probe so the endpoint still leaves\n  the healthy pool instead of being selected while never completing.\n\nAdd regression coverage for a malformed endpoint alongside an ordinary\nfailed probe, for subsequent rounds after removing it, and for a future\nthat fails before producing a result."
    },
    {
      "commit": "c0bf67f074cd720840c2a5e4b22b36d18d4c509a",
      "tree": "9f74e4b6e076f2b9aa4986e698a54b260cd2ab23",
      "parents": [
        "52339b2c717d6af9f9b271142cc2582d754de2d7"
      ],
      "author": {
        "name": "hanzhe-one",
        "email": "200491821+hanzhe-one@users.noreply.github.com",
        "time": "Tue Oct 27 20:56:17 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:56:17 2026 +0800"
      },
      "message": "fix(divide): scope the default sticky binding cookie to its rule (#8147)\n\nRules that enable sticky affinity without naming a cookie all wrote\nShenyu-Route with Path\u003d/, so on a shared host the response of one rule\nreplaced the binding of another. The signed payload still rejected the\nforeign binding, so STRICT did not preserve the overwritten cookie either:\nalternating rules kept losing their established targets.\n\nThe default name is now a base name and the effective name carries a\nsuffix derived from the rule id, so every rule owns its browser cookie.\nAn explicitly configured name is still used verbatim, which keeps\ndeployments that pin a name working and lets operators opt into a shared\ncookie; the signed rule id keeps a foreign binding a miss.\n\nSignature verification, key rotation, expiry, candidate admission and the\nREBIND/STRICT policies are unchanged. Documented the scoping, the shared\nexplicit-name behavior and the upgrade effect in\ndocs/divide-sticky-session-affinity.md.\n\nFixes #8136"
    },
    {
      "commit": "52339b2c717d6af9f9b271142cc2582d754de2d7",
      "tree": "ae37fa86e774c68de2399db8a5e7a76af3fc81f7",
      "parents": [
        "aab453f06dbd135da9b329ee153758ceac0e1834"
      ],
      "author": {
        "name": "build",
        "email": "142670241+klT45@users.noreply.github.com",
        "time": "Tue Oct 27 17:18:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 17:18:48 2026 +0800"
      },
      "message": "fix(ai-proxy): validate credentials before body aggregation (#8124) (#8129)\n\n- reject invalid, missing, or disabled proxy keys before resolving config or joining the body\n- redact cache debug identifiers with a truncated SHA-256 digest\n- add regression coverage for body subscription, selector isolation and deletion, body limits, and log arguments"
    },
    {
      "commit": "aab453f06dbd135da9b329ee153758ceac0e1834",
      "tree": "6a64e39afba5be6dff2684001c3b5f4b8ae0cbfa",
      "parents": [
        "127aa7ad90008faebdd6d114a82acb38aad62540"
      ],
      "author": {
        "name": "eye-gu",
        "email": "eyegu@apache.org",
        "time": "Mon Oct 26 22:16:40 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 22:16:40 2026 +0800"
      },
      "message": "feat(api-doc): support request parameter parsing for RPC types (Dubbo/SOFA/TARS/gRPC) (#6339)\n\n* feat(api-doc): support request parameter parsing for RPC types (Dubbo/SOFA/TARS/gRPC)\n\n* fix license\n\n* fix checkstyle exclude generated source\n\n* fix checkstyle\n\n* fix review\n\n* Fix Protobuf field schema parsing logic\n\n* fix use common version\n\n* chore: trigger CI retest\n\n* fix RPC api-doc generation for protobuf nesting\n\n---------\n\nCo-authored-by: aias00 \u003cliuhongyu@apache.org\u003e"
    },
    {
      "commit": "127aa7ad90008faebdd6d114a82acb38aad62540",
      "tree": "f7556fce47c2f69d8a19b5cd4cbc6acded444ced",
      "parents": [
        "8a4650437d72c4ba98f6f371142acd7f14542423"
      ],
      "author": {
        "name": "imDwAaY",
        "email": "wuwangyi000@gmail.com",
        "time": "Mon Oct 26 21:51:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 21:51:15 2026 +0800"
      },
      "message": "[ISSUE #7979] update stale matching-cache documentation after trie removal (#8117)\n\nThe Trie L2 cache was removed in #6303, but comments still described the\nL1/L2/Trie lookup chain. Describe the actual matching path instead: the\nbounded per-path match cache followed by default matching on a miss.\n\nAlso drop the remaining Trie references from maintained matching docs:\nremove the orphaned L2 config comment, rename the L1 cache comments to\nmatch cache, fix the trie wording in CommonPluginDataSubscriber and\nLocalPluginController, and point HttpRouteParser at the current\nmatchSelector method.\n\nHistorical references in RELEASE-NOTES.md are kept."
    },
    {
      "commit": "8a4650437d72c4ba98f6f371142acd7f14542423",
      "tree": "886d805d193e49925ed6492d73149c201386101c",
      "parents": [
        "987ef785519ca29edd17c73e57cf9471e4b61982"
      ],
      "author": {
        "name": "redyyang",
        "email": "3202137046@qq.com",
        "time": "Mon Oct 26 20:25:09 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 20:25:09 2026 +0800"
      },
      "message": "refactor(deps): declare Guava only in consuming modules (#7867)\n\n* refactor(deps): declare Guava only in consuming modules\n\n* test(tracing): await span export in real HTTP continuity checks\n\nThe request completion can reach StepVerifier before TracingPlugin.doFinally ends and exports the gateway span. Await a finished span with a bounded timeout before retaining the exact count and parent/trace assertions.\n\n* test(ci): align cryptor failures and wait for usable SDK routes\n\n* ci: retain compose diagnostics when integration startup fails\n\n* fix(deps): retain Guava in packaged integration gateways\n\nRestore compile-scope Guava inheritance for integration applications and remove narrower child declarations so Spring Boot includes Guava at runtime. Targeted starter reactor packaging, the Apache Dubbo IT repackage and dependency trees pass on Java 17. The repackaged jar contains Guava and failureaccess; Maps and ApacheDubboMetaDataHandler initialize from its extracted runtime jars. Full Docker IT execution remains pending.\n\n* docs(deps): make integration gateway Guava runtime scope explicit"
    },
    {
      "commit": "987ef785519ca29edd17c73e57cf9471e4b61982",
      "tree": "b8660512b2622fc79e941311ba6ffddee4330c58",
      "parents": [
        "baf548fc2305523aed73162eb19d1e76ac51faad"
      ],
      "author": {
        "name": "redyyang",
        "email": "3202137046@qq.com",
        "time": "Mon Oct 26 20:25:02 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 20:25:02 2026 +0800"
      },
      "message": "fix(ai): make token accounting atomic and expiry regression null-safe (#8059)"
    },
    {
      "commit": "baf548fc2305523aed73162eb19d1e76ac51faad",
      "tree": "303d54e449ff99209205146529f0503e6e527d44",
      "parents": [
        "74696002b0b0fa67d650a8e24eaccad40906c9fd"
      ],
      "author": {
        "name": "Southern",
        "email": "491852417@qq.com",
        "time": "Mon Oct 26 20:24:55 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 20:24:55 2026 +0800"
      },
      "message": "fix: preserve alert receiver fields during partial updates (#6711) (#7038)\n\n* fix: preserve alert receiver fields during partial updates (#6711)\n\n  Use selective updates for alert receivers and convert enable and matchAll to nullable Boolean values.\n  Preserve database values when these fields are omitted, keep true as the default for new receivers, and add null-safe\n  alert dispatch handling.\n\n* fix ci\n\n* • fix: use VARCHAR for alert receiver access tokens\n\n  Map accessToken as VARCHAR in the insert, full update, and selective update statements to match the Java field and\n  database column.\n\n  Add a mapper regression test that selectively updates a DingTalk access token, reads it back, and checks that an\n  unrelated field is preserved."
    },
    {
      "commit": "74696002b0b0fa67d650a8e24eaccad40906c9fd",
      "tree": "d61c241975247c285d6107ee2ead2007e6cf8993",
      "parents": [
        "5aa18c172ac7162a6d228c91baa5b5b9e7af2ddb"
      ],
      "author": {
        "name": "Duansg",
        "email": "siguoduan@gmail.com",
        "time": "Mon Oct 26 20:24:17 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 20:24:17 2026 +0800"
      },
      "message": "fix(admin): use two-argument CONCAT for Oracle instance IP search (#xxxx) (#8096)\n\n* fix(admin): use two-argument CONCAT for Oracle instance IP search (#xxxx)\n\n* fix(admin): use two-argument CONCAT for scale rule count queries"
    },
    {
      "commit": "5aa18c172ac7162a6d228c91baa5b5b9e7af2ddb",
      "tree": "f7f18d48b4c0b5064d20f5f521b9af611ec798b1",
      "parents": [
        "96a8de2ba2515c18c9bb83755a45e73e9736eb0d"
      ],
      "author": {
        "name": "Duansg",
        "email": "siguoduan@gmail.com",
        "time": "Mon Oct 26 20:24:11 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 20:24:11 2026 +0800"
      },
      "message": "fix(admin): sync sibling metadata rpcExt changes to gateway (#8104)"
    },
    {
      "commit": "96a8de2ba2515c18c9bb83755a45e73e9736eb0d",
      "tree": "6279f58f161aa2b69362ede1a5b4cbea8cc7f4e0",
      "parents": [
        "47186a836f247c5773042ca937b31e222495dfcd"
      ],
      "author": {
        "name": "Duansg",
        "email": "siguoduan@gmail.com",
        "time": "Mon Oct 26 20:24:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 20:24:03 2026 +0800"
      },
      "message": "fix(admin): compare detail CLOB field_value with DBMS_LOB.COMPARE on Oracle (#8109)"
    },
    {
      "commit": "47186a836f247c5773042ca937b31e222495dfcd",
      "tree": "a12aab6505a3b3e5ead0f532f28e375c951b4ef1",
      "parents": [
        "90c996ab64992a3ca467a681e9e17c49579e0bd8"
      ],
      "author": {
        "name": "Duansg",
        "email": "siguoduan@gmail.com",
        "time": "Mon Oct 26 20:23:56 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 20:23:56 2026 +0800"
      },
      "message": "fix(ai-proxy): evict disabled proxy api keys from gateway cache (#8114)"
    },
    {
      "commit": "90c996ab64992a3ca467a681e9e17c49579e0bd8",
      "tree": "1eb23c408fc2eced0ccf9beac762f35e3f82aa82",
      "parents": [
        "11af782d2508a5eeebaa27a9206673634d9c9d44"
      ],
      "author": {
        "name": "build",
        "email": "142670241+klT45@users.noreply.github.com",
        "time": "Mon Oct 26 15:31:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 15:31:15 2026 +0800"
      },
      "message": "fix(build): align ai-pii module parent versions with 2.7.3-SNAPSHOT (#8111)"
    },
    {
      "commit": "11af782d2508a5eeebaa27a9206673634d9c9d44",
      "tree": "34d3ba9273b0ade3489f94fec90b8243b6bc6b8f",
      "parents": [
        "e0578b9dcb1c89903231985c1a1ee2aa80798cbb"
      ],
      "author": {
        "name": "imDwAaY",
        "email": "wuwangyi000@gmail.com",
        "time": "Mon Oct 26 13:57:09 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:57:09 2026 +0800"
      },
      "message": "[ISSUE #8022] cap diagnostic collection by the remaining total budget (#8030)"
    },
    {
      "commit": "e0578b9dcb1c89903231985c1a1ee2aa80798cbb",
      "tree": "5d7b1091559eded409400fc7014cba79ebfc4dac",
      "parents": [
        "e82768e1c6916d5bad01c841f3c32dec075bfb85"
      ],
      "author": {
        "name": "BobSong",
        "email": "bobsongdev@gmail.com",
        "time": "Mon Oct 26 13:57:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:57:00 2026 +0800"
      },
      "message": "OSPP2: Add local and federated MCP resources (#7669)\n\n* feat(agent-gateway): add local and federated MCP resources\n\n* ci: rerun checks after external httpbin failure\n\n* test(agent-gateway): harden migration null fixture"
    },
    {
      "commit": "e82768e1c6916d5bad01c841f3c32dec075bfb85",
      "tree": "08ee7fd041eb7d0aa6db2e6778382b1df12562ad",
      "parents": [
        "16ec6f780087a17be1903ebb049a167e8c6d5c9d"
      ],
      "author": {
        "name": "build",
        "email": "142670241+klT45@users.noreply.github.com",
        "time": "Mon Oct 26 13:56:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:56:54 2026 +0800"
      },
      "message": "[ISSUE #8072] Harden container distributions and document the Kubernetes runtime contract (#8107)\n\n- Modernize the admin/bootstrap image bases: both images now use\n  amazoncorretto:17.0.21-alpine3.24 (linux/amd64, linux/arm64) with an\n  alpine:3.24 prepare stage; the bootstrap image no longer uses the EOL\n  CentOS 7 base.\n- Pin a fixed numeric non-root UID/GID (USER 10001:10001), declare\n  STOPSIGNAL SIGTERM and a HEALTHCHECK against /actuator/health, and keep the\n  runtime read-only friendly: /tmp is the only writable path by default. wget\n  is installed explicitly in both images (admin also keeps curl).\n- Rewrite both entrypoint.sh scripts as POSIX sh (the Alpine images do not\n  ship bash), exec the JVM so SIGTERM reaches the Spring Boot shutdown hooks,\n  support a read-only conf directory by falling back to a conf-ext classpath\n  override (and to the classpath when a writable copy only partially\n  succeeds), and keep the BOOT_JVM/ADMIN_JVM overrides intact.\n- Add docs/container-runtime.md: base-image update policy, runtime contract\n  (user, writable paths, signals/exit codes), JVM and container memory\n  budgets, Kubernetes requests/limits, readiness/liveness probe wiring\n  (including management.endpoint.health.probes.enabled and\n  initial-sync-readiness), Deployment/PDB examples for bootstrap and admin,\n  upgrade/rollback procedure (including the whole-pod-template caveat), measured\n  baseline image size/startup/memory numbers, and SBOM/scanning/signing\n  guidance that stays within the ASF release process.\n- Add script/docker-image-smoke.sh and .github/workflows/docker-image-smoke.yml:\n  CI smoke test for UID 10001, read-only rootfs, /tmp writability, conf-ext\n  overrides (read-only classpath fallback and legacy copy path),\n  BOOT_JVM/ADMIN_JVM, SIGTERM graceful shutdown (exit code 0/143, not 137),\n  restarts with the same mounted configuration and (real-dist mode) the\n  declared HEALTHCHECK plus /actuator/health \u003d UP.\n  SHENYU_SMOKE_REAL_DIST\u003d1 runs the same checks against real distributions, and\n  SHENYU_SMOKE_PREVIOUS_TAG\u003d\u003crelease\u003e verifies a previous published release\n  still starts and stops gracefully with the same mounts.\n- Add a make smoke-image convenience target, refresh the integrated-test\n  base-image pre-pull list, make the compose healthcheck read-only-rootfs\n  safe, add .gitattributes so the container scripts stay on LF, and fix the\n  pre-existing BOOSTRAP_REPOSITORY typo in the Makefile publish target."
    },
    {
      "commit": "16ec6f780087a17be1903ebb049a167e8c6d5c9d",
      "tree": "ab913af4a32668a0076a97e8d567c9a6fbf404cc",
      "parents": [
        "32d7b56755f9c6754d1a3dcca221599a10c83af8"
      ],
      "author": {
        "name": "Mingyu Yang",
        "email": "2208631663@qq.com",
        "time": "Mon Oct 26 13:56:46 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:56:46 2026 +0800"
      },
      "message": "fix (admin) : scope instance history by namespace. (#7855)"
    },
    {
      "commit": "32d7b56755f9c6754d1a3dcca221599a10c83af8",
      "tree": "44715bb1ce5d7c03289c1ca10411bc464b051fdc",
      "parents": [
        "004cb3608c25e11ca29111db7af3940ce679f447"
      ],
      "author": {
        "name": "IT-Althusser",
        "email": "3030577943@qq.com",
        "time": "Mon Oct 26 13:56:40 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:56:40 2026 +0800"
      },
      "message": "feat(plugin): add policy-driven PII detection for AI traffic (#8105)\n\n* feat(plugin): add ai pii detection plugin with detectors, chat profiles and response decorator (#8048)\n\n* fix(plugin): harden pii detection assembly, schema and enforcement semantics (#8048)\n\n- add AutoConfiguration.imports so the starter is assembled in bootstrap\n- add permission rows and the plugin: perms prefix across the four schemas\n- request scan hops off the netty event loop and catches detector deadlines\n- gzip, sse and unscannable responses honour failClosed; error envelopes pass through\n- responses enforce maxBodySize before buffering\n- rule compilation falls back on unusable detectors, scope and timeout values\n- one detector deadline per direction instead of per slot\n- cleared handles drop the compiled rule; luhn rejects repeated digit cards\n- document mutual exclusion with aiResponseTransformer\n\n* fix(plugin): close pii detection bypasses and bound the response aggregation (#8048)\n\n- scan successful openai-responses completions: \"error\": null is not an\n  error envelope, only a non null error object bypasses the scan\n- merge overlapping redaction ranges on the original coordinates before\n  replacing, so a contained detection never leaves a partially redacted\n  island behind\n- bound the response aggregation: a fail closed rule stops reading at the\n  bound, a fail open rule reads to the end and writes the complete body\n  back unscanned instead of truncating it\n- pass unsupported payloads through as the original bytes, a gzip body\n  never survives a utf-8 round trip\n- precheck streaming requests of a strict response scope before the model\n  is reached, even when the request text itself is not scanned\n- measure the request bound in utf-8 bytes instead of characters\n- default maxBodySize to 1 MiB (dto and the four schema dialects)\n- restore the upstream auto configuration verification script\n- add the plugin README and regression tests for every fix above\n\n* fix(plugin): bound the fail-open response path and align the precheck size limits (#8048)\n\n- a fail open rule whose response bound is exceeded now switches to\n  unscanned streaming instead of aggregating the whole body: the buffered\n  prefix is written, the overflowing chunk and every later chunk follow as\n  they arrive, memory stays at the prefix size and the client receives the\n  prefix while the upstream is still open; the upstream is subscribed once,\n  nothing is lost or duplicated\n- a fail closed rule still cancels the reading at the bound before any\n  byte was written and answers with the rejection body\n- the scanned completion path sets the content length of the rewritten body\n- the declared size bound now applies to the response-only precheck path too\n- a request that exceeds the codec in memory limit (independent of\n  maxBodySize) is rejected with a clear reason instead of surfacing a codec\n  exception\n- regression tests: prefix readability before the upstream completes,\n  declared over-limit precheck, codec-limit rejection; README updated\n\n* fix(plugin): enforce the precheck byte bound and release pooled buffers at the switch (#8048)\n\n- the response-only precheck measures the actual utf-8 length of an\n  undeclared chunked body, so the maxBodySize bound no longer depends on\n  how the request is transported\n- the fail-open switch point copies the overflowing chunk out of its\n  upstream buffer and releases the buffer immediately: what the switch\n  emits is array backed, a cancellation between the replayed prefix and\n  the chunk cannot leak pooled memory; a doOnDiscard hook covers a chunk\n  that was taken from the upstream but never emitted\n- regression tests: a real netty pooled buffer proves both chunk buffers\n  reach refCnt 0 when the downstream cancels after the prefix, an\n  undeclared 1 KiB body over a 128 byte rule bound is rejected, and the\n  streaming test now replays a non empty prefix\n\n* fix(ai): validate pii protocol shapes and configuration bounds\n\nValidate extraction shapes while preserving textless tool calls, normalize negative body limits, bound custom regex configuration before compilation, reject configured rules without compiled policies, and document fail-open response-only behavior. Add regression tests for protocol and configuration boundaries.\n\n* test(plugin): satisfy pii configuration checkstyle\n\n---------\n\nCo-authored-by: IT-Althusser \u003cIT-Althusser@users.noreply.github.com\u003e"
    },
    {
      "commit": "004cb3608c25e11ca29111db7af3940ce679f447",
      "tree": "f097fe28234127e187295a8de6f9b79ddec3c1d7",
      "parents": [
        "ce63f7851a89b2e62640569b98e8a90ddd405c8b"
      ],
      "author": {
        "name": "lymerin",
        "email": "884917500@qq.com",
        "time": "Mon Oct 26 13:56:34 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:56:34 2026 +0800"
      },
      "message": "fix(e2e): synchronize readiness and isolate prerequisite failures (#8091)\n\n* fix(e2e): check MySQL readiness over TCP\n\n* fix(e2e): wait for gateway configuration convergence\n\n* fix(e2e): synchronize RocketMQ logging prerequisites\n\n* fix(ci): preserve E2E artifacts and isolate prerequisite failures\n\n* fix(ci): prepare Maven inputs before E2E matrices"
    },
    {
      "commit": "ce63f7851a89b2e62640569b98e8a90ddd405c8b",
      "tree": "fb9bfdf1a575aac9db46fe4ad2b13602f88a7684",
      "parents": [
        "8a2fc92e19896a3d83cebefea7864527539a74c5"
      ],
      "author": {
        "name": "Jesen Kwan",
        "email": "guan.zhenxing@foxmail.com",
        "time": "Mon Oct 26 13:56:27 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:56:27 2026 +0800"
      },
      "message": "feat(admin): idempotent app-auth lifecycle API for machine callers (#7877)\n\n* feat(admin): idempotent app-auth lifecycle endpoints\n\nAdd a machine-caller-oriented lifecycle API for app auth management:\n\n- four endpoints under /appAuth/lifecycle (apply / result / revoke /\n  replacePaths) guarded by dedicated system:authen:lifecycle* permissions\n- app_auth_request idempotency table with unique triple key\n  (callerKey, namespaceId, requestId); apply reserves the key first and\n  creates app_auth atomically (open\u003dtrue, enabled\u003dfalse)\n- revoke writes a REVOKED tombstone in the same transaction so late\n  applies can never resurrect revoked credentials\n- replacePaths replaces the managed paths as a whole; an empty array\n  really clears all authorization\n- result is a read-only, recoverable query that only returns credentials\n  for CREATED records\n- batchDelete marks associated records REVOKED under the unified lock\n  order instead of silently dropping linkage\n- service-account whitelist (shenyu.app-auth.lifecycle.service-users)\n  defaults to deny-all; caller identity derives from the immutable userId\n\nSigned-off-by: jesen \u003cguan.zhenxing@foxmail.com\u003e\n\n* test(admin) + db: lifecycle tests and multi-database schema\n\n- port the lifecycle test suite: access-policy deny matrix, controller\n  access contract, mapper CAS semantics and the real-MySQL series\n  (apply/result/revoke/races/replacePaths/legacy-delete linkage) guarded\n  by explicit shenyu.auth.test.* connection properties\n- add app_auth_request DDL to the h2 schema, mysql/pg/oracle init scripts\n  and all five 2.7.2 upgrade dialects, plus the four lifecycle button\n  resources under the auth menu (seeds follow the 2.7.2 upgrade pattern)\n- stub AppAuthRequestMapper in AppAuthServiceTest/ConfigsImportDuplicateTest\n  for the new constructor argument\n\nSigned-off-by: jesen \u003cguan.zhenxing@foxmail.com\u003e\n\n* test(admin): drop internal codenames and fix ported references\n\n- replace the remaining internal codename in javadoc with neutral wording\n- point test resources at the renamed app-auth-request-sqlmap.xml\n- align test permission strings with the system:authen:lifecycle* names\n- rename the isolated test-database convention to shenyu_auth_test.*,\n  the probe table and the mapper environment accordingly\n- drop the obsolete flm_schema_migration cleanup: upstream has no such table\n\nSigned-off-by: jesen \u003cguan.zhenxing@foxmail.com\u003e\n\n* fix(admin): publish lifecycle sync events inside the transaction\n\nThe dispatcher defers data-changed events to afterCommit itself. Publishing\nfrom inside a registered afterCommit callback made it register another\nafterCommit on an ending synchronization, so the event was never delivered\nand gateways kept stale auth paths. Publish in the transactional body and\nlet the dispatcher own the commit boundary.\n\nSigned-off-by: jesen \u003cguan.zhenxing@foxmail.com\u003e\n\n* chore(admin): remove internal codenames from the lifecycle API\n\nDrop the remaining internal project references (log tag prefix, variable\nnames and test method names) so the API reads as a generic ShenYu feature.\n\nSigned-off-by: jesen \u003cguan.zhenxing@foxmail.com\u003e\n\n* chore: retrigger CI (wasm-fixtures wrapper download was transient)\n\nSigned-off-by: jesen \u003cguan.zhenxing@foxmail.com\u003e\n\n* fix(ci): grant lifecycle buttons to the admin role and ignore *.sha256 in license-eye\n\nTwo CI failures on the fresh-install checks:\n\n- native-sql matrix requires every resource row to carry an admin-role\n  permission row; the four lifecycle button resources were inserted\n  without their permission counterparts. Add the four grants next to\n  each resource insert across the nine SQL files.\n- check-license-header runs skywalking-eyes (.licenserc.yaml), which is\n  separate from the RAT plugin excludes; add \u0027**/*.sha256\u0027 to its\n  paths-ignore for the canonical-request digest fixture.\n\nSigned-off-by: jesen \u003cguan.zhenxing@foxmail.com\u003e\n\n* fix(admin): reject a null Shiro subject in the access policy\n\nSecurityUtils.getSubject() returns null (instead of throwing) when a\nSecurityManager is bound but cannot produce a subject, e.g. a mock left\nin the JVM by PermissionServiceTest, making the full-suite run of\nmissingShiroContextIsRejected die with a NullPointerException instead\nof the documented rejection. Guard isPermitted against a null subject\nand add a regression test that binds a mock SecurityManager.\n\n---------\n\nSigned-off-by: jesen \u003cguan.zhenxing@foxmail.com\u003e"
    },
    {
      "commit": "8a2fc92e19896a3d83cebefea7864527539a74c5",
      "tree": "e94ceaf7046b45e323ac65b68977869d393d67a0",
      "parents": [
        "b955ec6dc92e1a8e0f8f276dde67703fb1a9d43f"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Mon Oct 26 13:56:22 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:56:22 2026 +0800"
      },
      "message": "feat(admin,divide): draining admission lets instances stop receiving new work without deregistering (#8042) (#8101)"
    },
    {
      "commit": "b955ec6dc92e1a8e0f8f276dde67703fb1a9d43f",
      "tree": "46a474dfca04ff08744dccdf651ee01881592b90",
      "parents": [
        "7a5cd42422015f017871b860b48a19af4530f2d0"
      ],
      "author": {
        "name": "redyyang",
        "email": "3202137046@qq.com",
        "time": "Mon Oct 26 13:56:17 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:56:17 2026 +0800"
      },
      "message": "feat(sync): negotiate compact Discovery payloads per connection (#8108)\n\n* feat(sync): negotiate compact discovery payloads per connection\n\n* test(sync): verify negotiated snapshot framing and capability reset"
    },
    {
      "commit": "7a5cd42422015f017871b860b48a19af4530f2d0",
      "tree": "b6abb1f5e888d077dad986e17189a61aa49e99bb",
      "parents": [
        "b940b2c6310f82bfd3e5d2d815b3ea1b6b5d6c7b"
      ],
      "author": {
        "name": "redyyang",
        "email": "3202137046@qq.com",
        "time": "Mon Oct 26 13:56:08 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:56:08 2026 +0800"
      },
      "message": "feat(wasm): add opt-in execution deadlines and memory budgets (#7948)\n\n* feat(wasm): bound guest execution and linear memory with opt-in limits\n\n* fix(wasm): diagnose invalid properties and support memory-free guests\n\n* test(ci): align cryptor failures and wait for usable SDK routes\n\n* docs(wasm): clarify memory-free guest failure timing"
    },
    {
      "commit": "b940b2c6310f82bfd3e5d2d815b3ea1b6b5d6c7b",
      "tree": "802f9848e02a64d2c0339a4682fe18c74fb4462f",
      "parents": [
        "8da48df589b560ca0d6d0a1a4a0438e1151eb63d"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Mon Oct 26 13:56:02 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:56:02 2026 +0800"
      },
      "message": "feat(divide): add optional sticky session affinity composed with load balancing (#8037) (#8098)"
    },
    {
      "commit": "8da48df589b560ca0d6d0a1a4a0438e1151eb63d",
      "tree": "4d1b53dda7f01db6ddf231bd2d2ed41669888968",
      "parents": [
        "b46bf15c3a243e926994cb32c3f0a23eadc41adf"
      ],
      "author": {
        "name": "shown",
        "email": "yuluo08290126@gmail.com",
        "time": "Mon Oct 26 13:55:56 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:55:56 2026 +0800"
      },
      "message": "prepare release v2.7.2 (#8100)\n\n* [maven-release-plugin] prepare release v2.7.2\n\n* [maven-release-plugin] prepare for next development iteration\n\n* fix: sync examples and integration test versions for 2.7.3\n\n* fix: update release notices and license inventories\n\n* [maven-release-plugin] prepare release v2.7.2\n\n* [maven-release-plugin] prepare for next development iteration"
    },
    {
      "commit": "b46bf15c3a243e926994cb32c3f0a23eadc41adf",
      "tree": "9c78097a1ccb57b48c7c7da648118e37990d85ec",
      "parents": [
        "0ec5e419cd09e8baaf712baa614bc0062171a06a"
      ],
      "author": {
        "name": "Daming",
        "email": "haochao.zhuang@gmail.com",
        "time": "Mon Oct 26 13:55:50 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:55:50 2026 +0800"
      },
      "message": "docs: add plugin graph orchestration contract and compatibility audit (#8007)\n\nAdd the Phase-1 design artifacts for optional DAG-based plugin orchestration\n(parent proposal #7993):\n\n- docs/plugin-graph-orchestration.md: versioned graph schema, node/condition\n  semantics, Phase-1 structural restrictions, graph limits, wrapper-scope\n  classes, the dual-executor (LEGACY/GRAPH) contract with sequence diagrams,\n  and explicit decisions for repeated continuations, mandatory dependencies\n  (fail closed) and the no-legacy-fallback rule.\n- docs/plugin-graph-compatibility-audit.md: category-level classification of\n  every PluginEnum-shipped plugin into wrapper-scope class + continuation\n  behaviour + Phase-1 verdict, with representative deep-dives (global/context\n  init, Sentinel-style wrapper, response owner/writer, proxy terminal + retry,\n  fork() internal dispatch) and the validation rules derived for #7995.\n\nThese are design documents for community review; no runtime behaviour changes.\n\nFixes #7994\nRefs #7993\n\nCo-authored-by: Luke Haochao Zhuang \u003cLukeHaochao.Zhuang@starbucks.cn\u003e"
    },
    {
      "commit": "0ec5e419cd09e8baaf712baa614bc0062171a06a",
      "tree": "eb0a06c607cdddb276d1563359de8c0218564c8e",
      "parents": [
        "19d3876dcde4f67a28ee1161db5c50b1d14b6dcf"
      ],
      "author": {
        "name": "hanzhe-one",
        "email": "200491821+hanzhe-one@users.noreply.github.com",
        "time": "Mon Oct 26 13:55:45 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:55:45 2026 +0800"
      },
      "message": "fix(loadbalancer): count outstanding requests for websocket and dubbo (#8043)\n\n* fix(loadbalancer): count outstanding requests for websocket and dubbo\n\nLeastActiveLoadBalance reads Upstream#getInflight(), but only the divide\nplugin maintained it. WebSocket and apache dubbo gray routing left every\nupstream at the same baseline, so leastActive degenerated to weighted\nrandom on those paths.\n\nWebSocketPlugin reserves the chosen upstream when the proxied session is\nsubscribed and releases it in doFinally, mirroring DividePlugin. The\nreservation sits inside Mono.defer so a session that is never subscribed\ncannot leak the count.\n\nThe dubbo gray load balance has no lifecycle hook of its own, so it hands\nback a delegating Invoker for leastActive. The count is increased when the\nRPC starts rather than when the invoker is selected: Dubbo\u0027s cluster can\npick an invoker and then discard the pick, and a selection-time\nreservation would leak those counts. It is released exactly once, on\nresult completion or on a synchronous throw.\n\nThe wrapper delegates equals and hashCode to the invoker it wraps. Dubbo\u0027s\ncluster keeps the selected invoker in its already-tried list and in its\nconnectivity-invalidation set and compares by identity there, so a wrapper\nthat did not delegate equality would make failover retry the same\nprovider and would stop unhealthy providers from being removed.\n\nshortestResponse also needs the average elapsed time of successful\nrequests, which only divide records, so it still falls back to weight\noutside the divide plugin. The grpc picker, the tcp proxy and the java sdk\nrebuild their Upstream objects on every call and cannot share a count;\nboth limits are documented in the balancer javadoc and RELEASE-NOTES.\n\n* fix(websocket): count the proxied session, not the upgrade handshake\n\nReview on #8043 showed the count was attached to the wrong Mono. The Mono\nreturned by WebSocketService.handleRequest completes when the upgrade\nhandshake finishes: reactor-netty\u0027s withWebsocketSupport returns a Mono\nover the handshaker promise and subscribes the session handler separately\ninside doOnEach. A session open for an hour was therefore counted for a\nfew milliseconds, and leastActive still saw nothing from the websocket\npath.\n\nThe count now sits on the WebSocketHandler the service is given, whose\nMono terminates when the session ends. It is released on that Mono\u0027s\ntermination, and also when the handler fails before starting or returns\nnothing, so a failure cannot leave the upstream reserved.\n\nInflightInvoker had the same class of bug in miniature: a single\nAtomicBoolean per invoker meant a second invocation on a reused invoker\nincreased the count and never released it. The guard is now per call.\nDubbo\u0027s own RpcStatus counts per invocation for the same reason.\n\nAlso from the review: the dubbo fallback that discards a gray pick now\nsays so, and the wrapper delegates toString so log lines name the\nprovider.\n\nThe websocket tests no longer stub the service to Mono.never(), which\npinned the wrong assumption. They drive the real handler and assert that\nthe count is still held after the handshake completes."
    },
    {
      "commit": "19d3876dcde4f67a28ee1161db5c50b1d14b6dcf",
      "tree": "83cf03e87116630588425f9c9a6148fec7846702",
      "parents": [
        "9d07ba0817f4842fd4fc9c8a6959a71b99cc2ed7"
      ],
      "author": {
        "name": "lymerin",
        "email": "884917500@qq.com",
        "time": "Mon Oct 26 13:55:40 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:55:40 2026 +0800"
      },
      "message": "fix(logging): fix logging not resuming after re-enabling with unchanged config (#7513)"
    },
    {
      "commit": "9d07ba0817f4842fd4fc9c8a6959a71b99cc2ed7",
      "tree": "83c5363dae38d20675163b240b9d57f3cb9b13c0",
      "parents": [
        "58d74a57ac65f09c5205bb50961bceaa6e652483"
      ],
      "author": {
        "name": "redyyang",
        "email": "3202137046@qq.com",
        "time": "Mon Oct 26 13:55:34 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:55:34 2026 +0800"
      },
      "message": "fix(plugin): preserve dynamic candidate matching after cache warmup (#8106)\n\n* fix(plugin): check competing candidates before caching positive matches\n\n* fix(plugin): exclude timed matches and align rewritten cache paths"
    },
    {
      "commit": "58d74a57ac65f09c5205bb50961bceaa6e652483",
      "tree": "cc3a5485cc895a3c3fe815dc06aeea549080e95f",
      "parents": [
        "87155d493b07fc5687d14f769cdb7baae7ed8bb7"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Mon Oct 26 13:55:26 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:55:26 2026 +0800"
      },
      "message": "fix(mcp-server): rebuild the SSE transport when the message endpoint changes (#8044) (#8086)\n\n* fix(mcp-server): rebuild the SSE transport when the message endpoint changes (#8044)\n\n* fix(mcp-server): tear down the previous transport even when the manager no longer knows it (#8044)"
    },
    {
      "commit": "87155d493b07fc5687d14f769cdb7baae7ed8bb7",
      "tree": "3c89f287fc400189becb48e7470f1f1124d8db7d",
      "parents": [
        "052a0369e94818c32334cf6c24583d26d9502ffc"
      ],
      "author": {
        "name": "Jerry聊AI",
        "email": "1394367234@qq.com",
        "time": "Mon Oct 26 13:55:20 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:55:20 2026 +0800"
      },
      "message": "fix(admin): keep instance health sync scheduled after failures (#6496) (#7414)\n\n* fix(admin): keep instance health sync scheduled after failures (#6496)\n\n* fix(admin): isolate instance health sync failures (#6496)\n\nSigned-off-by: jerry \u003c1394367234@qq.com\u003e\n\n* test(admin): disambiguate sync exception assertions (#6496)\n\n---------\n\nSigned-off-by: jerry \u003c1394367234@qq.com\u003e"
    },
    {
      "commit": "052a0369e94818c32334cf6c24583d26d9502ffc",
      "tree": "25e2929ee1c96c2d16240c3e287169206cc09bdb",
      "parents": [
        "8f30c696a40ccde49d32c7f9d2e9eb6ec50687a1"
      ],
      "author": {
        "name": "Daming",
        "email": "haochao.zhuang@gmail.com",
        "time": "Mon Oct 26 13:55:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:55:15 2026 +0800"
      },
      "message": "fix: pair P2C inflight accounting for singleton upstream selection (#7980)\n\n* fix: pair P2C inflight accounting for singleton upstream selection\n\nAbstractLoadBalancer.select short-circuits a singleton candidate list and\nreturns the only upstream without calling P2cLoadBalancer.doSelect, so the\ninflight increment is skipped. Divide\u0027s P2C completion callback still\ndecrements the selected upstream, so repeated singleton requests drive the\ninflight counter below its baseline and eventually negative, which P2C then\nuses in its load calculation.\n\nOverride select in P2cLoadBalancer to perform the same increment (and\nlastPicked update) that doSelect does when the candidate list is a singleton,\nkeeping start/completion accounting paired.\n\nAdd regression tests covering the single increment and the paired\nselect/decrement loop from the issue reproduction.\n\n* fix: release P2C inflight on failover retry upstream (#7982)\n\nDefaultRetryStrategy.resend re-selects a retry upstream through LoadbalancerUtils.getForExchange, which increments the P2C inflight counter of the newly picked upstream. Divide\u0027s completion callback only captures the initially selected upstream, so nothing released the retry attempt\u0027s increment. Repeated failovers therefore inflated inflight on retry destinations and distorted subsequent P2C load estimates.\n\nAttach a doFinally cleanup that decrements the retry upstream\u0027s inflight on success, failure and cancellation, guarded to the P2C algorithm (the only balancer that increments on selection), so every P2C attempt keeps paired accounting on its own selected upstream.\n\nStacked on the #7974 singleton-selection fix so the release is also correct when a single retry candidate remains and P2C selection is short-circuited.\n\nFixes #7975\n\nCo-authored-by: Luke Haochao Zhuang \u003cLukeHaochao.Zhuang@starbucks.cn\u003e\n\n---------\n\nCo-authored-by: Luke Haochao Zhuang \u003cLukeHaochao.Zhuang@starbucks.cn\u003e"
    },
    {
      "commit": "8f30c696a40ccde49d32c7f9d2e9eb6ec50687a1",
      "tree": "830a03206d3f99380ce300347b83237fed4b3125",
      "parents": [
        "2f85d674e13fd31219e91f698e3d5bd194b2f79c"
      ],
      "author": {
        "name": "redyyang",
        "email": "3202137046@qq.com",
        "time": "Mon Oct 26 13:54:14 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:54:14 2026 +0800"
      },
      "message": "docs: explain Windows long-path checkout and recovery (#8102)"
    },
    {
      "commit": "2f85d674e13fd31219e91f698e3d5bd194b2f79c",
      "tree": "64ff06ef27b6eaa9e241a0221ae857bdbf6d83b1",
      "parents": [
        "90f1ab5e6211777b0a05bb2381b04fb12a0c6e9f"
      ],
      "author": {
        "name": "shown",
        "email": "yuluo08290126@gmail.com",
        "time": "Sun Oct 25 13:03:47 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 13:03:47 2026 +0800"
      },
      "message": "infra: refactor GHA command (#8087)"
    },
    {
      "commit": "90f1ab5e6211777b0a05bb2381b04fb12a0c6e9f",
      "tree": "665f9056fdfd6a78548803f88092db06cd4aa55b",
      "parents": [
        "f2e7a99489b03752b91c28dbc2c7f9c597921646"
      ],
      "author": {
        "name": "hanzhe-one",
        "email": "200491821+hanzhe-one@users.noreply.github.com",
        "time": "Sun Oct 25 09:11:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 09:11:15 2026 +0800"
      },
      "message": "fix(web): make the diagnostic manifest describe the archived sections (#8085)\n\n* fix(web): make the diagnostic manifest describe the archived sections\n\nDiagnosticBundleWriter serialised manifest.json before applying the\narchive-wide section budget and then cut section bytes without touching\nthe already-written manifest. A section could therefore be reported OK\nwith its original sizeBytes while its entry was truncated or empty, and\nmanifest.json itself was not counted against the documented total\nuncompressed budget.\n\nPlan the archive before writing it: cap each section, render the\nmanifest from that plan, trim the plan until the manifest plus sections\nfit maxTotalBytes, and re-plan until the manifest and the plan agree.\nSections cut by the total budget become TRUNCATED, sections that receive\nno allowance become SKIPPED with an empty entry, and a budget too small\nfor the mandatory manifest now fails explicitly instead of silently\nexceeding the bound. Cuts land on UTF-8 sequence boundaries.\n\nFixes #8023\n\n* fix(web): cut every diagnostic size cap on a UTF-8 boundary\n\nThe per-section cap in DiagnosticBundleWriter.plan and in\nDiagnosticBundleService.capSection used Arrays.copyOf at an arbitrary byte\noffset, so a section ending a multi-byte character exactly on\nmaxSectionBytes was archived as an undecodable entry. Only the\ntotal-budget path went through the boundary helper.\n\nMove the boundary arithmetic into a package-private Utf8Boundary and route\nboth per-section caps through it. A cap below one whole character now\nyields no content, reported as SKIPPED rather than as an empty truncated\nsection. Cover the helper with a parameterised test over a 3-byte\ncharacter straddling the limit, plus a service-level case for the\ncollector path.\n\nAlso correct the pass-bound comment, which claimed each round removes at\nleast the overflow: a character-boundary cut can leave a byte or two, and\ntruncation adds reason text to the manifest, so termination rests on the\npass bound rather than monotone shrinkage. The unsatisfiable-budget\nfallback now renders an empty plan without mutating the caller\u0027s\nallocation array."
    },
    {
      "commit": "f2e7a99489b03752b91c28dbc2c7f9c597921646",
      "tree": "88be0afb650a61305f3b8063f1496141d5be6a3b",
      "parents": [
        "e426a06fe24e1cbc547c5313b5731eaf63240643"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Sun Oct 25 09:11:08 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 09:11:08 2026 +0800"
      },
      "message": "fix(mcp-server): resolve SSE transports by the canonical server path (#8045) (#8084)\n\n* fix(mcp-server): resolve SSE transports by the canonical server path (#8045)\n\n* test(mcp-server): restore the disabled streamable-http test and tighten assertions (#8045)"
    },
    {
      "commit": "e426a06fe24e1cbc547c5313b5731eaf63240643",
      "tree": "d9e74f03474d4f9944638ac837130b27c8adff08",
      "parents": [
        "4690befef6ab08434688e9ec8319c63e64b1fc72"
      ],
      "author": {
        "name": "redyyang",
        "email": "3202137046@qq.com",
        "time": "Sun Oct 25 09:11:02 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 09:11:02 2026 +0800"
      },
      "message": "fix(admin): preserve omitted tag fields in descendant ancestry (#8057)\n\n* fix(admin): preserve omitted tag fields in descendant ancestry\n\n* docs(admin): explain partial tag field clearing semantics\n\n* docs(admin): place tag update rules beside their assignments"
    },
    {
      "commit": "4690befef6ab08434688e9ec8319c63e64b1fc72",
      "tree": "fbaa59afad6637532fc099168f21ae2a9e2c8143",
      "parents": [
        "745df1535e4d5ed86e97826c029f693142773e10"
      ],
      "author": {
        "name": "Duansg",
        "email": "siguoduan@gmail.com",
        "time": "Sun Oct 25 09:08:44 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 09:08:44 2026 +0800"
      },
      "message": "fix(admin): scope namespace plugin enable to the request namespace (#8029)"
    },
    {
      "commit": "745df1535e4d5ed86e97826c029f693142773e10",
      "tree": "8d4002ea3c4f0cb83fea68ec18a6a170befc6236",
      "parents": [
        "f41d26fb2657bc92807cdce40bbc0fc5cb3f984d"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Sun Oct 25 09:08:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 09:08:38 2026 +0800"
      },
      "message": "fix(admin): keep accepted heartbeats when restoring instances from the database (#7763) (#7780)"
    },
    {
      "commit": "f41d26fb2657bc92807cdce40bbc0fc5cb3f984d",
      "tree": "0ab93aceadf7796d1940824351ac91a31a027c4d",
      "parents": [
        "466aa979d71334e8a83d846e9d4c83b24a4d975b"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Sun Oct 25 09:08:32 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 09:08:32 2026 +0800"
      },
      "message": "fix(logging): clear the selector sampler override when its handle is emptied (#7750) (#7766)"
    },
    {
      "commit": "466aa979d71334e8a83d846e9d4c83b24a4d975b",
      "tree": "bd2611a011dc0922ca7447e9b573c9f99c253851",
      "parents": [
        "9063ffcb27b356782c493e38ae8d1f8593d1333e"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Sun Oct 25 09:08:27 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 09:08:27 2026 +0800"
      },
      "message": "fix(dubbo): resolve single name-mapped parameters instead of using the mapping JSON as a type name (#7736) (#7746)"
    },
    {
      "commit": "9063ffcb27b356782c493e38ae8d1f8593d1333e",
      "tree": "7a27157818bb842c1bc1949f5c686db308b126db",
      "parents": [
        "9b9652b92f9785fb0ee8c6714d4ede86616d275c"
      ],
      "author": {
        "name": "Jerry聊AI",
        "email": "1394367234@qq.com",
        "time": "Sun Oct 25 09:08:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 09:08:18 2026 +0800"
      },
      "message": "fix(admin): remove deprecated raw-password lookup (#7413)"
    },
    {
      "commit": "9b9652b92f9785fb0ee8c6714d4ede86616d275c",
      "tree": "2f363a73a577ea33918bb74d5d8c3d5311e47a95",
      "parents": [
        "a8080aef28356171ca7b67088a5f0f2b7212965e"
      ],
      "author": {
        "name": "Jerry聊AI",
        "email": "1394367234@qq.com",
        "time": "Sun Oct 25 09:08:08 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 09:08:08 2026 +0800"
      },
      "message": "fix(admin): keep cluster election scheduled after failures (#6495) (#7406)\n\n* fix(admin): keep cluster election scheduled after failures (#6495)\n\n* fix(admin): make master retry test timing-safe\n\nSigned-off-by: jerry \u003c1394367234@qq.com\u003e\n\n---------\n\nSigned-off-by: jerry \u003c1394367234@qq.com\u003e"
    },
    {
      "commit": "a8080aef28356171ca7b67088a5f0f2b7212965e",
      "tree": "4879d5030d4760ca0518cfbbf4db7681e1e0f097",
      "parents": [
        "434366a6b9d982a25e7bdab92700b6df240acc09"
      ],
      "author": {
        "name": "cloudbase-ai",
        "email": "aias94coffee@gmail.com",
        "time": "Sat Oct 24 23:16:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 23:16:04 2026 +0800"
      },
      "message": "fix(mqtt): scope session state per instance and guard a missing client id (#8021) (#8092)\n\nSessionRepository kept its sessions in a static map while every other\nrepository in the package keeps them per instance. Two consequences:\n\n- state leaked between instances, so a repository created for one\n  connection, or for one test, could observe and evict the sessions of\n  another;\n- the module tests only passed because Singleton still held whatever the\n  previously executed test class had registered.\n\nSubscribe and Unsubscribe look the session up with the client id taken from\nChannelRepository, which is null for a channel that CONNECT never registered\nor whose ownership was taken over. The session index rejects a null key, so\nthe SUBSCRIBE failed with an NPE before the SUBACK was sent. Publish and\nPubRel already guard this case; the two handlers now do the same.\n\nTests: SessionRepositoryTest covers the instance isolation, SubscribeQosTest\nand UnsubscribeTest cover the missing client id, and MqttTransportHandlerTest\nregisters the repositories it reaches through the handler so it no longer\ndepends on a leaked Singleton.\n\nCo-authored-by: cloudbase-ai \u003c22498243+cloudbase-ai@users.noreply.github.com\u003e"
    },
    {
      "commit": "434366a6b9d982a25e7bdab92700b6df240acc09",
      "tree": "85c03f8741ad72cfa63009695aa0119cf536e9e2",
      "parents": [
        "d21ca82360a0e54f450518e7b4653894a0bbebfe"
      ],
      "author": {
        "name": "SouthwestAsiaFloat",
        "email": "2034946972@qq.com",
        "time": "Sat Oct 24 23:15:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 23:15:10 2026 +0800"
      },
      "message": "feat(metrics): add canary routing metrics (#8090)"
    },
    {
      "commit": "d21ca82360a0e54f450518e7b4653894a0bbebfe",
      "tree": "adae37043f4f3156e6aed00119451170727e21a9",
      "parents": [
        "7cb5e4810dab438889a17b4a83c8cf9eb55c0141"
      ],
      "author": {
        "name": "cloudbase-ai",
        "email": "aias94coffee@gmail.com",
        "time": "Sat Oct 24 22:54:43 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 22:54:43 2026 +0800"
      },
      "message": "ci(e2e): rebuild the image artifact when a retest cannot download it (#8094)\n\nThe e2e workflow downloads the shenyu-images artifact that\nbuild-docker-images uploads with retention-days: 1. /retest calls\nreRunWorkflowFailedJobs, which re-executes only the failed jobs: the\nproducer job stays successful and is never re-run. Once the artifact has\nexpired, every retry of e2e-case or e2e-storage fails on the download\n\n  Unable to download artifact(s): Artifact not found for name: shenyu-images\n\nand no amount of /retest can recover the run.\n\nretest.yml now probes the artifacts of an e2e run before retrying it and\nfalls back to a full workflow rerun when shenyu-images is missing or\nexpired, so build-docker-images runs again and regenerates it. Runs that\nstill have the artifact keep the cheaper failed-job rerun.\n\ne2e-k8s.yml also checks the two image tarballs after the download, so a\nmanual \"Re-run failed jobs\" fails with an actionable message instead of an\nerror from docker load.\n\nCo-authored-by: cloudbase-ai \u003c22498243+cloudbase-ai@users.noreply.github.com\u003e"
    },
    {
      "commit": "7cb5e4810dab438889a17b4a83c8cf9eb55c0141",
      "tree": "d4ce04fdd8bf0bd333e3deff71f87ce5bca65ef0",
      "parents": [
        "f81d8cc8c86fb20424d5f042a60ed4e2f7b3e7ad"
      ],
      "author": {
        "name": "cloudbase-ai",
        "email": "aias94coffee@gmail.com",
        "time": "Sat Oct 24 22:53:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 22:53:58 2026 +0800"
      },
      "message": "test(mqtt): use real repositories in SubscribeTest and cover the session update (#8093)\n\nSubscribeTest mocked ChannelRepository and SessionRepository, and a mock\nanswers null for every lookup. subscribe() therefore always took the\n\"no session\" branch: the client id was null, the session was null, and the\ncode that stores the granted subscriptions on the session never ran. The\nthree assertions only covered SUBACK, so a regression there would have gone\nunnoticed.\n\nThe channel and session repositories are now real instances, the connected\nchannel is registered in the channel repository, and a fourth test asserts\nthat the subscriptions land on the session. SubscribeRepository and\nTopicRepository stay mocked, because subscribe() writes to the first and the\nsecond is only observed through verify().\n\nThis also supersedes #8089, which adds the same real instances but keeps the\n@Mock fields with the same names and does not compile.\n\nCo-authored-by: cloudbase-ai \u003c22498243+cloudbase-ai@users.noreply.github.com\u003e"
    },
    {
      "commit": "f81d8cc8c86fb20424d5f042a60ed4e2f7b3e7ad",
      "tree": "c505a1c07c8a31c7d21da44f18bc82a1caf21fbc",
      "parents": [
        "1861aadfe40f8ade50fffc7654a000920ac44b20"
      ],
      "author": {
        "name": "imDwAaY",
        "email": "wuwangyi000@gmail.com",
        "time": "Sat Oct 24 19:47:57 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 19:47:57 2026 +0800"
      },
      "message": "[ISSUE #7965] Register the scaling observer so metric-driven policies actuate (#7966)\n\n* [ISSUE #7965] Register the scaling observer so metric-driven policies actuate\n\n* [ISSUE #7965] Add Spring context test for observer discovery"
    },
    {
      "commit": "1861aadfe40f8ade50fffc7654a000920ac44b20",
      "tree": "3d4395e1bcbdb71b234ef3dc9287a5c3a140682e",
      "parents": [
        "13de0bffec66a54a9a34016cb4fd07326845f15e"
      ],
      "author": {
        "name": "redyyang",
        "email": "3202137046@qq.com",
        "time": "Sat Oct 24 19:27:23 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 19:27:23 2026 +0800"
      },
      "message": "fix(divide): retain resolved canary partition during HTTP failover (#8076)"
    },
    {
      "commit": "13de0bffec66a54a9a34016cb4fd07326845f15e",
      "tree": "f8bbe40a7d05422f70314e459e50cf881d7d8595",
      "parents": [
        "2083ce6aa6b03db349fd38025af542425d089a0b"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Sat Oct 24 19:26:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 19:26:00 2026 +0800"
      },
      "message": "fix(grpc): drain client and bidi streams according to outbound readiness (#7927) (#8035)"
    },
    {
      "commit": "2083ce6aa6b03db349fd38025af542425d089a0b",
      "tree": "ac20a07d450e80cb266a65710005ae5099a5e39e",
      "parents": [
        "c51f3a819b3f71da92229f7c0899c35b4ce626cb"
      ],
      "author": {
        "name": "Harsh Raj",
        "email": "zry8j4kz7p@privaterelay.appleid.com",
        "time": "Sat Oct 24 16:55:37 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 19:25:37 2026 +0800"
      },
      "message": "[ISSUE #7744] Isolate instance db sync from heartbeat check scheduler (#7749)\n\nCo-authored-by: Harsh \u003charshkha3417@gmail.com\u003e"
    },
    {
      "commit": "c51f3a819b3f71da92229f7c0899c35b4ce626cb",
      "tree": "e98fdd42d6976d0f5a417ad315541994f06335f4",
      "parents": [
        "b7cea28e01fd61589488a08228b2b478b42bfc5d"
      ],
      "author": {
        "name": "konlue",
        "email": "2362586639@qq.com",
        "time": "Sat Oct 24 19:25:14 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 19:25:14 2026 +0800"
      },
      "message": "fix(mqtt): make inbound packet id register/release atomic per client (#8021) (#8075)"
    },
    {
      "commit": "b7cea28e01fd61589488a08228b2b478b42bfc5d",
      "tree": "620519d2440462dfaf75129dbc90d9924bbf0fb7",
      "parents": [
        "7e5a1e713d7efce66dc23bcb5f5f47155518c986"
      ],
      "author": {
        "name": "redyyang",
        "email": "3202137046@qq.com",
        "time": "Sat Oct 24 12:16:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 12:16:00 2026 +0800"
      },
      "message": "fix(ai): inherit response transformer defaults and refresh clients (#8058)"
    },
    {
      "commit": "7e5a1e713d7efce66dc23bcb5f5f47155518c986",
      "tree": "4cb2b93164c651ff3ede9e8c009a1f49c62bcca3",
      "parents": [
        "7c16fad7c040f51eadb176f3f60d4ae1f8fa8f3b"
      ],
      "author": {
        "name": "Harsh Raj",
        "email": "zry8j4kz7p@privaterelay.appleid.com",
        "time": "Sat Oct 24 09:40:49 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 12:10:49 2026 +0800"
      },
      "message": "fix(divide): account for header names and framing in headerMaxSize (#… (#7821)\n\nCo-authored-by: Harsh \u003charshkha3417@gmail.com\u003e"
    },
    {
      "commit": "7c16fad7c040f51eadb176f3f60d4ae1f8fa8f3b",
      "tree": "9e23f5b9f2c20765af5d16d1851b652390a5e9f0",
      "parents": [
        "a0b196afaa063c29ff1a4bd7fd236d25e8ffdc77"
      ],
      "author": {
        "name": "zzk",
        "email": "67047497+pig-tongzhi@users.noreply.github.com",
        "time": "Sat Oct 24 11:41:36 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:41:36 2026 +0800"
      },
      "message": "chore(ci): bump actions/checkout to v4 in three workflows (#8077)"
    },
    {
      "commit": "a0b196afaa063c29ff1a4bd7fd236d25e8ffdc77",
      "tree": "a214873541885f8a43b8bdd0e61a02d5e79bc941",
      "parents": [
        "ff60949fe431b284fb8e5b28c08856a01ffdb406"
      ],
      "author": {
        "name": "Sean-Walker0",
        "email": "jast_zsh@foxmail.com",
        "time": "Sat Oct 24 11:36:59 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:36:59 2026 +0800"
      },
      "message": "fix(divide): enforce requestMaxSize on chunked request bodies (#8033)\n\nCo-authored-by: shown \u003cyuluo08290126@gmail.com\u003e"
    },
    {
      "commit": "ff60949fe431b284fb8e5b28c08856a01ffdb406",
      "tree": "901f99010d31695360a7a89694577716d1dca2b3",
      "parents": [
        "68f25c2df3a0d25723423a55b5b9a7a697d0120c"
      ],
      "author": {
        "name": "shown",
        "email": "yuluo08290126@gmail.com",
        "time": "Sat Oct 24 11:36:46 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:36:46 2026 +0800"
      },
      "message": "infra: add cc and hold command (#7862)\n\nSigned-off-by: yuluo-yx \u003cyuluo08290126@gmail.com\u003e"
    },
    {
      "commit": "68f25c2df3a0d25723423a55b5b9a7a697d0120c",
      "tree": "10fd10eada69881dc77f6089b603508da48ddc43",
      "parents": [
        "4f6f6105ce40347c37b233c6719d1649a1349909"
      ],
      "author": {
        "name": "ocean",
        "email": "boundlessocean@icloud.com",
        "time": "Sat Oct 24 11:35:25 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:35:25 2026 +0800"
      },
      "message": "[ISSUE #6373] Document split client migration and contribution workflow. (#7624)"
    },
    {
      "commit": "4f6f6105ce40347c37b233c6719d1649a1349909",
      "tree": "080d4ee25bcef9f274b3cfd094b5c851d0ae80c7",
      "parents": [
        "401798a5d00b28bbcbcc60d8bfa362b4ee07ec53"
      ],
      "author": {
        "name": "Harsh Raj",
        "email": "zry8j4kz7p@privaterelay.appleid.com",
        "time": "Sat Oct 24 09:05:10 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:35:10 2026 +0800"
      },
      "message": "[ISSUE #7644] Support configurable pending acquisition capacity in HT… (#7684)\n\nCo-authored-by: Harsh \u003charshkha3417@gmail.com\u003e"
    },
    {
      "commit": "401798a5d00b28bbcbcc60d8bfa362b4ee07ec53",
      "tree": "88685a8e7367d99ab35fe9e0ddc5588f9f765977",
      "parents": [
        "4c80117007d067b10aaa8022ee27a466ed37eed9"
      ],
      "author": {
        "name": "甜梦守护者",
        "email": "100402400+Neymar-10-JR@users.noreply.github.com",
        "time": "Sat Oct 24 11:34:49 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:34:49 2026 +0800"
      },
      "message": "[ISSUE #7761] Encode MCP form and multipart request bodies (#7823)"
    },
    {
      "commit": "4c80117007d067b10aaa8022ee27a466ed37eed9",
      "tree": "2fcd6003684266ed84eeba2189f1a3c6e7613f76",
      "parents": [
        "be3413b482f6a592421812338c89d80e9db7e06e"
      ],
      "author": {
        "name": "aias00",
        "email": "liuhongyu@apache.org",
        "time": "Sat Oct 24 11:32:11 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:32:11 2026 +0800"
      },
      "message": "admin(dashboard): sync dashboard build from apache/shenyu-dashboard@e12b29d2b1efb9c8bde55487417702aa3dbe1b4c (#8080)\n\nCo-authored-by: GitHub Action \u003caction@github.com\u003e"
    },
    {
      "commit": "be3413b482f6a592421812338c89d80e9db7e06e",
      "tree": "0b30855a8310c57c120d7944d817b1eea5952813",
      "parents": [
        "98c80932c7805507a77742ab90e3bd599fea3f28"
      ],
      "author": {
        "name": "imDwAaY",
        "email": "wuwangyi000@gmail.com",
        "time": "Sat Oct 24 11:31:16 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:31:16 2026 +0800"
      },
      "message": "[ISSUE #8024][ISSUE #8025] revoke MCP tool registrations by their applied identity (#8032)"
    },
    {
      "commit": "98c80932c7805507a77742ab90e3bd599fea3f28",
      "tree": "887671769f0abc445113f7fbcae137adef8fe8aa",
      "parents": [
        "5d672de81f8be261cbb2fada351dcec75cae9dea"
      ],
      "author": {
        "name": "cloudbase-ai",
        "email": "aias94coffee@gmail.com",
        "time": "Sat Oct 24 11:30:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:30:48 2026 +0800"
      },
      "message": "fix(ai-proxy): align the token limiter usage test with the conversion abstraction (#8083)"
    },
    {
      "commit": "5d672de81f8be261cbb2fada351dcec75cae9dea",
      "tree": "8c1cff10a5d8d3db3215b331d45adbec4c19987f",
      "parents": [
        "d021746878b96a5d5a4c3e7f6348564f2cbc28a0"
      ],
      "author": {
        "name": "ocean",
        "email": "boundlessocean@icloud.com",
        "time": "Sat Oct 24 11:30:32 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:30:32 2026 +0800"
      },
      "message": "docs client : reconcile migration ownership and compatibility guidance. (#8082)"
    },
    {
      "commit": "d021746878b96a5d5a4c3e7f6348564f2cbc28a0",
      "tree": "bb3691edd162c6039930fd1ce0469d6aedbe3403",
      "parents": [
        "8af439bfbd4a7b571afa6f18258bc818bc166e9e"
      ],
      "author": {
        "name": "redyyang",
        "email": "3202137046@qq.com",
        "time": "Sat Oct 24 11:30:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:30:19 2026 +0800"
      },
      "message": "fix(grpc): propagate invocation cancellation to the transport (#8078)"
    },
    {
      "commit": "8af439bfbd4a7b571afa6f18258bc818bc166e9e",
      "tree": "a3bcf738f7144a91b183d76365d88ed0dddf9f77",
      "parents": [
        "4faa5ac084babf62456eb3ab8866a93ae4290830"
      ],
      "author": {
        "name": "Duansg",
        "email": "siguoduan@gmail.com",
        "time": "Sat Oct 24 11:28:32 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:28:32 2026 +0800"
      },
      "message": "fix(request): escape literal \u0027+\u0027 when rebuilding query parameters (#8006)"
    },
    {
      "commit": "4faa5ac084babf62456eb3ab8866a93ae4290830",
      "tree": "90d3d59331461edd04a9421f33fd2c2251685e8f",
      "parents": [
        "4637211953dd03a04ec9b98a6653197e471b8f80"
      ],
      "author": {
        "name": "Duansg",
        "email": "siguoduan@gmail.com",
        "time": "Sat Oct 24 11:27:45 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:27:45 2026 +0800"
      },
      "message": "fix(loadbalancer): avoid int overflow of uptime in warmup weight calculation (#8005)"
    },
    {
      "commit": "4637211953dd03a04ec9b98a6653197e471b8f80",
      "tree": "d4dee96efc661fc6e71546443a5dbc5b5ce17efa",
      "parents": [
        "86e932cdf46c007130b1d59821f42e2f552a6071"
      ],
      "author": {
        "name": "hengyuss",
        "email": "hengyuss@apache.org",
        "time": "Sat Oct 24 11:03:17 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:03:17 2026 +0800"
      },
      "message": "  fix: reconcile upstream snapshots without retaining removed instances (#7172)\n\n* fix: reconcile upstream snapshots without retaining removed instances\n\n  Convert registry instance events into complete upstream snapshots after\n  updating the database. Previously, syncData contained only the changed\n  instance, which could cause snapshot reconciliation to remove other\n  valid upstreams. Publish empty snapshots when the last instance is removed.\n\n  Use the health-check lock for cache updates and removal. This prevents\n  health checks from moving upstreams between healthy and unhealthy caches\n  during reconciliation, causing removed instances to survive cleanup.\n\n  Add regression tests for snapshot publication, stale upstream removal,\n  health-state preservation, and concurrent health checks.\n\n* fix: resolve conflicts\n\n* fix: fix checkstyle\n\n---------\n\nCo-authored-by: aias00 \u003cliuhongyu@apache.org\u003e"
    },
    {
      "commit": "86e932cdf46c007130b1d59821f42e2f552a6071",
      "tree": "2c2d84058cd363e2befa6a432d7902ba510a1682",
      "parents": [
        "77611e941878445a5456506c8e2c50d96e472cea"
      ],
      "author": {
        "name": "cloudbase-ai",
        "email": "aias94coffee@gmail.com",
        "time": "Sat Oct 24 09:30:30 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 18:30:30 2026 -0700"
      },
      "message": "fix cache : replay a response that carries Vary only for the matching request headers (#8079)\n\nCo-authored-by: cloudbase-ai \u003c22498243+cloudbase-ai@users.noreply.github.com\u003e"
    },
    {
      "commit": "77611e941878445a5456506c8e2c50d96e472cea",
      "tree": "4150b94a49060599fee63409fa8c166a898f18bd",
      "parents": [
        "34f2ed036747936a5e28aea2c94cd9b3cddcce47"
      ],
      "author": {
        "name": "cloudbase-ai",
        "email": "aias94coffee@gmail.com",
        "time": "Sat Oct 24 09:29:49 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 18:29:49 2026 -0700"
      },
      "message": "ci : select the http integration suite for plugin changes that match no protocol keyword (#8081)\n\nCo-authored-by: cloudbase-ai \u003c22498243+cloudbase-ai@users.noreply.github.com\u003e"
    },
    {
      "commit": "34f2ed036747936a5e28aea2c94cd9b3cddcce47",
      "tree": "c4de5fc6ccb0d15de58d22b86e711eb3b3d74933",
      "parents": [
        "6a1a0e67532ffba6a121f941d9ffa9c486bd61e9"
      ],
      "author": {
        "name": "Laomo",
        "email": "lin2399773@gmail.com",
        "time": "Fri Oct 23 11:39:41 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 11:39:41 2026 +0800"
      },
      "message": "fix common : align annotation dependency versions. (#7688)\n\nRefs apache/shenyu#7679. Manage checker-qual 3.33.0 and error_prone_annotations 2.41.0 at the existing highest versions requested on the shenyu-common dependency paths."
    },
    {
      "commit": "6a1a0e67532ffba6a121f941d9ffa9c486bd61e9",
      "tree": "47b08ba83c606e5e6de4508fe574af96a453db17",
      "parents": [
        "d04715da5dbb8b414515fdb001d7824671d50e6f"
      ],
      "author": {
        "name": "甜梦守护者",
        "email": "100402400+Neymar-10-JR@users.noreply.github.com",
        "time": "Fri Oct 23 11:39:30 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 11:39:30 2026 +0800"
      },
      "message": "fix(admin): apply namespace name filter for administrators. (#7728)"
    }
  ],
  "next": "d04715da5dbb8b414515fdb001d7824671d50e6f"
}
