)]}'
{
  "log": [
    {
      "commit": "832124aaacf0283445d379e935ff5d73695fa84d",
      "tree": "5fc088f98bf4c87559e4a7dae3a09c244712a52e",
      "parents": [
        "5f54b6a8cc9702abb320aa324784176689878ed0"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Thu Sep 10 10:00:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 10:00:33 2026 +0800"
      },
      "message": "build(deps): bump google.golang.org/grpc from 1.64.1 to 1.83.2 (#3722)\n\nBumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.64.1 to 1.83.2.\n- [Release notes](https://github.com/grpc/grpc-go/releases)\n- [Commits](https://github.com/grpc/grpc-go/compare/v1.64.1...v1.83.2)\n\n---\nupdated-dependencies:\n- dependency-name: google.golang.org/grpc\n  dependency-version: 1.83.2\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": "5f54b6a8cc9702abb320aa324784176689878ed0",
      "tree": "4e221337ddb2cd9e83c411eb816843d32cbc25b3",
      "parents": [
        "17ce297fbf55de96c9d6050d83443b44aa116a82"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Sun Sep 06 17:01:02 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 06 17:01:02 2026 +0800"
      },
      "message": "feat(triple): cut per-message marshal allocations with a pooled MarshalAppend codec path (#3718)\n\n* feat(triple): add marshalAppender optional codec interface\n\nToday the proto codec marshals via proto.Marshal, which always builds a fresh\n[]byte from scratch, so every unary call allocates the whole payload even\nthough the request buffer pool already holds reusable capacity. The marshaler\nshould instead be able to serialize into a caller-provided buffer.\n\nThis commit adds marshalAppender, an optional Codec extension whose\nMarshalAppend serializes the message into a caller-supplied dst slice.\nprotoBinaryCodec implements it by delegating to\nproto.MarshalOptions{}.MarshalAppend, and tripleServerCodecSession implements\nit too, wrapping the generic response before forwarding when needed, so both\nIDL and non-IDL server calls expose the new capability. Codecs without the\nextension (hessian2, json, msgpack, third-party codecs) are untouched and\nkeep their exact previous behavior, so the change is purely additive.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* feat(triple): add pooled marshal pipeline via marshalToPool\n\nAdds marshalToPool, the shared borrow-marshal-adopt dance that the envelope\nwriter and the unary marshaler both need. It borrows a buffer from the pool,\nlets the codec\u0027s MarshalAppend fill its spare capacity, and when MarshalAppend\nhad to grow the backing array, swaps the larger array back into the pooled\nbuffer so the capacity is recycled instead of dropped. On the happy path\nnothing is allocated and the buffer is handed to the caller ready to be\nwrapped or written.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* feat(triple): use marshalAppend fast path in envelope writer\n\nThe envelope writer used to marshal with codec.Marshal and then copy the\nfreshly allocated slice into the outgoing envelope, so every message paid one\nallocation plus an extra copy. It now probes the codec for marshalAppender\nand, when present, runs marshalAndWrite: marshalToPool fills a pooled buffer\nin place and the bytes are wrapped straight into the envelope.\n\nThe previous logic is kept as marshalWithFallback and serves codecs without\nthe extension, so the produced bytes stay identical on both paths.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* feat(triple): add marshalAppend fast path and shared compression tail\n\ntripleUnaryMarshaler.Marshal used to serialize every unary payload with\ncodec.Marshal, which allocates the whole []byte from scratch, and then ran the\ncompression and write tail inline at the end of the function.\n\nMarshal now probes the codec for marshalAppender: capable codecs take the new\nmarshalAndWrite path, which marshals into a pooled buffer via marshalToPool so\nthe common case allocates nothing, while codecs without the extension keep the\nold path. To keep the two paths from ever drifting, the compression tail was\nextracted from Marshal into one shared compressAndWrite that both paths call,\nso the threshold check, pooled gzip, sendMaxBytes enforcement, compression\nheader and final write always behave the same.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): add marshal fast-path A/B benchmarks\n\nAdds A/B benchmarks that run the pooled MarshalAppend fast path against the\nplain codec.Marshal slow path, for both the unary marshaler and the envelope\nwriter, with and without gzip. The fast path is expected to allocate nothing\nper op while the slow-path benches keep measuring the old baseline, so a\nregression in the fast path shows up immediately as an allocation or\nthroughput change in the bench output.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): add regression tests for pooled marshal fast path\n\nAdds nine TestMarshalPerf* regression cases that lock the pooled marshal\nbehavior in place so the fast and slow paths cannot silently diverge.\nWireParity asserts both paths emit byte-identical bodies and headers for every\npayload size, compressed or not; PoolInvariants and LargeBufferDropped check\nthat pooled buffers come back clean and oversized ones are released;\nBackupCodecFallback, TypeGuard and ErrorGuard keep the previous fallback,\ntype-guard and error semantics; CompressionAndMaxBytes and ConcurrentSend\nverify compression, sendMaxBytes and pool safety under concurrency; and\nServerSessionFastPath drives tripleServerCodecSession through the fast path\nend to end.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* style(triple): modernize regression test syntax for CI fmt check\n\n* style(triple): apply modernize and gofmt to marshal perf regression test\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* style(triple): align test comments with repo style and clarify semantics\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): strengthen concurrent marshal regression tests\n\nReplace the concurrent send test\u0027s length-only assertion with per-frame\ncontent verification: each goroutine marshals globally unique messages and\nthe output is decoded frame by frame, so cross-goroutine buffer reuse that\ncorrupts payloads fails even without -race.\n\nAdd a start gate so the shared buffer pool is actually contended, plus a\nfastPathProbeCodec-based test asserting envelopeWriter.Marshal takes the\nMarshalAppend fast path. Clarify that syncBuffer must not be shared by\nconcurrent writers.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n---------\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "17ce297fbf55de96c9d6050d83443b44aa116a82",
      "tree": "f84dfef6e7bf58db44100cdf8d5128bd213ad208",
      "parents": [
        "643ffa3c4f16d4c52684ce5917b92d5a1e369176"
      ],
      "author": {
        "name": "Modo",
        "email": "witty8010@outlook.com",
        "time": "Wed Sep 02 21:23:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 02 21:23:39 2026 +0800"
      },
      "message": "feat(metadata): classify errors and add useful context (#3707)\n\n* feat: classify errors, enrich them with useful context, and add failure-path tests\n\n* fix test"
    },
    {
      "commit": "643ffa3c4f16d4c52684ce5917b92d5a1e369176",
      "tree": "bd66f9b950c85e818b61c69bb295c9a8ff3b06a7",
      "parents": [
        "4da5e9e0a63b0e18377638ff36f7b26e6c04de99",
        "d4b4fbfbcab0e30b9285ceb5d8a73281970a0fa4"
      ],
      "author": {
        "name": "alanxtl",
        "email": "m134679102365478@163.com",
        "time": "Wed Sep 02 20:43:50 2026 +0800"
      },
      "committer": {
        "name": "alanxtl",
        "email": "m134679102365478@163.com",
        "time": "Wed Sep 02 20:43:50 2026 +0800"
      },
      "message": "Merge remote-tracking branch \u0027upstream/develop\u0027\n"
    },
    {
      "commit": "d4b4fbfbcab0e30b9285ceb5d8a73281970a0fa4",
      "tree": "bd66f9b950c85e818b61c69bb295c9a8ff3b06a7",
      "parents": [
        "b7086bd1e5a3254f3220e8ca06d25f337302de21"
      ],
      "author": {
        "name": "xiaobaicai66695",
        "email": "575121043@qq.com",
        "time": "Wed Sep 02 15:07:37 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 02 15:07:37 2026 +0800"
      },
      "message": "refactor: replace golang mock with uber mock (#3699)\n\n* refactor: replace golang mock with uber mock\n\n* test: remove redundant scaffold mock check\n\n* build: remove redundant mock generation target\n\n* ci: retrigger checks"
    },
    {
      "commit": "b7086bd1e5a3254f3220e8ca06d25f337302de21",
      "tree": "667b47404870963259e1955297a372e74c4aecf0",
      "parents": [
        "56889b4982a0fee044335cbb2196a2f9c8cad114"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Wed Sep 02 13:23:56 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 02 13:23:56 2026 +0800"
      },
      "message": "feat(triple): performance optimization for Triple unary hot path (#3706)\n\n* feat(protocol): add unary fast path config switch\n\nAdd the UnaryFastPath toggle so the fast path stays off by default:\n- global: add UnaryFastPath field to TripleConfig (yaml/json/property)\n  and copy it in Clone\n- option: add WithUnaryFastPath client option\n- config chain: propagate through clientConfig and\n  protocolClientParams into NewConn\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* feat(protocol): implement unary fast path for Triple unary RPCs\n\nReplace duplexHTTPCall with a synchronous unaryFastPathCall: no\nio.Pipe, no per-request makeRequest goroutine, pooled buffers,\ndeclared Content-Length, and direct response reading. Select it in\ntripleClient.NewConn when the stream type is unary and the switch is\non.\n\nAlso hoist tri.WithTriple() so HTTP/1.1, HTTP/2 and HTTP/3 all\nexplicitly select the Triple protocol: HTTP/2 (the actual default\ntransport) previously fell back to the gRPC protocol and the fast\npath living on tripleClient.NewConn was unreachable.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): add NewConn routing A/B test for the unary fast path\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): guard the unary fast path against concurrent Send/RequestHeader/CloseRequest races\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): cover unary fast path call behavior including wire format and error handling\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): verify unary fast path body round-trips, Content-Length and buffer reuse\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): add A/B benchmark for unary fast path vs duplex\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* style(triple): apply make fmt to the unary fast path tests\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* feat(triple): enable the unary fast path by default\n\nFlip the UnaryFastPath default from off to on so every Triple unary\ncall runs through unaryFastPathCall (no io.Pipe, no per-request\ngoroutine) unless explicitly opted out:\n- triple_protocol: newClientConfig defaults UnaryFastPath to true, and\n  a new WithoutUnaryFastPath client option lets callers roll back to\n  the duplex (io.Pipe) path\n- global: DefaultTripleConfig sets UnaryFastPath to true, so configs\n  that never mention unary-fast-path inherit the on-by-default behavior\n- protocol/triple: newClientManager explicitly maps the config flag to\n  With/WithoutUnaryFastPath, so an explicit unary-fast-path: false in\n  the config opts back out of the default\n- bench_test: BenchmarkUnaryDuplex pins the control group to the\n  explicit opt-out so it keeps measuring duplexHTTPCall\n\nStreaming calls and the gRPC protocol are unaffected: the fast path\nbranch is still gated on StreamTypeUnary in tripleClient.NewConn, and\ngrpcClient.NewConn never reads the toggle.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* fix(triple): recycle pooled buffer on zero-length fast-path writes\n\nEmpty payloads (Send(nil), an empty protobuf message, or an explicit\nWrite of an empty slice) pulled a buffer out of the pool in Write, but\nmakeRequest switched to http.NoBody for the zero-length body without\nreturning it, leaking one pooled slot plus an allocation per call.\n\nWrite now short-circuits zero-length writes and makeRequest recycles a\nleftover empty buffer before falling back to http.NoBody.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): add regression tests for zero-length fast-path writes\n\nCover the empty-payload pool behavior: zero-length writes leave the\nbody buffer untouched, makeRequest recycles a leftover empty buffer\nbefore falling back to http.NoBody, and an empty protobuf message\ncompletes a unary call end to end.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* fix(triple): restore gRPC as the default wire format for Triple clients\n\nUnconditionally applying WithTriple forced every Triple client onto the\nconnect wire format and broke interop with dubbo-java (415 Unsupported\nMedia Type). Remove the unconditional option so HTTP/2/3 clients go back\nto the default gRPC wire format, and keep WithTriple only on the\nHTTP/1.1 branch, where the connect format is required because HTTP/1.1\nhas no trailer support. The unary fast path stays on by default and\nremains reachable over the connect wire format.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* feat(triple): route gRPC protocol unary calls through the fast path\n\nThe unary fast path was only reachable on the connect (Triple) wire\nformat, so the default gRPC format never took it and the switch had no\neffect on the RPC-layer hot path. Route unary calls through\nunaryFastPathCall in grpcClient.NewConn as well, keeping streaming calls\non duplexHTTPCall. grpcClientConn now stores the unaryClientCall\ninterface instead of a concrete *duplexHTTPCall, and CloseResponse reads\ntrailers through ResponseTrailer(). Update the config and protocol\ncomments that claimed the gRPC wire never reaches the fast path, and\ntidy stale or informal comments in unary_fastpath.go.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): verify fast path routing and public-entry wire signature\n\nFlip the gRPC routing assertion from \"always duplex\" to \"unary routes to\nthe fast path when enabled and to duplex otherwise; streaming calls\nalways use duplex\". Add a regression test that issues a call through the\npublic client entry (clientManager.callUnary, the path reached by\nTripleInvoker.Invoke) and checks the server sees a pre-declared\nContent-Length with the fast path on and -1 when it is explicitly\ndisabled, plus error-path equivalence between the fast path and duplex.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): drive public-entry tests through Refer and TripleInvoker.Invoke\n\nReplace the direct newClientManager/callUnary setup in the unary fast path\npublic-entry tests with the production entry: TripleProtocol.Refer followed\nby TripleInvoker.Invoke with a real invocation, so the tests guard the full\nRefer/Invoker/Invoke dispatch instead of the client manager in isolation.\n\nThe server-side Content-Length capture now excludes the background gRPC\nhealth-check stream, whose streaming body previously clobbered the\nfast-path signature.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* docs(triple): clarify unary fast path scope and caveats\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* fix(triple): keep unary fast path enabled when config omits the toggle\n\nUnaryFastPath was a plain bool, so any TripleConfig built or decoded\nwithout the field silently disabled the fast path even though the\ndefault is on. Change it to *bool: nil means \"not explicitly set\" and\nkeeps the default (enabled); explicit true/false still override. Align\nClone with the *bool deep-copy style used across the global config\nstructs.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): cover unary fast path config toggle states\n\nExercise the *bool three-state semantics end to end through the\nproduction Refer/Invoke entry: nil and explicit true keep the fast path\non, explicit false falls back to duplex, and a config built without the\ntoggle (e.g. only KeepAliveInterval) keeps the default-on behavior.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n---------\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "56889b4982a0fee044335cbb2196a2f9c8cad114",
      "tree": "11cf27b619e2b661a691037c066c191ff89a6129",
      "parents": [
        "130b2a686841f319ee95ff8052e693cfa9731eeb"
      ],
      "author": {
        "name": "DaWesen",
        "email": "3880255095@qq.com",
        "time": "Wed Sep 02 10:09:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 02 10:09:54 2026 +0800"
      },
      "message": "refactor(deps): migrate gost stdlib thin wrappers, uber atomic and pkg/errors to stdlib (#3695)\n\n* refactor: migrate gost stdlib thin wrappers, uber atomic and pkg/errors to stdlib\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e\n\n* fix: satisfy staticcheck ST1005/ST1012 and testifylint after stdlib migration\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e\n\n* test: add regression tests for stdlib migration (timeout, error chain, recover, pagination)\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e\n\n* test: clarify getty request timeout regression test comment\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e\n\n* style: fix gofmt formatting in files touched by stdlib migration\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e\n\n* style: apply repo import grouping and use any instead of interface{}\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e\n\n* fix: address PR review feedback\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e\n\n* fix: silence ST1012 for historical error var names\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e\n\n* fix: restore uber atomic fields, gxpage Pager alias, drop redundant wrappers\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e\n\n* fix: silence ST1023 in external compat test\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e\n\n* fix: silence ST1023/S1021 in external compat test\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e\n\n* revert page wrapper, restore comments, fix perrors migration\n\n* fix: adapt getty test mock to upstream selectSession changes\n\n---------\n\nSigned-off-by: DaWesen \u003c3880255095@qq.com\u003e"
    },
    {
      "commit": "130b2a686841f319ee95ff8052e693cfa9731eeb",
      "tree": "7e09c9705f891bae7925c70ab49b387627dc95b2",
      "parents": [
        "2046d8decbf889e7676be963cdad5e74d1bf66fd"
      ],
      "author": {
        "name": "Xuetao Li",
        "email": "m134679102365478@163.com",
        "time": "Tue Sep 01 17:14:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 01 17:14:39 2026 +0800"
      },
      "message": "fix(getty): fix the getty poll bug described at #3509 (#3592)\n\n* fix 3509\n\n* import format\n\n* fmt\n\n* fix format\n\n* fix comment\n\n* fix comment\n\n* fix comment\n\n* fix race"
    },
    {
      "commit": "2046d8decbf889e7676be963cdad5e74d1bf66fd",
      "tree": "ba5bf00bb7b9c4226ce5d3d622861e0cbb1f9494",
      "parents": [
        "744af790bf08e4c5fa2c7381271b5a72a6981517"
      ],
      "author": {
        "name": "wm_03",
        "email": "3134058368@qq.com",
        "time": "Tue Sep 01 17:13:17 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 01 17:13:17 2026 +0800"
      },
      "message": "Feat: Add ZK config cache (#3612)\n\n* feat: add Zookeeper config cache\n\n* test: cover Zookeeper cache and watch flows\n\n* refactor(zookeeper): bound config cache path locks\n\n* fix(zookeeper): bound config cache entries\n\n* refactor(zookeeper): track watcher ownership\n\n* fix(zookeeper): bound automatic watches\n\n* fix(zookeeper): complete config watch lifecycle\n\n* fix(zookeeper): align listener paths and empty config events\n\n* fix(zookeeper): restore and clean up watches on reconnect\n\n* fix(zookeeper): safely remove expired cache entries\n\n* fix(zookeeper): restore business watches with cache disabled\n\n* fix(zookeeper): release configuration listener wait group\n\n* ci: configure ZooKeeper dependency for tests\n\n* fix(zookeeper): adapt config watches to upstream API\n\n* test(zookeeper): cover session-aware watch registration\n\n* test(zookeeper): cover retired watch lifecycle\n\n* fix(zookeeper): restore watches across sessions\n\n* fix(zookeeper): synchronize config watch lifecycle\n\n* fix(zookeeper): synchronize watch ownership and retries\n\n* fix(zookeeper): reject stale watch results\n\n* fix(zookeeper): synchronize listener watch retries\n\n* fix: Add the TTL upper and lower bounds\n\n* annotations: Add relevant annotations for the core concepts"
    },
    {
      "commit": "744af790bf08e4c5fa2c7381271b5a72a6981517",
      "tree": "264bca2c95632d67a86efa4595acd1fb0ae90457",
      "parents": [
        "4154395f7eefd5810cf4af73d5d76847e866de76"
      ],
      "author": {
        "name": "Oxidaner",
        "email": "80675726+Oxidaner@users.noreply.github.com",
        "time": "Tue Sep 01 17:09:16 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 01 17:09:16 2026 +0800"
      },
      "message": "fix(generic): honor m tag options (#3709)\n\n* fix(generic): honor m tag options\n\nSigned-off-by: Oxidaner \u003c18622412361@163.com\u003e\n\n* fix forma\nt\n\nSigned-off-by: Oxidaner \u003c18622412361@163.com\u003e\n\n* fix(generic): preserve parent class when squashing POJO\n\n* fix(generic): lowercase the first rune, not the first byte\n\ntoUnexport derived an untagged field\u0027s wire key with\nstrings.ToLower(a[:1]) + a[1:], which slices one byte. For a field whose\nfirst rune is multi-byte that splits the rune, so an exported field named\nwith a non-ASCII letter generalized to a key containing an invalid UTF-8\nfragment — and realization, matching case-insensitively against the intact\nGo name, could not find it again.\n\nDecoding the rune first keeps ASCII names byte-identical and makes the\nnon-ASCII case round-trip.\n\n* style(generic): modernize unicode test type lookup\n\n---------\n\nSigned-off-by: Oxidaner \u003c18622412361@163.com\u003e"
    },
    {
      "commit": "4154395f7eefd5810cf4af73d5d76847e866de76",
      "tree": "5d1b5382a2688f6206ec67fd3528ddfa37db7ea3",
      "parents": [
        "e3802a892bb91324b36ffe30bfe07271fd4a377a"
      ],
      "author": {
        "name": "CAICAII",
        "email": "3360776475@qq.com",
        "time": "Tue Sep 01 10:13:16 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 01 10:13:16 2026 +0800"
      },
      "message": "feat(triple): add HTTP/3 receive window config (#3704)\n\n* feat(triple): add HTTP/3 receive window config\n\nSigned-off-by: CAICAIIs \u003c3360776475@qq.com\u003e\n\n* fix(triple): validate HTTP/3 receive window config\n\nSigned-off-by: CAICAIIs \u003c3360776475@qq.com\u003e\n\n* fix(triple): format HTTP/3 receive window test imports\n\n---------\n\nSigned-off-by: CAICAIIs \u003c3360776475@qq.com\u003e"
    },
    {
      "commit": "e3802a892bb91324b36ffe30bfe07271fd4a377a",
      "tree": "f2f757bf28edc12ae7e45b417e5eb160ad498bf4",
      "parents": [
        "672933f0270675182a71925ff546a8f7cc4da239"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Tue Sep 01 10:11:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 01 10:11:28 2026 +0800"
      },
      "message": "fix(filter): make access log goroutine shutdown test race-safe (#3713)\n\n* fix(filter): make access log goroutine shutdown test race-safe\n\nReplace the timing-sensitive runtime.NumGoroutine() assertions with\ndeterministic started/done lifecycle signals on Filter, and wait on\nthem in TestAccessLogFilterGoroutineShutdown so it no longer flakes\nunder -race.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(filter): track processLogs goroutine by ID for race-safe shutdown\n\nRework TestAccessLogFilterGoroutineShutdown to drop the process-wide\ngoroutine count, which is timing-sensitive under -race: a leftover\ngoroutine from a previous test exiting concurrently with a newly\nstarted one cancels out the count change. The test walks runtime.Stack\nto find the processLogs goroutine started by the real newFilter,\ncaptures its ID, and asserts that exact goroutine exits after Shutdown.\nAlso reverts the started/done channel fields previously added to Filter,\nkeeping production code untouched.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* style(filter): use bytes.SplitSeq to satisfy the CI fmt check\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n---------\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "672933f0270675182a71925ff546a8f7cc4da239",
      "tree": "967193cf9777cdc42f77521d09032f5def3ffe76",
      "parents": [
        "76de7fe385c09a7a25c9e4706b51f4375ef5ce23"
      ],
      "author": {
        "name": "eye-gu",
        "email": "eyegu@apache.org",
        "time": "Sun Aug 30 03:45:59 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 30 03:45:59 2026 +0800"
      },
      "message": "fix(dubbo): accept bare-ms timeout attachment so failover retries keep the configured timeout (#3714)\n\n* fix(dubbo): accept bare-ms timeout attachment so failover retries keep the configured timeout\n\n* fix(dubbo): guard bare-ms timeout attachment against time.Duration overflow"
    },
    {
      "commit": "76de7fe385c09a7a25c9e4706b51f4375ef5ce23",
      "tree": "5c778532705b1a4e8b9e9810b4fafe99740d93ff",
      "parents": [
        "d9557d57219a3fcdcbabb6191c16ce97ac2410f3"
      ],
      "author": {
        "name": "Gerard",
        "email": "gigabytewiki@163.com",
        "time": "Tue Aug 25 19:42:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 25 19:42:54 2026 +0800"
      },
      "message": "chore: upgrade logging dependencies (logrus, zap, go-isatty) (#3703)\n\nUpgrade go.uber.org/zap v1.21.0 -\u003e v1.28.0, github.com/sirupsen/logrus\nv1.9.4 -\u003e v1.10.1, and github.com/mattn/go-isatty v0.0.16 -\u003e v0.0.24.\nThis is a minimal safe subset of issue #3692. High-risk deps\n(gopsutil/v3, jsonparser, etcd) are left for follow-up PRs.\n\nFixes: #3692\n\nSigned-off-by: GerardGao \u003c213731635+GerardGao@users.noreply.github.com\u003e\nCo-authored-by: GerardGao \u003c213731635+GerardGao@users.noreply.github.com\u003e"
    },
    {
      "commit": "d9557d57219a3fcdcbabb6191c16ce97ac2410f3",
      "tree": "16a95117748a6ee5cb11f957153da6963575a181",
      "parents": [
        "8e1e721dfb5fd273f331185c3460f107934f11ed"
      ],
      "author": {
        "name": "Modo",
        "email": "witty8010@outlook.com",
        "time": "Tue Aug 25 10:25:20 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 25 10:25:20 2026 +0800"
      },
      "message": "feat(metadata): expose observability for metadata source, storage typ… (#3685)\n\n* feat(metadata): expose observability for metadata source, storage type, revision, and cache hit/miss along the metadata path\n\n* modified HELP information\n\n* fix ci\n\n* feat: restore metadata fetch metrics after listener refactor\n\n* feat: add logs for cache hit/miss"
    },
    {
      "commit": "8e1e721dfb5fd273f331185c3460f107934f11ed",
      "tree": "abc2f30cee3f6995ae54e4ef5d8bdacf22bdb38b",
      "parents": [
        "422a66ada0b99b6e3adca22f8d86c8ea6a92983c"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Tue Aug 25 10:14:25 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 25 10:14:25 2026 +0800"
      },
      "message": "build(deps): bump github.com/gorilla/websocket from 1.4.2 to 1.5.3 (#3702)\n\nBumps [github.com/gorilla/websocket](https://github.com/gorilla/websocket) from 1.4.2 to 1.5.3.\n- [Release notes](https://github.com/gorilla/websocket/releases)\n- [Commits](https://github.com/gorilla/websocket/compare/v1.4.2...v1.5.3)\n\n---\nupdated-dependencies:\n- dependency-name: github.com/gorilla/websocket\n  dependency-version: 1.5.3\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: alexstocks \u003calexstocks@foxmail.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e\nCo-authored-by: Xuetao Li \u003cm134679102365478@163.com\u003e"
    },
    {
      "commit": "422a66ada0b99b6e3adca22f8d86c8ea6a92983c",
      "tree": "c7760edbc188e70a23d3660ee61a0c19d3c565f7",
      "parents": [
        "c6a4a61d7e18fd73d97da0def05d4dd72d827429"
      ],
      "author": {
        "name": "hysu",
        "email": "dame3902@gmail.com",
        "time": "Mon Aug 24 00:03:20 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 24 15:03:20 2026 +0800"
      },
      "message": "fix(polaris): resolve nil pointer panic on startup and route miss (#3303) (#3697)\n\n* fix(polaris): resolve nil pointer panic on startup and route miss (#3303)\n\n- Disable route filtering during directory initialization.\n- Fall back to all instances in polarisRouter.Route on route miss.\n- Add nil guards to failfast/failsafe/failback cluster\n\nSigned-off-by: hysu \u003cdame3902@gmail.com\u003e\n\n* refactor: replace perrors with fmt.Errorf per code review\n\nSigned-off-by: hysu \u003cdame3902@gmail.com\u003e\n\n* refactor: replace fmt.Errorf with errors.New\n\nSigned-off-by: hysu \u003cdame3902@gmail.com\u003e\n\n---------\n\nSigned-off-by: hysu \u003cdame3902@gmail.com\u003e"
    },
    {
      "commit": "c6a4a61d7e18fd73d97da0def05d4dd72d827429",
      "tree": "40a5fb52060fe0f2bd8871de5dd00a4860a07063",
      "parents": [
        "c150ca471ffe4003f76079e39bd2fdc55db1e37b"
      ],
      "author": {
        "name": "xiaobaicai66695",
        "email": "575121043@qq.com",
        "time": "Mon Aug 24 14:50:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 24 14:50:38 2026 +0800"
      },
      "message": "refactor: replace vault jsonutil usage (#3696)\n\n* refactor: replace vault jsonutil usage\n\n* refactor: improve JSON utility implementation\n\n* test: satisfy JSON utility checks\n\n* test: cover etcd service update events"
    },
    {
      "commit": "4da5e9e0a63b0e18377638ff36f7b26e6c04de99",
      "tree": "e3ca04495ef49f346e8f5fc298b8a68c4b10c60f",
      "parents": [
        "f0ef1490bfce53ac2f7acb0aa586cf46499b9fb0",
        "c150ca471ffe4003f76079e39bd2fdc55db1e37b"
      ],
      "author": {
        "name": "alexstocks",
        "email": "alexstocks@foxmail.com",
        "time": "Mon Aug 24 14:38:14 2026 +0800"
      },
      "committer": {
        "name": "alexstocks",
        "email": "alexstocks@foxmail.com",
        "time": "Mon Aug 24 14:38:14 2026 +0800"
      },
      "message": "Merge branch \u0027develop\u0027 of https://github.com/apache/dubbo-go into develop\n"
    },
    {
      "commit": "c150ca471ffe4003f76079e39bd2fdc55db1e37b",
      "tree": "e3ca04495ef49f346e8f5fc298b8a68c4b10c60f",
      "parents": [
        "a9e32b5ec36ef1e34fd44b4d3c3bc807bbb71971"
      ],
      "author": {
        "name": "超級の新人",
        "email": "chaoji_xinren@163.com",
        "time": "Sun Aug 23 21:47:53 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 23 21:47:53 2026 +0800"
      },
      "message": "perf(remoting): share one backend client per ZK/Nacos cluster across registry, config-center and metadata-report (#3573) (#3635)\n\nThe gost client pool is keyed by name, but each role passed a different\nkey, so a single application held three sessions to the same cluster:\n\n- zookeeper: metadata-report used a fixed name with share\u003dfalse while\n  registry/config-center already share via url.Location; align it to\n  the same pool key and enable sharing (3 sessions -\u003e 1).\n- nacos: all roles set share\u003dtrue but role-prefixed client names never\n  matched; derive the pool key from the connection identity (endpoint,\n  address, namespace, credentials) instead (3 clients -\u003e 2, naming and\n  config clients are distinct SDK types).\n\netcd is left as a follow-up: gost has no pool for it and callers hold\nthe concrete client type.\n\nSigned-off-by: chaojixinren \u003cchaoji_xinren@163.com\u003e"
    },
    {
      "commit": "a9e32b5ec36ef1e34fd44b4d3c3bc807bbb71971",
      "tree": "17467f17ec1ca7ad864b887b8aa18e7f3def7ef6",
      "parents": [
        "630e2839fe8cf043ab8640a1d652e427c824997f"
      ],
      "author": {
        "name": "Yuxuan Lv",
        "email": "3656828039@qq.com",
        "time": "Sun Aug 23 11:48:11 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 23 11:48:11 2026 +0800"
      },
      "message": "deps(zookeeper): migrate from dubbogo/go-zookeeper fork to upstream go-zookeeper/zk (#3459) (#3690)\n\n* deps(zookeeper): migrate from dubbogo/go-zookeeper fork to upstream go-zookeeper/zk\n\nReplaces the forked github.com/dubbogo/go-zookeeper/zk dependency with\nthe upstream github.com/go-zookeeper/zk v1.0.4 across remoting/zookeeper,\nregistry/zookeeper, config_center/zookeeper and metadata/report/zookeeper,\nper apache/dubbo-go#3459. All call sites only used error variables,\nEvent/State constants and Stat, which are unchanged upstream, so this is\na mechanical import swap everywhere except config_center/zookeeper/impl_test.go,\nwhich is adjusted for gost\u0027s new NewMockZookeeperClient signature (3 return\nvalues instead of 4, no more embedded *zk.TestCluster since upstream\nzk has no importable TestCluster API) and now skips cleanly when no real\nzookeeper is reachable at ZK_ADDR/127.0.0.1:2181.\n\nTwo temporary items, both to be undone once dubbogo/gost publishes a\nrelease with the upstream zk dependency:\n- go.mod carries a local `replace github.com/dubbogo/gost \u003d\u003e ../gost`\n  pointing at the not-yet-released gost feat/upstream-zk branch, marked\n  with a TODO(#3459).\n- go.sum therefore no longer carries checksum lines for dubbogo/gost,\n  since a locally-replaced module isn\u0027t verified via go.sum.\n\n`go mod tidy` also picked up two unrelated indirect version bumps that\nwere already the correct MVS-selected versions but had drifted in the\ncommitted go.mod/go.sum (github.com/buger/jsonparser v1.1.1-\u003ev1.1.2,\nalready required by the published dubbogo/gost v1.14.3; and\ngithub.com/spf13/afero v1.6.0-\u003ev1.9.2, already required by\ngithub.com/envoyproxy/protoc-gen-validate v0.9.1).\n\ntools/dubbogo-cli is intentionally left untouched: it is a separate Go\nmodule pinned to the published dubbo.apache.org/dubbo-go/v3 v3.0.1, so\nits indirect dubbogo/go-zookeeper entry and embedded scaffold templates\ncannot move until a dubbo-go release carries this migration.\n\n* chore(zookeeper): bump temporary gost replace to pick up review fixes\n\nPulls in dubbogo/gost#147 review feedback: run-scoped zookeeper test\nroot, session-establishment wait in NewMockZookeeperClient, and doc\ncomments. The replace directive remains temporary until gost cuts a\nrelease (see TODO in go.mod).\n\n* chore(zookeeper): follow gost review renames\n\ngost review renamed NewMockZookeeperClient to NewZookeeperClientFromEnv\n(it connects to a real zookeeper from ZK_ADDR, not a mock). Update the\ncall sites and bump the temporary gost replace accordingly.\n\n* fix(zookeeper): correct import group ordering after go-zookeeper migration\n\nThe switch from github.com/dubbogo/go-zookeeper to github.com/go-zookeeper/zk\nleft these files\u0027 import groups in the wrong alphabetical order, which\ntools/imports-formatter (run by make check-fmt in CI) flags.\n\n* deps(zookeeper): drop temporary gost fork replace now that #147 is merged\n\ndubbogo/gost#147 (migration off the forked github.com/dubbogo/go-zookeeper\npackage, review-addressed rename of NewMockZookeeperClient to\nNewZookeeperClientFromEnv included) has been merged upstream. Point the\ngost require directly at that merged commit on the official\ngithub.com/dubbogo/gost repo and remove the replace directive that pinned\nit to github.com/NeverENG/gost, which was flagged as a supply-chain risk\nand a reproducible-build hazard for downstream consumers.\n\n* test(zookeeper): address review feedback on migration tests and CI\n\n- Rename TestPublishAndRemoveConfigWithMockZk and TestGetPropertiesWithMockZk\n  (and their skip messages) to drop \"Mock\", since NewZookeeperClientFromEnv\n  connects to a real, externally configured ZooKeeper rather than an\n  in-process mock.\n- Give each test a randomly generated, unique root path instead of the\n  fixed /dubbo/config, and clean it up via t.Cleanup once the test\n  finishes, so runs no longer risk colliding with other data on a shared\n  ZooKeeper server. The cleanup is registered to run before the client is\n  closed, since t.Cleanup callbacks only run after a function\u0027s defers.\n- Fail instead of silently skipping when ZooKeeper is unreachable while\n  running under CI (detected via the CI environment variable), so these\n  migration regression tests can\u0027t pass green without actually exercising\n  the ZooKeeper client; keep skipping outside CI so a developer machine\n  without ZooKeeper isn\u0027t blocked.\n- Add an isolated ZooKeeper service container to the CI unit-test job,\n  with a readiness wait before tests run and ZK_ADDR pointed at it, so the\n  above tests run for real by default instead of skipping in CI.\n\n* test(zookeeper): key the CI fail/skip decision off ZK_ADDR, not a CI heuristic\n\nfailOrSkipZkUnavailable previously decided whether an unreachable\nZooKeeper should fail or skip the test by checking the generic CI\nenvironment variable. That\u0027s an indirect signal: it ties correctness to\none convention among CI vendors instead of to what the test actually\ndepends on, so a differently configured runner could still skip past a\nreal regression.\n\nSwitch the check to ZK_ADDR itself: if it\u0027s explicitly set - as the CI\nworkflow\u0027s unit-test job now does at the job level, so it also covers\nthe Race Test step - an unreachable server is a genuine failure of\nwhatever explicitly pointed at it, not something to pass over quietly.\nLeft unset, the common case on a developer machine, it still skips.\n\n* test(etcdv3): stop bumped gost dependency from hanging etcd tests for 10m\n\nBumping github.com/dubbogo/gost to the commit that merges the zk client\nmigration (#147) also pulls in dubbogo/gost@3412137, an unrelated, earlier\nchange that dropped grpc.WithBlock() from the etcd v3 client\u0027s dial without\nbounding the synchronous keepSession call it guards. keepSession creates an\netcd concurrency Session (granting a lease over RPC) with no deadline\nattached, so against an unreachable etcd - which every affected test here\ndials deliberately, to exercise that exact case - NewClient can now block\nindefinitely regardless of the timeout passed to it, instead of failing\nwithin that timeout as it used to.\n\nConfirmed empirically: registry/etcdv3.TestNewEtcdV3ServiceDiscovery and\nremoting/etcdv3.TestValidateClient hung for the full 10-minute per-package\ngo test timeout and failed the build; the same tests pass in ~5s against\nunmodified develop\u0027s older gost pin.\n\nWrap the four call sites that construct an etcd client against an address\nwith nothing listening (TestNewEtcdV3ServiceDiscovery, TestFunction,\nTestValidateClient, TestNewServiceDiscoveryClient) in a bounded\nrunOrSkipOnHang helper (one per package) that skips with a clear diagnostic\ninstead of hanging or asserting behavior the current dependency can no\nlonger guarantee. This is a real upstream gost bug, not a local\nenvironment issue, and skipping here is a stopgap pending a fix there -\nit isn\u0027t the same \"why did this silently skip\" concern the ZK_ADDR-gated\nchecks elsewhere in this PR address, since it is unrelated to CI\u0027s\nZooKeeper setup.\n\n* deps(zookeeper): bump gost to v1.14.5 and drop etcd hang skip (#3459)\n\ngost v1.14.5 includes the upstream go-zookeeper/zk migration (dubbogo/gost#147) and the etcd initial-grant timeout fix (dubbogo/gost#146), so the temporary runOrSkipOnHang workaround is no longer needed. Verified with go build ./... and the etcd/zookeeper test packages.\n\n* build: use go.yaml.in/yaml/v4 in benchmark client\n\ntools/benchmark/client/main.go was the only main-module file still importing gopkg.in/yaml.v3, which promoted it back to a direct dependency. Switch it to go.yaml.in/yaml/v4 so yaml.v3 stays indirect, matching #3586.\n\n* Revert \"build: use go.yaml.in/yaml/v4 in benchmark client\"\n\nThis reverts commit 91c99071f381e7b8fe9b42177c9e0538fc2a6aae.\n\n* Revert \"Revert \"build: use go.yaml.in/yaml/v4 in benchmark client\"\"\n\nThis reverts commit 537af3854111ecaac9cf36ac9ce70ac2785aa102.\n\n* ci: drop unit-test zookeeper service per review\n\nAlanxtl noted the integration-test job already starts ZooKeeper through its docker setup, so the extra ZK service/env in the unit-test job is unnecessary. Keep the migrated config_center/zookeeper tests as-is; they skip when no ZooKeeper is configured and the real cluster paths are covered by integration tests."
    },
    {
      "commit": "630e2839fe8cf043ab8640a1d652e427c824997f",
      "tree": "a3e057dedf4369f1839288518416d88ab232369b",
      "parents": [
        "6647d6a1237e9aaef5db0926dc7f6c947d94684d"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Sat Aug 22 21:58:49 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 22 21:58:49 2026 +0800"
      },
      "message": "fix(triple): stop HTTP/2/HTTP/3 startup from hanging Run (#3645)\n\n* fix(triple): pre-bind TCP and UDP sockets and guard the dual-protocol startup path\n\nstartHttp2AndHttp3 launched HTTP/2 and HTTP/3 inside a plain\nerrgroup.Group{} whose Wait() only returns after ALL goroutines finish.\nWhen either the TCP or the UDP port was occupied, the failing side\nreturned its bind error while the successful side kept listening, so\nWait() never returned and Run hung forever, leaving the successful\nlistener unclosed.\n\nBind both sockets up front — net.Listen for TCP (HTTP/2) and\nnet.ListenPacket for UDP (HTTP/3) — and return the bind error immediately\nwhen either fails. Validate TLS readiness (Certificates / GetCertificate /\nGetConfigForClient) before binding so ServeTLS cannot fail inside a\ngoroutine, and when either Serve exits abnormally, close the other side\nexplicitly so eg.Wait does not block on the still-listening socket. The\nservers are then started concurrently on the pre-bound sockets via\nServeTLS and http3 Serve.\n\nFixes: #3640\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): add regression tests for dual-protocol startup and shutdown\n\nCover the startup and shutdown paths of the dual-protocol server, one\ntest per scenario:\n- Run fails fast with a bind error when the TCP or the UDP port is occupied\n- Run returns an error when TLS has no usable certificate\n- Run returns the Serve error and releases the other side\u0027s port when\n  either Serve exits abnormally after a successful bind\n- the TCP and UDP ports can be rebound after Stop and GracefulStop\n- concurrent start-and-stop cycles pass under the race detector, guarding\n  the uatomic.Pointer server fields against regression\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* fix(triple): abort dual-protocol startup when Stop lands during bind\n\nStop and GracefulStop only close the servers already stored in the\nuatomic.Pointer fields. During the pre-bind and store steps of\nstartHttp2AndHttp3 both fields are still nil, so a concurrent Stop\nfound nothing to close, returned success, and startup went on to serve —\nthe caller believed the server was stopped while it kept listening.\n\nEvery Stop and GracefulStop now increments a stop count that startup\nsnapshots before binding; the startup aborts before serving when the\ncount changed. The deferred closes then release the pre-bound sockets.\nThe count (instead of a boolean flag) keeps repeated start/stop cycles\nworking, and atomic loads make the handoff race-free.\n\nFixes: #3640\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): cover Stop landing during the dual-protocol startup window\n\nInject Stop from the netListen hook, right after the TCP socket is\npre-bound while both server fields are still nil. Run must then abort\ninstead of serving: the tests assert that Run returns without serving\n(no connection can be established), the TCP and UDP ports can be\nrebound, and no listener leaks. They fail before the fix (Run hangs)\nand pass after it.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): cover Stop landing before Run executes\n\nRegister the epoch synchronously, Stop, then release Run: the entry\ncheckpoint must abort without binding any socket. Cover both the\ndual-protocol and the single-protocol path, and assert the TCP port can\nstill be rebound so no listener leaks. These tests hang before the fix\nand pass after it.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* fix(triple): abort server startup when Stop lands before Run\n\nThe startup epoch was snapshotted inside the transport goroutine, so a\nStop that completed before the goroutine read the stop count was absorbed:\nRun loaded the already-incremented value as its new baseline and kept\nlistening, so the first Stop returned while the server still served.\n\nRegister the epoch synchronously in startTransport before the goroutine\nlaunches, pass it into Run, and check it at Run\u0027s entry before any socket\nis bound or served. The entry checkpoint guards every protocol path, so a\nStop landing after registration but before Run aborts the startup.\n\nFixes: #3640\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): build the test TLS config before the transport goroutine\n\nTestServer_HTTP2AndHTTP3_StopBeforeRunAbortsStartup called\nnewTestTLSConfig(t) inside the transport goroutine, but the helper\nasserts via t, which violates testifylint\u0027s go-require rule and made\nmake lint report one issue. Build the config in the test goroutine and\npass the value into the transport goroutine; behavior is unchanged.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* fix(triple): re-check the epoch after publishing the server\n\nThe single-protocol paths had no second epoch check between publishing\nthe server and listening, so a Stop landing there returned success while\nthe startup kept listening. Re-check the epoch after the store in\nstartHttp2 and startHttp3, mirroring the dual-protocol path.\n\nFixes: #3640\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): deterministically cover the single-protocol checkpoints\n\nAdd StopBetweenCheckpointAndServe tests that Stop first, then call\nstartHttp2 and startHttp3 directly with a stale epoch so the post-store\ncheckpoint aborts deterministically, and assert the port stays free.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* fix(triple): restore two-argument Run and hide the startup epoch\n\nThe exported Run(callProtocol, tlsConf) was widened to three arguments\nto carry the startup epoch, breaking source compatibility for pre-3640\nconsumers.\n\nKeep Run two-argument: it snapshots the epoch itself and delegates to a\nprivate run(callProtocol, tlsConf, epoch). A new exported Start snapshots\nthe epoch synchronously before the transport goroutine runs, which the\nadaptation layer now calls instead of snapshotting by hand.\n\nFixes: #3640\n\n* test(triple): guard two-argument Run signature\n\nAdd an external-package test that calls Run with the pre-3640\ntwo-argument shape and serves a real HTTP/2 start/stop cycle. The\nexternal package sees only the exported API, so a future signature\nwidening fails compilation here.\n\n---------\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "6647d6a1237e9aaef5db0926dc7f6c947d94684d",
      "tree": "1df638efcb17b6e2ca56a6f83e180363003de6db",
      "parents": [
        "106675bb54e85b7f0dfe90ab6ba48b72c0c76a31"
      ],
      "author": {
        "name": "AsperforMias",
        "email": "asperformias000@outlook.com",
        "time": "Fri Aug 21 18:57:53 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 21 18:57:53 2026 +0800"
      },
      "message": "fix: retry failed application-level AddListener with capped backoff (#3624) (#3634)\n\n* fix: retry failed application-level AddListener with capped backoff (#3624)\n\nsubscribeAndNotify ran serviceDiscovery.AddListener fire-and-forget: a\ntransient registry error (reconnect storm, leader election) was logged\nonce and never retried, so the consumer silently missed every instance\npush until restart.\n\nAdd a retry loop mirroring the interface-level subscribe backoff from\nregistry/nacos (#3178): one pending retry per serviceNamesKey,\nexponential backoff (1s..30s) with 25% jitter, unlimited attempts\nwhile subscribers remain. A successful retry re-syncs the latest\ninstance snapshot so changes missed while the subscription was down\nare picked up. Pending retries are canceled on Destroy and are not\narmed once the registry is destroyed or no subscriber remains.\n\nAlso fix the inverted event.Succ flag and a %s/%d log mismatch in the\ntouched subscribe path.\n\n* fix: remove notify listener by the same key subscribe used (#3624)\n\nUnSubscribe called RemoveListener with url.ServiceKey() while\nSubscribeURL had registered the notify listener under\nurl.ServiceKey()+\":\"+protocol, so the entry was never removed and\nsubscriber-count-based cleanup could never fire.\n\nRemoveListener now uses the same protocolServiceKeyOf key, and the\nlast unsubscribe cancels any pending AddListener retry for the key.\n\n* test: regression tests for application-level subscribe retry (#3624)\n\nCover the issue scenario and the retry contract:\n- first AddListener fails, retry establishes the subscription and\n  re-syncs the latest snapshot so the consumer receives instance\n  events without a restart;\n- backoff grows exponentially, is capped, and stays inside the\n  [delay, delay+25%] jitter band;\n- retries stop after UnSubscribe and after Destroy, and no new timer\n  is armed once the registry is destroyed;\n- repeated failing subscribes share a single pending retry timer.\n\n* fix: resolve pending subscribe retry on success and preserve in-flight state (#3624)\n\nTwo review findings on the retry lifecycle:\n\n- A subscribe that succeeded while a retry was still pending did not\n  cancel the timer, so it later fired an extra AddListener. That is not\n  safe for service discoveries whose AddListener is not idempotent\n  (Polaris AddSubscriber, ZooKeeper ListenServiceEvent). A successful\n  AddListener now resolves the pending retry for the same listener.\n- retryAddListener deleted the state before the external call, so a\n  concurrent failing subscribe could seed a fresh attempts\u003d0 state and\n  the in-flight attempt\u0027s grown backoff was dropped on the next dedup.\n  The state now stays in the map while in flight (marked inFlight), the\n  failure path re-arms it in place under the lock, and a canceled flag\n  stops a superseded in-flight attempt from rescheduling.\n\nRegression tests (verified to fail without the fix):\n- first subscribe fails, a concurrent one succeeds: no third\n  AddListener call after the backoff window;\n- a failing subscribe during an in-flight retry dedups against the\n  in-flight state instead of replacing it."
    },
    {
      "commit": "106675bb54e85b7f0dfe90ab6ba48b72c0c76a31",
      "tree": "e912328bbce07d1c4e394f928525d12c20a06ee7",
      "parents": [
        "0f0ee4c9c0dc48cda032e81d5be78222330a0364"
      ],
      "author": {
        "name": "AsperforMias",
        "email": "asperformias000@outlook.com",
        "time": "Fri Aug 21 10:18:05 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 21 10:18:05 2026 +0800"
      },
      "message": "fix: self-heal application-level discovery after transient metadata failure (#3615) (#3625)\n\n* fix: self-heal application-level discovery after transient metadata failure (#3615)\n\nTwo stacked recovery gaps made a transient MetadataService fetch failure\npermanent for application-level service discovery:\n\n1. ServiceInstancesChangedListenerImpl skipped instances whose metadata\n   fetch failed and never retried; with no further registry event the\n   consumer directory stayed empty forever. Add a shared retry timer per\n   listener: unresolved revisions are re-resolved by replaying the latest\n   instance snapshot with capped exponential backoff (1s..30s + jitter,\n   unlimited attempts). Retries stop naturally when instances leave the\n   snapshot, subscribers are detached, or the registry is destroyed.\n   Metadata RPCs no longer run under the listener state mutex.\n\n2. RegistryDirectory\u0027s closing tombstone vetoed the rebuild even after a\n   successful retry when the provider restarted with the same address,\n   because a stale pre-shutdown snapshot and a genuine restart were\n   indistinguishable. The tombstone now records the export timestamp and\n   only vetoes re-adds carrying the same timestamp; a different timestamp\n   proves a genuine restart and clears the tombstone.\n\n* refactor: address review comments (#3615)\n\n- Drop the caller-less hasActiveClosingTombstone wrapper; production code\n  uses activeClosingTombstone directly and the tests keep a local helper.\n- Demote the per-event \"received instance notification\" log to debug:\n  it fires on every registry push and is too noisy at info level.\n- refreshServiceURLs now reports whether every revision resolved, and\n  OnEvent surfaces unresolved revisions as an error so registry\n  dispatchers log the partial failure instead of it staying silent.\n  The retry loop is unchanged and still self-schedules.\n\n* fix: close metadata retry lifecycle gaps found in review (#3615)\n\nA retry timer could outlive its listener in three ways:\n\n- scheduleMetadataRetry only checked unresolvedRevisions, so a refresh\n  that failed before any subscriber attached (the SubscribeURL order)\n  armed the timer, and a listener discarded after losing the install\n  race kept retrying — and was kept alive by the timer closure.\n- RemoveListener racing with the timer callback still allowed the\n  callback to refresh and re-schedule with no subscribers left.\n- Destroy raced with an in-flight refresh: stopMetadataRetry canceled\n  the pending timer, but the refresh\u0027s trailing scheduleMetadataRetry\n  armed a new one after the registry was gone.\n\nThe listener now has a closed flag; the scheduler and the timer\ncallback re-check closed and subscriber presence under the mutex, and\na refresh that fails with no subscribers is re-armed by the next\nAddListenerAndNotify instead of running detached. SubscribeURL closes\nthe listener that loses the install race.\n\n* fix: discard subscribes that outlive registry Destroy (#3615)\n\nclosed covered listeners already installed when Destroy runs, but a\nSubscribeURL still in its initial GetInstances/metadata phase is\ninvisible to Destroy\u0027s listener sweep: when the call finished after\nDestroy returned, it would install the listener, attach the subscriber\nand arm a fresh unlimited retry timer on a dead registry (a blocking\nfetch probe shows metadata fetches continuing to grow after Destroy).\n\nThe registry now carries a destroyed flag. SubscribeURL bails early on\ndestroyed registries and re-checks the flag under the write lock right\nbefore installing: a late listener is closed and discarded instead of\ninstalled, so no AddListener call and no retry timer can appear after\nDestroy.\n\nAdds the deterministic SubscribeURL x Destroy interleaving test\nrequested in review (blocking fetch probe; verified to fail without\nthe fix: listener installed, AddListener called, fetches continue)\nplus a post-Destroy subscribe no-op test.\n\n* fix: unsubscribe with the same protocol-qualified listener key (#3615)\n\nSubscribeURL registers the notify listener under url.ServiceKey()+\":\"+protocol,\nbut UnSubscribe removed it with the bare url.ServiceKey(), so the last\nsubscriber was never detached and the metadata retry timer kept probing after\nUnSubscribe. Derive both sides from a shared protocolSubscribeKey helper and\ncover the public SubscribeURL -\u003e UnSubscribe lifecycle with a regression test."
    },
    {
      "commit": "0f0ee4c9c0dc48cda032e81d5be78222330a0364",
      "tree": "e729b07813e1cec1635fc1f2637c10fb6a082c7a",
      "parents": [
        "788f55894264c2d6885bc473806ed88e828ca715"
      ],
      "author": {
        "name": "班尼牛",
        "email": "126126333+HTFSince2018@users.noreply.github.com",
        "time": "Thu Aug 20 13:39:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 20 13:39:00 2026 +0800"
      },
      "message": "docs: complete Triple configuration field comments (#3674)\n\n* docs: complete Triple configuration field comments\n\nSigned-off-by: 班尼牛 \u003c863647842@qq.com\u003e\n\n* style: apply modernize fix to map generalizer test\n\nSigned-off-by: 班尼牛 \u003c863647842@qq.com\u003e\n\n---------\n\nSigned-off-by: 班尼牛 \u003c863647842@qq.com\u003e"
    },
    {
      "commit": "788f55894264c2d6885bc473806ed88e828ca715",
      "tree": "9b092abd9d5a9a3dd2659d1e80adee06e776cf49",
      "parents": [
        "ca39fe208417ffb165e024d8a79948947411007d"
      ],
      "author": {
        "name": "Modo",
        "email": "witty8010@outlook.com",
        "time": "Thu Aug 20 13:36:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 20 13:36:04 2026 +0800"
      },
      "message": "Feat: enhance mapping observability (#3605)\n\n* add metrics and logs for mapping operation\n\n* fix ci\n\n* add test covering MetadataMetricCollector.start()\n\n* fix: address review comments\n\n* refactor: move mapping metrics to ServiceNameMapping\n\nrefactor: move mapping metrics to ServiceNameMapping\n\n* fix ci\n\n* fix empty event in early-return and add test\n\n* fix: hide sensitive information"
    },
    {
      "commit": "ca39fe208417ffb165e024d8a79948947411007d",
      "tree": "ed649f775940ca44b09de63dca0f9dfabe4595ed",
      "parents": [
        "221046200f20b511132243c0d747d4935d9a46c7"
      ],
      "author": {
        "name": "Nene7ko_",
        "email": "141395478+XnLemon@users.noreply.github.com",
        "time": "Thu Aug 20 13:35:36 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 20 13:35:36 2026 +0800"
      },
      "message": "fix(graceful_shutdown, loadbalance): prevent hard exits and P2C panics (#3591)\n\n* fix crash risks in shutdown and p2c load balancer\n\n* fix graceful shutdown timeout propagation\n\n* test: fix graceful shutdown helper arguments\n\n* test: avoid leaking graceful shutdown signal goroutine\n\n* test: isolate P2C metrics state"
    },
    {
      "commit": "221046200f20b511132243c0d747d4935d9a46c7",
      "tree": "1ed11416612138845ff06e0196ee37682954e782",
      "parents": [
        "c79f6166fda32c3047cb1444d9ccff4476f85630"
      ],
      "author": {
        "name": "Nene7ko_",
        "email": "141395478+XnLemon@users.noreply.github.com",
        "time": "Thu Aug 20 13:27:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 20 13:27:54 2026 +0800"
      },
      "message": "fix(metadata, protocol, proxy): preserve request context across RPC paths (#3579)\n\n* fix(context): preserve request context across RPC paths\n\n* fix: resolve context propagation lint findings\n\n* fix(rest): stop invocation after parameter parse errors\n\n* fix(context): address PR review cancellation feedback\n\n* fix: address context lint review findings\n\n* refactor(registry): simplify metadata lookup\n\n* fix(jsonrpc): preserve pipelined response order\n\n* refactor(jsonrpc): reuse content type header constant\n\n* fix(jsonrpc): isolate pipelined request timeouts\n\n* fix(jsonrpc): bound pipelined request window\n\n* chore(jsonrpc): apply modernize formatting"
    },
    {
      "commit": "c79f6166fda32c3047cb1444d9ccff4476f85630",
      "tree": "6cfccdd9e05e2bbd2d10e63d35da5edf255ad889",
      "parents": [
        "da5838678668437077f09e55f7f9fac9697a6c3c"
      ],
      "author": {
        "name": "xiaobaicai66695",
        "email": "575121043@qq.com",
        "time": "Thu Aug 20 13:26:05 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 20 13:26:05 2026 +0800"
      },
      "message": "fix:cache manager race #3569 (#3601)\n\n* fix: guard service discovery cache manager access\n\n* test: verify cache manager dump lifecycle\n\n* style: modernize cache manager concurrency tests\n\n* test: reduce cache manager test complexity\n\n* test: verify cache manager get all snapshot\n\n* test: cover cache manager stop dump deadlock"
    },
    {
      "commit": "da5838678668437077f09e55f7f9fac9697a6c3c",
      "tree": "97ef78e7bfb51c3c192c279c81f22f9815567c56",
      "parents": [
        "598aa49eacc925a11c9a907a90c5e8aedfb08bb0"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Thu Aug 20 13:13:11 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 20 13:13:11 2026 +0800"
      },
      "message": "fix(triple): filter http.ErrServerClosed in single-protocol server shutdown (#3671)\n\n* fix(triple): filter http.ErrServerClosed in single-protocol server shutdown\n\nstartHttp2 and startHttp3 returned the net/http serve error verbatim, so a normal Stop surfaced http.ErrServerClosed from Server.Run and the outer startTransport goroutine logged a spurious \"server serve failed\" error. The dual-protocol startHttp2AndHttp3 already swallowed this normal-shutdown signal inside its errgroup. Filter it in both single-protocol paths so Run returns nil after a clean shutdown, matching the dual-protocol behavior. Only http.ErrServerClosed is swallowed; genuine serve errors still propagate.\n\nFixes: #3670\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): assert clean shutdown in single-protocol lifecycle tests\n\nThe StartAndStop tests previously asserted that Run returns http.ErrServerClosed after a normal Stop, pinning the leak as expected behavior. Switch the six assertions to NoError and fold the now-uniform if/else in TestServer_RepeatedStartStop into a single assertion. Add TestServerRunReturnsBindErrorWhenPortInUse and TestServerRunHTTP3ReturnsBindErrorWhenPortInUse, which assert that genuine serve errors (port conflicts) still propagate, guarding the filter boundary. They fail on the pre-fix code and pass with the filter.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n---------\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "598aa49eacc925a11c9a907a90c5e8aedfb08bb0",
      "tree": "719c1c531e336aabdc418be23a2914b7d5b8ef2b",
      "parents": [
        "3945883ad5c8e726143e08ea6f27266d1e25e163"
      ],
      "author": {
        "name": "Lcos",
        "email": "3349888061@qq.com",
        "time": "Thu Aug 20 13:12:14 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 20 13:12:14 2026 +0800"
      },
      "message": "fix(invocation): guard ActualMethodName type assertion to avoid panic (#3684)\n\n* fix(invocation): guard ActualMethodName type assertion to avoid panic\n\nIsGenericInvocation only guarantees len(Arguments)\u003d\u003d3, not the element\ntypes. The bare type assertion in ActualMethodName (arg[0].(string))\ncould panic on a malformed $invoke request. Replace it with comma-ok\nform and fall back to MethodName() on mismatch, since the interface\nsignature has no error return. The interface and all 7 call sites are\nunaffected.\n\nFixes #3683\n\nSigned-off-by: Lcos \u003c3349888061@qq.com\u003e\nSigned-off-by: user.email \u003c3349888061@qq.com\u003e\n\n* refactor(invocation): address copilot review feedback\n\n- Extract args :\u003d r.Arguments() before assertion for clarity.\n- Wrap test assertion in require.NotPanics for intention-revealing.\n\nSigned-off-by: Lcos \u003c3349888061@qq.com\u003e\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": "3945883ad5c8e726143e08ea6f27266d1e25e163",
      "tree": "53ec51b250d7a301a785f885c542b2a3bea19901",
      "parents": [
        "6dea7f500e0e5ae6c0590a08f8ffa4cf937e639a"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Thu Aug 20 13:11:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 20 13:11:03 2026 +0800"
      },
      "message": "fix(benchmark): Add support for dubbo-java benchmark (#3689)\n\n* build(tool): fix dubbo-java pom to compile and package\n\nThe dubbo-java benchmark server failed to build because the spring-boot\nparent version referenced ${spring-boot.version}, which Maven cannot\nresolve during parent POM resolution. Replace the parent with an\nexplicit 2.7.18 version, and add the triple rpc + protobuf build\nplugins, \u003cfinalName\u003e alignment with README_CN, and a\nServicesResourceTransformer to preserve Java SPI files after shading.\n\nFixes #3688\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* feat(tool): migrate dubbo-java server to triple protocol\n\nThe server spoke the legacy dubbo protocol with hand-written message\nclasses, so the Go benchmark client (triple + protobuf only, resolving\nbenchmark.BenchmarkService) could never reach it. Switch to triple:\nmove the service into the benchmark package (git mv, keeping history),\nuse protobuf-generated BenchmarkProto messages, and keep UnaryCall\n(capital U) to match the method name generated on the Go side.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* fix(tool): keep dubbo-java server alive and scan benchmark package\n\nTwo startup issues blocked benchmarking the Java server: the non-web\nSpring Boot app exited right after main() returned (port 20001 never\nlistened), and @EnableDubbo\u0027s default scan missed the implementation\nafter it moved to the benchmark package. Block the main thread with a\nCountDownLatch and point @EnableDubbo at the benchmark package.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* feat(tool): support dubbo-java in benchmark client and scripts\n\nREADME_CN documents dubbo-java as a supported framework, but neither\nthe client nor the scripts implemented it, so the Java server could\nnever be benchmarked end-to-end. Accept --framework dubbo-java in the\nclient (triple client, port 20001, unary + protobuf only) and add\ndubbo-java branches to run_single.sh / run_all.sh (mvn package +\njava -jar).\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n---------\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "6dea7f500e0e5ae6c0590a08f8ffa4cf937e639a",
      "tree": "d1fa821dd8ea312d39562a5839cd2088e435c5d3",
      "parents": [
        "9757e7735d720e4f3bba348f8c4f94803b5fb61d"
      ],
      "author": {
        "name": "Oxidaner",
        "email": "80675726+Oxidaner@users.noreply.github.com",
        "time": "Wed Aug 19 22:25:34 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 19 22:25:34 2026 +0800"
      },
      "message": "fix(generic): honor m tags during realization (#3505)"
    },
    {
      "commit": "9757e7735d720e4f3bba348f8c4f94803b5fb61d",
      "tree": "d37ad531cd69a1284045176b1d95699577cf06ae",
      "parents": [
        "a65cdc1ff7dabcb4a6dbf23afa3e151833932bfc"
      ],
      "author": {
        "name": "MaoMeng",
        "email": "1707647656@qq.com",
        "time": "Wed Aug 19 14:25:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 19 14:25:54 2026 +0800"
      },
      "message": "docs(router): complete script router comments and unit test coverage (#3682)\n\n* docs(router): complete script router comments and unit test coverage\n\n* test(router): fix CI failures in script router tests"
    },
    {
      "commit": "a65cdc1ff7dabcb4a6dbf23afa3e151833932bfc",
      "tree": "9d8e41d38eeef0ed603f6050a21c90a5436c5734",
      "parents": [
        "fcb2e5d4bdab1661737a0c69bf6be53dc2fb52a3"
      ],
      "author": {
        "name": "DaWesen",
        "email": "3880255095@qq.com",
        "time": "Wed Aug 19 12:47:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 19 12:47:48 2026 +0800"
      },
      "message": "chore: add doc comments and unit tests for metadata customizers (#3678)\n\n* chore: add doc comments and unit tests for metadata customizers\n\n* chore: align import blocks with imports-formatter\n\n* chore: resolve testifylint issues in metadata customizer tests\n\n* chore: align customizer comments with metadata service URL semantics"
    },
    {
      "commit": "fcb2e5d4bdab1661737a0c69bf6be53dc2fb52a3",
      "tree": "6e3cd8830069c05735212114a6e78e347e91360c",
      "parents": [
        "c32066f97c2ff2ae9470b89f11d30a7e3567c019"
      ],
      "author": {
        "name": "CAICAII",
        "email": "3360776475@qq.com",
        "time": "Wed Aug 19 11:46:07 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 19 11:46:07 2026 +0800"
      },
      "message": "feat(triple): add HTTP/3 transport options (#3681)\n\n* feat(triple): add http3 transport options\n\nSigned-off-by: CAICAIIs \u003c3360776475@qq.com\u003e\n\n* refactor(triple): use with-style http3 options\n\nSigned-off-by: CAICAIIs \u003c3360776475@qq.com\u003e\n\n* refactor(triple): deprecate legacy http3 option aliases\n\nSigned-off-by: CAICAIIs \u003c3360776475@qq.com\u003e\n\n---------\n\nSigned-off-by: CAICAIIs \u003c3360776475@qq.com\u003e"
    },
    {
      "commit": "c32066f97c2ff2ae9470b89f11d30a7e3567c019",
      "tree": "d53ac19e791a0708f1fc91e43e74c6d7002eda4a",
      "parents": [
        "0c194ebfb228792bfbd1af4058ef5515ee2e2b46"
      ],
      "author": {
        "name": "Lcos",
        "email": "3349888061@qq.com",
        "time": "Tue Aug 18 23:01:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 23:01:33 2026 +0800"
      },
      "message": "fix(filter/generic): guard $invoke arg type assertions to avoid panic (#3680)\n\n* fix(filter/generic): guard $invoke arg type assertions to avoid panic\n\nIsGenericInvocation only guarantees len(Arguments)\u003d\u003d3, not the element\ntypes. The two bare type assertions in genericServiceFilter.Invoke\n(arg[0].(string) and arg[2].([]hessian.Object)) could panic on a\nmalformed or malicious $invoke request. Replace them with comma-ok\nform and return a perrors-wrapped error via RPCResult{Err}, matching\nthe existing error-return style in the same function.\n\nFixes #3679\n\nSigned-off-by: Lcos \u003c3349888061@qq.com\u003e\nSigned-off-by: user.email \u003c3349888061@qq.com\u003e\n\n* Update filter/generic/service_filter.go\n\nCo-authored-by: Xuetao Li \u003cxuetaoli@apache.org\u003e\n\n---------\n\nSigned-off-by: Lcos \u003c3349888061@qq.com\u003e\nSigned-off-by: user.email \u003c3349888061@qq.com\u003e\nCo-authored-by: Xuetao Li \u003cxuetaoli@apache.org\u003e"
    },
    {
      "commit": "0c194ebfb228792bfbd1af4058ef5515ee2e2b46",
      "tree": "797624f12ceb59fa48133dfc8f20aec3e0bcd078",
      "parents": [
        "6443c823b2b16ce50dfa71b4757104dee9e5a4ee"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Tue Aug 18 17:21:41 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 17:21:41 2026 +0800"
      },
      "message": "fix(tool): drain in-flight requests before canceling ctx in engine.Stop() (#3677)\n\nThe engine.Stop() method cancels the parent context before draining\nin-flight requests, causing up to concurrency-many requests to be\nrecorded as context canceled failures on every benchmark teardown.\nIn low-QPS scenarios (1MiB payload), the failure rate reaches 0.86%,\nmaking the success-rate metric inaccurate.\n\nSwap e.cancel() and e.wg.Wait() so that in-flight requests complete\nnaturally before the context is canceled, eliminating the spurious\nfailures.\n\nFixes #3675\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "6443c823b2b16ce50dfa71b4757104dee9e5a4ee",
      "tree": "0402d64f52a441f28d2bd7ad5aff22fcd2131188",
      "parents": [
        "3996cc839bc827c48c1b1e24e5f098825784bd17"
      ],
      "author": {
        "name": "DaWesen",
        "email": "3880255095@qq.com",
        "time": "Tue Aug 18 17:15:16 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 17:15:16 2026 +0800"
      },
      "message": "chore: add doc comments and unit tests for instance customizers (#3676)"
    },
    {
      "commit": "3996cc839bc827c48c1b1e24e5f098825784bd17",
      "tree": "8fd53fe6461de11d2f7330a211c1fb68da70f14a",
      "parents": [
        "08a4387b7ea295b8068de0bc5cd64c3df92c9d48"
      ],
      "author": {
        "name": "eye-gu",
        "email": "eyegu@apache.org",
        "time": "Tue Aug 18 10:47:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 10:47:28 2026 +0800"
      },
      "message": "feat(triple): dispatch non-IDL wrapper decoding by SerializeType (#3550)\n\n* feat(triple): dispatch non-IDL wrapper decoding by SerializeType\n\n* fix(triple): normalize hessian4 serialize type for Java interop\n\n* harden non-IDL inner codec registry and add serialize-type allowlist\n\n* fix(triple): unwrap response container and validate SerializeType for empty Data\n\n* fix format"
    },
    {
      "commit": "08a4387b7ea295b8068de0bc5cd64c3df92c9d48",
      "tree": "564d806d78f9c203b3e2e7fe292ad356e654e5d7",
      "parents": [
        "9fba1ad6e4ee47a696b085ff63f88048bdc5317b"
      ],
      "author": {
        "name": "Lcos",
        "email": "3349888061@qq.com",
        "time": "Mon Aug 17 17:31:24 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 17 17:31:24 2026 +0800"
      },
      "message": "fix(protocol/triple): SendHeader writes into ResponseHeader instead of RequestHeader (#3668)\n\nSendHeader merged user headers into conn.RequestHeader(), so the headers\nwere never flushed to the client (grpcHandlerConn.Send only flushes\nhc.responseHeader) and the inbound request header map was polluted.\nAlign with the sibling SetHeader by writing into conn.ResponseHeader().\n\nTests:\n- header_test.go: upgrade mockHandlerConn to expose a real RequestHeader\n  and a Send call counter; add TestSendHeader and TestSendHeaderOutsideHandler.\n- triple_ext_test.go: add TestSendHeaderInUnaryHandler, an end-to-end test\n  over a real HTTP transport that exercises net/http\u0027s WriteHeader snapshot\n  semantics (the mock does not) and the unary handler\u0027s double-Send path\n  (SendHeader\u0027s conn.Send(nil) followed by the framework\u0027s conn.Send(msg)).\n\nFor #3667.\n\nSigned-off-by: Lcos-000 \u003c3349888061@qq.com\u003e"
    },
    {
      "commit": "9fba1ad6e4ee47a696b085ff63f88048bdc5317b",
      "tree": "14d914c94274e3349a5d85cb30a9acf97626be34",
      "parents": [
        "a31acfb67e9feb0694bd11cbfaf24689aec9146a"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Mon Aug 17 15:53:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 17 15:53:38 2026 +0800"
      },
      "message": "fix(config): guard the global dynamicConfiguration with a RWMutex (#3669)\n\n* fix(config): guard the global dynamicConfiguration with a RWMutex\n\nThe Environment singleton keeps dynamicConfiguration as a lock-free field.\nTestNewRegistryDirectoryConsumerListenerUsesResolvedApplicationName writes\nit via SetDynamicConfiguration while subscription goroutines leaked from\nearlier normalRegistryDir tests keep reading it through\nGetDynamicConfiguration (tag.PriorityRouter.Notify) — a data race that the\nCI -race job caught. Guard the field with a sync.RWMutex: Set takes the\nwrite lock, Get takes the read lock. The API and nil semantics are\nunchanged, so existing callers and tests are unaffected.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(config): add a concurrent Set/Get race regression test\n\nTestDynamicConfigurationRace drives 100k concurrent reads and writes on\nthe global Environment dynamicConfiguration, mirroring the CI flaky race\nwhere a registry subscription goroutine kept reading the field while a\ntest goroutine wrote it. It fails on the previous lock-free field under\n-race and passes with the RWMutex guard.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(config): gate the writer until the race test reader is ready\n\nTestDynamicConfigurationRace starts the reader goroutine and immediately begins the 100k writes, so on some schedulers the writer can finish before the reader is scheduled, making the pre-fix race reproduction probabilistic rather than guaranteed. Gate the writer behind a ready/start barrier: the reader reports ready and blocks until the writer closes the start channel, so the concurrent access always overlaps. The test now fails deterministically on the previous lock-free field under -race.\n\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e\n\n* style(config): release the dynamicConfiguration mutex with defer\n\n---------\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "a31acfb67e9feb0694bd11cbfaf24689aec9146a",
      "tree": "2aeff08c732f639c0acb302475dc83de767fb60f",
      "parents": [
        "e74a8d7143fa777b6a44b5fcea4acac7fe6da538"
      ],
      "author": {
        "name": "Yu",
        "email": "zhiyujiang364@gmail.com",
        "time": "Sun Aug 16 12:22:02 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 16 12:22:02 2026 +0800"
      },
      "message": "docs(metrics): improve comments and test coverage of metrics options and rpc error classifier (#3665)\n\n* chore(metrics): add godoc comments and tests for metrics options and rpc error classifier"
    },
    {
      "commit": "e74a8d7143fa777b6a44b5fcea4acac7fe6da538",
      "tree": "21ec508c1d4ca6509221bba023ae26ae0cd39ccd",
      "parents": [
        "c2d08ba8fe7c265d8147e01774df26c76243fa4e"
      ],
      "author": {
        "name": "anchor",
        "email": "codeanqiang@gmail.com",
        "time": "Sun Aug 16 08:22:37 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 16 08:22:37 2026 +0800"
      },
      "message": "fix(triple): preserve CodeBizError over the Triple unary transport (#3655)\n\nOver the Triple (non-gRPC) unary transport, tripleWireError.asError()\nclamped any code outside [minCode, maxCode] to CodeUnknown, so a\nserver-returned CodeBizError (17) reached the client as CodeUnknown (2).\nThe clamp comes from connect-go, which only defines codes 1..16;\nCodeBizError is a dubbo-go extension and maxCode was never updated.\ncode.go already goes out of its way to keep such codes intact, so that\nUnmarshalText round-trips them, and asError then discarded them again.\n\nAs a result failover.isBizError stopped recognizing business errors and\nretried them, and metrics/rpc counted them as unknown failures. The gRPC\ntransport was unaffected because grpcErrorFromTrailer does not clamp.\n\nExempt CodeBizError from the clamp and add a regression test asserting\nthe client-visible code over both transports.\n\nFixes: #3654\n\nAssisted-by: Cursor (Claude Opus 5)\n\nSigned-off-by: codeAnqiang-ma \u003c273298913+codeAnqiang-ma@users.noreply.github.com\u003e\nCo-authored-by: codeAnqiang-ma \u003c273298913+codeAnqiang-ma@users.noreply.github.com\u003e\nCo-authored-by: Cursor \u003ccursoragent@cursor.com\u003e"
    },
    {
      "commit": "c2d08ba8fe7c265d8147e01774df26c76243fa4e",
      "tree": "686467e61d0d9e0bd9f0482fe54a556823ca81bb",
      "parents": [
        "27de37524f62147e756467aef03aa162a422e664"
      ],
      "author": {
        "name": "SouthwestAsiaFloat",
        "email": "2034946972@qq.com",
        "time": "Sun Aug 16 08:13:57 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 16 08:13:57 2026 +0800"
      },
      "message": "feat(ospp): task 10 (#3662)"
    },
    {
      "commit": "27de37524f62147e756467aef03aa162a422e664",
      "tree": "8aa03d5607c7ffd74e4822d56e82bb0c2e7e7593",
      "parents": [
        "77cef1a512f9edde2607c4b48136ccf1f1099650"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Sun Aug 16 08:12:52 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 16 08:12:52 2026 +0800"
      },
      "message": "chore(triple): add doc comments and boundary tests for stream APIs (#3663)\n\n* docs(triple): add doc comments for stream exported APIs\n\nDocument the close paths, error propagation, stop semantics, nil msg\nhandling and metadata behavior of the stream exported APIs, and add a doc\ncomment for NewCompatStreamHandler which had none. Fix the misleading nil\nmsg comment on ServerStream.Send and BidiStream.Send: it commits the\nresponse headers without writing a message frame.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): add boundary tests for stream close and error propagation\n\nAdd 20 tests covering stream close, repeated close, error propagation and\nempty metadata, using two minimal stubs that drive errors and count close\ncalls without a real transport.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* docs(triple): clarify CloseAndReceive close is best-effort\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(triple): implement Spec and Peer on the streaming client stub\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n---------\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "77cef1a512f9edde2607c4b48136ccf1f1099650",
      "tree": "bae2324d1019a22733225c7a7b947bfdc6587ee7",
      "parents": [
        "5eb9b25a7851127cb40b953afecb66b0919633e3"
      ],
      "author": {
        "name": "MaoMeng",
        "email": "1707647656@qq.com",
        "time": "Sat Aug 15 23:45:49 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 15 23:45:49 2026 +0800"
      },
      "message": "docs(metadata): complete metadata option comments and unit test coverage (#3657)\n\n* docs(metadata): complete metadata option comments and unit test coverage\n\n* docs(metadata): refine WithMetadataType/WithMetadataProtocol/WithProtocol comments"
    },
    {
      "commit": "5eb9b25a7851127cb40b953afecb66b0919633e3",
      "tree": "c30f0c139e7747fadd8060b54b80c556424af186",
      "parents": [
        "b3adb3362ae7a1f90db43f8575c1664203c1f134"
      ],
      "author": {
        "name": "MaoMeng",
        "email": "1707647656@qq.com",
        "time": "Sat Aug 15 23:44:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 15 23:44:48 2026 +0800"
      },
      "message": "docs(metadata): complete metadatainfo comments and unit test coverage (#3666)\n\n* docs(metadata): complete metadatainfo comments and unit test coverage\n\n* docs(metadata): add some unit test to metadatainfo"
    },
    {
      "commit": "b3adb3362ae7a1f90db43f8575c1664203c1f134",
      "tree": "39b628fdc20214e714835713105c081e1bc578e4",
      "parents": [
        "d4733b12bf965e4be1516de5164833ec007aa7c3"
      ],
      "author": {
        "name": "Li Zining",
        "email": "lizining1231@outlook.com",
        "time": "Fri Aug 14 20:55:51 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 14 20:55:51 2026 +0800"
      },
      "message": "fix(registry): publish app metadata only once after registering all instances (#3590)\n\n* fix(registry): publish app metadata only once after registering all instances\n\nRegisterService previously published the full app metadata inside the\nper-URL loop, writing an identical payload N times for N exported services.\nMove the publish out of the loop so the metadata center is written exactly\nonce, reducing startup write amplification and metadata center pressure.\n\nFixes: #3570\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(registry): verify app metadata is published exactly once\n\nAdd TestServiceDiscoveryRegistryRegisterPublishesMetadataOnce which\nregisters two services and asserts that app metadata is published exactly\nonce. The test fails on the previous per-URL publish implementation.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(registry): cover RegisterService publish error paths\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(registry): fix testifylint require-error in publish test\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* fix(registry): publish app metadata before registering service instances\n\nRegisterService registered every instance first and only published the app\nmetadata afterwards. If the publish failed, the already-registered instances\nstayed routable while the server only rolled back after a fully successful\nstartup, leaving orphan instances. It also entered the publish path with an\nempty exported URL list (e.g. pure consumers), writing empty keys or hitting a\nnil report dereference, and started the renew timer while the revision was\nstill \"0\", spinning as a no-op.\n\nBuild all instances and compute the revision first, publish app metadata\nexactly once, then register each instance. Return early when there are no\nexported URLs, keep the metadata report nil check before any dereference, and\nskip starting the renew timer until a revision exists.\n\nFixes: #3570\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(registry): cover publish failure, retry and metadata edge cases\n\nAdd tests for the reworked RegisterService: a failed publish registers no\ninstances and leaves none behind, a retry then registers them exactly once,\npure consumers with remote metadata never publish or register, a nil metadata\nreport returns an error instead of panicking, non-remote metadata mode\npublishes zero times, and the renew timer is not started while the revision\nis empty.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* fix(registry): skip starting the renew timer for empty revisions\n\nThe renew timer should not start while the revision is empty, and a\nrevision is empty when nothing real has been published yet: it starts as\n\"\", becomes \"0\" after exported URLs are cleared, and falls back to \"N/A\"\nin the customizer. startMetadataTimers previously did not check the\nrevision at all and doRenewAppMetadata only skipped \"0\", so \"\" and \"N/A\"\ncould still start the timer or trigger a renew. isPublishableRevision now\ntreats all three as empty, so the timer stays off until a real revision\nexists.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(registry): verify the renew timer is not started for empty revision markers\n\nTurn TestServiceDiscoveryRegistry_StartMetadataTimersSkipsEmptyRevision into\na table-driven test covering \"\", \"0\" and \"N/A\". All three cases keep the\nrenew timer from starting.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(server): return an error from ServeContext when metadata publish fails\n\nAdd TestServeContextReturnsErrorWhenMetadataPublishFails. The registry mock\ncalls PublishAppMetadata while the metadata report is mocked to fail, so\nServeContext returns an error for the publish failure.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* style(server): replace context.WithCancel with t.Context() in test\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* style(server): fix gost import order to satisfy imports-formatter\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* test(registry): disable the startup renew in the publish-once test\n\nRegisterService starts a background renew goroutine when the metadata\nreport enables metadata.renew.on.startup. That goroutine also calls\nPublishAppMetadata, so the count asserted by\nTestServiceDiscoveryRegistryRegisterPublishesMetadataOnce can be raced\nand is not reliable proof of exactly-once. Give the mock report a URL\nthat disables the startup renew and stop the timer at the end of the\ntest, leaving the counter updated only by the synchronous publish.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* ci(registry): gate servicediscovery tests with the race detector\n\nRegisterService starts a background metadata renew goroutine that can\nrace the assertions of tests counting app-metadata publishes, and plain\ngo test does not detect that locally. Add a test-race target that runs\ngo test -race on the servicediscovery package and wire it into the CI\nworkflow so any newly introduced race is caught before merge, and the\nintentionally racy TestServiceDiscoveryRegistryUnRegister_Concurrent is\nexcluded via the -skip flag.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n* ci(race): run the race detector across the whole repo\n\nThe test-race target previously only ran on the servicediscovery package,\nso races in failback, chain, apollo, dubbo, grpc, getty and server tests\nwent undetected. Extend it to \u0027go test -race ./...\u0027 and skip the tests\nwith known issues via a RACE_SKIP_TESTS variable so the whole-repo race\nrun can pass; each skipped test should be fixed and removed from the list\nover time.\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e\n\n---------\n\nSigned-off-by: lizining \u003clizining1231@outlook.com\u003e"
    },
    {
      "commit": "d4733b12bf965e4be1516de5164833ec007aa7c3",
      "tree": "fd31465773a026f4a21ae7b71673b0bf637dccb6",
      "parents": [
        "840949261ff9a9b771631422542bc9b134b7ff0c"
      ],
      "author": {
        "name": "CAICAII",
        "email": "3360776475@qq.com",
        "time": "Fri Aug 14 12:27:06 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 14 12:27:06 2026 +0800"
      },
      "message": "feat(triple): share HTTP/3 QUIC config with client (#3620)\n\n* feat(triple): share http3 quic config with client\n\nSigned-off-by: CAICAIIs \u003c3360776475@qq.com\u003e"
    },
    {
      "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": "f0ef1490bfce53ac2f7acb0aa586cf46499b9fb0",
      "tree": "bcf679cbf3108bad12d4d4858402a1ba54a4fce2",
      "parents": [
        "81abe9ddb6d0ffd4a8fd7e1b895894e444654949",
        "7125a09bdbfdadd1c5922d669730e29d7416c395"
      ],
      "author": {
        "name": "alexstocks",
        "email": "alexstocks@foxmail.com",
        "time": "Wed Aug 12 15:49:21 2026 +0800"
      },
      "committer": {
        "name": "alexstocks",
        "email": "alexstocks@foxmail.com",
        "time": "Wed Aug 12 15:49:21 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"
    }
  ],
  "next": "bcd6aa42be158b28f969e7669c43ae8f543ac7e5"
}
