)]}'
{
  "log": [
    {
      "commit": "840949261ff9a9b771631422542bc9b134b7ff0c",
      "tree": "0d892454c293df407a1c419674fcbb81b530f382",
      "parents": [
        "419c84a4eda76f452869a5bdf5623a461b0600c9"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Fri Aug 14 03:55:51 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 14 11:55:51 2026 +0800"
      },
      "message": "chore: simplify issue templates (#3659)"
    },
    {
      "commit": "419c84a4eda76f452869a5bdf5623a461b0600c9",
      "tree": "f989577cc1d062be62d9f913a617f2c1d2dc623d",
      "parents": [
        "a10df2f7e1407b9116c15d14392504e9276080e6"
      ],
      "author": {
        "name": "alanxtl",
        "email": "m134679102365478@163.com",
        "time": "Fri Aug 14 11:27:01 2026 +0800"
      },
      "committer": {
        "name": "alanxtl",
        "email": "m134679102365478@163.com",
        "time": "Fri Aug 14 11:27:01 2026 +0800"
      },
      "message": "modernize github ci\n"
    },
    {
      "commit": "a10df2f7e1407b9116c15d14392504e9276080e6",
      "tree": "7d04751f737292d55e8b9276eb6f51d3ab42b4e7",
      "parents": [
        "581b831aee8bcd3a288248c3998928446cfc56ef"
      ],
      "author": {
        "name": "xiaobaicai66695",
        "email": "575121043@qq.com",
        "time": "Fri Aug 14 08:38:21 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 14 08:38:21 2026 +0800"
      },
      "message": "fix(router): preserve v3.0 condition flags (#3658)\n\nFixes apache/dubbo-go#3656."
    },
    {
      "commit": "581b831aee8bcd3a288248c3998928446cfc56ef",
      "tree": "e7a0b995c2baf21d9efee8996b2b8e9fa8575f55",
      "parents": [
        "ffbbcc3d9998c8463d7410bcf1304fd5026fe248"
      ],
      "author": {
        "name": "641-git641",
        "email": "2371076392@qq.com",
        "time": "Thu Aug 13 21:56:11 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 21:56:11 2026 +0800"
      },
      "message": "docs(registry): complete Registry Options comments and unit test cove… (#3653)\n\n* docs(registry): complete Registry Options comments and unit test coverage\n\n* docs(registry): format imports with imports-formatter\n\n---------\n\nCo-authored-by: 641-git641 \u003c641-git641@users.noreply.github.com\u003e"
    },
    {
      "commit": "ffbbcc3d9998c8463d7410bcf1304fd5026fe248",
      "tree": "06a20fe9244a3eeba9a2495880ae3209e387dc4d",
      "parents": [
        "830dfbbb3e0e0a5e8340a247349916ad7ecdc513"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Thu Aug 13 09:10:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 09:10:33 2026 +0800"
      },
      "message": "docs(triple): complete Triple Header/Error comments and unit test coverage (#3649)\n\n* docs(triple): add doc comments for header, trailer and error exported APIs\n\nSeveral exported APIs in the triple protocol lacked doc comments or had\nincomplete ones. Add a doc comment for ExtractFromOutgoingContext\ndescribing what it returns and how the framework uses it internally:\non the client side to populate request headers, and on the server side\nto merge handler-set headers into response trailers. Augment the\nSetHeader, SetTrailer and SendHeader comments to state that they return\na CodeInternal error when called outside a Triple handler context. Add\na doc comment for Error.Error describing its format.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): add boundary tests for header, trailer and error APIs\n\nAdd 13 tests covering previously untested branches and edge cases:\n\nheader_test.go (8 tests):\n- DecodeBinaryHeader: empty, unpadded, padded and naturally-aligned inputs\n- ExtractFromOutgoingContext: nil return when no headers set, correct\n  return when headers exist\n- NewOutgoingContext: second call replaces existing headers instead of\n  merging\n- AppendToOutgoingContext: panics on odd number of kv arguments\n- SetHeader/SetTrailer: normal path merges headers into the response\n  buffer\n- SetHeader/SetTrailer outside a handler context: returns CodeInternal\n\nerror_test.go (5 tests):\n- NewWireError + IsWireError: wire, plain, non-triple and wrapped cases\n- NewErrorDetail with *anypb.Any: skips double wrapping\n- ErrorDetail.Bytes: returns a copy, mutation does not affect internal\n  state\n- wrapIfContextError: Canceled, DeadlineExceeded, already-coded, plain\n  error and nil\n- wrapIfUncoded: nil, already-coded, context.Canceled and plain error\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* style(triple): silence staticcheck SA5012 in the odd-kv panic test\n\nThe test deliberately passes a single kv argument to\nAppendToOutgoingContext to verify it panics on an odd number of\narguments. staticcheck SA5012 flags the variadic call as having an odd\nelement count, which fails the CI lint. Annotate the call with\n//nolint:staticcheck, following the existing convention in\nhandler_compat.go and handler_stream_compat.go.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n---------\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "830dfbbb3e0e0a5e8340a247349916ad7ecdc513",
      "tree": "a5c49dfce75fd11e898a39889e379996d9f7fe11",
      "parents": [
        "387ea9adcfa655a1e3ddf55cc1dc0abdf173a579"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Thu Aug 13 00:59:47 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 08:59:47 2026 +0800"
      },
      "message": "ci: fixes codeql ci fail (#3652)"
    },
    {
      "commit": "387ea9adcfa655a1e3ddf55cc1dc0abdf173a579",
      "tree": "bcf679cbf3108bad12d4d4858402a1ba54a4fce2",
      "parents": [
        "81abe9ddb6d0ffd4a8fd7e1b895894e444654949",
        "7125a09bdbfdadd1c5922d669730e29d7416c395"
      ],
      "author": {
        "name": "Xin.Zh",
        "email": "alexstocks@foxmail.com",
        "time": "Wed Aug 12 15:57:46 2026 +0800"
      },
      "committer": {
        "name": "Xin.Zh",
        "email": "alexstocks@foxmail.com",
        "time": "Wed Aug 12 15:57:46 2026 +0800"
      },
      "message": "Merge branch \u0027main\u0027 into develop\n"
    },
    {
      "commit": "7125a09bdbfdadd1c5922d669730e29d7416c395",
      "tree": "2c6f585c989df2c2b57ad36adc0f714793a5434e",
      "parents": [
        "48d6e696e755d46df2425bbf71c413bbd1887f3f"
      ],
      "author": {
        "name": "xiaobaicai66695",
        "email": "575121043@qq.com",
        "time": "Wed Aug 12 15:43:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 15:43:33 2026 +0800"
      },
      "message": "perf(metadata): pipeline ZooKeeper revision reads (#3602)\n\n* perf(metadata): pipeline ZooKeeper revision reads"
    },
    {
      "commit": "81abe9ddb6d0ffd4a8fd7e1b895894e444654949",
      "tree": "95ed27bf671ca86a76a6efa02b24fcce2a9e0609",
      "parents": [
        "fc7a3ca99d8b2a0fd0a8b6149740da01b020f7bc"
      ],
      "author": {
        "name": "XiaoFei",
        "email": "2017382524@qq.com",
        "time": "Wed Aug 12 15:40:53 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 15:40:53 2026 +0800"
      },
      "message": "Fix(generic): complete typed result and generic mode handling (#3618)\n\n* fix(generic): complete typed result handling"
    },
    {
      "commit": "fc7a3ca99d8b2a0fd0a8b6149740da01b020f7bc",
      "tree": "7dab9389ebff56a0a5e7bcb3c802c896437039ea",
      "parents": [
        "910b3895d32540d094e2243e267da3b23acf3426"
      ],
      "author": {
        "name": "xiaobaicai66695",
        "email": "575121043@qq.com",
        "time": "Wed Aug 12 15:31:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 15:31:54 2026 +0800"
      },
      "message": "docs: improve functional option API comments (#3642)\n\n* docs: improve functional option API comments\n\n* style: modernize nacos concurrency tests\n\n* docs: clarify functional option behavior and usage\n\n* docs: preserve functional option TODOs"
    },
    {
      "commit": "910b3895d32540d094e2243e267da3b23acf3426",
      "tree": "dbcbe045b12cfa53781c42737fa9374e6a3a60aa",
      "parents": [
        "e373d9d6697f858b8983b4086955ab5972db0238"
      ],
      "author": {
        "name": "翎",
        "email": "1820661379@qq.com",
        "time": "Tue Aug 11 23:13:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 23:13:18 2026 +0800"
      },
      "message": "Refactor/triple comments helpers (#3643)\n\n* refactor(triple): clarify client keepalive helpers\n\n* refactor(triple): rename server handler option helper\n\n* docs(triple): formalize handler flow comments\n\n* refactor(triple): align client KeepAlive naming\n\n* docs(triple): restore TODO comments"
    },
    {
      "commit": "e373d9d6697f858b8983b4086955ab5972db0238",
      "tree": "322579a5af89627bf63b9f51eeae675857cf9208",
      "parents": [
        "e1bd4e817942e38824e03e4ebf8c79dffa81b98b"
      ],
      "author": {
        "name": "XiaoFei",
        "email": "2017382524@qq.com",
        "time": "Tue Aug 11 21:25:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 21:25:04 2026 +0800"
      },
      "message": "feat(openapi): support oneof fields for protoc-gen-triple-openapi (#3637)\n\n* feat(openapi): support oneof fields for protoc-gen-triple-openapi\n\n* test(openapi): cover proto3 optional synthetic oneofs\n\n* fix:ci"
    },
    {
      "commit": "e1bd4e817942e38824e03e4ebf8c79dffa81b98b",
      "tree": "31409666f91f359992be01fa437581da544898c1",
      "parents": [
        "755f48efc4194cc625180de676d2453fe7ea8e34"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Tue Aug 11 20:32:32 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 20:32:32 2026 +0800"
      },
      "message": "fix(triple): guard httpSrv/http3Srv access with atomic pointers (#3639)\n\n* fix(triple): guard httpSrv/http3Srv access with atomic pointers\n\nServer starts the HTTP/2 and HTTP/3 listeners in background goroutines\n(startHttp2/startHttp3/startHttp2AndHttp3 write s.httpSrv and s.http3Srv\non the start path) while Stop and GracefulStop read and close them on a\ndifferent goroutine, with no synchronization in between. Under -race this\nreports a data race on both fields every time TestCfgAPI_Export runs.\n\nStore the two servers in uatomic.Pointer fields: every write goes through\nStore and every read through Load, and Stop/GracefulStop load once into a\nlocal snapshot before checking nil and closing.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): verify triple server start and stop behavior\n\nAdd 13 tests that start the real HTTP/2, HTTP/3 and dual-protocol\nservers on random ports, stop or gracefully stop them, and assert the\nhttpSrv/http3Srv uatomic.Pointer fields across start and stop. Also\ncover stopping before start, repeated start/stop for every protocol,\nand the missing-TLS / unsupported-protocol error paths. These tests\nfail on the previous unsynchronized fields under -race.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): adapt nil assertions to uatomic.Pointer fields\n\nThe fields became uatomic.Pointer in the race fix, which is never nil itself; load the pointer before the nil assertion.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n---------\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "755f48efc4194cc625180de676d2453fe7ea8e34",
      "tree": "d8ed2901216377f8e92f4c1f7650bd9c731a56c5",
      "parents": [
        "39eeb2bda23613fad65545dfb05de9b45209b5e7"
      ],
      "author": {
        "name": "翎",
        "email": "1820661379@qq.com",
        "time": "Tue Aug 11 18:53:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 18:53:18 2026 +0800"
      },
      "message": "feature(triple): support bean generic mode and retain protobuf compatibility  (#3507)\n\n* test(triple): cover supported generic modes\n\n* fix(triple): retain protobuf generic compatibility\n\n* fix(ci): use local dubbo-go for integration tests\n\n* fix(triple): clarify protobuf legacy generic routing\n\n* chore(ci): restore integration test comment"
    },
    {
      "commit": "39eeb2bda23613fad65545dfb05de9b45209b5e7",
      "tree": "e9e078c5519d6cb99aead84fcc54883c8f443b5d",
      "parents": [
        "e506f0d4a9401d346404ac697ff8eb4b53ac9f8e"
      ],
      "author": {
        "name": "Nene7ko_",
        "email": "141395478+XnLemon@users.noreply.github.com",
        "time": "Tue Aug 11 18:51:35 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 18:51:35 2026 +0800"
      },
      "message": "fix(protocol, registry, remoting, graceful_shutdown): handle ignored errors across rpc paths (#3574)\n\n* fix: handle ignored errors across rpc paths\n\n* style: fix getty import formatting\n\n* fix: avoid shadowing hessian encode error\n\n* fix: address PR 3574 review feedback\n\n* fix: satisfy testifylint error assertion"
    },
    {
      "commit": "e506f0d4a9401d346404ac697ff8eb4b53ac9f8e",
      "tree": "dff11d9c48679ba4ff86938d9c7fd30d88a4d50f",
      "parents": [
        "b6dc2352d3b98fe4ed38932ed9b95f29f472a3a1"
      ],
      "author": {
        "name": "aias00",
        "email": "liuhongyu@apache.org",
        "time": "Tue Aug 11 13:56:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 13:56:58 2026 +0800"
      },
      "message": "fix(config_center/nacos): remove unused context.WithCancel and call CancelListenConfig on last listener removal (#3441)\n\n* fix(config_center/nacos): remove unused context.WithCancel and call CancelListenConfig on last listener removal\n\nThe addListener() function created context.WithCancel but the cancel\nfunction was never called, causing a goroutine and context leak.\nAdditionally, removeListener() never called CancelListenConfig to\nunsubscribe from the nacos server, leaving stale config change\nlisteners active indefinitely.\n\nChanges:\n- Remove unused context.WithCancel calls in addListener()\n- Replace context.CancelFunc value type with struct{} in keyListeners\n  map (the cancel function was never used)\n- In removeListener(), call CancelListenConfig when the last listener\n  for a key is removed (matching Apollo and File implementations)\n- Clean up keyListeners entry when no listeners remain\n- Add nil client guard for test compatibility\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* fix(config_center/nacos): use keyListenerSet with mutex for thread-safe listener management\n\nAddress Copilot review feedback:\n1. Race condition: Replace bare sync.Map with keyListenerSet struct that\n   uses sync.Mutex to make add/remove/check-empty atomic, preventing\n   concurrent addListener from racing with removeListener\u0027s emptiness\n   check and CancelListenConfig call.\n2. DataId/Group consistency: Store the resolved group string in\n   keyListenerSet so that CancelListenConfig uses the exact same group\n   that was passed to ListenConfig, avoiding mismatch from re-derivation.\n3. Delete keyListeners entry before CancelListenConfig to prevent new\n   addListener from finding a stale set after cancellation.\n4. Use snapshot() for callback iteration to safely iterate while\n   mutations may occur.\n\nAlso add test for multi-listener removal behavior.\n\n* fix(config_center/nacos): guard listener lifecycle race\n\n* style(config_center/nacos): apply imports-formatter to concurrency test\n\nResolve the `make check-fmt` failure flagged in PR review: the new\nlistener_concurrency_test.go did not follow the repo\u0027s import grouping\norder. Re-run `make fmt`; `check-fmt` now passes.\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n---------\n\nCo-authored-by: Claude \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "b6dc2352d3b98fe4ed38932ed9b95f29f472a3a1",
      "tree": "1b10b4c61c39c4de0e623a24bf776294e89e231c",
      "parents": [
        "4649e859233ee226951fa25aa9b38161aa9a7e80"
      ],
      "author": {
        "name": "Lcos",
        "email": "3349888061@qq.com",
        "time": "Tue Aug 11 11:44:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 03:44:38 2026 +0000"
      },
      "message": "fix: subscribe provided-by applications initially (#3623)\n\n* fix: subscribe provided-by applications initially\n\nSubscribe the initial application set directly instead of routing it through the mapping change listener. This prevents provided-by from being treated as an unchanged mapping and skipping instance discovery.\\n\\nAdd a regression test covering the initial instance lookup and listener installation.\\n\\nFixes: #3617\n\nSigned-off-by: Lcos \u003c3349888061@qq.com\u003e\n\n* fix: narrow provided-by fix, keep metadata-report OnEvent baseline\n\nThe initial fix routed both provided-by and metadata-report mapping through a direct SubscribeURL, which dropped the mapping listener baseline update on the metadata-report path. Replaying an identical mapping set then went through the \u0027old is empty\u0027 branch and called ServiceDiscovery.AddListener a second time (re-registered the listener).\n\nNarrow the fix: only the provided-by path subscribes directly; the metadata-report path keeps the initial subscription on OnEvent so oldServiceNames is updated and later A-\u003eA is a no-op.\n\nAdd AddListener call counting to mockServiceDiscovery and two regression tests:\n- TestServiceDiscoveryRegistrySubscribeWithProvidedBy asserts AddListener fires exactly once for provided-by.\n- TestServiceDiscoveryRegistrySubscribeMetadataReportA2A asserts that replaying identical mapping to the installed mapping listener does not trigger another AddListener.\n\nAddresses P1 review feedback on #3623.\n\nSigned-off-by: user.email \u003c3349888061@qq.com\u003e\n\n* test: use require for error assertion to satisfy testifylint\n\nSigned-off-by: user.email \u003c3349888061@qq.com\u003e\n\n---------\n\nSigned-off-by: Lcos \u003c3349888061@qq.com\u003e\nSigned-off-by: user.email \u003c3349888061@qq.com\u003e"
    },
    {
      "commit": "4649e859233ee226951fa25aa9b38161aa9a7e80",
      "tree": "1c1a7c51b32812aaa8d186dd0ce1879cb480db9d",
      "parents": [
        "8b14fdadc63fd320e30488ab65aa95169fab6a80"
      ],
      "author": {
        "name": "DadaVinqi",
        "email": "llp507187@gmail.com",
        "time": "Tue Aug 11 11:16:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 11:16:58 2026 +0800"
      },
      "message": "fix: make lifecycle waits cancellable (#3599)\n\n* fix: make lifecycle waits cancellable\n\nSigned-off-by: DadaVinqi \u003cDadaVinqi@users.noreply.github.com\u003e\n\n* fix: refine shutdown wait semantics\n\nSigned-off-by: DadaVinqi \u003cDadaVinqi@users.noreply.github.com\u003e\n\n* refactor: reduce shutdown code complexity\n\nSigned-off-by: DadaVinqi \u003cDadaVinqi@users.noreply.github.com\u003e\n\n* test: cover getty close before publish\n\nSigned-off-by: DadaVinqi \u003cDadaVinqi@users.noreply.github.com\u003e\n\n---------\n\nSigned-off-by: DadaVinqi \u003cDadaVinqi@users.noreply.github.com\u003e\nCo-authored-by: DadaVinqi \u003cDadaVinqi@users.noreply.github.com\u003e"
    },
    {
      "commit": "8b14fdadc63fd320e30488ab65aa95169fab6a80",
      "tree": "3f6625bd2af7230a22c1566e5571dbf5f603a17e",
      "parents": [
        "e50cfc62f0e3ba62fd64b0a43d7349f7df3a7793"
      ],
      "author": {
        "name": "Yash Israni",
        "email": "118755067+yashisrani@users.noreply.github.com",
        "time": "Mon Aug 10 18:38:12 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 21:08:12 2026 +0800"
      },
      "message": "fix(protocol/triple): return standard errors in SetHeader, SetTrailer, SendHeader (#3633)\n\n* fix(protocol/triple): return standard errors in SetHeader, SetTrailer, SendHeader\n\nSigned-off-by: Yash Israni \u003c118755067+yashisrani@users.noreply.github.com\u003e\n\n* Update protocol/triple/triple_protocol/header.go\n\nCo-authored-by: Xuetao Li \u003cxuetaoli@apache.org\u003e\n\n* Update protocol/triple/triple_protocol/header.go\n\nCo-authored-by: Xuetao Li \u003cxuetaoli@apache.org\u003e\n\n* Update protocol/triple/triple_protocol/header.go\n\nCo-authored-by: Xuetao Li \u003cxuetaoli@apache.org\u003e\n\n---------\n\nSigned-off-by: Yash Israni \u003c118755067+yashisrani@users.noreply.github.com\u003e\nCo-authored-by: Xuetao Li \u003cxuetaoli@apache.org\u003e"
    },
    {
      "commit": "e50cfc62f0e3ba62fd64b0a43d7349f7df3a7793",
      "tree": "f1fb6ad3ba81e5a5c66790179f6167f3ca446eb1",
      "parents": [
        "2edb07e4292b377d0456922d0890ab9857beb163"
      ],
      "author": {
        "name": "XiaoFei",
        "email": "2017382524@qq.com",
        "time": "Mon Aug 10 16:14:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 16:14:10 2026 +0800"
      },
      "message": "feat(openapi): generate descriptions from proto comments (#3630)\n\n* feat(openapi): generate descriptions from proto comments\n\n* fix: reuse protobuf description helper in triple openapi converter"
    },
    {
      "commit": "2edb07e4292b377d0456922d0890ab9857beb163",
      "tree": "64f3976996d20b80c53e1fb906273952a210245c",
      "parents": [
        "d39c99722ac5104eece3bf78a98c3b0e87ae68ee"
      ],
      "author": {
        "name": "Yash Israni",
        "email": "118755067+yashisrani@users.noreply.github.com",
        "time": "Sun Aug 09 17:50:18 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 20:20:18 2026 +0800"
      },
      "message": "test(protocol/triple): add unit tests for hessian2Codec and msgpackCodec (#3627)\n\nSigned-off-by: Yash Israni \u003c118755067+yashisrani@users.noreply.github.com\u003e"
    },
    {
      "commit": "d39c99722ac5104eece3bf78a98c3b0e87ae68ee",
      "tree": "7242a4447c2d879b4e563cbb516ea54864aa42ba",
      "parents": [
        "ee88f77d4398a5b7a79d1b8e3f9afdb96dd9cdeb"
      ],
      "author": {
        "name": "Yash Israni",
        "email": "118755067+yashisrani@users.noreply.github.com",
        "time": "Sun Aug 09 10:31:49 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 13:01:49 2026 +0800"
      },
      "message": "fix(protocol/triple): handle ParseDuration error for keepalive config (#3622)\n\nSigned-off-by: Yash Israni \u003c118755067+yashisrani@users.noreply.github.com\u003e"
    },
    {
      "commit": "ee88f77d4398a5b7a79d1b8e3f9afdb96dd9cdeb",
      "tree": "dd0f7ecdb74404d29b5b47041d0c4ab5920ba247",
      "parents": [
        "b2ab70e49a69a023fe8205f3f39809bebf1a95f5"
      ],
      "author": {
        "name": "Nene7ko_",
        "email": "141395478+XnLemon@users.noreply.github.com",
        "time": "Sun Aug 09 12:52:22 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 12:52:22 2026 +0800"
      },
      "message": "feat(metadata): add descriptions for GetMethods(), GetParams() and NewServiceInfoWithURL() (#3619)"
    },
    {
      "commit": "b2ab70e49a69a023fe8205f3f39809bebf1a95f5",
      "tree": "b6ec6b2ae2db759fbb34340f19a7c2ccf2bb396b",
      "parents": [
        "115af01da805090d153f68cfd4974dc41e69fdcc"
      ],
      "author": {
        "name": "MaoMeng",
        "email": "1707647656@qq.com",
        "time": "Sun Aug 09 12:50:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 12:50:03 2026 +0800"
      },
      "message": "chore(global): global config formatting (#3616)"
    },
    {
      "commit": "115af01da805090d153f68cfd4974dc41e69fdcc",
      "tree": "a7e379519393677804f4a5e25c683b0bebce5e0e",
      "parents": [
        "0a0ce09631ccb72264f86223fdbbf61021c5a01e"
      ],
      "author": {
        "name": "XiaoFei",
        "email": "2017382524@qq.com",
        "time": "Sat Aug 08 18:31:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 18:31:04 2026 +0800"
      },
      "message": "fix(openapi): generate enum components and map value schemas (#3609)\n\n* fix(openapi): generate enum components and map value schemas\n\n* fix(openapi): cover map reference values and error schema collisions"
    },
    {
      "commit": "0a0ce09631ccb72264f86223fdbbf61021c5a01e",
      "tree": "1f6a63264e0119b6dba2c94c9d1509d912281cbe",
      "parents": [
        "5f9deabac98261c389a29ae8cde6b67d4205a29c"
      ],
      "author": {
        "name": "xiaobaicai66695",
        "email": "575121043@qq.com",
        "time": "Fri Aug 07 12:24:37 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 07 12:24:37 2026 +0800"
      },
      "message": "docs(protocol): unify protocol option comments (#3610)"
    },
    {
      "commit": "5f9deabac98261c389a29ae8cde6b67d4205a29c",
      "tree": "2bb340fde59725538e9d1b1ff9f5806f23d86d04",
      "parents": [
        "f2ec52e4c3d3e53af878eed891e4654164a59afb"
      ],
      "author": {
        "name": "XiaoFei",
        "email": "2017382524@qq.com",
        "time": "Fri Aug 07 10:40:05 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 07 10:40:05 2026 +0800"
      },
      "message": "test(openAPI): add golden tests for protoc-gen-triple-openapi (#3606)\n\n* test(openAPI): add golden tests for protoc-gen-triple-openapi\n\n* fix(openapi): normalize golden test line endings"
    },
    {
      "commit": "f2ec52e4c3d3e53af878eed891e4654164a59afb",
      "tree": "18bf1edfcb0cca705c102d1c6da56a03907510cc",
      "parents": [
        "0d06f3be9ebfc588c4138617877269094a6a79d3"
      ],
      "author": {
        "name": "MaoMeng",
        "email": "1707647656@qq.com",
        "time": "Fri Aug 07 10:35:45 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 07 10:35:45 2026 +0800"
      },
      "message": "fix: correct inverted guard in WithRegistryIDs/WithProtocolIDs (#3604)"
    },
    {
      "commit": "0d06f3be9ebfc588c4138617877269094a6a79d3",
      "tree": "39ae6054ce16f6f9e9e8b0f00bd256e536cb935f",
      "parents": [
        "a350e10d541c9de885b480cc3f7ee2db03d9423f"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Fri Aug 07 10:31:30 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 07 10:31:30 2026 +0800"
      },
      "message": "chore(triple): clean up draft TODOs and unify comment style in the triple link (#3607)\n\nRemove stale and duplicate draft TODOs, fix malformed ones, and turn vague\n\"Enrich transport config\" TODOs into real descriptions. Unify inline comment\nstyle in the Triple mainline: idl-\u003eIDL, capitalized first letters for inline\ncomments, TODO in all caps with a colon, and consistent Compatibility notes.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "a350e10d541c9de885b480cc3f7ee2db03d9423f",
      "tree": "f4e10fc6128c0bf8d7672b2e6a9c5be895155676",
      "parents": [
        "62476d5109e41eb2fb47afc5868372dab35f6e9f"
      ],
      "author": {
        "name": "aias00",
        "email": "liuhongyu@apache.org",
        "time": "Thu Aug 06 19:28:27 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 07 10:28:27 2026 +0800"
      },
      "message": "docs(metrics): document RPC error classifier categories (#3603)\n\nAdd Go doc comments to every ErrorType constant and to classifyError,\nexplaining which Triple/gRPC status code each category maps to and which\nlayer (caller/deadline, back-pressure, service availability, business,\nnetwork, codec) it represents. Clarify why ErrorTypeNetworkFailure and\nErrorTypeCodec are reserved but not yet produced: both candidate source\ncodes collapse into the catch-all CodeInternal, which cannot be split\nreliably at the status-code level, so they fall through to\nErrorTypeUnknown today.\n\nRefs #3598 (task #21)"
    },
    {
      "commit": "62476d5109e41eb2fb47afc5868372dab35f6e9f",
      "tree": "05e4cf7c526290bc536c8d2819057222f0aa17fb",
      "parents": [
        "973a6082777ebfadd7ae3eeb99babbc67697e71c"
      ],
      "author": {
        "name": "Nene7ko_",
        "email": "141395478+XnLemon@users.noreply.github.com",
        "time": "Thu Aug 06 15:58:52 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 06 15:58:52 2026 +0800"
      },
      "message": "fix(filter, protocol, registry, config_center): guard unsafe type assertions (#3563)\n\n* fix: guard unsafe type assertions\n\n* fix: address PR 3563 review findings\n\nSigned-off-by: Nene7ko_ \u003c1604009816@qq.com\u003e\n\n---------\n\nSigned-off-by: Nene7ko_ \u003c1604009816@qq.com\u003e"
    },
    {
      "commit": "973a6082777ebfadd7ae3eeb99babbc67697e71c",
      "tree": "49aee114978eb4a62c306e3a028403597a30ef0a",
      "parents": [
        "c7452e1749f9f558ccf9665db0a32bfd83113ce0"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Wed Aug 05 04:35:00 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 05 12:35:00 2026 +0800"
      },
      "message": "chore(doc): Update copyright year in NOTICE file (#3593)\n\n* Update copyright year in NOTICE file\n\n* Improve README with updated CHANGELOG link\n\nUpdated link to CHANGELOG.md for better accessibility."
    },
    {
      "commit": "c7452e1749f9f558ccf9665db0a32bfd83113ce0",
      "tree": "0b566fd0caeed53419481eda6d2b95ee548f4952",
      "parents": [
        "51154987a2d0c77b9b4ccf879d266512ba445ba2"
      ],
      "author": {
        "name": "CAICAII",
        "email": "3360776475@qq.com",
        "time": "Wed Aug 05 07:50:20 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 05 07:50:20 2026 +0800"
      },
      "message": "feat(triple): add server http3 quic config helper (#3299)\n\n* feat(triple): add server http3 quic config helper\n\n* refactor(triple): drop http3 config compat mirror\n\n* test(triple): satisfy lint for http3 server tests\n\n* fix(global): align http3 json tags and decode aliases\n\n* style(global): format http3 config file\n\n* refactor(global): remove http3 json compat decoder\n\nSigned-off-by: CAICAIIs \u003c3360776475@qq.com\u003e\n\n---------\n\nSigned-off-by: CAICAIIs \u003c3360776475@qq.com\u003e"
    },
    {
      "commit": "51154987a2d0c77b9b4ccf879d266512ba445ba2",
      "tree": "d8dc3cafdc313e005cc4b9b4c6de958b3bef324d",
      "parents": [
        "46026183c06a0ce4576ff83e89eb80211270322b"
      ],
      "author": {
        "name": "_衣服修改",
        "email": "16643288780@163.com",
        "time": "Wed Aug 05 07:47:07 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 05 07:47:07 2026 +0800"
      },
      "message": "feat(tools): add benchmark suite for Dubbo-Go, Dubbo-Java and gRPC (#3502)\n\n* feat: add benchmark suite for Dubbo-Go, Dubbo-Java and gRPC\n\n- Add benchmark framework with client/server implementations\n- Support Dubbo-Go, Dubbo-Java and gRPC protocols\n- Add config.yaml for test parameters\n- Use standard protoc-gen-go-triple plugin for triple code generation\n- Add .gitignore rules for benchmark artifacts\n\n* fix: add replace directive in benchmark go.mod to use local dubbo-go\n\n* fix: remove benchmark go.mod to avoid replace directive in CI\n\nRemove tools/benchmark/go.mod and go.sum to integrate benchmark\nas part of the main project. This avoids CI failures caused by\nreplace directive pointing to local paths which don\u0027t work in CI.\n\n* fix: address lint issues in benchmark code\n\n- Fix error strings capitalization (ST1005)\n- Fix shadow variable declarations\n- Add generated file lint exclusion comments\n- Ensure code formatting passes make fmt\n\n* Update integrate_test.sh\n\n* update readme:tools/benchmark的介绍\n\n* fix: integrate_test.sh use local path replace and add benchmark docs to README\n\n- Fix integrate_test.sh to use local checked-out dubbo-go code\n  instead of remote path which causes 500 error for fork PRs\n- Add benchmark tool introduction to README.md and README_CN.md\n\n* fix: format statistics.go with slices.Sort and fix integrate_test.sh\n\n- Replace sort.Slice with slices.Sort for Go 1.21+ idiomatic code\n- Fix integrate_test.sh to use local path replace instead of remote\n  fork module resolution which causes 500 Internal Server Error in CI\n\n* fix: fallback to working directory when data dir not writable\n\n* feat: run full benchmark suite and update README with real test results\n\n- Synced with upstream develop v3.3.2\n- Ran 16 benchmark test cases (2 frameworks x 4 payloads x 2 concurrency)\n- Fixed data directory fallback when executable path not writable\n- Updated README.md and README_CN.md with actual benchmark data:\n  - Dubbo-Go: 19.7k-310 QPS, 3.3-795ms P99 latency\n  - gRPC: 106.6k-1,453 QPS, 0.94-109ms P99 latency\n  - Resource usage comparison\n\n* fix:readme\n\n* update readme\n\n* sync readme_CN\n\n* Update README_CN.md\n\n* Update README_CN.md\n\n* Update dubbo_client.go\n\n* fix\n\n* fix\n\n* Update main.go\n\n* update readme"
    },
    {
      "commit": "46026183c06a0ce4576ff83e89eb80211270322b",
      "tree": "ce51959e161f51a0d1a11891b5fe718bdcd4fd34",
      "parents": [
        "e94fa7ea3a408baabd1829c48bec7ec9be0b886b"
      ],
      "author": {
        "name": "Nene7ko_",
        "email": "141395478+XnLemon@users.noreply.github.com",
        "time": "Wed Aug 05 07:45:06 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 05 07:45:06 2026 +0800"
      },
      "message": "fix(filter, registry): close access log files on error paths (#3561)\n\n* fix: close access log files on error paths\n\n* add test"
    },
    {
      "commit": "e94fa7ea3a408baabd1829c48bec7ec9be0b886b",
      "tree": "f27ae1c2ba5dcafb5c12ed480cadfd073c9ad4c4",
      "parents": [
        "b12066608dd6babb11484ab24896a6c0b8b7313a"
      ],
      "author": {
        "name": "XiaoFei",
        "email": "2017382524@qq.com",
        "time": "Wed Aug 05 07:43:35 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 05 07:43:35 2026 +0800"
      },
      "message": "fix(generic): reject unsupported generic modes in filters (#3501)"
    },
    {
      "commit": "b12066608dd6babb11484ab24896a6c0b8b7313a",
      "tree": "0085147aca112f294735738432257530ec7404a0",
      "parents": [
        "e487ba381a7c0d14c15ab968b25a38d789139a21"
      ],
      "author": {
        "name": "Yuxuan Lv",
        "email": "3656828039@qq.com",
        "time": "Wed Aug 05 07:41:49 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 05 07:41:49 2026 +0800"
      },
      "message": "feat(generic): validate generic mode and clarify config API (#3500)\n\nFail fast on an unknown generic mode when the reference is created, instead\nof silently falling back to the Map generalizer at runtime, and keep the\naccepted generic-mode set consistent between reference-creation validation\nand Triple\u0027s invoker routing.\n\n- add internal.IsGenericMode as the single source of truth for the accepted\n  generic modes (true/gson/protobuf-json/bean, plus legacy protobuf), and\n  build internal.ValidateGenericType on top of it, rejecting unknown values\n- wire the validation into ReferenceOptions.init\n- route protocol/triple/triple.go:isGenericCall through internal.IsGenericMode\n  so a reference created with WithGenericType(\"bean\") is recognized as generic\n  and dispatched to the $invoke-capable NewTripleInvoker instead of\n  NewDubbo3Invoker\n- clarify that generic mode and transport serialization are independent, and\n  document the scope of generic.include.class, in WithGenericType and\n  NewGenericService docs\n- cover the validation and isGenericCall (including bean) with table-driven tests\n\nPart of #3472\n\nSigned-off-by: bang \u003c3656828039@qq.com\u003e\nCo-authored-by: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "e487ba381a7c0d14c15ab968b25a38d789139a21",
      "tree": "4c4181064f940f1cf4ebca5a766a4fc66fc9d63f",
      "parents": [
        "48d6e696e755d46df2425bbf71c413bbd1887f3f"
      ],
      "author": {
        "name": "Modo",
        "email": "witty8010@outlook.com",
        "time": "Wed Aug 05 07:39:34 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 05 07:39:34 2026 +0800"
      },
      "message": "refactor: use GenericException from dubbo-go-hessian2 (#3498)\n\n* refactor: use GenericException from dubbo-go-hessian2\n\n* fix: add backward-compat stubs for GenericException and ToGenericException\n\n* fix ci failure\n\n* fix: assert exact fields in GenericExceptionCompat string-path test\n\n* fix GenericException comment"
    },
    {
      "commit": "48d6e696e755d46df2425bbf71c413bbd1887f3f",
      "tree": "4b4c40ca89b6ee97544dfae78c758ede84e20d8f",
      "parents": [
        "a3634343fcd9c1bd97e0603157610a77b4fb89cc"
      ],
      "author": {
        "name": "Xin.Zh",
        "email": "alexstocks@foxmail.com",
        "time": "Sun Aug 02 22:11:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 02 22:11:18 2026 +0800"
      },
      "message": "fix: restore go.sum for generated CLI projects (#3589)\n\n* Document the Sonar CLI lockfile repair\n\nDefine the evidence-backed scope, dependency checksum design, TDD regression, Linux verification, and release boundary for restoring generated-project go.sum files.\n\nConstraint: Preserve the dynamic protobuf generation architecture and target only the two CLI scaffolds.\n\nConfidence: high\n\nScope-risk: narrow\n\nTested: git diff --check; specification placeholder and scope scan.\n\nNot-tested: Implementation tests are deferred to the execution plan.\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* fix: restore dependency locks for generated CLI projects\n\nSonarCloud flags the newApp and newDemo scaffold go.mod files because their dependency lockfiles were removed while the generator still emits buildable Go modules.\n\nRestore one shared generated go.sum payload, emit it from both generator paths, keep matching golden fixtures, and add a regression test for the direct dependency checksums.\n\nConstraint: Preserve dynamic protobuf generation and the existing minimal go.mod templates.\n\nConfidence: high\n\nScope-risk: narrow\n\nRed: go test ./cmd -run \u0027^TestGeneratedProjectsIncludeDependencyLocks$\u0027 -count\u003d1 -v failed because both generated go.sum files were absent.\n\nGreen: targeted generator tests, Windows and WSL go test ./... and go vet ./..., plus WSL make test-generated-projects.\n\nTested: Go 1.26.2 on Windows; Go 1.25.1 on WSL/Linux; generated newApp and newDemo make test flows.\n\nNot-tested: SonarCloud remote Quality Gate requires the pushed PR check.\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* docs: remove superpower planning artifacts\n\nThe docs/superpowers directory contains local agent design and implementation plans rather than project documentation.\n\nRemove all tracked files from that directory and ignore the root path so future local plans are not added to Git.\n\nConstraint: Preserve the existing Sonar CLI lockfile repair.\n\nConfidence: high\n\nScope-risk: narrow\n\nTested: git diff --cached --check; repository-wide docs path and content scans; git check-ignore positive and negative probes.\n\nNot-tested: Go tests were not rerun because no source, dependency, generator, or test files changed.\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n---------\n\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e"
    },
    {
      "commit": "a3634343fcd9c1bd97e0603157610a77b4fb89cc",
      "tree": "5020713ddec814580652872f7cd3770aff4546b9",
      "parents": [
        "484ff8fee648986a514e13f3b20f6b2b4a43bc83"
      ],
      "author": {
        "name": "nightcityblade",
        "email": "jackchen@haloailabs.com",
        "time": "Sun Aug 02 22:10:53 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 02 22:10:53 2026 +0800"
      },
      "message": "fix: preserve wrapped error handling (#3580)\n\n* fix: preserve wrapped error handling\n\nUse errors.Is for sentinel error checks and retain exporter error chains with %w.\n\nFixes: #3560\nSigned-off-by: nightcityblade \u003cnightcityblade@gmail.com\u003e\n\n* test: cover wrapped error handling\n\n* chore: format reflection test\n\n---------\n\nSigned-off-by: nightcityblade \u003cnightcityblade@gmail.com\u003e\nCo-authored-by: nightcityblade \u003cnightcityblade@gmail.com\u003e"
    },
    {
      "commit": "484ff8fee648986a514e13f3b20f6b2b4a43bc83",
      "tree": "7d9f738da5d5d05ecd1aaea595d451f253100b51",
      "parents": [
        "cdda54be1f353e372a80940729cdb380702c325e"
      ],
      "author": {
        "name": "dev_Hakaze",
        "email": "af.nawfal@gmail.com",
        "time": "Sun Aug 02 17:35:05 2026 +0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 02 18:35:05 2026 +0800"
      },
      "message": "build: upgrade direct YAML usage to go.yaml.in/yaml/v4 (#3586)\n\n* build: upgrade direct YAML usage to go.yaml.in/yaml/v4\n\nReplace main-module imports of gopkg.in/yaml.v3 with go.yaml.in/yaml/v4\nfor config center, routers, REST/gRPC/Getty config, and Triple OpenAPI\nencoding. Direct dependency is now go.yaml.in/yaml/v4; gopkg.in/yaml.v3\nremains only as a transitive (indirect) dependency.\n\nFixes: #3582\nSigned-off-by: arimu1 \u003c19286898+arimu1@users.noreply.github.com\u003e\n\n* style: fix go.yaml.in import order in grpc client\n\nmake check-fmt / imports-formatter requires go.yaml.in/yaml/v4 before\ngoogle.golang.org imports in protocol/grpc/client.go.\n\nSigned-off-by: arimu1 \u003c19286898+arimu1@users.noreply.github.com\u003e\n\n* ci: re-trigger integration test after 6h timeout\n\n---------\n\nSigned-off-by: arimu1 \u003c19286898+arimu1@users.noreply.github.com\u003e\nCo-authored-by: arimu1 \u003c19286898+arimu1@users.noreply.github.com\u003e"
    },
    {
      "commit": "cdda54be1f353e372a80940729cdb380702c325e",
      "tree": "284ea776972fea9c6cd097f640eb8ac05ce1f0eb",
      "parents": [
        "144d127e099545880756f9d92efd15942f744a8a"
      ],
      "author": {
        "name": "Xin.Zh",
        "email": "alexstocks@foxmail.com",
        "time": "Sat Aug 01 15:51:11 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 01 15:51:11 2026 +0800"
      },
      "message": "docs: add Dubbo-Go 3.3.2 changelog (#3588)\n\n* docs: make the Dubbo-Go 3.3.2 release scope auditable\n\nRecord the exact v3.3.1-to-3.3.2 release range so maintainers and users can identify upgrade-impacting changes, notable fixes, supporting documentation, CI updates, and contributors from one canonical changelog entry.\n\nConstraint: Limit the release-documentation commit to CHANGELOG.md and changes merged in v3.3.1..53d81d17c0f658b7151fb8c44f0d80371ef047e7.\n\nConfidence: high\n\nScope-risk: narrow\n\nTested: git diff --cached --check; exact release-range validation for all 104 linked PRs; contributor-set validation for 34 human contributors.\n\nNot-tested: Code tests were not run because this commit changes release documentation only.\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* docs: keep v3.3.2 notes aligned with the final merge range\n\nInclude the toolchain and generated-project work merged through PRs #3585 and #3587 so the canonical changelog reflects the release candidate now present on develop.\n\nConstraint: Limit the repository change to CHANGELOG.md while maintaining the separate unpublished Release and Discussion drafts outside the checkout.\n\nConfidence: high\n\nScope-risk: narrow\n\nTested: git diff --cached --check; 106-link release-range gate; direct source checks for tool versions, generator defaults, CLI proto generation, wrapped EOF handling, and Linux generated-project CI.\n\nNot-tested: Code tests were not rerun because this follow-up changes release prose only and the merged implementation PRs already passed their GitHub checks.\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* docs: describe the final 3.3.2 CLI scaffold state\n\nRemove the superseded dependency-lock claim because PR #3585 deleted the template go.sum files and replaced embedded dependency metadata with generated-project proto and tidy workflows.\n\nConstraint: Limit the repository fix to the reviewed CHANGELOG.md line and keep unpublished release drafts outside the PR.\n\nConfidence: high\n\nScope-risk: narrow\n\nTested: git diff --cached --check; 105-link release-range gate; final develop tree check for removed go.sum and gosum.go artifacts; stale-claim scan across Release and Discussion drafts.\n\nNot-tested: Code tests were not rerun because this correction changes release prose only.\n\nRelated: PR #3588 review comment 3694862025\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* docs: standardize Dubbo-go naming in 3.3.2 notes\n\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n---------\n\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e"
    },
    {
      "commit": "144d127e099545880756f9d92efd15942f744a8a",
      "tree": "dc0230dace7ba70a2d63b322447f905368f08bcb",
      "parents": [
        "a62a44a266c63c00e9d22a2c018b4fdccae1dab1"
      ],
      "author": {
        "name": "Xin.Zh",
        "email": "alexstocks@foxmail.com",
        "time": "Sat Aug 01 14:16:23 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 01 14:16:23 2026 +0800"
      },
      "message": "fix: update dubbogo CLI templates for Dubbo-Go 3.3 (#3587)\n\n* fix: update dubbogo CLI templates for Dubbo-Go 3.3\n\nRegenerate the embedded Triple stubs for the current client and server APIs, update template dependencies, and compile generated projects in regression tests.\n\nConstraint: Limit the change to tools/dubbogo-cli templates, generated fixtures, dependency metadata, tests, and matching README file names.\n\nConfidence: High; generator-to-golden equality, direct generated-project compilation, module tests, vet, tidy-diff, formatting, and staged diff checks passed.\n\nScope-risk: Generated applications now require Go 1.24 and Dubbo-Go v3.3.1; Linux was not locally exercised because WSL has no Go toolchain.\n\nRed: TestGeneratedProjectsCompile failed on the removed logger package, legacy NewGreeterClient signature, and legacy RegisterGreeterServer contract.\n\nGreen: CLI, newApp, and newDemo tests and vet passed; both generated modules are tidy and compile against Dubbo-Go v3.3.1.\n\nTested: go test ./... and go vet ./... in tools/dubbogo-cli, newApp, and newDemo; go mod tidy -diff for both generated modules; gofmt -l; git diff --cached --check.\n\nNot-tested: WSL/Linux because go is not installed in the available WSL environment.\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* fix: satisfy CLI template import formatting\n\nGroup the generated project logger import according to the repository imports-formatter rules and keep generator sources synchronized with golden files.\n\nConstraint: Limit the change to the three affected generator templates and their three golden outputs.\n\nConfidence: High; the repository format steps produced no additional diff after the import grouping change.\n\nScope-risk: Import layout only; generated application behavior and dependencies are unchanged.\n\nRed: The Linux CI Check Code Format step rewrote three golden files and failed make check-fmt.\n\nGreen: The equivalent modernize, go fmt, imports-formatter, and CLI go fmt chain leaves no unstaged diff.\n\nTested: go test ./... and go vet ./... in tools/dubbogo-cli; go vet ./... and go mod tidy -diff in both generated modules; git diff --cached --check.\n\nNot-tested: WSL/Linux locally because Go is not installed in WSL; GitHub Actions will provide the Linux confirmation.\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* docs: define PR 3587 reconciliation design\n\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* Document the approved PR 3587 implementation sequence\n\nRecord the exact merge conflict policy, TDD steps, Linux E2E coverage, mutation proof, and race-safe push checks needed to reconcile the two CLI template pull requests.\n\nConstraint: Preserve the scaffold architecture already merged through PR 3585\n\nTested: plan placeholder scan and staged whitespace validation\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* Pin generated CLI projects to the stable Dubbo-Go release\n\nReplace the dated prerelease dependency in both generators and golden projects while retaining the removed-logger regression guard.\n\nConstraint: Keep the generated module language version at Go 1.25\n\nTested: targeted generator version logger and golden consistency tests\n\nRelated: Task 2/7\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* Make fresh CLI scaffolds self-contained under make test\n\nGenerate protocol sources and tidy modules before compilation, then exercise that public workflow against newly generated app and demo projects.\n\nConstraint: Generated protobuf and Triple sources remain outside the templates\n\nTested: DUBBOGO_CLI_E2E\u003d1 generated-project compilation and golden consistency tests\n\nRelated: Task 3/7\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* Recognize wrapped EOF errors in generated stream handlers\n\nUse errors.Is in both generator templates and golden outputs so wrapped end-of-stream errors terminate normally instead of being returned as failures.\n\nConstraint: Preserve the existing stream control flow outside EOF classification\n\nTested: generated-output EOF assertions golden consistency and fresh-project compilation\n\nRelated: Task 4/7\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* Gate CLI scaffold compilation in Linux CI\n\nInstall the protocol generators used by fresh projects and run the explicit generated-project E2E target before the existing repository checks.\n\nConstraint: Ordinary CLI unit tests remain independent of a local protoc toolchain\n\nTested: make generated-project target and environment-gated skip behavior\n\nRelated: Task 5/7\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n* Install protoc plugin from the locked module graph\n\nResolve protoc-gen-go through the root go.mod and go.sum with -mod\u003dreadonly so the CI toolchain remains pinned to v1.34.2 without an inline version literal.\n\nConstraint: Keep the generated-project toolchain reproducible and satisfy SonarCloud githubactions:S8545 without suppressions\n\nTested: isolated GOBIN install plus make -C tools/dubbogo-cli test-generated-projects\n\nRelated: PR #3587 SonarCloud follow-up\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\n\n---------\n\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e"
    },
    {
      "commit": "a62a44a266c63c00e9d22a2c018b4fdccae1dab1",
      "tree": "ca25ea2aec35cd8eb87444d79e183f8e95acc41d",
      "parents": [
        "53d81d17c0f658b7151fb8c44f0d80371ef047e7"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Sat Aug 01 02:57:59 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 01 10:57:59 2026 +0800"
      },
      "message": "update tools (#3585)"
    },
    {
      "commit": "53d81d17c0f658b7151fb8c44f0d80371ef047e7",
      "tree": "fb2a19aa534f399a07c7d479bb6ed723e4fb5147",
      "parents": [
        "5e87b0673f70273e1986e3b9508f7ea007a88fb2"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Mon Jul 27 02:21:58 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 27 10:21:58 2026 +0800"
      },
      "message": "chore: prepare the release for version 3.3.2 (#3469)\n\n* chore: prepare 3.3.2 release\n\n* ci: use local source for integration tests\n\n* fix(registry): add lock protection for serviceListeners map access (#3442)\n\n* fix(registry): add lock protection for serviceListeners map access\n\nserviceListeners map was read/written without holding the lock in\nSubscribeURL and UnSubscribe, while the same struct\u0027s serviceMappingListeners\nalready had proper lock protection. This could cause data races when\nconcurrent subscribe/unsubscribe operations access the map.\n\n- SubscribeURL: use s.lock.Lock() to protect the check-then-act read+write\n  of serviceListeners (write lock needed to prevent TOCTOU race)\n- UnSubscribe: use s.lock.RLock() for the read access of serviceListeners\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* fix(registry): use defer+lambda for serviceListeners lock to prevent deadlock on panic\n\nWrap lock/unlock in anonymous functions with defer to ensure the lock\nis always released even if a panic occurs between Lock() and Unlock(),\nas suggested in PR review.\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* fix(registry): narrow service-discovery lock to map check/install only\n\nAddress [P1] review on PR #3442: the write lock previously wrapped\nGetInstances and listener.OnEvent, which may perform external RPC /\nmetadata-report calls and block every other subscribe/unsubscribe on\nthe same registry.\n\n- Move GetInstances/OnEvent out of the lock; build the listener first.\n- Install under a short write lock with a double-check so a concurrent\n  subscriber for the same key does not install a duplicate listener.\n- UnSubscribe uses the new getServiceListener helper (short RLock) in\n  place of the inline lambda.\n- Add TestServiceDiscoveryRegistrySubscribeURLDoesNotHoldLockOnExternalCall\n  which blocks GetInstances for one service and asserts that subscribing a\n  different service is not stalled. The test fails on the previous\n  lock-during-GetInstances implementation.\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* chore: trigger CI rerun on Integration Test\n\nRe-runs the Integration Test job, which previously failed due to a\ntransient 500 from sum.golang.org while indexing the freshly-pushed\nfork commit (not a code issue; the CI unit-test job passed).\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* ci: skip sumdb for fork integration test replace\n\n---------\n\nCo-authored-by: Claude \u003cnoreply@anthropic.com\u003e\n\n---------\n\nCo-authored-by: aias00 \u003cliuhongyu@apache.org\u003e\nCo-authored-by: Claude \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "5e87b0673f70273e1986e3b9508f7ea007a88fb2",
      "tree": "6941f695a1f2ab80a98c56784895d5cf4c9b84f5",
      "parents": [
        "0f71ba09e67bcaf84a089ae098965c93c933ed57"
      ],
      "author": {
        "name": "aias00",
        "email": "liuhongyu@apache.org",
        "time": "Sun Jul 26 18:41:24 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 27 09:41:24 2026 +0800"
      },
      "message": "fix(registry): add lock protection for serviceListeners map access (#3442)\n\n* fix(registry): add lock protection for serviceListeners map access\n\nserviceListeners map was read/written without holding the lock in\nSubscribeURL and UnSubscribe, while the same struct\u0027s serviceMappingListeners\nalready had proper lock protection. This could cause data races when\nconcurrent subscribe/unsubscribe operations access the map.\n\n- SubscribeURL: use s.lock.Lock() to protect the check-then-act read+write\n  of serviceListeners (write lock needed to prevent TOCTOU race)\n- UnSubscribe: use s.lock.RLock() for the read access of serviceListeners\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* fix(registry): use defer+lambda for serviceListeners lock to prevent deadlock on panic\n\nWrap lock/unlock in anonymous functions with defer to ensure the lock\nis always released even if a panic occurs between Lock() and Unlock(),\nas suggested in PR review.\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* fix(registry): narrow service-discovery lock to map check/install only\n\nAddress [P1] review on PR #3442: the write lock previously wrapped\nGetInstances and listener.OnEvent, which may perform external RPC /\nmetadata-report calls and block every other subscribe/unsubscribe on\nthe same registry.\n\n- Move GetInstances/OnEvent out of the lock; build the listener first.\n- Install under a short write lock with a double-check so a concurrent\n  subscriber for the same key does not install a duplicate listener.\n- UnSubscribe uses the new getServiceListener helper (short RLock) in\n  place of the inline lambda.\n- Add TestServiceDiscoveryRegistrySubscribeURLDoesNotHoldLockOnExternalCall\n  which blocks GetInstances for one service and asserts that subscribing a\n  different service is not stalled. The test fails on the previous\n  lock-during-GetInstances implementation.\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* chore: trigger CI rerun on Integration Test\n\nRe-runs the Integration Test job, which previously failed due to a\ntransient 500 from sum.golang.org while indexing the freshly-pushed\nfork commit (not a code issue; the CI unit-test job passed).\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* ci: skip sumdb for fork integration test replace\n\n---------\n\nCo-authored-by: Claude \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "0f71ba09e67bcaf84a089ae098965c93c933ed57",
      "tree": "8131d8f5907a17bfabece532f9858b2140355fdf",
      "parents": [
        "110bd656c49979d31cf5ddd3fee79c39de384d9a"
      ],
      "author": {
        "name": "aias00",
        "email": "liuhongyu@apache.org",
        "time": "Sat Jul 25 18:20:24 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jul 26 09:20:24 2026 +0800"
      },
      "message": "fix(cluster): eliminate data race on StickyInvoker with atomic.Value (#3439)\n\n* fix(cluster): eliminate data race on StickyInvoker with atomic.Value\n\nStickyInvoker in BaseClusterInvoker was a plain field read/written by\nmultiple goroutines (e.g. failback retry goroutine + Invoke goroutine)\nwithout any synchronization, causing a data race on the RPC hot path.\n\nReplace the unexported StickyInvoker field with an atomic.Value,\naccessed via getStickyInvoker()/setStickyInvoker() helpers. This\neliminates the race while keeping the lock-free read path fast.\n\nKey changes:\n- StickyInvoker base.Invoker -\u003e stickyInvoker atomic.Value (unexported)\n- Add getStickyInvoker() / setStickyInvoker() helpers\n- Update IsAvailable() and DoSelect() to use atomic accessors\n- DoSelect reads sticky invoker into a local variable to avoid\n  redundant atomic loads and ensure consistent logic within one call\n- Add concurrent tests (TestStickyConcurrentDoSelect,\n  TestStickyConcurrentIsAvailableAndDoSelect) that pass with -race\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* fix(cluster): use wrapper type for atomic.Value to prevent nil Store and type mismatch panics\n\nAddress Copilot review feedback:\n1. atomic.Value.Store(nil) panics - wrap base.Invoker in stickyInvokerWrapper\n   struct so nil invoker is stored as {invoker: nil} (non-nil wrapper)\n2. atomic.Value requires consistent concrete type - the wrapper struct\n   ensures the same type is always stored regardless of Invoker impl\n3. Fix test TestStickyConcurrentIsAvailableAndDoSelect to actually call\n   IsAvailable() with a proper mock Directory (instead of getStickyInvoker)\n4. Fix imports formatting per dubbo-go convention (separate import groups)\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* style: fix import formatting in test file per imports-formatter\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* refactor(cluster): use atomic.Pointer for StickyInvoker, return *BaseClusterInvoker from constructor\n\n- Replace atomic.Value + stickyInvokerWrapper + getter/setter with\n  atomic.Pointer[base.Invoker] — idiomatic Go, nil-safe, type-safe,\n  no wrapper needed\n- NewBaseClusterInvoker now returns *BaseClusterInvoker (pointer),\n  preventing accidental value copies of the struct containing atomic\n  fields\n- All 9 cluster implementations updated to use pointer embedding\n  (*base.BaseClusterInvoker) to match the new constructor return type\n- StickyInvoker field remains exported (atomic.Pointer is safe for\n  concurrent access by design)\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* fix(cluster): fix StickyInvoker data race without breaking exported v3 API\n\nAddress [P1] review on PR #3439: the previous fix changed two exported\nsymbols already released in v3.3.2-20260709 — the StickyInvoker field\ntype (base.Invoker -\u003e atomic.Pointer[base.Invoker]) and the\nNewBaseClusterInvoker return type (value -\u003e pointer) — breaking source\ncompatibility for external consumers.\n\nRestore the original signatures and implement the race fix via\nunexported internal state instead:\n\n- Keep StickyInvoker as the exported base.Invoker field.\n- Keep NewBaseClusterInvoker returning BaseClusterInvoker by value.\n- Revert cluster invoker embeddings back to value embeddings.\n- Guard StickyInvoker access in IsAvailable / DoSelect with an\n  unexported stickyLock sync.RWMutex via getStickyInvoker /\n  setStickyInvoker accessors, eliminating the read/write data race\n  without touching any exported symbol.\n\nThe existing TestStickyConcurrent* tests continue to pass under -race.\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n---------\n\nCo-authored-by: Claude \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "110bd656c49979d31cf5ddd3fee79c39de384d9a",
      "tree": "f35fefec8e9956c04a84e645eff816c782bd73fa",
      "parents": [
        "e2eb0c451b9843c9a6f59f8598aea3ea4d7f4d50"
      ],
      "author": {
        "name": "Mochimia",
        "email": "2755364178@qq.com",
        "time": "Sun Jul 26 09:18:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jul 26 09:18:15 2026 +0800"
      },
      "message": "fix(polaris): reconcile initial subscribe snapshot (#3482)\n\n* fix(polaris): reconcile initial subscribe snapshot"
    },
    {
      "commit": "e2eb0c451b9843c9a6f59f8598aea3ea4d7f4d50",
      "tree": "2d2b1076df96da85240b5673a565f2888d6944d4",
      "parents": [
        "bcd6aa42be158b28f969e7669c43ae8f543ac7e5"
      ],
      "author": {
        "name": "超級の新人",
        "email": "chaoji_xinren@163.com",
        "time": "Sun Jul 19 16:02:09 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jul 19 16:02:09 2026 +0800"
      },
      "message": "perf(common): optimize IsEquals and ToMap to reduce allocations (#3488)\n\nOptimize URL equality comparison and map conversion to avoid unnecessary\nallocations. IsEquals() now compares fields directly instead of materializing\ntwo full maps via ToMap(). ToMap() pre-sizes the map and uses single-pass\nLocation parsing with IndexByte.\n\nKey improvements:\n- ToMap: 38-57% faster, 35-51% less memory, 43-77% fewer allocations\n- IsEquals: 40-76% faster, 50-100% less memory, 58-100% fewer allocations\n- Removed duplicate Protocol assignment in ToMap\n\nFixes: #3394\n\nSigned-off-by: chaojixinren \u003cchaoji_xinren@163.com\u003e"
    },
    {
      "commit": "bcd6aa42be158b28f969e7669c43ae8f543ac7e5",
      "tree": "8550f42e7f39ca443782251a2000c83e925e8c4b",
      "parents": [
        "1360af3fe710e0c5a3a0d8c7e687e9e3c0549e7f"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Tue Jul 14 03:26:33 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jul 14 11:26:33 2026 +0800"
      },
      "message": "fix triple unary response metadata (#3446)"
    },
    {
      "commit": "1360af3fe710e0c5a3a0d8c7e687e9e3c0549e7f",
      "tree": "1a667b96625366cf30191c2c3629910a4bec3485",
      "parents": [
        "c1db7f18e621108d107d9e9b98bca9787f2bb158"
      ],
      "author": {
        "name": "Xin.Zh",
        "email": "alexstocks@foxmail.com",
        "time": "Mon Jul 13 14:23:07 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 13 14:23:07 2026 +0800"
      },
      "message": "style: clean up minor review issues (#3484)\n\nAvoid scanning the same suffix twice when extracting sub-properties, and remove an unnecessary blank statement from the SequenceID concurrency test.\n\nTested: gofmt -w common/config/environment.go remoting/exchange_test.go; go test ./common/config ./remoting -count\u003d1; go vet ./common/config ./remoting; git diff --check; wsl bash -lc \u0027cd /mnt/d/test/github/dubbo-go \u0026\u0026 go test ./common/config ./remoting -count\u003d1\u0027\n\nSigned-off-by: Xin.Zh \u003calexstocks@foxmail.com\u003e\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e"
    },
    {
      "commit": "c1db7f18e621108d107d9e9b98bca9787f2bb158",
      "tree": "76f331fa39cf5aef994164b0791e95261cfbd6bf",
      "parents": [
        "b87881aa2982cdef7b8e7a74a78b3b9682c5af48"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Mon Jul 13 05:40:49 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 13 13:40:49 2026 +0800"
      },
      "message": "chore(style): modernize the code style (#3471)\n\n* modernize"
    },
    {
      "commit": "b87881aa2982cdef7b8e7a74a78b3b9682c5af48",
      "tree": "0f96ca21626cdd6b2d1e43b1ceaa9377b40e8b75",
      "parents": [
        "ca069ff629a5d4ef3688138f1c6baeb61e36c860"
      ],
      "author": {
        "name": "Xin.Zh",
        "email": "alexstocks@foxmail.com",
        "time": "Sat Jul 11 19:39:26 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jul 11 19:39:26 2026 +0800"
      },
      "message": "fix: generate dependency locks for CLI scaffolds (#3483)\n\n* fix: generate dependency locks for CLI scaffolds\n\nAdd go.sum files to generated application and demo scaffolds, and share the checksum content between both generators.\n\nTested: cd tools/dubbogo-cli \u0026\u0026 go test ./cmd ./generator/...\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\n\n* style: format CLI scaffold imports\n\nUse the repository-required import block form so imports-formatter leaves both scaffold generator files unchanged.\n\nTested: go run ./tools/imports-formatter against both target files; cd tools/dubbogo-cli \u0026\u0026 go test ./cmd ./generator/...\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e\n\n---------\n\nCo-authored-by: OmX \u003comx@oh-my-codex.dev\u003e"
    },
    {
      "commit": "ca069ff629a5d4ef3688138f1c6baeb61e36c860",
      "tree": "d735db0d27bc90aa7a44ffa1380d730a4d9b7fd2",
      "parents": [
        "25d2f0c7f5367b7f7bf6e22754126578209c378d"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Sat Jul 11 07:51:35 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jul 11 15:51:35 2026 +0800"
      },
      "message": "chore(CI-riscv): Add CI for RISC-V build (#3470)\n\n* add risc-v build ci\n\n* update\n\n* update\n\n* Potential fix for pull request finding\n\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e\n\n* add tab\n\n* delete space\n\n---------\n\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "25d2f0c7f5367b7f7bf6e22754126578209c378d",
      "tree": "116c0287cb627693f031b0d8e6defafffaff17fb",
      "parents": [
        "4879a3c4111cd30f60116baa9607aafc6daabf42"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Sat Jul 11 07:50:40 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jul 11 15:50:40 2026 +0800"
      },
      "message": "expose (#3481)"
    },
    {
      "commit": "4879a3c4111cd30f60116baa9607aafc6daabf42",
      "tree": "212ab64aba2716cf1353eba60df7bca062f018e1",
      "parents": [
        "5683612b1dfbbf755e5bb10bfcc6faf56d7d1d19"
      ],
      "author": {
        "name": "aias00",
        "email": "liuhongyu@apache.org",
        "time": "Sat Jul 11 14:55:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jul 11 14:55:48 2026 +0800"
      },
      "message": "fix(remoting): clean up pendingResponses on error paths to prevent map leak (#3440)\n\n* fix(remoting): clean up pendingResponses on error paths to prevent map leak\n\nThe global pendingResponses sync.Map is cleaned up on the success path\nvia Response.Handle() -\u003e removePendingResponse(), but entries were never\nremoved when requests fail:\n\n- ExchangeClient.Request(): AddPendingResponse called before\n  client.Request(), but on error the entry was left in the map\n- ExchangeClient.AsyncRequest(): same pattern, same leak\n- getty heartbeat(): timeout branch never called removePendingResponse,\n  leaving the entry to accumulate indefinitely\n\nAdd removePendingResponse calls in all three error/timeout paths. Export\nRemovePendingResponse so the getty package (external to remoting) can\ncall it from its heartbeat timeout handler.\n\n* refactor(remoting): export removePendingResponse directly instead of wrapper\n\nAddress review feedback: the extra RemovePendingResponse wrapper added no\nvalue and was inconsistent with its siblings AddPendingResponse/\nGetPendingResponse, which are exported directly. Rename removePendingResponse\nto the exported RemovePendingResponse and update all in-package call sites.\n\n* test(remoting): add regression tests for pendingResponses cleanup on error paths\n\nCover the map-leak fix with tests that fail if the cleanup is removed:\n- ExchangeClient Request/AsyncRequest remove the pending response when the\n  underlying client.Request returns an error\n- getty heartbeat removes the pending response on read timeout\n\n* test(remoting): use any instead of interface{} in heartbeat test mock"
    },
    {
      "commit": "5683612b1dfbbf755e5bb10bfcc6faf56d7d1d19",
      "tree": "05cfff5cd185331ae2f5cff491be690b602ebf32",
      "parents": [
        "17c74786787d0a63b73747b2ccbeafd6b1eaf2a0"
      ],
      "author": {
        "name": "AsperforMias",
        "email": "asperformias000@outlook.com",
        "time": "Wed Jul 08 19:27:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 08 19:27:28 2026 +0800"
      },
      "message": "fix: remove stale providers after initial subscribe load (#3479)\n\n* fix(registry/nacos): seed listener with initial instances"
    },
    {
      "commit": "17c74786787d0a63b73747b2ccbeafd6b1eaf2a0",
      "tree": "a36583e5d917d34d6c2ea682fd2424b964710a7b",
      "parents": [
        "9c5f8203fdce09650290f90af627da8d15420cb7"
      ],
      "author": {
        "name": "aias00",
        "email": "liuhongyu@apache.org",
        "time": "Wed Jul 08 10:56:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 08 10:56:39 2026 +0800"
      },
      "message": "fix(otel): fix metadataSupplier Get/Set type mismatch breaking trace propagation (#3433)\n\nSet stored values as string but Get expected []string, causing type\nassertion failure when OTel propagator Inject followed by Extract.\nTrace context (traceparent etc.) was lost during propagation.\n\n- Set: store []string{value} instead of string, consistent with\n  triple\u0027s generateAttachments which stores http.Header values as\n  []string\n- Get: add defensive string type handling alongside []string, matching\n  RPCInvocation.GetAttachment\u0027s pattern for robustness\n\nCo-authored-by: Claude \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "9c5f8203fdce09650290f90af627da8d15420cb7",
      "tree": "fc0405a35a3b9b23b346fa9ee7b45f3dee1fc026",
      "parents": [
        "6f95e3446c17d741d5f544d6122cf2f459acdfbb"
      ],
      "author": {
        "name": "Mochimia",
        "email": "2755364178@qq.com",
        "time": "Tue Jul 07 10:52:31 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jul 07 10:52:31 2026 +0800"
      },
      "message": "fix(triple): make stream response close non-blocking (#3466)\n\n* fix(triple): make stream response close non-blocking\n\n* test(triple): stabilize stream close regression tests\n\n* test(triple): avoid shadowing error in stream close test\n\n* test(triple): clarify stream close lifecycle comments"
    },
    {
      "commit": "6f95e3446c17d741d5f544d6122cf2f459acdfbb",
      "tree": "4b923fcbef1b2760577a8f113448e878b12876bb",
      "parents": [
        "630393dad785691b47bd26362dbf015a196d7c70"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sat Jul 04 20:57:32 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jul 04 20:57:32 2026 +0800"
      },
      "message": "build(deps): bump golang.org/x/net from 0.52.0 to 0.55.0 (#3467)\n\nBumps [golang.org/x/net](https://github.com/golang/net) from 0.52.0 to 0.55.0.\n- [Commits](https://github.com/golang/net/compare/v0.52.0...v0.55.0)\n\n---\nupdated-dependencies:\n- dependency-name: golang.org/x/net\n  dependency-version: 0.55.0\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "630393dad785691b47bd26362dbf015a196d7c70",
      "tree": "955af69ad2e3f646b152f070c62530a0587e10c8",
      "parents": [
        "9c955e957050a97ae23d0e29a7fd7b268323ace1"
      ],
      "author": {
        "name": "aias00",
        "email": "liuhongyu@apache.org",
        "time": "Tue Jun 30 10:54:47 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 30 10:54:47 2026 +0800"
      },
      "message": "fix(triple_protocol): replace Buf Technologies license header with ASF header (#3464)\n\n* fix(triple_protocol): replace Buf Technologies license header with ASF header\n\n- Replace Buf Technologies copyright header with Apache Software Foundation header in 55 Go files\n- Replace Buf Technologies copyright header in 4 proto files\n- Remove license-header tool from Makefile to prevent auto-generation of Buf headers\n- Remove COPYRIGHT_YEARS and LICENSE_IGNORE variables from Makefile\n\nThis ensures all files have proper ASF license headers for Apache Dubbo project.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* fix(triple_protocol): restore build constraints in maxbytes.go\n\n- Add //go:build go1.19 and // +build go1.19 constraints\n- Build constraints must precede license header per Go convention\n- Remove duplicate leftover license text lines\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n* fix(triple_protocol): restore missing package declaration in triple_ext_test.go\n\nThe package declaration was accidentally removed when replacing the license header.\n\nCo-Authored-By: Claude \u003cnoreply@anthropic.com\u003e\n\n---------\n\nCo-authored-by: Claude \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "9c955e957050a97ae23d0e29a7fd7b268323ace1",
      "tree": "e4940fa3754ee59c073b835b39316157ee2a6c3b",
      "parents": [
        "c8add4bb6720c15fcc625b8436d7f2bec0bcea3a"
      ],
      "author": {
        "name": "超級の新人",
        "email": "chaoji_xinren@163.com",
        "time": "Tue Jun 30 09:39:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 30 09:39:04 2026 +0800"
      },
      "message": "test(triple): add concurrent send/close guards for duplexHTTPCall (#3462)\n\nInvestigate whether connect-go v1.19.2\u0027s fix for the concurrent Send +\nCloseAndReceive nil-pointer dereference (connectrpc/connect-go#919) applies\nto Dubbo-go\u0027s forked Triple runtime.\n\nduplexHTTPCall is not affected: newDuplexHTTPCall allocates the request-body\nio.Pipe at construction and never reassigns requestBodyWriter, so it is always\nnon-nil and concurrent Write/CloseWrite are safe in any order. The upstream\nrace, where the pipe was created lazily on the first Send and a racing\nCloseWrite could leave it nil, is structurally impossible here, so no\nsynchronization change is ported.\n\n- add TestDuplexHTTPCallConcurrentWriteAndCloseWrite and\n  TestDuplexHTTPCallConcurrentWriteCloseRace as regression guards (run under\n  -race) that pin the construction-time pipe invariant\n- document the invariant on requestBodyWriter to keep the allocation out of a\n  lazy/first-send path\n\nRef: #3458"
    },
    {
      "commit": "c8add4bb6720c15fcc625b8436d7f2bec0bcea3a",
      "tree": "c271a59e2104128deb9ac296a0cb0d2654504b5e",
      "parents": [
        "c7459997f41fd6c606156e270f7eae6462b9d62e"
      ],
      "author": {
        "name": "eye-gu",
        "email": "734164350@qq.com",
        "time": "Fri Jun 26 11:06:29 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 26 11:06:29 2026 +0800"
      },
      "message": "feat(metadata): add renew and GC policy for app-level metadata (#3371)\n\n* feat(metadata): add renew and GC policy for app-level metadata\n\n* fix ci\n\n* fix ci\n\n* fix review\n\n* fix nil\n\n* rebase develop, resolve conflicts, add units"
    },
    {
      "commit": "c7459997f41fd6c606156e270f7eae6462b9d62e",
      "tree": "ad34d544d8192b7b2a1294068cf9c3f692f58843",
      "parents": [
        "706090f7ed00917644e89fa537e90c557d214891"
      ],
      "author": {
        "name": "jieguo",
        "email": "1193249232@qq.com",
        "time": "Thu Jun 25 16:53:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 25 16:53:15 2026 +0800"
      },
      "message": "feat(metadata): add concurrency safety for application-level metadata state (#3353) (#3367)\n\n* feat(metadata): add internal RWMutex for MetadataInfo and fix json serialization (#3353)\n\nAdd sync.RWMutex to MetadataInfo struct with json:\"-\" / hessian:\"-\"\ntags to skip serialization. All mutating methods (AddService, RemoveService,\nAddSubscribeURL, RemoveSubscribeURL) acquire the write lock, and read\nmethods (GetExportedServiceURLs, GetSubscribedURLs, GetServices) acquire\nthe read lock. The new GetServices method returns a snapshot copy.\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n* feat(metadata): add lock protection for global registry and instances (#3353)\n\nAdd sync.RWMutex to protect registryMetadataInfo in metadata.go and\ninstances in report_instance.go. Extract getMetadataReportUnsafe helper\nto avoid reentrant RLock deadlock in GetMetadataReportByRegistry fallback.\nFix nacos report_test to use pointer to MetadataInfo for json.Marshal.\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n* feat(metadata): fix concurrency safety in listener callbacks and external calls (#3353)\n\nAdd mutex locking to AddListenerAndNotify and RemoveListener to protect\nshared fields listeners and serviceUrls. Replace direct access to\nMetadataInfo.Services with safe GetServices method in OnEvent and\nconvertV2 to prevent unprotected map reads.\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n* style: format import blocks using dubbo-go imports-formatter\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n* style: format metadata.go and report_instance.go to pass CI\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n* fix(metadata): resolve data races pointed out in code review\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n* test: fix failing tests and improve unit test coverage\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n* test: fix testifylint error by avoiding require in goroutines\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n* fix(metadata): deep copy ServiceInfo to prevent write-on-read data race and reduce lock granularity in report creation\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n* chore: trigger CI re-run for codecov gpg issue\n\n* refactor(metadata): implement no-lock helper to fix data race and avoid deadlocks in ReplaceExportedServices\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n* test: fix compilation error in instance changed listener tests by adding missing registryId argument\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n* fix(metadata): add RLock around global map lookup in RemoveService and RemoveSubscribeURL to prevent concurrent map read/write\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e\n\n---------\n\nSigned-off-by: jieguo-coder \u003c1193249232@qq.com\u003e"
    },
    {
      "commit": "706090f7ed00917644e89fa537e90c557d214891",
      "tree": "baddd10cf53c6f64d96764bef74f0cc13af6c0d1",
      "parents": [
        "8b5bbcf192aaac782e2fcf1ea2a6c7c90d9e3e1c"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Thu Jun 25 08:52:45 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 25 16:52:45 2026 +0800"
      },
      "message": "feat(service-discovery): 稳定应用级服务发现使用的元数据key (#3362)\n\n* stablize_register_services\n\n* imprt format"
    },
    {
      "commit": "8b5bbcf192aaac782e2fcf1ea2a6c7c90d9e3e1c",
      "tree": "99795b387f9210f8db9c77c62266a42ac861e629",
      "parents": [
        "01e36dacadb6ba4009c7ca5c8858a37336f95c77"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Thu Jun 25 01:29:23 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 25 09:29:23 2026 +0800"
      },
      "message": "[config] Decouple config reader and remove config package (#3449)\n\n* decouple config reader\n\n* complete delete config package"
    },
    {
      "commit": "01e36dacadb6ba4009c7ca5c8858a37336f95c77",
      "tree": "2e2a50f57491fdeed355299734bee95c648ed0e4",
      "parents": [
        "e0e291cd53f7eded6319b265e96362263969e382"
      ],
      "author": {
        "name": "翎",
        "email": "1820661379@qq.com",
        "time": "Mon Jun 22 12:40:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 22 12:40:58 2026 +0800"
      },
      "message": "refactor: remove root config compatibility bridge (#3448)"
    },
    {
      "commit": "e0e291cd53f7eded6319b265e96362263969e382",
      "tree": "40ff6805ae7899c84af6bdaa4b1c9d4e05e23cb1",
      "parents": [
        "ccb2f6609ac48c67659a1b48115118f85ab2bf75"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Mon Jun 22 01:22:47 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 22 09:22:47 2026 +0800"
      },
      "message": "docs: update filter README (#3447)"
    },
    {
      "commit": "ccb2f6609ac48c67659a1b48115118f85ab2bf75",
      "tree": "c2dac75f9bd6ab11faec3d0050af29081471e301",
      "parents": [
        "9fcee8d6907548cdec9614972d91b0f4bbf3c0bd"
      ],
      "author": {
        "name": "Oxidaner",
        "email": "80675726+Oxidaner@users.noreply.github.com",
        "time": "Fri Jun 19 22:42:42 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 19 22:42:42 2026 +0800"
      },
      "message": "refactor: migrate graceful shutdown config to global (#3386)\n\n* refactor: migrate graceful shutdown config to global\n\n* refactor: remove config dependency from graceful shutdown\n\n* refactor: centralize shutdown config defaults\n\n* fix: align graceful shutdown config logging\n\n* fix: protocol/triple/triple_protocol/triple_ext_test.go gRPC streaming does not support HTTP/1"
    },
    {
      "commit": "9fcee8d6907548cdec9614972d91b0f4bbf3c0bd",
      "tree": "2cb65f8b157aa9081b41d35610ff560877eb670f",
      "parents": [
        "0d97613232c3936d20d31c86e83fe969b5509be0"
      ],
      "author": {
        "name": "ヴァニラシ",
        "email": "2755364178@qq.com",
        "time": "Fri Jun 19 16:03:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 19 16:03:18 2026 +0800"
      },
      "message": "feat(triple): expose unary response metadata via call options (#3443)\n\n* feat(triple): expose unary response metadata via call options\n\n* fix(triple): capture unary response metadata on error\n\n* docs(client): clarify response metadata capture on errors\n\n* fix(triple): validate response metadata capture attributes\n\nSigned-off-by: Vanillaxi \u003c2755364178@qq.com\u003e\n\n* style(triple): format client test imports\n\n---------\n\nSigned-off-by: Vanillaxi \u003c2755364178@qq.com\u003e"
    },
    {
      "commit": "0d97613232c3936d20d31c86e83fe969b5509be0",
      "tree": "1df34c2f77c31a4a8b120a6a72f2d10d2e1040dc",
      "parents": [
        "43348b4b341ef024bb1139b4408380d8e80dd18d"
      ],
      "author": {
        "name": "吴杨帆",
        "email": "39647285+leno23@users.noreply.github.com",
        "time": "Thu Jun 18 19:39:26 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 18 19:39:26 2026 +0800"
      },
      "message": "fix(triple): skip unsupported compat trailer attachments (#3418)\n\n* fix(triple): skip unsupported compat trailer attachments\n\n* test(triple): format compat attachment test imports\n\n* test(triple): satisfy compat attachment lint"
    },
    {
      "commit": "43348b4b341ef024bb1139b4408380d8e80dd18d",
      "tree": "50dcc4c08ca7148dc99e195e8bbb8c32d4cfadeb",
      "parents": [
        "04b27a9bf6ea5f6ec58406234473863345065097"
      ],
      "author": {
        "name": "aias00",
        "email": "liuhongyu@apache.org",
        "time": "Thu Jun 18 12:36:32 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 18 12:36:32 2026 +0800"
      },
      "message": "fix(getty): check error before using buf in server Write (#3434)\n\nIn RpcServerPackageHandler.Write, both EncodeResponse and EncodeRequest\nwere using buf.Len() before checking err. If the encode call returns an\nerror, buf could be nil, causing a nil pointer panic. The client-side\nWrite already checks err first; this aligns server-side to the same\npattern.\n\nCo-authored-by: Claude \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "04b27a9bf6ea5f6ec58406234473863345065097",
      "tree": "caf7e4a1d03161d6e1d8b674011228bcd762d46a",
      "parents": [
        "fcbbd092031d3b9e7f165fc2973c277a0d6791fa"
      ],
      "author": {
        "name": "aias00",
        "email": "liuhongyu@apache.org",
        "time": "Thu Jun 18 12:29:26 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 18 12:29:26 2026 +0800"
      },
      "message": "fix(loadbalance): fix data race in RoundRobin setWeight and increaseCurrent (#3435)\n\nThe weightedRoundRobin struct had mixed atomic and non-atomic access\nto the weight and current fields:\n- setWeight() used plain writes while Weight() used atomic.LoadInt64\n- increaseCurrent() read weight with a plain read while other methods\n  used atomic operations on the same field\n\nReplace all non-atomic accesses with atomic operations:\n- setWeight: use atomic.StoreInt64 for both weight and current\n- increaseCurrent: use atomic.LoadInt64 to read weight\n\nCo-authored-by: Claude \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "fcbbd092031d3b9e7f165fc2973c277a0d6791fa",
      "tree": "d77f8a07340bfbf32a2bd92f27da006354a86522",
      "parents": [
        "93fe03a4962bb4f3e02e172141dd538df33be951"
      ],
      "author": {
        "name": "Stefano Maffeis",
        "email": "lesbass@gmail.com",
        "time": "Wed Jun 17 12:17:46 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 17 18:17:46 2026 +0800"
      },
      "message": "fix: toKey now uses configured hash.arguments indexes instead of slice positions (#3432)\n\n* fix: toKey now uses configured hash.arguments indexes instead of slice positions\n\nPreviously toKey iterated with `for i :\u003d range c.argumentIndex` which\nused the slice index (0,1,2,...) as the argument position to read from\nargs. With a configuration like hash.arguments\u003d1, this still read\nargs[0] instead of args[1], making consistent hashing route by the\nwrong argument.\n\nAlso replaced the unsafe args[i].(string) type assertion with\nfmt.Fprint to avoid panicking on non-string arguments.\n\nFixes: #3431\n\nSigned-off-by: RepoScout \u003creposcout@ai-newsroom.ai\u003e\nCo-Authored-By: Paperclip \u003cnoreply@paperclip.ing\u003e\n\n* fix: toKey now uses configured hash.arguments indexes and avoids fmt.Fprint for strings\n\nPreviously toKey iterated with `for i :\u003d range c.argumentIndex` which\nused the slice index (0,1,2,...) as the argument position to read from\nargs. With a configuration like hash.arguments\u003d1, this still read\nargs[0] instead of args[1].\n\nAdded a type switch so the common string case uses the cheaper\nsb.WriteString instead of fmt.Fprint.\n\nFixes: #3431\n\nSigned-off-by: RepoScout \u003creposcout@ai-newsroom.ai\u003e\nCo-Authored-By: Paperclip \u003cnoreply@paperclip.ing\u003e\n\n---------\n\nSigned-off-by: RepoScout \u003creposcout@ai-newsroom.ai\u003e\nCo-authored-by: RepoScout \u003creposcout@ai-newsroom.ai\u003e\nCo-authored-by: Paperclip \u003cnoreply@paperclip.ing\u003e"
    },
    {
      "commit": "93fe03a4962bb4f3e02e172141dd538df33be951",
      "tree": "7a2f692a7469bd674f84120593b143f07d553f68",
      "parents": [
        "e741e0e7e54ce1f7acda67e919eacb1e3519b440"
      ],
      "author": {
        "name": "aias00",
        "email": "liuhongyu@apache.org",
        "time": "Wed Jun 17 13:41:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 17 13:41:10 2026 +0800"
      },
      "message": "fix(loadbalance): prevent panic in consistent hash toKey for non-string args (#3430)\n\nThe hard type assertion args[i].(string) panics for any non-string\nargument (int, struct, etc.), while Java Dubbo uses toString() which\nnever fails. Replace with fmt.Fprint(\u0026sb, args[i]) which safely\nconverts any type to its string representation."
    },
    {
      "commit": "e741e0e7e54ce1f7acda67e919eacb1e3519b440",
      "tree": "8bfa047630057fa8091fdf183ffa4119d9d240fc",
      "parents": [
        "fd4dea4f8ccef79a3190ba1d4a60af775d615135"
      ],
      "author": {
        "name": "吴杨帆",
        "email": "39647285+leno23@users.noreply.github.com",
        "time": "Tue Jun 16 15:42:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 16 15:42:10 2026 +0800"
      },
      "message": "fix(triple): canonicalize context metadata headers (#3428)\n\n* fix(triple): canonicalize context metadata headers\n\nSigned-off-by: wuyangfan \u003cyangfan.wu@succaiss.com\u003e\n\n* test(triple): cover reserved header normalization\n\n* fix(triple): clone incoming context headers\n\n* test(triple): avoid noncanonical header key lookup\n\n* docs(triple): clarify metadata header casing\n\n---------\n\nSigned-off-by: wuyangfan \u003cyangfan.wu@succaiss.com\u003e"
    },
    {
      "commit": "fd4dea4f8ccef79a3190ba1d4a60af775d615135",
      "tree": "991013034f207b787f0fc1383e8356f011c797c8",
      "parents": [
        "7165f97bbbdd6a16cb89b7ce25be27adb29a4e8e"
      ],
      "author": {
        "name": "吴杨帆",
        "email": "39647285+leno23@users.noreply.github.com",
        "time": "Tue Jun 16 12:52:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 16 12:52:33 2026 +0800"
      },
      "message": "fix(router): avoid script process panic on invalid config (#3417)\n\n* fix(router): avoid script process panic on invalid config\n\n* fix(router): handle script delete without config body\n\n* test(router): cover active script delete event"
    },
    {
      "commit": "7165f97bbbdd6a16cb89b7ce25be27adb29a4e8e",
      "tree": "b3442ef29ff5e0699b24314968b1ebdd155951e1",
      "parents": [
        "d4ce453382a0e6ea18c9840e3a69ac8264790f60"
      ],
      "author": {
        "name": "吴杨帆",
        "email": "39647285+leno23@users.noreply.github.com",
        "time": "Mon Jun 15 16:32:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 15 16:32:48 2026 +0800"
      },
      "message": "build: update grpc dependencies (#3427)\n\nSigned-off-by: wuyangfan \u003cyangfan.wu@succaiss.com\u003e"
    },
    {
      "commit": "d4ce453382a0e6ea18c9840e3a69ac8264790f60",
      "tree": "cbe9276f836de577f7f8d1c9acc93a0467372f22",
      "parents": [
        "54b65bdef41abad81eef5ef4de768b5ac5c86dba"
      ],
      "author": {
        "name": "Harsh Mehta",
        "email": "harshmehta010102@gmail.com",
        "time": "Sun Jun 14 18:57:52 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 14 21:27:52 2026 +0800"
      },
      "message": "perf(triple): add fast paths for common content-type canonicalization (#3416)\n\n* perf(triple): add fast paths for common content-type canonicalization\n\nSigned-off-by: Harsh Mehta \u003charshmehta010102@gmail.com\u003e\n\n* perf(protocol): implement fast path for content-type canonicalization\n\nSigned-off-by: Harsh Mehta \u003charshmehta010102@gmail.com\u003e\n\n---------\n\nSigned-off-by: Harsh Mehta \u003charshmehta010102@gmail.com\u003e"
    },
    {
      "commit": "54b65bdef41abad81eef5ef4de768b5ac5c86dba",
      "tree": "dc81083158e9708ff7da817e85a5d20418cf8816",
      "parents": [
        "0139a9bad92b941b93fed8bce08e2e7389a6f9e7"
      ],
      "author": {
        "name": "吴杨帆",
        "email": "39647285+leno23@users.noreply.github.com",
        "time": "Sun Jun 14 15:40:42 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 14 15:40:42 2026 +0800"
      },
      "message": "refactor(extension): use registry for shutdown callbacks (#3388)\n\n* refactor(extension): use registry for shutdown callbacks\n\n* refactor(extension): simplify shutdown callback registration"
    },
    {
      "commit": "0139a9bad92b941b93fed8bce08e2e7389a6f9e7",
      "tree": "5711330a25b98d849c1e89408ba6cb731d93ed88",
      "parents": [
        "bd1c9f1ea11ebb60e407aba4678a459f4b691d4e"
      ],
      "author": {
        "name": "ヴァニラシ",
        "email": "2755364178@qq.com",
        "time": "Sun Jun 14 15:20:23 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 14 15:20:23 2026 +0800"
      },
      "message": "perf(loadbalance): reduce temporary selection allocations (#3415)"
    },
    {
      "commit": "bd1c9f1ea11ebb60e407aba4678a459f4b691d4e",
      "tree": "fc3c76747558261d08556e623775ff5353ad46c5",
      "parents": [
        "885bc36c37e727fa68bde7a34429d665a35c0e17"
      ],
      "author": {
        "name": "Harsh Mehta",
        "email": "harshmehta010102@gmail.com",
        "time": "Sun Jun 14 11:42:01 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 14 14:12:01 2026 +0800"
      },
      "message": "feat(loadbalance): introduce GetWeightAt for consistent weight calculation using Unix timestamp (#3410)\n\nSigned-off-by: Harsh Mehta \u003charshmehta010102@gmail.com\u003e"
    },
    {
      "commit": "885bc36c37e727fa68bde7a34429d665a35c0e17",
      "tree": "6e233c56ece44c1094706ec01df30c399b658003",
      "parents": [
        "56fe55baa6a8db2d17a0149567a27235171dba84"
      ],
      "author": {
        "name": "wm_03",
        "email": "3134058368@qq.com",
        "time": "Sun Jun 14 13:14:41 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 14 13:14:41 2026 +0800"
      },
      "message": "perf(registry): pre-size service-discovery maps and slices on instance changes (#3414)"
    },
    {
      "commit": "56fe55baa6a8db2d17a0149567a27235171dba84",
      "tree": "ef1e401fff52dad9c140e4d5677895c02622630f",
      "parents": [
        "4e030749525195ae4824bd7a88d9a33d33b8b2e5"
      ],
      "author": {
        "name": "ヴァニラシ",
        "email": "2755364178@qq.com",
        "time": "Sun Jun 14 13:12:47 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 14 13:12:47 2026 +0800"
      },
      "message": "refactor: remove legacy config handling from variadicrpccheck (#3413)"
    },
    {
      "commit": "4e030749525195ae4824bd7a88d9a33d33b8b2e5",
      "tree": "3bff79e3bb4cf660080426e599cc0a3466c691a0",
      "parents": [
        "4d93c115a2ac2b75d104dc6c93e40448b0955185"
      ],
      "author": {
        "name": "wm_03",
        "email": "3134058368@qq.com",
        "time": "Sat Jun 13 20:33:52 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 20:33:52 2026 +0800"
      },
      "message": "perf(common): optimize URL key string construction (#3412)"
    },
    {
      "commit": "4d93c115a2ac2b75d104dc6c93e40448b0955185",
      "tree": "8e0462675c4271b3c9638f8608ddfe90b0a97e3a",
      "parents": [
        "ad0c578be22dbdb20f5b45fac001733aec270d04"
      ],
      "author": {
        "name": "Nene7ko_",
        "email": "141395478+XnLemon@users.noreply.github.com",
        "time": "Sat Jun 13 19:23:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 19:23:00 2026 +0800"
      },
      "message": "fix(metadata): harden remote MetadataInfo loading with fallback, nil guards and error chain (#3395)\n\n* test(metadata): update cache key format and add GetMetadataInfo tests\n\n* fix(metadata): add fallback and nil URL guards for remote MetadataInfo loading\n\n* fix(metadata): address review issues in fallback and nil URL guard changes\n\n* fix(metadata): address PR review issues — error chain, context, comments, tests\n\n- Wrap combined fallback error with perrors.Wrapf instead of Errorf so the\n  rpcErr chain is preserved for errors.Is/As callers (issue #1)\n- Annotate the reportErr\u003d\u003dnil fallback failure path with [Metadata-Fallback]\n  context instead of returning a bare RPC error (issue #2)\n- Wrap local/default path RPC error with app/registry/revision context,\n  consistent with the remote path (issue #3)\n- Mark unused ctx parameters as _ with TODO(context-propagation) comments\n  in both getMetadataInfo implementations and the interface (issue #4)\n- Update GetMetadataInfo doc comment to accurately describe cache, fallback,\n  and nil guard behavior (issue #5)\n- Align \u0027treat as local\u0027 comment and \u0027defaulting to RPC\u0027 log to use consistent\n  \u0027local\u0027 storage-type vocabulary (issue #6)\n- Clarify \u0027// local / default storage path\u0027 comment to say RPC is used (issue #7)\n- Fix listenerMockMetadataReport.GetAppMetadata to use comma-ok assertion,\n  preventing panic when Return(nil, err) is used in future tests (issue #8)\n- Add TestGetMetadataInfo_ReportReturnsNil_RPCSucceeds covering the\n  report-(nil,nil) -\u003e RPC fallback path (gap #9)\n- Add TestGetMetadataInfo_RPCReturnsNilMetadata covering the nil-meta\n  guard in the RPC result path (gap #10)\n- Add TestGetMetadataInfo_NilMetadataMap covering the nil-Metadata-map\n  guard at line 264, reachable only via direct call not OnEvent (gap #11)\n\n* fix ci fail\n\n* fix(metadata): isolate metadata cache by provider app and add port guard\n\nAddress PR review feedback:\n\n- Scope the metadata cache key by provider application instead of the\n  subscribing consumer app. OnEvent keyed revisionToInstances,\n  revisionToMetadata and the disk cache on revision alone (or consumer\n  app + revision), so two provider apps sharing a revision could\n  overwrite each other. Key on metadataCacheKey(providerApp, registryId,\n  revision) throughout; pass instance.GetServiceName() to GetMetadataInfo.\n\n- buildStandardMetadataServiceURL now returns (*common.URL, error) and\n  reports missing protocol and missing port at the URL layer, instead of\n  only guarding a nil URL in the caller.\n\n- Align test names/comments with what they actually cover and fix error\n  assertions to use require (testifylint require-error).\n\n* fix ci fail\n\n---------\n\nCo-authored-by: xnlemon \u003cxianingawa@gmail.com\u003e"
    },
    {
      "commit": "ad0c578be22dbdb20f5b45fac001733aec270d04",
      "tree": "3989b41b3f1434ecded9852c7b89e27f6f198d3a",
      "parents": [
        "a7b6ee632a2d2e4c908cd5c10434d062c5040fe8"
      ],
      "author": {
        "name": "Yuqi Qiao",
        "email": "19606363088@163.com",
        "time": "Sat Jun 13 19:19:57 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 19:19:57 2026 +0800"
      },
      "message": "refactor(getty): remove legacy config dependency from remoting/getty (#3401)\n\n* refactor(getty): remove legacy config dependency from remoting/getty\n\nReplace all config.Get*() calls in initClient and initServer with URL\nattribute reads, following the pattern already used by triple/grpc/dubbo3\nprotocols. The URL attributes (ProtocolConfigKey, TLSConfigKey,\nApplicationKey) are already populated by callers in server/action.go\nand client/action.go, so the legacy config fallback path is redundant.\n\nChanges:\n- getty_client.go: replace config.GetApplicationConfig() / config.GetRootConfig().Protocols / config.GetRootConfig().TLSConfig with url.GetAttribute() reads. Collapse two redundant TLS blocks into one, fixing a copy-paste bug where srvConf was used instead of clientConf. Add IsClientTLSValid validation that was missing in the legacy TLS path.\n- getty_server.go: same config → URL attribute migration.\n- Imports: remove dubbo.apache.org/dubbo-go/v3/config and dubbo.apache.org/dubbo-go/v3, add common/config for EnsureApplicationAttribute.\n- Update stale comments referencing rootConfig.\n\n* refactor(getty): simplify protocol guard by removing ineffective GetParam check\n\nThe protocol name is stored in url.Protocol field, not in URL params.\nGetParam(constant.ProtocolKey) always returns empty string in normal\nflow, making the outer condition a no-op. Replace the nested check\nwith a direct url.GetAttribute(ProtocolConfigKey) guard.\n\n* refactor(getty): merge redundant protocol guard and retrieval\n\nThe guard and the subsequent GetAttribute call both read the same\nProtocolConfigKey attribute. Since the guard already verified existence\nand returned on miss, the second GetAttribute\u0027s !ok branch was dead\ncode. Merge into a single read block.\n\n* refactor(getty): merge type assertion and TLS validity check into single if statement\n\n* fix(getty): fail-secure on TLSConfigKey type assertion failure\n\nWhen TLSConfigKey is present but not of type *global.TLSConfig, log an\nerror and return instead of silently skipping TLS initialization.\nThis prevents misconfigured TLS from being silently downgraded to\nplaintext — consistent with how other protocols (gRPC, triple) handle\nthe same scenario.\n\nAlso add TestInitClientTLS and TestInitServerTLS to cover:\n- valid TLS config → SSLEnabled/TLSBuilder set\n- invalid TLS config → TLS remains disabled\n- wrong TLSConfigKey type → error logged, early return"
    },
    {
      "commit": "a7b6ee632a2d2e4c908cd5c10434d062c5040fe8",
      "tree": "6965411f43f490662dbf1bb2ae9499b4c88b8561",
      "parents": [
        "f7f350cfe4fbcfe35d609306a48b4f72de5b923d"
      ],
      "author": {
        "name": "wm_03",
        "email": "3134058368@qq.com",
        "time": "Sat Jun 13 14:25:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 14:25:15 2026 +0800"
      },
      "message": "perf(common): optimize URL.String() locking and string building (#3404)"
    },
    {
      "commit": "f7f350cfe4fbcfe35d609306a48b4f72de5b923d",
      "tree": "62d7f34ea952c7b27e1661dc0f3fa88362ba7493",
      "parents": [
        "1ce8314a06eb9a51c3d9befc5878e23dd15b62e7"
      ],
      "author": {
        "name": "ヴァニラシ",
        "email": "2755364178@qq.com",
        "time": "Sat Jun 13 13:49:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 13:49:54 2026 +0800"
      },
      "message": "perf(common): reduce URL CloneWithFilter and MergeURL params copying (#3403)"
    },
    {
      "commit": "1ce8314a06eb9a51c3d9befc5878e23dd15b62e7",
      "tree": "785fa96df66acfb32300cf69ae9bb1e535779ef0",
      "parents": [
        "5774b3d4e52bf0a0ff70e9315ce5bd91d00debd4"
      ],
      "author": {
        "name": "wm_03",
        "email": "3134058368@qq.com",
        "time": "Fri Jun 12 11:28:45 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 12 11:28:45 2026 +0800"
      },
      "message": "Feat: add benchmarks for common.URL (#3399)\n\n* test: add benchmarks for common.URL.\n\n* test: keep full identity params across URL benchmark tiers\n\n* test: add URL filter benchmarks with nested sub-URLs"
    },
    {
      "commit": "5774b3d4e52bf0a0ff70e9315ce5bd91d00debd4",
      "tree": "97ae079e13fd7d961465a98dd99950951272d49f",
      "parents": [
        "e1031b70dba9d1ac0407376f6b7d442ef31f79c9"
      ],
      "author": {
        "name": "Aether",
        "email": "98370028+Aetherance@users.noreply.github.com",
        "time": "Fri Jun 12 11:26:40 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 12 11:26:40 2026 +0800"
      },
      "message": "fix(metadata): preserve application tag in metadata info (#3400)"
    },
    {
      "commit": "e1031b70dba9d1ac0407376f6b7d442ef31f79c9",
      "tree": "e1a5323314782f958e462fc741604aa4ea64192f",
      "parents": [
        "c26a24ce8c93f38047506f3b0c072bbd7ddf64ca"
      ],
      "author": {
        "name": "Yuqi Qiao",
        "email": "19606363088@163.com",
        "time": "Fri Jun 12 09:39:29 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 12 09:39:29 2026 +0800"
      },
      "message": "Feat/revision canonical metadata (#3370)\n\n* feat(metadata): add canonical revision calculation for MetadataInfo\nAdd three methods to replace CRC32-based revision with MD5 over\ndeterministic ServiceInfo serialization, aligning with Java dubbo\u0027s\nMetadataInfo.calAndGetRevision().\n- ServiceInfo.toDescString(): deterministic string representation\n  in format (name|group|version|protocol|port|path|params|methods),\n  with sorted params/methods keys for stable output.\n- CalRevision(app, services): computes MD5 hex digest from app name\n  concatenated with sorted ServiceInfo.toDescString() outputs.\n  Returns 0 for empty services (matches Java EMPTY_REVISION).\n- MetadataInfo.CalAndGetRevision(): updates info.Revision in-place.\nThis replaces the coarse app+path+version+port+method CRC32 approach\nin resolveRevision, ensuring group/protocol/params changes are captured\nand revision is strongly bound to the serialized MetadataInfo content.\n\n* refactor(revision): replace CRC32 revision with canonical MD5-based calculation\n\nRefactor resolveRevision to derive revision from canonical ServiceInfo\nobjects rather than raw URLs, aligning with Java dubbo\u0027s\nMetadataInfo.calAndGetRevision().\n\nChanges in service_revision_customizer.go:\n- resolveRevision now converts URLs to ServiceInfo via NewServiceInfoWithURL,\n  groups by MatchKey, and delegates to info.CalRevision (MD5 over sorted\n  toDescString) instead of CRC32-summing app+path+version+port+method.\n- Customizers now source URLs from instance.GetServiceMetadata() rather\n  than the global GetMetadataService(), so each instance\u0027s revision is\n  scoped to its own MetadataInfo. This fixes cross-test state leakage.\n\nChanges in service_revision_customizer_test.go (new, 10 cases):\n- Group / protocol / params / methods / version change triggers revision change\n- Deterministic: same input always produces same revision\n- Empty URL list returns 0\n- Ordering-independent: URL insertion order and param key order do not\n  affect revision\n- Non-IncludeKeys params are ignored\n\n* fix: remove useless assertion leftover from debugging\n\n* fix(metadata): replace MD5 with SHA-512 in revision calculation\n\nSwitch the hash algorithm used in CalRevision from MD5 (32 hex chars)\nto SHA-512 (128 hex chars) for stronger collision resistance.\n\n* fix(metadata): exclude EnvironmentKey from ServiceInfo IncludeKeys\n\nEnvironment is instance-level routing metadata (per the consumer-side\ncomment in service_instances_changed_listener_impl.go). The consumer\nalways overrides it from the current instance metadata, regardless of\nwhat is cached by revision. Including it in IncludeKeys caused revision\nto change between instances with different environment tags, producing\nspurious revision updates with no routing impact.\n\n* chore:delete useless comments\n\n* chore: go fmt\n\n* refactor(metadata): use incremental hash and add CalAndGetRevision test\n\n* refactor(metadata): remove unused CalAndGetRevision method\n\nNo callers in production code. Go\u0027s MetadataInfo.Revision is set\nexternally by the registry/customizer path, unlike Java where\ncalAndGetRevision() manages the revision internally. CalRevision\nremains as the public API for revision calculation.\n\n* chore: retrigger CI"
    },
    {
      "commit": "c26a24ce8c93f38047506f3b0c072bbd7ddf64ca",
      "tree": "c7956185a33ea14be4fac34ab5280a03091532ef",
      "parents": [
        "d44bc18940bdc9ba38c739af5d363dac5547efd7"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Thu Jun 11 17:37:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 11 17:37:33 2026 +0800"
      },
      "message": "[doc] update readme farmework pic (#3358)\n\n* Add files via upload\n\n* Add files via upload\n\n* Add files via upload"
    },
    {
      "commit": "d44bc18940bdc9ba38c739af5d363dac5547efd7",
      "tree": "b28bf5cb002080bd7de2d9637ac9a39efe7323b3",
      "parents": [
        "ab00bd40810a944593738270838e8273a44bcb56"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Thu Jun 11 17:37:13 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 11 17:37:13 2026 +0800"
      },
      "message": "[FEAT] delete synthesizer logic (#3360)\n\n* delete synthesizer logic\n\n* Potential fix for pull request finding\n\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e\n\n---------\n\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "ab00bd40810a944593738270838e8273a44bcb56",
      "tree": "9266d9fbf9b7298855f268dbc4742e23b387e9ad",
      "parents": [
        "fc7f14f35369350e8d319fe9bbd6deaa4b0d259c"
      ],
      "author": {
        "name": "Aether",
        "email": "98370028+Aetherance@users.noreply.github.com",
        "time": "Wed Jun 10 21:36:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 10 21:36:58 2026 +0800"
      },
      "message": "feat(router): add router chain snapshot cache (#3305)\n\n* feat(router): add invoker-snapshot cache for Poolable route\n\nIntroduce routerCache on RouterChain, rebuilt in SetInvokers. Add FindAddrPoolWithInvokers to atomically read snapshot and pool.\n\n* test(router): add unit tests for tag router bitmap cache path\n\n* test(router): add benchmarks for tag router snapshot cache\n\n* fix: strengthen cache invalidation checks to avoid wrong invoker selection\n\n* fix(router): make FindAddrPool return pool and invokers atomically\n\n* fix(router): tag router failover should return untagged providers only\n\n* docs: add comment explaining cache only works when TagRouter is first in chain\n\n* fix: use atomic.Value for TagRouter.cache to prevent data race\n\n* fix: add defensive check and TODO comment for TagRouter cache\n\n* chore: use roaring.Iterator to avoid intermediate allocation in collectInvokers\n\n* chore: enable memory allocation reporting in tag router benchmarks\n\n* chore: extract bitmap key prefixes to constants for Poolable routers\n\n* chore: remove unnecessary copy in FindAddrPool\n\n* fix(router): incorrect tag routing and regex overhead for match field with non-indexed keys\n\n* refactor(router): split tag router code into router.go, cache.go, and match.go\n\n* fix(router): guard tag router cache path with chain snapshot generation\n\n* fix router cache injection for added routers"
    },
    {
      "commit": "fc7f14f35369350e8d319fe9bbd6deaa4b0d259c",
      "tree": "98ca6966587ec1baaff2c6844bac5c8260652d9a",
      "parents": [
        "cdf6f2f8b5b5b1ece181540002c4b12730dcea60"
      ],
      "author": {
        "name": "Nene7ko_",
        "email": "141395478+XnLemon@users.noreply.github.com",
        "time": "Wed Jun 10 12:58:29 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 10 12:58:29 2026 +0800"
      },
      "message": "feat(metadata): Clarify metadata report selection for multi-registry and multi-instance scenarios (#3369)\n\n* fix(metadata): make GetMetadataReport() deterministic in multi-registry setup\n\n* fix(metadata): Remove() fans out to all reports, consistent with Map()\n\n* fix(metadata): thread registryId through GetMetadataFromMetadataReport call chain\n\n* fix(metadata): scope revision calculation to per-registry services, thread registryId through createInstance\n\n* fix(metadata): GetMetadataReportByRegistry returns nil for unknown registryId instead of silently falling back to wrong registry\n\nWhen a caller provides a specific non-empty registryId that has no\nregistered report, the previous implementation silently fell back to\nGetMetadataReport() and returned an arbitrary report from a different\nregistry. This undermined the per-registry scoping added in the earlier\ncommits: metadata for registry A could be fetched from registry B\u0027s\nreport without any indication.\n\nFix: return nil (with a Warnf log) when a specific registryId is not\nfound. The existing nil-guard in GetMetadataFromMetadataReport (client.go)\nalready surfaces this as an error to the caller, which is the correct\nbehaviour.\n\nThe empty-string path is unchanged: it still delegates to\nGetMetadataReport() because callers that pass \"\" have no registry\ncontext and should receive the stable default.\n\nAlso expose ClearMetadataReportInstances() to allow cross-package test\nisolation of the package-level instances map.\n\n* fix(metadata): ServiceNameMapping.Remove collects all errors instead of returning only the last one\n\nThe previous implementation used a lastErr variable that was overwritten\non each iteration. If the first report failed and the second succeeded,\nthe error was silently discarded and the caller saw no error despite a\npartial failure — leaving a stale mapping in the first registry.\n\nFix: collect all errors with errors.Join so the caller receives the full\nfailure picture. The loop continues past individual failures (best-effort\nfan-out) so a transient error in one registry does not prevent removal\nfrom the others.\n\nAdd a comment explaining the intentional behavioural difference from\nMap(), which is fail-fast: Map stops at the first report failure, while\nRemove continues and collects all errors so every reachable registry gets\nthe removal attempt.\n\n* test: expand coverage for per-registry metadata report selection\n\nThree gaps identified in PR review, all addressed:\n\n1. metadata/client_test.go — rewrite TestGetMetadataFromMetadataReport\n   - Add sub-test: specific registryId routes to its own report (not default)\n   - Add sub-test: unknown registryId returns error, not silent wrong-registry result\n   - Each sub-test now resets instances independently to prevent state leakage\n\n2. registry/servicediscovery/customizer/service_revision_customizer_test.go\n   - Add TestExportedRevisionMissingRegistryIdYieldsZero: instance with no\n     RegistryIdKey gets revision \"0\" and does not borrow another registry\u0027s\n     service list\n   - Add TestSubscribedRevisionMissingRegistryIdYieldsZero: same for subscribed\n   - Add t.Cleanup(ClearMetadataReportInstances) + unique registry-id prefixes\n     to all four tests to prevent cross-test global map pollution\n\n3. registry/servicediscovery/service_instances_changed_listener_impl_test.go\n   - Add TestListenerUsesRegistryIdToFetchRemoteMetadata: creates a listener\n     with registryId\u003d\"remote-reg-test\", registers a mock MetadataReport under\n     that id, triggers OnEvent with a RemoteMetadataStorageType instance, and\n     asserts via mock.AssertExpectations that the correct per-registry report\n     was called — end-to-end proof that registryId threads from\n     NewServiceInstancesChangedListener through to GetMetadataFromMetadataReport\n\n* chore: translate Chinese comments to English, remove UTF-8 BOM\n\n- metadata/report_instance_test.go: translate inline comments and\n  testify assertion messages in TestGetMetadataReportIsDeterministic\n  from Chinese to English, consistent with the rest of the file\n\n- registry/servicediscovery/customizer/service_revision_customizer.go:\n  translate Customize doc-comments for both exported and subscribed\n  customizers from Chinese to English\n\n- registry/servicediscovery/service_instances_changed_listener_impl_test.go:\n  strip the UTF-8 BOM (EF BB BF) that was introduced at line 1;\n  Go toolchain accepts BOMs but they are not idiomatic and cause\n  spurious diffs in some editors and CI tools\n\n* style(metadata): fix import formatting\n\n* fix(registry): upgrade missing-registryId log from Warn to Error with accurate consequence\n\nThe previous Warnf said \u0027revision will be empty\u0027, which is wrong on two\ncounts: the actual computed revision is \"0\" (not empty), and revision\n\"0\" causes OnEvent to silently skip the instance entirely, making it\npermanently invisible to all consumers.\n\nUpgrade to Errorf and describe the actual outcome so operators can\ndiagnose misconfigurations immediately. Applies to both exported and\nsubscribed revision customizers.\n\n* fix(registry): scope metaCache key to (registryId, revision) to prevent cross-registry metadata poisoning\n\nThe cache in GetMetadataInfo was keyed by revision string only. In a\nmulti-registry setup, if two registries happen to produce the same\nrevision value (e.g. identical service sets yielding the same CRC, or\ntest fixtures using literal revision strings), the second registry\u0027s\nlistener would get a cache hit and return MetadataInfo fetched via a\ndifferent registry\u0027s report — silently serving wrong endpoints with no\nerror surfaced.\n\nFix: use registryId+\":\"+revision as the cache key for both Get and Set,\nso each registry\u0027s metadata is cached independently.\n\nUpdate all test helpers and direct metaCache.Set/Delete calls to use\nthe same composite key (with constant.DefaultKey as the registryId for\nall existing single-registry test listeners).\n\n* docs(registry): restore TODO for multi-instance metadata service URL alignment\n\nThe previous commit removed the TODO without fixing the underlying issue.\nGetMetadataService() still returns a global singleton, so all instances\nacross registries receive the same metadata service URL regardless of\nwhich registry they belong to.\n\nRestore the TODO with a more detailed explanation so the gap is visible\nto future contributors. The fix requires per-registry MetadataService\nsupport and is out of scope for this PR.\n\n* Revert \"docs(registry): restore TODO for multi-instance metadata service URL alignment\"\n\nThis reverts commit 5d7bcc6cf69f6d05646c4e61beda666fc31ad4eb.\n\n* style(metadata): fix import formatting\n\n* fix(debug) : fix review problems\n\n* style(metadata): fix format issue \u0026\u0026 revert some changes\n\n* fix(metadata): update tests and comment to match default fallback in GetMetadataReportByRegistry\n\nGetMetadataReportByRegistry intentionally falls back to the \u0027default\u0027\nreport when a specific registryId is not found. This supports standalone\nmetadata-report configs registered under \u0027default\u0027 being used by named\nregistries (e.g. nacos, zk). Update tests and doc comment to reflect\nthis behavior instead of the old \u0027return nil for unknown id\u0027 contract.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n\n* fix: address review comments on clarify-metadata-report-selection\n\n- fix(registry): unify registryId default to constant.DefaultKey before\n  GetMetadataInfo lookup in RegisterService, eliminating empty-string\n  fallback mismatch and redundant GetParam calls\n- fix(metadata): scope metaCache key to app:registryId:revision to\n  prevent cross-registry cache collisions\n- fix(metadata/mapping): bind MappingListener to deterministic primary\n  report via GetMetadataReport() instead of non-deterministic i\u003d\u003d0\n- fix(metadata): include registryId in GetMetadataFromMetadataReport\n  error message for easier misconfiguration diagnosis\n- test: add t.Cleanup to remove AddService/AddSubscribeURL entries and\n  prevent global state leakage between tests\n- docs: restore TODO comment explaining GetMetadataService() singleton\n  limitation in multi-registry metadata service URL alignment\n\n* fix: fix test isolation and cache key format after review changes\n\n- fix(test): update metaCache keys in service_instances_changed_listener_impl_test\n  to match new app:registryId:revision format\n- test: use t.Name()+UnixNano as regID in service_discovery_registry_test\n  to prevent cross-test global state pollution without expanding production API\n\n---------\n\nCo-authored-by: xnlemon \u003cxianingawa@gmail.com\u003e\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "cdf6f2f8b5b5b1ece181540002c4b12730dcea60",
      "tree": "114fe489fd28237ef6518e4fa95581164d753211",
      "parents": [
        "60dfab6c5476161ef8868247b3682798866bca61"
      ],
      "author": {
        "name": "Yuxuan Lv",
        "email": "3656828039@qq.com",
        "time": "Wed Jun 10 09:18:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 10 09:18:03 2026 +0800"
      },
      "message": "feat(metadata): strengthen service-app mapping consistency, retry and… (#3373)\n\n* feat(metadata): strengthen service-app mapping consistency, retry and dedup (#3354)\n\nMake interface-to-app mapping registration safe under concurrent providers and\ngive it a proper retry policy.\n\n- Optimistic concurrency across all backends so concurrent appends no longer\n  clobber each other: etcd (GetValAndRev + UpdateWithRev), zookeeper (versioned\n  SetContent), nacos (CasMd5). Each backend wraps its native conflict\n  (ErrCompareFail / ErrBadVersion / ErrNodeExists / nacos publish failure) into\n  the shared report.ErrMappingCASConflict sentinel via %w.\n- Graded retry: registerWithRetry retries only CAS conflicts (errors.Is) with\n  exponential backoff + jitter, and returns permanent errors immediately\n  instead of burning the whole retry budget.\n- Extract shared logic: report.MergeServiceAppMapping (whole-element dedup,\n  fixing the strings.Contains substring false positive and the leading-comma\n  bug on empty values) and report.DecodeServiceAppNames (skips empty elements).\n- Listener cleanup: zookeeper removal via CacheListener.RemoveKeyListeners;\n  etcd documents the listener as unsupported instead of silently succeeding.\n- Tests: helper unit tests plus a concurrency test that reproduces the\n  lost-update bug and proves CAS preserves every writer (200 writers /\n  20 readers, passes under -race).\n\nKnown nacos-only limitation (documented in code): CasMd5 is an optimistic\nUPDATE and cannot guard the first INSERT, so the initial concurrent\nregistration of a brand-new interface can still race. etcd and zookeeper are\nnot affected.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e\n\n* fix(metadata): address review feedback on mapping consistency (#3354)\n\n- nacos: stop swallowing the getConfig read error. On a failed read the old\n  value was treated as empty, so registration would publish only the current\n  app and overwrite an existing set (e.g. appA,appB -\u003e appC). Return the error\n  instead so an existing mapping is never clobbered. A genuinely absent config\n  still returns (\"\", nil) and takes the first-write path.\n- zookeeper: CacheListener.DataChange now builds the set via\n  report.DecodeServiceAppNames, so mapping change events no longer surface\n  empty app names from legacy/malformed comma-separated values (\",app\",\n  \"app,,other\"). Added a listener test covering this.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e\n\n* fix(metadata): treat nacos \"config data not exist\" as empty in mapping registration\n\nThe previous commit returned any getConfig error from RegisterServiceAppMapping.\nNacos signals a never-written key with a \"config data not exist\" error (not an\nempty value), so the first registration of a fresh interface failed and the\nprovider panicked on service export (broke the registry/nacos integration test).\n\nOnly treat genuine read failures (network/auth/server) as errors; the not-found\nsignal is handled as an empty old value so the first write can create the key.\nDetection mirrors config_center/nacos\u0027s isConfigNotExistErr.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e\n\n* fix(metadata): drop insecure rand jitter from mapping retry backoff\n\nSonarCloud flagged math/rand as an insecure PRNG. The jitter only spread\nout contending writers and is not worth a crypto/rand dependency, so use\nplain exponential backoff instead.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e\n\n* fix(metadata): suppress SonarCloud weak-hash hotspot on Nacos CAS MD5\n\nThe MD5 in nacos report is the checksum mandated by the Nacos CAS wire\nprotocol (PublishConfig forwards CasMd5 for the server to compare), not a\nsecurity hash, so the algorithm is not ours to change. Mark it NOSONAR\nwith an explanation to clear the quality-gate security hotspot.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "60dfab6c5476161ef8868247b3682798866bca61",
      "tree": "944510ee214ee5afdf2ff664dddd0575bd926db7",
      "parents": [
        "e17b91ce10b2b1d70a208be054aee90ad7814281"
      ],
      "author": {
        "name": "吴杨帆",
        "email": "39647285+leno23@users.noreply.github.com",
        "time": "Wed Jun 10 09:17:09 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 10 09:17:09 2026 +0800"
      },
      "message": "test(triple): allow invalid stream send close errors (#3379)\n\nCo-authored-by: wuyangfan \u003cyangfan.wu@succaiss.com\u003e"
    },
    {
      "commit": "e17b91ce10b2b1d70a208be054aee90ad7814281",
      "tree": "a9e3111deaab07d3f1fdc4e27e5e729d31fbb65e",
      "parents": [
        "f23f29b20e4aba200f8a78b5cd13716a3cc367f0"
      ],
      "author": {
        "name": "hurukawa",
        "email": "61525444+nagisa-kunhah@users.noreply.github.com",
        "time": "Wed Jun 10 09:14:06 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 10 09:14:06 2026 +0800"
      },
      "message": "[Enhancement] remove legacy config package (#3372)\n\n* pr1: remove config.GetRootConfig()、config.GetProviderConfig()、config.GetProviderService()、config.GetShutDown()"
    },
    {
      "commit": "f23f29b20e4aba200f8a78b5cd13716a3cc367f0",
      "tree": "c0737f21b79572c3bbb30e3a1f3d3e496f705a75",
      "parents": [
        "8e96ea3de33a3a8dddbf70f4293cdd6eeca41421"
      ],
      "author": {
        "name": "吴杨帆",
        "email": "39647285+leno23@users.noreply.github.com",
        "time": "Tue Jun 09 17:31:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 17:31:54 2026 +0800"
      },
      "message": "refactor(url): clarify append param API (#3390)\n\n* refactor(url): clarify append param API\n\n* refactor(url): group string parameters\n\n* refactor(url): use SetParam for single-value URL params\n\n---------\n\nCo-authored-by: wuyangfan \u003cyangfan.wu@succaiss.com\u003e"
    }
  ],
  "next": "8e96ea3de33a3a8dddbf70f4293cdd6eeca41421"
}
