)]}'
{
  "log": [
    {
      "commit": "634ed15dfd9249cfb57a52541dddba05b377df0a",
      "tree": "ceff91252813830ac25b9e01b83cf4cc88dbe57d",
      "parents": [
        "567fcf6c26fc38367c1bda81ca0541c6ab861086"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Sat Jul 11 17:30:21 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jul 11 09:30:21 2026 +0000"
      },
      "message": "fix(rdb): reject over-large declared lengths when loading RDB payloads (#3550)\n\nThe RDB load path sized buffers from an attacker-declared 64-bit length\nbefore checking the stream actually holds that many bytes. A write-level\nclient could send a `RESTORE` payload declaring a huge length and make\nthe server allocate it up front and crash (OOM) — via both the plain\nstring path (`read_string.resize(len)`) and the LZF path (`out_buf(len,\n0)`).\n\nAdd `RdbStream::EnsureRemainingBytes()` and validate every length that\ndrives a read or allocation against the bytes still remaining in the\nstream, so a value can never be declared larger than the input that\ncarries it. The LZF decompressed size may legitimately exceed the\nremaining stream, so it is additionally capped against\n`proto-max-bulk-len`.\n\nAdd gocase regression tests for both the plain-string and LZF-encoded\n`RESTORE` payloads: the server now returns an error and stays up."
    },
    {
      "commit": "567fcf6c26fc38367c1bda81ca0541c6ab861086",
      "tree": "ac9063ced9baf34e324a7f8160f5d89ce1346b44",
      "parents": [
        "e887721cbcc11406769445ea7d66ad0c71a5502e"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Thu Jul 09 11:11:23 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 09 03:11:23 2026 +0000"
      },
      "message": "fix(scripting): guard against stack overflow on deeply nested Lua reply (#3547)\n\nReplyToRedisReply() converts a Lua return value into a RESP reply with\nnative C++ recursion that runs after lua_pcall() returns,\nso Lua\u0027s own recursion guard does not apply. A deeply self-nested table\ncould recurse until the worker thread stack overflowed and crashed\nthe whole server (the Lua VM is shared per worker).\n\nAdd a lua_checkstack() guard so such a reply fails with \"reached lua\nstack limit\"\ninstead of crashing. Includes a Go regression test in the scripting\nsuite.\n\nAssistant-By Claude Fable 5"
    },
    {
      "commit": "e887721cbcc11406769445ea7d66ad0c71a5502e",
      "tree": "5b2d17f1779d9dc7ea9422bad89efc3ac3a4b194",
      "parents": [
        "cace9a0fd3ddc4d330e0d50602d8cd095e09b6c8"
      ],
      "author": {
        "name": "nhancdt2602",
        "email": "55862577+nhancdt2602@users.noreply.github.com",
        "time": "Wed Jul 08 20:41:46 2026 +0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 08 21:41:46 2026 +0800"
      },
      "message": "feat(info): support FORMAT (TXT | JSON) for the INFO command (#3549)\n\n## Summary\n\nAdd an optional `FORMAT (TXT | JSON)` option to the `INFO` command:\n\n```\nINFO [\u003csection\u003e ...] [FORMAT (TXT | JSON)]\n```\n\n- `FORMAT TXT` (the default) keeps the existing Redis-compatible text\noutput.\n- `FORMAT JSON` emits the same data as a JSON object keyed by section.\n\n```\n127.0.0.1:6666\u003e INFO server FORMAT JSON\n{\"Server\":{\"version\":\"unstable\",\"tcp_port\":6666,\"process_id\":123,...}}\n```\n\nCloses #2302.\n\n## Changes\n\n- `CommandInfo`: parse the optional `FORMAT` keyword, separating it from\nsection names.\n- `InfoEntry`: store each value as a typed `std::variant`, with\n`InfoEntry::ToString()` for the text form; `GetInfo` serializes to text\nor JSON.\n- Add `TestInfoFormat` integration tests.\n\n## Implementation Note\n\nEach `INFO` value carries its original type in the `InfoEntry` variant\n`std::variant\u003cstd::string, int64_t, double, bool\u003e`, captured in the\nconstructors, so the collectors stay unchanged and each format renders\nthe value at serialization time:\n\n- **Text** (`InfoEntry::ToString`): booleans as `0/1`, numbers via\n`std::to_string`, strings verbatim — identical to the previous output.\n- **JSON**: native types — numbers unquoted, booleans as `true/false`,\nstrings quoted.\n\nThe `FORMAT` keyword is case-insensitive; an unknown or missing value\nreturns `syntax error`.\n\n---------\n\nSigned-off-by: nhancdt \u003cnhancu2602@gmail.com\u003e\nCo-authored-by: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e\nCo-authored-by: Twice \u003ctwice@apache.org\u003e\nCo-authored-by: Twice \u003ctwice.mliu@gmail.com\u003e"
    },
    {
      "commit": "cace9a0fd3ddc4d330e0d50602d8cd095e09b6c8",
      "tree": "570f4042201b17922fe9e9172bd859afa02b1052",
      "parents": [
        "bfe3cbdf86e19d750673780ae3a82ecd7d33b65d"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Wed Jul 08 00:43:09 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 08 00:43:09 2026 +0800"
      },
      "message": "fix(ci): update docker/build-push-action to v7.3.0 (#3548)\n\nThe CI workflow fails at startup because the ASF org allowed-actions\nlist removed the expired ref docker/build-push-action@d08e5c35 (v7.0.0)\nin apache/infrastructure-actions@062f6aa1, so any run referencing it is\nnow rejected before jobs start:\nhttps://github.com/apache/kvrocks/actions/runs/28851612255\n\nUpdate the pin in kvrocks.yaml and nightly.yaml to 53b7df96 (v7.3.0),\nwhich is on the current allowlist:\n\nhttps://github.com/apache/infrastructure-actions/blob/f9d4ef191a045ce5cbd552828450081a24e425fa/approved_patterns.yml#L134"
    },
    {
      "commit": "bfe3cbdf86e19d750673780ae3a82ecd7d33b65d",
      "tree": "1187bde42a8d5cb2a4179eb1091323f416997800",
      "parents": [
        "8830e26ebd82308741bb04d4f220ef0091c42c22"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Mon Jul 06 12:48:43 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 06 04:48:43 2026 +0000"
      },
      "message": "refactor(cluster): remove the redis-command migration type (#3544)\n\nThis PR removes the `redis-command` slot migration type, leaving\nraw-key-value\nas the only migration path. The raw-key-value type has been introduced\nfor a long time, and it outperforms the redis-command type in both\nresource consumption and migration speed, so we can remove it to\nsimplify the slot migration code. Also, the redis command migration\ndidn\u0027t work well after introducing more and more new data types.\n\nTo be noticed, there is no fallback anymore, the migration now fails\nwith the error `destination node doesn\u0027t support the APPLYBATCH command`\nif the destination\nnode doesn\u0027t support the APPLYBATCH command, instead of silently falling\nback to the redis-command type.\n\nAssistant By Claude Fable 5"
    },
    {
      "commit": "8830e26ebd82308741bb04d4f220ef0091c42c22",
      "tree": "8503dd3df1bd659d7d2055a90bc24d4dda0b3983",
      "parents": [
        "970c2876034b9cea2d3364b5cde345ccf57e17fe"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Mon Jul 06 11:35:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 06 11:35:19 2026 +0800"
      },
      "message": "fix(cluster): release forbidden slot range on CLUSTER RESET (#3545)\n\nAfter a slot has been migrated away, the source node keeps\n`forbidden_slot_range_` set. That is normally harmless because the\ntopology no longer routes the slot to this node, so the forbidden-slot\ncheck is never reached. But `CLUSTER RESET` clears the topology while\nleaving the migrator\u0027s forbidden range intact — a subsequent SETNODES\nthat reassigns the slot back to this node then spuriously rejects writes\nwith `TRYAGAIN Can\u0027t write to slot being migrated`. Explicitly release\nthe forbidden slot range in `Cluster::Reset` to fix this.\n\nAssistant-By: Claude Opus 4.7"
    },
    {
      "commit": "970c2876034b9cea2d3364b5cde345ccf57e17fe",
      "tree": "960a2678bd82221462be92acedb5b5fc362454a9",
      "parents": [
        "504220e80142fe0fe2640b7cbc415b54afa9e4a6"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Thu Jul 02 14:44:58 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 02 11:44:58 2026 +0000"
      },
      "message": "chore(deps): bump libevent to 2.1.13-stable (#3540)\n\nBump libevent to 2.1.13-stable (see:\nhttps://github.com/libevent/libevent/releases/tag/release-2.1.13-stable)\n\nSecurity fix release and some backports compiler warnings and fixes for\nopenssl 3 compatability."
    },
    {
      "commit": "504220e80142fe0fe2640b7cbc415b54afa9e4a6",
      "tree": "a22c5b46a5e252aa5b7da6a62385af37c4bf156b",
      "parents": [
        "8e0fdefd4c304ab6c0f81f83c0ba405a545b2e06"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Thu Jul 02 16:53:34 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 02 08:53:34 2026 +0000"
      },
      "message": "fix(ci): update the sonarscan to v8.2.0 (#3542)\n\nFix CI issue due to using the deprecated\nversion:https://github.com/apache/kvrocks/actions/runs/28533264944"
    },
    {
      "commit": "8e0fdefd4c304ab6c0f81f83c0ba405a545b2e06",
      "tree": "d2eaa780876f3af63b1953768938ca4efb2c2c1e",
      "parents": [
        "df461ea19c71ddddd826d1a7547db388d07c8353"
      ],
      "author": {
        "name": "hurukawa",
        "email": "61525444+nagisa-kunhah@users.noreply.github.com",
        "time": "Mon Jun 29 09:55:27 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 29 01:55:27 2026 +0000"
      },
      "message": "feat(cf): add cf.add command (#3481)\n\ntask id: #3351\n\n---------\n\nCo-authored-by: qiang_liu \u003cliuqiang9596@gmail.com\u003e\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "df461ea19c71ddddd826d1a7547db388d07c8353",
      "tree": "3c981a6996e91fdffd1252cfdee1bf990cc18528",
      "parents": [
        "6367221c55ec6470df5531389107bbc911684d68"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Fri Jun 26 05:33:31 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 26 10:33:31 2026 +0800"
      },
      "message": "chore(deps): bump rocksdb to v11.1.2 (#3537)\n\nBump rocksdb to v11.1.2 (bugfix release, see:\nhttps://github.com/facebook/rocksdb/releases/tag/v11.1.2)\n\nFixed a bug where closing a read-only DB instance could delete live SST\nfiles created by a concurrent read-write DB sharing the same directory"
    },
    {
      "commit": "6367221c55ec6470df5531389107bbc911684d68",
      "tree": "fef928c97687ee05631045a2622ad4c6cd989c0c",
      "parents": [
        "b0ae44fe7c8c4b3052d779f4ff3acd4b6aff078c"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Tue Jun 23 13:22:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 23 05:22:00 2026 +0000"
      },
      "message": "fix(server): scope CLIENT LIST/INFO/KILL to caller\u0027s namespace (#3536)\n\nNon-admin (tenant) connections could previously enumerate and terminate\nconnections belonging to other namespaces — including the admin\nnamespace and replication links — via CLIENT LIST and CLIENT KILL.\nFilter both per-worker iteration and the slave-thread enumeration by the\ncaller\u0027s namespace, allowing only admin (default-namespace) callers to\nsee or kill connections outside their own namespace.\n\nAssistant By Claude Opus 4.7"
    },
    {
      "commit": "b0ae44fe7c8c4b3052d779f4ff3acd4b6aff078c",
      "tree": "d8376963b7eb2af10416caff52f90f1afce8f361",
      "parents": [
        "ee98a2dafbb33aebabbbcab94c728a7e10fbc36e"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Mon Jun 22 08:59:01 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 22 08:59:01 2026 +0800"
      },
      "message": "chore(.asf.yaml): add 2.16 into protected branches (#3535)\n\nWe can add `2.16` to protected branches since it\u0027s released now."
    },
    {
      "commit": "ee98a2dafbb33aebabbbcab94c728a7e10fbc36e",
      "tree": "586f4cd056d2b1868fe152d0099d880759699f3e",
      "parents": [
        "d51384c05cecbcf4ac3b2adc4451444f45abaaac"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Thu Jun 18 19:44:38 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 19 00:44:38 2026 +0800"
      },
      "message": "chore(deps): bump fmtlib to 12.2.0 (#3532)\n\nBump fmtlib to 12.2.0 (changelog:\nhttps://github.com/fmtlib/fmt/releases/tag/12.2.0)\n\n**Key changes**\n\n- Added a C11 API that brings fast, type-safe formatting to C\n- Added a separate fmt::fmt-module CMake target for C++20 modules and a\nCI workflow that exercises module-based builds\n- Enabled the full Dragonbox lookup cache by default for floating-point\nformatting unless optimizing for binary size, giving a ~10–25% speedup.\n- Improved integer formatting performance by ~3%\n- Added support for formatting std::unexpected\n- Made various code, build and test improvements"
    },
    {
      "commit": "d51384c05cecbcf4ac3b2adc4451444f45abaaac",
      "tree": "3b2a94e775705055ae4bf3346b76e1c330d58ceb",
      "parents": [
        "812386c33fd5801377895abb39c65a429c48a20c"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Thu Jun 18 18:51:49 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 18 10:51:49 2026 +0000"
      },
      "message": "fix(test): extend the replication wait time to prevent the flaky test (#3531)\n\nCurrently, WaitForSync only allows 5s for master_link_status to reach\n\"up\",\nwhich is not enough under loaded CI runners (e.g. SonarCloud coverage\nbuilds);\n\nReproduced locally by running 16 background CPU burners and looping the\ntest:\n```\nfor i in $(seq 1 6); do\n   go test -count\u003d1 -run TestReplicationWithLimitSpeed$ \\\n      ./integration/replication/... \\\n      -binPath\u003d.../build/kvrocks -workspace\u003d/tmp/kvrocks-test-ws\ndone\n```\n\nBefore the fix: 1/6 runs failed with the same trace as the CI flake\n(\"Condition never satisfied\" at client.go:50, called from\nreplication_test.go:362).\nAfter the fix: 8/8 runs pass under the same CPU load (run times 34-51s\nvs. an\nunloaded baseline of ~28s, confirming load was active).\n\n\nRelated flaky run:\nhttps://github.com/apache/kvrocks/actions/runs/27660686644/job/81804342125\n\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-authored-by: Claude Opus 4.7 (1M context) \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "812386c33fd5801377895abb39c65a429c48a20c",
      "tree": "a25ac0b9955f86d26953f000d8229cae0f47eb1a",
      "parents": [
        "34f4e707fb8559d8cc2ce44f856013da60b24c1a"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Wed Jun 17 09:59:01 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 17 09:59:01 2026 +0800"
      },
      "message": "ci: fix version of docker/login-action (#3525)\n\nRefer to https://github.com/apache/kvrocks/actions/runs/27584460435\n\u003e The action\ndocker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 is not\nallowed in apache/kvrocks because all actions must be from a repository\nowned by your enterprise, created by GitHub, or match one of the\npatterns\n\nSo we need to update the version to one that appears in\nhttps://github.com/apache/infrastructure-actions/blob/main/approved_patterns.yml."
    },
    {
      "commit": "34f4e707fb8559d8cc2ce44f856013da60b24c1a",
      "tree": "9ffffee7d12dd9ef467ae66c82eaeb3c36c30a2a",
      "parents": [
        "082653ab258abd14b7987b58186be86ed4993fc3"
      ],
      "author": {
        "name": "Reilly.tang",
        "email": "tang.ruilin@foxmail.com",
        "time": "Tue Jun 16 19:36:44 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 16 19:36:44 2026 +0800"
      },
      "message": "perf(test): parallelize bitmap subtests and optimize Set2SetBit with pipeline (#3507)\n\nPart of #2642\n\n- Add t.Parallel() to all 34 subtests for concurrent execution\n- Use util.KeyPrefix(t) for unique key names per subtest\n- Replace per-bit SETBIT calls with pipelined SETBIT in Set2SetBit\n(reduces ~8000 RTTs to 1 RTT for 1000-byte vectors)\n- Replace defer with t.Cleanup() so resources live until subtests finish\n- Move KeyPrefix helper to dedicated keys.go\n- Fix duplicate test name \"BITPOS BIT not found check check\"\n- Test time: 52s → 11s (~4.7x speedup)\n\nAssisted-by: Claude Code:DeepSeek-v4-pro\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "082653ab258abd14b7987b58186be86ed4993fc3",
      "tree": "2c867fb5f3e85b58d6f94313f40ea82b6cae20e6",
      "parents": [
        "f7ea9b2ac8194789f4460c66dead5c180ec794a7"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Tue Jun 16 02:59:27 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 15 23:59:27 2026 +0000"
      },
      "message": "chore(deps): bump jsoncons to 1.8.1 (#3514)\n\nBump jsoncons to 1.8.0 (changelog:\nhttps://github.com/danielaparker/jsoncons/releases/tag/v1.8.0)\n\n**Key changes**\n\n- Bug fix (a lot of bugs are fixed!)\n- The types json_pointer_arg_t and json_const_pointer_arg_t have been\nrenamed to json_ptr_arg_t and const_json_ptr_arg_t, and the constants\njson_pointer_arg and json_const_pointer_arg have been renamed to\njson_ptr_arg and const_json_ptr_arg.\n- Since 1.8.0, the basic_json copy constructor makes a deep copy of any\nconst_json_ref and json_ref pointers it may hold."
    },
    {
      "commit": "f7ea9b2ac8194789f4460c66dead5c180ec794a7",
      "tree": "cab48b3e05ae9e140f8e56df5aae77f63879077b",
      "parents": [
        "77107c80fcf8268316cafaa73c6aa70230660d2b"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Fri Jun 12 22:36:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 12 14:36:48 2026 +0000"
      },
      "message": "fix(rdb): reject malformed intset lengths (#3519)\n\nRESTORE loads intset contents from a length-prefixed RDB string. The\nparser checked IntSetHeaderSize + len * record_size using 32-bit\narithmetic, so a large len could overflow the product and make a\nheader-only intset appear correctly sized. It then entered the entry\nloop and read beyond the provided input.\n\nBefore this patch, a RESTORE payload using int64 intset encoding and len\n0x20000000 timed out or terminated the server instead of returning a\nparse error. After this patch, the same payload returns \"ERR invalid\nintset length,\" and the server continues to respond to PING.\n\nValidate the encoding before using it as a record size, compare the\ndeclared length with the remaining payload to ensure no overflow, and\nperform a bounds check before each record read.\n\nAssistant By GPT-5.5 HIGH"
    },
    {
      "commit": "77107c80fcf8268316cafaa73c6aa70230660d2b",
      "tree": "474c7fa44f38c4f95e4ceae6fe47be9c3c6f8d1c",
      "parents": [
        "01c3426ac7a7c35e8898029c6101228ac91f5663"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Tue Jun 09 06:22:15 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 11:22:15 2026 +0800"
      },
      "message": "chore(deps): bump fast_float to v8.2.7 (#3513)\n\nBump fast_float to v8.2.7 (see:\nhttps://github.com/fastfloat/fast_float/releases/tag/v8.2.7)\n\n**Changes**\n\n- Skip materializing parsed_number_string_t spans on the hot path\n- Unroll the integer-part digit scan (straight-line for the common 1-5\ndigit case)\n- Add a 4-digit SWAR follow-up to loop_parse_if_eight_digits (clang)\n- Parallelize the exhaustive float32 sweeps across hardware threads\n(~75-88x)"
    },
    {
      "commit": "01c3426ac7a7c35e8898029c6101228ac91f5663",
      "tree": "8f8f4917f4d674836e315e5944a9a52cbd8fed9e",
      "parents": [
        "d90f248235b328dea3c0153c90e2f048c55bdd27"
      ],
      "author": {
        "name": "纪华裕",
        "email": "jihuayu123@gmail.com",
        "time": "Mon Jun 08 19:46:41 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 08 19:46:41 2026 +0800"
      },
      "message": "ci: exclude kvrocks2redis from sonar coverage (#3512)\n\nThe previous go test code coverage data could be overwritten by the\ncoverage data from kvrocks2redis, which caused the overall coverage\nmetric to be lower than expected.\n\nThis PR disables the `kvrocks2redis` tests in the SonarCloud coverage\njob to prevent them from corrupting gcov data generated by the main C++\nand Go tests.\n\n\nAssisted-by: Codex/GPT5.5 xhigh"
    },
    {
      "commit": "d90f248235b328dea3c0153c90e2f048c55bdd27",
      "tree": "ca8d5f20a46d46f52aed869d6135c8aa32f620fe",
      "parents": [
        "e51eb2ed9132385c40b3f6b06f30287681d8e2eb"
      ],
      "author": {
        "name": "Jarek Potiuk",
        "email": "jarek@potiuk.com",
        "time": "Fri Jun 05 04:32:04 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 05 10:32:04 2026 +0800"
      },
      "message": "chore(security): add draft threat model and SECURITY.md for security-model discoverability (#3509)\n\n**This is a draft proposal for the Kvrocks PMC to review — please\ncorrect, reject, or discuss as needed.** Nothing here is a requirement;\nthe maintainers are the decision-makers, and this document describes\nKvrocks *as the PMC says it is*.\n\nThis PR adds **`THREAT_MODEL.md`** + **`SECURITY.md`** and a\n**Security** section in `AGENTS.md`, so an automated scan agent can\nmechanically find the model via `AGENTS.md → SECURITY.md →\nTHREAT_MODEL.md`.\n\nIt is **draft-first and mostly inferred** (~16 documented / 0 maintainer\n/ ~50 inferred). Every `*(inferred)*` claim routes to a numbered\nquestion in **§14 Open questions** — the fastest review is to walk §14\n(three short waves) and answer in-thread; we then promote the tags to\n`*(maintainer)*`.\n\nThe **wave-1** rulings are load-bearing:\n\n- Is running **without `requirepass`** (the default) a supported posture\nrelying on `bind`/network controls, or must operators set it before\nexposing the port — i.e. is an unauthenticated-access report `BY-DESIGN`\nor `VALID`?\n- Same for **TLS-off** on an untrusted network — operator responsibility\nor a claimed gap?\n- Are **replication / cluster peers** trusted (out of the adversary\nmodel) or should a malicious peer be in scope?\n\n`apache/kvrocks-controller` is in scope for the scan too; per §14 q10 it\nwill get its **own** model (its trust surface — the cluster control\nplane — differs), which we\u0027ll open as a separate PR.\n\nContext: the ASF Security team is preparing the project for an automated\nagentic security scan we\u0027re piloting; a complete, discoverable threat\nmodel keeps that scan\u0027s output signal-rich. We drafted this via the\n[threat-model-producer](https://gist.github.com/potiuk/da14a826283038ddfe38cc9fe6310573)\nrubric. If you\u0027d rather author it yourselves, close this PR and we\u0027ll\nregroup."
    },
    {
      "commit": "e51eb2ed9132385c40b3f6b06f30287681d8e2eb",
      "tree": "cb6f78f792d72fa752a82affd87736eec2818959",
      "parents": [
        "82eaa90ecb57ceb6acf0d5345d1eecf57ee9a7aa"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Sat May 30 22:28:09 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat May 30 22:28:09 2026 +0800"
      },
      "message": "feat(hash): add HFE expire and TTL commands (#3506)\n\nCompletes the hash field expiration command family by adding the\nremaining HFE commands and wiring them through the existing metadata and\nfield-expiration helpers.\n\nCommands covered in this PR:\n- `HPEXPIRE`\n- `HEXPIREAT`\n- `HPEXPIREAT`\n- `HTTL`\n- `HPTTL`\n- `HEXPIRETIME`\n- `HPEXPIRETIME`\n\nThe PR also keeps `HEXPIRE` and `HPERSIST` on the same shared\nimplementation path, and adds C++/Go coverage for command semantics,\nparsing, time boundaries, legacy encoding rejection, and metadata\nbehavior.\n\nTracking issue: https://github.com/apache/kvrocks/issues/3436\nProposal: https://github.com/apache/kvrocks/discussions/3432\n\nAssisted-by: Codex/GPT5.5"
    },
    {
      "commit": "82eaa90ecb57ceb6acf0d5345d1eecf57ee9a7aa",
      "tree": "231e3516c08d1bc48cdc44a833f91c8d1afbdbdd",
      "parents": [
        "5264d5922189cecd1371d2a713244e6a7891950b"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Wed May 27 11:02:53 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 27 11:02:53 2026 +0800"
      },
      "message": "feat(hash): support HFE compaction filter (#3503)\n\nImplement HFE-aware RocksDB compaction filtering so expired hash fields\ncan be safely dropped, and whole hash metadata can be removed when all\nTTL fields are past the tracked upper bound.\n\nReferences the HFE proposal in #3432 and tracking issue #3436.\n\nAssisted-by: Codex/GPT5.5 xhigh"
    },
    {
      "commit": "5264d5922189cecd1371d2a713244e6a7891950b",
      "tree": "768164d2561afe8e06771b3014837ed8dec9fae7",
      "parents": [
        "27a6d8a780d11f1e88ef2292114a26604bf049ce"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Tue May 26 18:31:12 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue May 26 18:31:12 2026 +0800"
      },
      "message": "feat(hash): implement hlen scan repair (#3501)\n\nImplements the HLEN fast-path algorithms and SCAN_AND_REPAIR lazy\ndeletion for hash field expiration, including APPROX/REPAIR handling and\ncoverage for expired physical fields and compaction ghosts.\n\nFollows the HFE proposal in #3432 and addresses the HLEN/SCAN_AND_REPAIR\ntask from tracking issue #3436.\n\nAssisted-by: Codex/GPT5.5 xhigh"
    },
    {
      "commit": "27a6d8a780d11f1e88ef2292114a26604bf049ce",
      "tree": "fb006f282fe6b78a88d163721354089cf44c2375",
      "parents": [
        "41ee6ae547941ae1261e16540ca18af25c607f23"
      ],
      "author": {
        "name": "纪华裕",
        "email": "jihuayu123@gmail.com",
        "time": "Wed May 20 10:54:40 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 20 10:54:40 2026 +0800"
      },
      "message": "fix(scripting): sanitize lua error replies (#3494)\n\nfix https://github.com/apache/kvrocks/issues/3493\n\n\nLua\u0027s error return poses an injection risk; see issues for details.\n\nI used codex gpt-5.5 to fix it."
    },
    {
      "commit": "41ee6ae547941ae1261e16540ca18af25c607f23",
      "tree": "e310e488cc196172ac08a06525458323aa1bd51e",
      "parents": [
        "9c411259020ad46e6ed04575db6768e83e26e32f"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Mon May 18 19:47:02 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon May 18 19:47:02 2026 +0800"
      },
      "message": "fix(scripting): bump LuaJIT to reject bytecode loading (#3492)\n\nUpgrade LuaJIT to a build that disables loading binary bytecode chunks,\nmitigating a DoS where crafted bytecode could crash the server. Add a\nregression test that confirms `loadstring` on malformed bytecode is\nrefused with \"attempt to load chunk with wrong mode\" and the server\nkeeps serving requests."
    },
    {
      "commit": "9c411259020ad46e6ed04575db6768e83e26e32f",
      "tree": "e0ce97ecba0a14cca92ee40fa1bdeba1ba166d53",
      "parents": [
        "88009fad36b3a4e1d71fb58db588ebce071761be"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Sun May 17 18:25:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun May 17 13:25:15 2026 +0300"
      },
      "message": "chore(scan): remove additional abstraction for subkey scanning (#3490)\n\nThese abstraction is for hash subkey scanning, but now we don\u0027t use it\nanymore. So better to remove them."
    },
    {
      "commit": "88009fad36b3a4e1d71fb58db588ebce071761be",
      "tree": "e1d1ff29a0e621eca5b329feef4369b93769bc89",
      "parents": [
        "13e5cae2ecea271e3edac4e33dea780b0eb4d23d"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Sun May 17 12:49:24 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun May 17 04:49:24 2026 +0000"
      },
      "message": "feat(hash): restrict condition for hash encoding mode (#3488)\n\n`encoded_mode \u003d\u003d 0` should not be valid here since when encoding mode is\nlegacy this field should be missing."
    },
    {
      "commit": "13e5cae2ecea271e3edac4e33dea780b0eb4d23d",
      "tree": "e1bb37b6a9ace7b26ff8c1fb02783fdcb1d9ee40",
      "parents": [
        "d42d0c7f74d51b26d8cf982961a9f10de1e33baa"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Fri May 15 23:58:26 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri May 15 15:58:26 2026 +0000"
      },
      "message": "feat(hash): track persistent hash fields \u0026 support hash field expiration commands (#3472)\n\nProposal #3432. Tracking issue #3436.  \n\nAdd hash field expiration support based on the new persistent-field\nmetadata model.\n\n  This PR:\n- Tracks persistent hash fields in metadata for field-expiration\nencoding.\n  - Adds `HEXPIRE` and `HPERSIST`.\n- Updates existing hash read/write commands to handle expired fields\ncorrectly.\n- Filters expired fields from hash read commands without mutating\nmetadata.\n- Adds C++ and Go coverage for persistent, TTL, expired, and\ncompaction-ghost states.\n\nAssisted-by: Codex/GPT 5.5 xhigh"
    },
    {
      "commit": "d42d0c7f74d51b26d8cf982961a9f10de1e33baa",
      "tree": "471f83c166008a44ae37a5e98e23304b57fddeae",
      "parents": [
        "b654013bb65a791cea2154bbc31789353c495332"
      ],
      "author": {
        "name": "纪华裕",
        "email": "jihuayu123@gmail.com",
        "time": "Wed May 13 14:19:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 13 14:19:04 2026 +0800"
      },
      "message": "fix(zset): register zdiffstore as write command (#3486)\n\n`ZDIFFSTORE` writes results to a destination key, but it was previously\nregistered as `read-only slow`. I fix it.\n\n\nI used codex gpt-5.5 to find and fix it."
    },
    {
      "commit": "b654013bb65a791cea2154bbc31789353c495332",
      "tree": "a7ca07d5ddb632b101398b257ba5382682c94b45",
      "parents": [
        "3e564ca4d0374130ad00a9c9ec03989c2ef44cf0"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Tue May 12 07:56:44 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue May 12 04:56:44 2026 +0000"
      },
      "message": "chore(test): bump Go-version to 1.25 for tests (#3485)\n\nI propose updating the minimum required Go version to 1.25.\n\nWe are not moving to 1.26 yet because our CI still builds on OpenSUSE\nLeap 15, where Go 1.25 (1.25.8) is the version available in the base\nrepositories. Go 1.26 is currently only present in the devel repository."
    },
    {
      "commit": "3e564ca4d0374130ad00a9c9ec03989c2ef44cf0",
      "tree": "526999a4e2a76f73003d2db3d8adc6c0f81e3e3c",
      "parents": [
        "47e08935c6fb4ec604d4d650860abca546b83c51"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Mon May 11 18:44:36 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon May 11 18:44:36 2026 +0800"
      },
      "message": "fix(replication): reject unsafe fullsync file names (#3483)\n\nReplication fullsync uses the peer\u0027s file names to fetch checkpoint\nfiles\nand materialize them in the local sync checkpoint directory. Previously,\nthose names were joined directly with local directories,\nso traversal components could escape the intended directory during\nexistence checks,\ntemporary file creation, rename, cleanup, or master-side file open.\n\nAssisted-by: Codex/GPT 5.5 xhigh"
    },
    {
      "commit": "47e08935c6fb4ec604d4d650860abca546b83c51",
      "tree": "9a6c779b52ed7e2f13ff97347c3b73865fb191ff",
      "parents": [
        "caf24a60f4a3a7330f34c1b7d8c07140ce872b23"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Mon May 11 12:22:55 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon May 11 12:22:55 2026 +0800"
      },
      "message": "fix(replication): require admin for transfer commands (#3484)\n\nMark PSYNC, _FETCH_META, and _FETCH_FILE as admin-only commands so\nnamespace users cannot invoke replication transfer internals.\n\nMove the regression coverage into the integration replication suite,\nwhere the command behavior is exercised against a running server.\n\nAssisted-by: Codex/GPT 5.5 xhigh"
    },
    {
      "commit": "caf24a60f4a3a7330f34c1b7d8c07140ce872b23",
      "tree": "45b58a43bc23866de475f7645bd030c89f825412",
      "parents": [
        "07a67beadd2efeaec6abfcb90f07b6c23e386e96"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Wed May 06 18:04:59 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 06 15:04:59 2026 +0000"
      },
      "message": "chore(build): bump golangci-lint to 2.12.1 (#3476)\n\nBump golangci-lint to 2.12.1 (changelog:\nhttps://golangci-lint.run/docs/product/changelog/#v2121)\n\nBugfix and update a lot of linters"
    },
    {
      "commit": "07a67beadd2efeaec6abfcb90f07b6c23e386e96",
      "tree": "443e8eba4aa0944c59f4a8ea3917073f9435b296",
      "parents": [
        "cbafb7a9142d234759fbdd9db1938757cb28f95f"
      ],
      "author": {
        "name": "kirito632",
        "email": "debuaqua40@gmail.com",
        "time": "Wed May 06 22:01:26 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 06 22:01:26 2026 +0800"
      },
      "message": "feat(string): support IFEQ/IFNE/IFDEQ/IFDNE in SET command (#3475)\n\n## What\nReintroduce conditional options IFEQ / IFNE / IFDEQ / IFDNE for the SET\ncommand.\n\n## Context\nThis is a clean, reworked version of the previously closed #3452.  \nIt addresses all previous feedback, reverts the accidental deletion of\n`CommandDelEX`, and is fully rebased onto the latest `unstable` branch.\n\nAll CI checks have been successfully run and verified on my personal\nfork before submission.\n\n## Behavior\n- IFEQ / IFNE: case-sensitive value comparison  \n- IFDEQ / IFDNE: case-insensitive digest comparison  \n- Return `WRONGTYPE` for non-string keys  \n- Mutually exclusive with NX/XX  \n- Fix: `SET key value NX GET` now correctly returns `WRONGTYPE` for\nnon-string keys (matching Redis 8.x behavior)\n\n## Testing\n- C++ unit test: Kept only the IFDEQ empty-string boundary coverage  \n- Go integration tests: Syntax, behavior, edge cases (uppercase \u0026\nmalformed digests), and regression coverage\n\n## AI-assisted Contribution Disclosure\nAI was used for code pattern suggestions, test scaffolding, and\ndebugging assistance.\nCore logic, bug fixes, validation, and final implementation were written\nand verified manually.\n\nCo-authored-by: hulk \u003chulk.website@gmail.com\u003e\nCo-authored-by: jihuayu \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "cbafb7a9142d234759fbdd9db1938757cb28f95f",
      "tree": "5ec02bb17a68172807f4d7359669ef39e448805f",
      "parents": [
        "fbe066f65b603b9da4bd5b3fefe3810cb59dd193"
      ],
      "author": {
        "name": "gongna-au",
        "email": "2036479155@qq.com",
        "time": "Wed May 06 11:45:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 06 03:45:15 2026 +0000"
      },
      "message": "feat(bit): add BYTE/BIT option support for BITPOS command (#3460)\n\n## Summary\nThis PR adds support for the `BYTE`/`BIT` unit option to the `BITPOS`\ncommand, aligning it with the Redis 7.0 specification.\n\nThe previous implementation only checked for `BIT` at a fixed argument\nposition (`args[5]`) and ignored `BYTE` entirely. This PR refactors the\nparser to correctly handle the full Redis 7.0 syntax:\n\n```\nBITPOS key bit [start [end [BYTE | BIT]]]\n```\n\nThe `BYTE|BIT` unit is strictly nested: it can only appear after both\n`start` and `end` are provided, matching Redis behavior exactly.\n\n## Changes\n### 1. Command Parser Refactor (`src/commands/cmd_bit.cc`)\n- Refactored `CommandBitPos::Parse` to cleanly separate argument parsing\nby count.\n- `args[4]` (the 5th argument) is always parsed as the `end` integer —\nnever as a unit keyword. This matches Redis, which rejects `BITPOS key 1\n0 BIT` with a \"not an integer\" error.\n- `args[5]` (the 6th argument) is checked for `BIT`/`BYTE` keyword, with\n`errInvalidSyntax` on anything else.\n- Added explicit `BYTE` recognition (previously only `BIT` was partially\nhandled).\n- Moved `bit` argument validation to the top for clarity.\n- Replaced verbose `ParseInt` + manual error check with `GET_OR_RET`\nmacro for consistency.\n\n### 2. Storage Layer — No Changes Needed\n- The `CHECK(stop_given)` assertion in `Bitmap::BitPos` is preserved as\na defensive guard. Since the parser guarantees `stop_given\u003dtrue`\nwhenever `is_bit_index\u003dtrue` (unit keyword requires `end` to be\npresent), this assertion is correct and protects against future\nregressions.\n\n## Compatibility\n\n| Command Form | Redis 7.0 | Kvrocks (after PR) |\n| --- | --- | --- |\n| `BITPOS key bit` | OK | OK |\n| `BITPOS key bit start` | OK | OK |\n| `BITPOS key bit start end` | OK | OK |\n| `BITPOS key bit start end BYTE` | OK (since 7.0) | **OK (new)** |\n| `BITPOS key bit start end BIT` | OK (since 7.0) | **OK (new)** |\n| `BITPOS key bit start BIT` | ERR not integer | ERR not integer |\n\n## Verification\n- Argument parsing logic verified against Redis 7.0 syntax definition:\n`BITPOS key bit [start [end [BYTE | BIT]]]`.\n- `is_bit_index` is only set when `args.size() \u003d\u003d 6`, guaranteeing\n`stop_given_ \u003d\u003d true`, so the `CHECK(stop_given)` assertion in the\nstorage layer is always satisfied.\n- `BITCOUNT` already has correct `BYTE/BIT` support and is not affected\nby this PR.\n\nCo-authored-by: gongna-au \u003cgongna1@xiaomi.com\u003e\nCo-authored-by: Sisyphus \u003cclio-agent@sisyphuslabs.ai\u003e\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "fbe066f65b603b9da4bd5b3fefe3810cb59dd193",
      "tree": "fee89836ff63f0407542af95665d63ea7072d90e",
      "parents": [
        "c8a66e2caf86217650786a5b58d852759a6877ac"
      ],
      "author": {
        "name": "Nikhil K Tyagi",
        "email": "nikhilq.75@gmail.com",
        "time": "Wed May 06 07:26:36 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 06 09:56:36 2026 +0800"
      },
      "message": "fix(bitfield): support Redis positional \u0027#N\u0027 offset syntax (#3470)\n\nLinked issue #3469 \n\n## Problem\n`BITFIELD` commands with positional offset `#N` syntax failed in\nkvrocks. Redis supports `#N` as shorthand for `N * bit_width`, so\n`INCRBY u16 #0 1` means bit\noffset `0 * 16 \u003d 0`, `#1` means `16`, etc.\nExample that worked in Redis but not kvrocks:\nBITFIELD mykey OVERFLOW SAT INCRBY u16 #0 1\n## Root Cause\n`GetBitOffsetFromArgument` called `ParseInt\u003cuint32_t\u003e` directly on\noffset string. `\"#0\"` fails integer parsing — `#` prefix was never\nhandled.\n## Fix\nIn `CommandBitfield::Parse()`, after encoding is parsed (bit width\nknown), detect `#` prefix and expand: `offset \u003d N * encoding.Bits()`.\nPlain integer offsets\n  unchanged.\n## Test\nAdded integration tests in\n`tests/gocase/unit/type/bitmap/bitmap_test.go` covering:\n- `SET`/`GET` with `#N` across multiple positions\n- `INCRBY` with `#N`\n- `OVERFLOW SAT INCRBY` with `#N` (original failing case)\n  - `BITFIELD_RO GET` with `#N`\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 \u003cnoreply@anthropic.com\u003e\nCo-authored-by: Vikram Alagh \u003csixthkrum@gmail.com\u003e\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e\nCo-authored-by: Aleks Lozovyuk \u003caleks.raiden@gmail.com\u003e"
    },
    {
      "commit": "c8a66e2caf86217650786a5b58d852759a6877ac",
      "tree": "16e15473b37b933bea84b97f6a9755d35c9b9885",
      "parents": [
        "5dcf4f6b31ebafd2da57f6b24212c496a3f6871a"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Mon May 04 11:53:44 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon May 04 16:53:44 2026 +0800"
      },
      "message": "chore(build): change base docker image to debian:trixie-slim (#3478)\n\nChange base docker image to debian:trixie-slim - current used bookworm\nare too old. So, I propose to use stable tagged Debian image - now it\u0027s\na codename trixie."
    },
    {
      "commit": "5dcf4f6b31ebafd2da57f6b24212c496a3f6871a",
      "tree": "c3fc5138c771d2ced7ca34d34936c5c780dd59cf",
      "parents": [
        "e23fdb4eedf7e9620a2e150514fe76ef5c125d3a"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Sun May 03 17:41:49 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun May 03 17:41:49 2026 +0300"
      },
      "message": "chore(deps): bump fast_float to 8.2.5 (#3479)\n\nBump fast_float to 8.2.5 (see:\nhttps://github.com/fastfloat/fast_float/releases/tag/v8.2.5)\n\nChanges\n - Replace std::min with ternary operators to avoid dependency"
    },
    {
      "commit": "e23fdb4eedf7e9620a2e150514fe76ef5c125d3a",
      "tree": "1c7b079b37e337a6229c18d9f00ce838a86c7c4c",
      "parents": [
        "acc9790b2aa2909b9c8fb8a624df8801baec43e5"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Sun May 03 16:00:11 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun May 03 13:00:11 2026 +0000"
      },
      "message": "chore(build): jemalloc disable flag for ArchLinux build (#3480)\n\nWe need to disable jemalloc (and use system) at Arch (due to error with\nstd::__throw_bad_alloc, its patch at this PR\nhttps://github.com/jemalloc/jemalloc/pull/2900)\n\n---------\n\nCo-authored-by: Twice \u003ctwice.mliu@gmail.com\u003e"
    },
    {
      "commit": "acc9790b2aa2909b9c8fb8a624df8801baec43e5",
      "tree": "9841f651d5db5a22473ec7de986fe05dc593b44f",
      "parents": [
        "4b4ce236870adf32ccfc217f1ce03f64180fa32b"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Sat May 02 20:21:04 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun May 03 01:21:04 2026 +0800"
      },
      "message": "chore(build): Move environment variables from RUN to dedicated ENV instruction (#3477)\n\nRemove `ENV` variables from the `RUN` instruction and use the dedicated\n`ENV` directive instead.\n\nThis change eliminates the following debconf warnings that appear during\npackage updates:\n\n`\n#8 5.404 debconf: unable to initialize frontend: Dialog\n#8 5.404 debconf: (TERM is not set, so the dialog frontend is not\nusable.)\n#8 5.404 debconf: falling back to frontend: Readline\n#8 5.404 debconf: unable to initialize frontend: Readline\n#8 5.404 debconf: (Can\u0027t locate Term/ReadLine.pm in @INC (you may need\nto install the Term::ReadLine module) (@INC contains: /etc/perl\n/usr/local/lib/x86_64-linux-gnu/perl/5.36.0 /usr/local/share/perl/5.36.0\n/usr/lib/x86_64-linux-gnu/perl5/5.36 /usr/share/perl5\n/usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.36\n/usr/share/perl/5.36 /usr/local/lib/site_perl) at\n/usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)\n#8 5.404 debconf: falling back to frontend: Teletype\n`"
    },
    {
      "commit": "4b4ce236870adf32ccfc217f1ce03f64180fa32b",
      "tree": "47ad4d38265cb73435c8fc9b6bcc8c3c4d8dc94c",
      "parents": [
        "7a34b9853007a846de654d1ebad1a22989cbbcfd"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Sat May 02 08:52:33 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat May 02 05:52:33 2026 +0000"
      },
      "message": "chore(deps): bump rocksdb to v11.1.1 (#3468)\n\nBump rocksdb to v11.1.1 (see:\nhttps://github.com/facebook/rocksdb/releases/tag/v11.1.1)\n\n**This PR need to merge** #3431 \n\n**Key changes**\n\n- Fix a bug in round-robin compaction that missed selecting input files\nthat are needed to guarantee data correctness and cause crashing in\ndebug builds or silent data corruption in release builds for Get()\n- Fix a memory accounting leak in IODispatcher\n- Add a new option open_files_async\n- Added BlockBasedTableOptions::kAuto index block search type that\nautomatically selects between binary and interpolation search on a\nper-index-block basis\n- Add memtable_batch_lookup_optimization option to use batch lookup\noptimization for memtable MultiGet\n- Added new mutable DB option verify_manifest_content_on_close (default:\nfalse)\n-\n\n---------\n\nCo-authored-by: PragmaTwice \u003ctwice@apache.org\u003e\nCo-authored-by: Twice \u003ctwice.mliu@gmail.com\u003e"
    },
    {
      "commit": "7a34b9853007a846de654d1ebad1a22989cbbcfd",
      "tree": "dd9a861a4cda36c49b3996a6ab819d00e4a5abab",
      "parents": [
        "3b29a4c768e4c37cc7ab051d8ac129e467bb1ea2"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Fri May 01 16:56:25 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri May 01 13:56:25 2026 +0000"
      },
      "message": "chore(deps): bump oneTBB to v2023.0.0 (#3473)\n\nBump oneTBB to v2023.0.0 (see:\nhttps://github.com/uxlfoundation/oneTBB/blob/master/RELEASE_NOTES.md)\n\nKey changes\n- Introduced ability to wait for a single task in a task_group instead\nof waiting for all tasks to finish. This increases reactivity and\ndecreases latency in key user workloads.\n- Introduced task_arena core type selector to better support hybrid\narchitectures with several core types\n- Added global control parameter to set default block time behavior on\nserver HW\n- Added new API to create a set of NUMA bound task arenas, simplifying\ncommon patterns used to optimize for NUMA architectures.\n- Using a hwloc version other than 1.11, 2.0, or 2.5 may cause an\nundefined behavior on Windows OS\n- Significantly improved scalability for concurrent ordered containers\non systems with many threads\n- Fixed ODR violations when public inline functions expose entities with\ninternal linkage\n-\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "3b29a4c768e4c37cc7ab051d8ac129e467bb1ea2",
      "tree": "8ab4c0bbdd870d0b200dbe3cd15cc8c0b244eedf",
      "parents": [
        "04d4e7fce8d1ad57178e56e5d97b7838dee619cc"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Fri May 01 15:59:15 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri May 01 20:59:15 2026 +0800"
      },
      "message": "chore(ci): bump crate-ci/typos to v1.46.0 (#3474)\n\nBump crate-ci/typos to v1.46.0\n\nChanges:\n\n- Updated the dictionary\n- Ignore ssh ed25519 public keys\n- (action) Use a temp dir for caching"
    },
    {
      "commit": "04d4e7fce8d1ad57178e56e5d97b7838dee619cc",
      "tree": "df1f62f3cb8a814f08e140e3e8033abb35953891",
      "parents": [
        "b04211e84efd6d694a0418d70ce029e02db2073e"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Wed Apr 29 05:59:12 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 29 02:59:12 2026 +0000"
      },
      "message": "chore(deps): bump jsoncons to v1.7.0 (#3464)\n\nBump jsoncons to v1.7.0 (full changelog:\nhttps://github.com/danielaparker/jsoncons/releases/tag/v1.7.0)\n\nKey changes\n\n- The jsonschema enum class walk_result has been renamed to walk_state\n- The enum staj_event_type has been redefined as a [BitMask\nType](https://en.cppreference.com/w/cpp/named_req/BitmaskType.html)\n- Reduced allocations in jsonschema compilation and validation\n- Fixed bugs"
    },
    {
      "commit": "b04211e84efd6d694a0418d70ce029e02db2073e",
      "tree": "7dd6702498a572f885638daf37ab32a8fba85689",
      "parents": [
        "27eae0d199b6a40b296d895073658354850087d6"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Wed Apr 29 09:59:24 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 29 09:59:24 2026 +0800"
      },
      "message": "fix(scripting): reject negative FCALL key count (#3466)\n\nFCALL and FCALL_RO accepted numkeys\u003d-1 because the validation only\nrejected values\nsmaller than -1. That value was then used to construct key/arg vector\nranges from\nthe command arguments, which can produce an invalid iterator range and\ncrash or\nmis-handle the request.\n\nReject all negative numkeys values before splitting keys and args,\nmatching the\ncommand error message and preventing malformed FCALL input from reaching\nthe Lua\ncall path.\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "27eae0d199b6a40b296d895073658354850087d6",
      "tree": "4a3088114bc8f502b90a726038d48f4a534ff69e",
      "parents": [
        "edb033e5eb910c8663b69432096a704885430354"
      ],
      "author": {
        "name": "gongna-au",
        "email": "2036479155@qq.com",
        "time": "Tue Apr 28 17:47:13 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Apr 28 17:47:13 2026 +0800"
      },
      "message": "feat(commands): implement CLIENT SETINFO subcommand (#3465)\n\n## Summary\n\nImplement the `CLIENT SETINFO` subcommand (introduced in Redis 7.2) to\nallow clients to set `lib-name` and `lib-ver` metadata on the\nconnection. Many modern Redis SDKs (go-redis v9, jedis 5, redis-py 5)\nautomatically send `CLIENT SETINFO` on connect — without this support,\nthose clients log errors on every new connection.\n\n## Changes\n\n- **`src/server/redis_connection.h`**: Add `lib_name_` / `lib_ver_`\nfields and getters/setters to the `Connection` class.\n- **`src/server/redis_connection.cc`**: Include `lib-name\u003d` and\n`lib-ver\u003d` in `CLIENT LIST` / `CLIENT INFO` output, matching the Redis\noutput format.\n- **`src/commands/cmd_server.cc`**: Add `SETINFO` subcommand parsing and\nexecution in `CommandClient`. Supports `LIB-NAME` and `LIB-VER`\nattributes, validates charset (same rules as `SETNAME`), and rejects\nunrecognized attributes.\n- **`tests/gocase/unit/client/client_setinfo_test.go`**: Integration\ntests covering set/get, `CLIENT INFO`/`LIST` output, case-insensitivity,\nempty value (clear), unknown attribute rejection, and invalid\ncharacters.\n\n## Behavior\n\n```\n\u003e CLIENT SETINFO LIB-NAME go-redis\nOK\n\u003e CLIENT SETINFO LIB-VER 9.7.0\nOK\n\u003e CLIENT INFO\nid\u003d3 addr\u003d127.0.0.1:6379 fd\u003d8 name\u003d age\u003d5 idle\u003d0 flags\u003dN namespace\u003d qbuf\u003d0 obuf\u003d0 cmd\u003dclient lib-name\u003dgo-redis lib-ver\u003d9.7.0\n```\n\n- `CLIENT SETINFO LIB-NAME \u003cvalue\u003e` — sets the client library name\n- `CLIENT SETINFO LIB-VER \u003cvalue\u003e` — sets the client library version\n- Empty string clears the field\n- Attribute names are case-insensitive\n- Values follow the same charset restriction as `CLIENT SETNAME` (no\nspaces/control chars)\n- Unrecognized attributes return: `ERR Unrecognized option \u0027\u003cattr\u003e\u0027`\n\n---------\n\nCo-authored-by: gongna-au \u003cgongna1@xiaomi.com\u003e\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "edb033e5eb910c8663b69432096a704885430354",
      "tree": "efb9f277b71513b5a7db27c150344c00a125b392",
      "parents": [
        "855bad3c13b6fd9fc9d8397ade8aa1a05dc747b5"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Tue Apr 28 10:25:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Apr 28 02:25:15 2026 +0000"
      },
      "message": "fix(stream): align XPENDING ID parsing and PEL range with XRANGE (incomplete IDs, exclusive bounds) (#3437)\n\nXPENDING extended form must use the same start/end ID rules as XRANGE:\nparse the end with ParseRangeEnd so a bare millisecond includes all\nsequence numbers in that ms; accept \u0027(\u0027 for exclusive start/end and\nhonor them when scanning the pending entry list.\n  \nRefs: https://redis.io/docs/latest/commands/xpending/ (\"in a similar way\nwe do it with XRANGE\")\nRefs: https://redis.io/docs/latest/commands/xrange/ (\"closed interval\" /\ninclusive unless \u0027(\u0027 prefix)\n\n---------\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "855bad3c13b6fd9fc9d8397ade8aa1a05dc747b5",
      "tree": "5754fbdbab88e255afa7e52e8fe16c4dc9ad0ef2",
      "parents": [
        "34ce39843bd3527d8e48e394b341fbb6c3c3a811"
      ],
      "author": {
        "name": "gongna-au",
        "email": "2036479155@qq.com",
        "time": "Mon Apr 27 21:20:35 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Apr 27 13:20:35 2026 +0000"
      },
      "message": "feat(server): implement LATENCY command set (Redis 7.0+ compatibility) (#3461)\n\n## Summary\nThis PR implements the `LATENCY` command for Kvrocks, focusing on the\n`LATENCY HISTOGRAM` subcommand introduced in Redis 7.0. It leverages the\nexisting histogram infrastructure (`histogram-bucket-boundaries` config\n+ `CommandHistogram` stats) to expose per-command latency distributions\nvia the standard Redis protocol.\n\n## Changes\n### New File: `src/commands/cmd_latency.cc`\n\nImplements `CommandLatency` with three subcommands:\n\n- **`LATENCY HISTOGRAM [command ...]`** — Returns a cumulative\ndistribution of command latencies.\n- Output uses the Redis 7.0 format: outer map keyed by command name,\neach value is a map with `calls` (integer) and `histogram_usec` (map of\nboundary → cumulative count).\n- Frequency counts from `CommandHistogram::buckets` are converted to\ncumulative sums at output time.\n- Empty leading buckets are skipped (matching Redis behavior of omitting\nzero-count ranges).\n  - The last bucket (overflow) is rendered as `\"inf\"`.\n- Returns an empty map if `histogram-bucket-boundaries` is not\nconfigured.\n\n- **`LATENCY RESET [event ...]`** — Returns `(integer) 0`.\n- In Redis, this resets the spike-sampling event system (`LATENCY\nLATEST`/`HISTORY`/`GRAPH`), which Kvrocks does not have. Per Redis docs,\nhistogram data is reset via `CONFIG RESETSTAT`, not `LATENCY RESET`.\nReturning 0 correctly indicates no event classes were reset.\n\n- **`LATENCY HELP`** — Returns usage information for all supported\nsubcommands.\n\n### Build System\nNo changes needed. The file is automatically picked up by\n`file(GLOB_RECURSE KVROCKS_SRCS src/*.cc)` in root `CMakeLists.txt`.\n\n### Command Registration\nRegistered under `CommandCategory::Server` via\n`REDIS_REGISTER_COMMANDS(Server, ...)`, same category as\n`cmd_server.cc`. This is safe because the macro generates unique static\nvariables per translation unit using `__LINE__`.\n\n## Compatibility\n\n| Subcommand | Redis | Kvrocks | Note |\n| --- | --- | --- | --- |\n| `LATENCY HISTOGRAM [cmd ...]` | 7.0+ | **Yes** | Cumulative\ndistribution, `histogram_usec` field, empty buckets skipped |\n| `LATENCY HELP` | 7.0+ | **Yes** | |\n| `LATENCY RESET [event ...]` | 2.8.13+ | **Yes** | Always returns 0 (no\nspike-sampling infrastructure) |\n| `LATENCY LATEST` | 2.8.13+ | No | Requires spike-sampling event system\n|\n| `LATENCY HISTORY event` | 2.8.13+ | No | Requires spike-sampling event\nsystem |\n| `LATENCY GRAPH event` | 2.8.13+ | No | Requires spike-sampling event\nsystem |\n| `LATENCY DOCTOR` | 2.8.13+ | No | Requires spike-sampling event system\n|\n\n## Configuration Prerequisite\nHistograms are only tracked when `histogram-bucket-boundaries` is set in\n`kvrocks.conf`. Example:\n```\nhistogram-bucket-boundaries 1,5,10,25,50,100,250,500,1000,2500,5000,10000\n```\nIf empty (default), `LATENCY HISTOGRAM` returns an empty map — this is\nexpected behavior, not an error.\n\n## RESP Protocol Details\n- Uses RESP3 Map (`%`) via `conn-\u003eHeaderOfMap()`, which auto-degrades to\ninterleaved RESP2 arrays.\n- Per-command entry structure:\n  ```\n  command_name \u003d\u003e {\n    \"calls\"          \u003d\u003e (integer) N,\n    \"histogram_usec\" \u003d\u003e {\n      boundary_1 \u003d\u003e (integer) cumulative_count_1,\n      boundary_2 \u003d\u003e (integer) cumulative_count_2,\n      ...\n      \"inf\"      \u003d\u003e (integer) total_calls\n    }\n  }\n  ```\n\nCo-authored-by: gongna-au \u003cgongna1@xiaomi.com\u003e\nCo-authored-by: Sisyphus \u003cclio-agent@sisyphuslabs.ai\u003e\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "34ce39843bd3527d8e48e394b341fbb6c3c3a811",
      "tree": "7989f716e2023a0b2d4a1d0f718347dc8544b5d7",
      "parents": [
        "2fb270c77e2175fd0a9f3be73e550712e0876cdb"
      ],
      "author": {
        "name": "kirito632",
        "email": "debuaqua40@gmail.com",
        "time": "Mon Apr 27 14:56:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Apr 27 06:56:04 2026 +0000"
      },
      "message": "feat(string): add digest length validation for DelEX IFDEQ/IFDNE (#3453)\n\n- Add 16-character digest validation for IFDEQ/IFDNE options in DelEX\ncommand\n- Return clear error if digest length is not exactly 16 hexadecimal\ncharacters\n- Add test case for invalid digest length rejection as requested by\nreviewer\n\n### AI-Assisted Contribution Disclosure\nThis contribution complies with the [ASF AI-assisted contribution\nguidelines](https://kvrocks.apache.org/community/contributing#guidelines-for-ai-assisted-contributions).\n* **AI Tool Usage :** AI was used to help format the Go test template\nbased on the reviewer\u0027s feedback and to reference the `util::EqualICase`\npattern.\n* **Human Implementation \u0026 Validation:** I manually implemented the\ncase-insensitive digest comparison logic for the `DelEX` command and\nintegrated the requested test cases. I fully understand these behavioral\nchanges (aligning with Redis Stack) and have successfully run all\nregression tests locally.\n\nThis commit only modifies DelEX command behavior.\n\n---------\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "2fb270c77e2175fd0a9f3be73e550712e0876cdb",
      "tree": "9e0c66bd1551db41703110c9935a9e44bedb0959",
      "parents": [
        "8d021258308790627524f2cae594c75f22be2c31"
      ],
      "author": {
        "name": "Reilly.tang",
        "email": "tang.ruilin@foxmail.com",
        "time": "Mon Apr 27 12:25:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Apr 27 12:25:15 2026 +0800"
      },
      "message": "fix(tdigest): fix incorrect min/max default initialization (#3463)"
    },
    {
      "commit": "8d021258308790627524f2cae594c75f22be2c31",
      "tree": "50ddffea422f47ffcb64713b7bc9382af8e68504",
      "parents": [
        "2520bdac5a61b3515c7db6aff3c145e04c26b1cb"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Fri Apr 24 13:18:31 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Apr 24 13:18:31 2026 +0800"
      },
      "message": "docs(agents): clarify agent workflow guidance (#3455)\n\nThis updates AGENTS.md to make repository-specific workflows clearer so\nagents can work more reliably and efficiently.\n\nAssisted-by: Codex"
    },
    {
      "commit": "2520bdac5a61b3515c7db6aff3c145e04c26b1cb",
      "tree": "2535319a0404ec8d7f6c23e68810aef414ff7d1d",
      "parents": [
        "7c4972814fcbeee94011fc17cafc542798379a51"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Wed Apr 22 10:33:35 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 22 02:33:35 2026 +0000"
      },
      "message": "fix(command): APPLYBATCH should use the admin permission (#3458)\n\nThe server will apply whatever it writes in APPLYBATCH command, so we\nshould make sure it is only being sent with the admin permission.\n\nThis is a breaking change from the user side, we need to highlight this\nin the release."
    },
    {
      "commit": "7c4972814fcbeee94011fc17cafc542798379a51",
      "tree": "c411a10ee127d8e9b95e19abfd02bfa39ca005f6",
      "parents": [
        "64188fedbe891aefaa6d24c4093b40c0c3f6d82a"
      ],
      "author": {
        "name": "纪华裕",
        "email": "jihuayu123@gmail.com",
        "time": "Tue Apr 21 22:22:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Apr 21 14:22:54 2026 +0000"
      },
      "message": "fix(geo): make geo store commands return the resulting set size with COUNT (#3457)\n\nFix the return value of geo store commands when `COUNT` is specified.\n\nPreviously, these commands stored only the limited number of members in\nthe destination zset, but returned the full matched result count instead\nof the actual stored count.\n\nAssisted-by: Codex"
    },
    {
      "commit": "64188fedbe891aefaa6d24c4093b40c0c3f6d82a",
      "tree": "98a4cf71b9c5480524ff6b9ed68990c9de93bd2b",
      "parents": [
        "98c051cacb0f77192f8f086050bcb3f5eee2351f"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Fri Apr 17 11:24:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Apr 17 03:24:38 2026 +0000"
      },
      "message": "fix(geo): delete store_key instead of user_key in SearchStore (#3456)\n\nWhen GEOSEARCHSTORE yields zero results, the code incorrectly deleted\nthe source key (user_key) instead of the destination key (store_key)."
    },
    {
      "commit": "98c051cacb0f77192f8f086050bcb3f5eee2351f",
      "tree": "4657789455738a021cccd94499e847eb57fec3ed",
      "parents": [
        "5ebde751f0e15058e9823978a02b062b3a20c115"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Fri Apr 17 09:13:43 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Apr 17 01:13:43 2026 +0000"
      },
      "message": "fix(stream): allow group and consumer names starting with digits (#3442)\n\nRedis does not restrict group or consumer names from starting with\ndigits. The restriction was kvrocks-specific and broke compatibility."
    },
    {
      "commit": "5ebde751f0e15058e9823978a02b062b3a20c115",
      "tree": "22938c57741d65456f9faa90e1123408aefc21e6",
      "parents": [
        "8d4d8ea6f40fb57fc1f0148e4d1582934592397f"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Thu Apr 16 22:26:12 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Apr 16 22:26:12 2026 +0800"
      },
      "message": "fix(hyperloglog): use namespace-prefixed key in PFMERGE GetMetadata (#3441)\n\nMerge called GetMetadata with the raw user key instead of the\nnamespace-prefixed key, causing the destination\u0027s existing metadata to\nnever be found and potentially orphaning old sub-keys.\n\n---------\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "8d4d8ea6f40fb57fc1f0148e4d1582934592397f",
      "tree": "b10a5c88324a593a156b14f6508eb0b192b38f94",
      "parents": [
        "d942f530af1bdbf442dd0ae063bb77c1965ff510"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Thu Apr 16 11:18:42 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Apr 16 11:18:42 2026 +0800"
      },
      "message": "feat(commands): expose hash, list and json metadata in kmetadata (#3454)\n\nThis extends KMETADATA to expose hash, list, and JSON-specific metadata\nfields. It makes debugging and tests easier by improving observability\naround internal metadata.\n\nAssisted-by: Codex"
    },
    {
      "commit": "d942f530af1bdbf442dd0ae063bb77c1965ff510",
      "tree": "91db75b2331e4f57dc1cf153ba1c0549f416bf66",
      "parents": [
        "27fbff104fe918ff8733bbf6d9ac8810facc0552"
      ],
      "author": {
        "name": "纪华裕",
        "email": "jihuayu123@gmail.com",
        "time": "Wed Apr 15 15:38:09 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 15 07:38:09 2026 +0000"
      },
      "message": "feat(ci): add caching for CMake FetchContent in CI workflow (#3448)\n\nDue to the current instability of GitHub services, dependency download\nfailures occur frequently during CI runs. I add FetchContent caching to\nprevent these network issues from failing the CI."
    },
    {
      "commit": "27fbff104fe918ff8733bbf6d9ac8810facc0552",
      "tree": "0aec4ea4d3b2684cd47ba922f90739ee65b9da89",
      "parents": [
        "505108c35fbce3eae16db870141bb34e9d3654bf"
      ],
      "author": {
        "name": "Reilly.tang",
        "email": "tang.ruilin@foxmail.com",
        "time": "Wed Apr 15 14:25:16 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 15 06:25:16 2026 +0000"
      },
      "message": "fix(tdigest): correct TDIGEST.MERGE parser for COMPRESSION parameter. (#3449)\n\nFix #3447\n\nThe parser incorrectly used two independent `if` statements to check\nCOMPRESSION and OVERRIDE parameters. When COMPRESSION was successfully\nparsed, the code continued to the second `if` which would fail since the\nparser had reached the end, causing \"ERR wrong keyword\" error.\n\nFixed by changing the second `if` to `else if` to form a proper\nif-else-if-else chain.\n\nSigned-off-by: reilly \u003creilly@example.com\u003e\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "505108c35fbce3eae16db870141bb34e9d3654bf",
      "tree": "4d5f0a0e575550784665db944d71546876c8b66a",
      "parents": [
        "75df3740ae2f65c4f1b5382a1a57ba42d947a8b2"
      ],
      "author": {
        "name": "Reilly.tang",
        "email": "tang.ruilin@foxmail.com",
        "time": "Wed Apr 15 10:42:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 15 02:42:04 2026 +0000"
      },
      "message": "fix(tdigest): merge into existing dest without OVERRIDE (#3412)\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e\nCo-authored-by: Edward Xu \u003cxuxiangad@gmail.com\u003e"
    },
    {
      "commit": "75df3740ae2f65c4f1b5382a1a57ba42d947a8b2",
      "tree": "0b022cc984d548dd128b974aa835c5cc698dc8e0",
      "parents": [
        "37140d6c30be4fa91e8a810e8be83981d618ce12"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Tue Apr 14 20:24:47 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Apr 14 17:24:47 2026 +0000"
      },
      "message": "chore(deps): bump jemalloc to 5.3.1 (#3451)\n\nBump jemalloc to 5.3.1 (use jemalloc repo again, see full changelog:\nhttps://github.com/jemalloc/jemalloc/releases/tag/5.3.1)\n\nLot of bugfix, portability improvements and optimizations.\n\nCo-authored-by: Twice \u003ctwice.mliu@gmail.com\u003e"
    },
    {
      "commit": "37140d6c30be4fa91e8a810e8be83981d618ce12",
      "tree": "d91829b64ec585fb661f3c25051c405e8b950c7d",
      "parents": [
        "94e4c8ef7e6bb5a98d892a05c4cbc6280c15f280"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Tue Apr 14 23:03:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Apr 14 23:03:38 2026 +0800"
      },
      "message": "feat(hash): initialize field expiration metadata and subkey en/decoding (#3444)\n\nPart of #3436. See proposal #3432.\n\nThis PR includes:\n- metadata changes for the new encoding\n- subkey encoding/decoding and related logic in `redis_hash.cc`\n- new config option adding\n- an enhancement to `SubKeyScanner` so that it can be used for HFE\n- run hash test cases for both modes\n\nAssisted-by: Codex"
    },
    {
      "commit": "94e4c8ef7e6bb5a98d892a05c4cbc6280c15f280",
      "tree": "9da937043f369d938354ebdea4a20987c0161404",
      "parents": [
        "61f4dc232704c589b28c9fd1b4374b31fffe7d7b"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Fri Apr 10 22:35:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Apr 10 14:35:19 2026 +0000"
      },
      "message": "fix(geo): use strict weak ordering in sortGeoPointDESC comparator (#3439)\n\nThe GEO sort DESC comparator used \u003e\u003d instead of \u003e, violating the strict\nweak\nordering requirement of std::sort and causing undefined behavior when\n    elements have equal distances."
    },
    {
      "commit": "61f4dc232704c589b28c9fd1b4374b31fffe7d7b",
      "tree": "778a031ce6529b8e4e8e243cc6bbb1fc7389e285",
      "parents": [
        "2815e082fe2478331f645feb9b994e733c9fbe42"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Fri Apr 10 13:46:20 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Apr 10 13:46:20 2026 +0800"
      },
      "message": "build: disable LTO by default (#3440)\n\nDisabled link-time optimization (LTO) by default and removed related\nconditions to simplify CMake configuration.\n\nUsers need to manually enable LTO by `-DENABLE_LTO\u003dON` if they want LTO."
    },
    {
      "commit": "2815e082fe2478331f645feb9b994e733c9fbe42",
      "tree": "dba9d96c74ca9d13c0fbc0f73c860f2d5c4d7c83",
      "parents": [
        "29b23731ca9096f60be82bbc72d8c1c45be8d021"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Fri Apr 10 11:26:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Apr 10 03:26:03 2026 +0000"
      },
      "message": "fix(stream): correct XREVRANGE minimum argument count from 2 to 4 (#3438)\n\nXREVRANGE requires key, end, start and [COUNT count] arguments (4\nminimum), but was registered with -2 which could cause out-of-bounds\naccess and crashes.\nRefs: https://redis.io/docs/latest/commands/xrevrange/"
    },
    {
      "commit": "29b23731ca9096f60be82bbc72d8c1c45be8d021",
      "tree": "41a257b5769f8687fa0cb9dc09269a7f45c69bac",
      "parents": [
        "ec523ccec1fe77bde23b942bba1bdef1542448e9"
      ],
      "author": {
        "name": "sryan yuan",
        "email": "sryan@qq.com",
        "time": "Thu Apr 09 15:20:44 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Apr 09 07:20:44 2026 +0000"
      },
      "message": "fix(command): fix static initialization crash on Kunpeng/Kylin platform (#3416)\n\n## Problem:\n\nWe\u0027ve identified a critical startup crash specific to Kunpeng processors\n(aarch64) running Kylin OS v10 with GCC 12.5.0. The root cause is a\nstatic initialization order issue where:\n\n* Static command registration objects (e.g., RegisterToCommandTable in\ncommand files) initialize before CommandTable\u0027s static containers\n* This leads to accessing uninitialized containers during startup:\n```cpp\nCommandTable::commands[attr.name] \u003d ...;  // ❌ Accesses uninitialized map\n```\n\n* On Kunpeng/Kylin/GCC12.5, this consistently manifests as:\n  * Segmentation faults during static initialization\n  * 100% failure rate in cold starts\n\n## Solution:\n\nImplement the \"construct on first use\" pattern to guarantee safe\ninitialization.\n\n## Key Changes:\n\n* Converted all static members in CommandTable to accessor functions\n* Updated all references to use function-call \n* Maintained identical public interface while fixing initialization\nguarantees\n\nCo-authored-by: Twice \u003ctwice.mliu@gmail.com\u003e"
    },
    {
      "commit": "ec523ccec1fe77bde23b942bba1bdef1542448e9",
      "tree": "1f6df0ba8f275ec5676c863a8e3c8e01ca08e55e",
      "parents": [
        "9a3b8176b8c976d759d571d5105da49f24d08b94"
      ],
      "author": {
        "name": "nagisa-kunhah",
        "email": "61525444+nagisa-kunhah@users.noreply.github.com",
        "time": "Thu Apr 09 13:04:31 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Apr 09 05:04:31 2026 +0000"
      },
      "message": "feat: Add support for dictionary compression settings (#3425)\n\nissue: #3409\n\n---------\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e\nCo-authored-by: Twice \u003ctwice.mliu@gmail.com\u003e"
    },
    {
      "commit": "9a3b8176b8c976d759d571d5105da49f24d08b94",
      "tree": "abf45dc920957a66900635585e52a4f3ecb96a4a",
      "parents": [
        "b272b5c1b673385ca6e58cf5c595fce252782e22"
      ],
      "author": {
        "name": "纪华裕",
        "email": "jihuayu123@gmail.com",
        "time": "Thu Apr 09 11:57:22 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Apr 09 03:57:22 2026 +0000"
      },
      "message": "fix(script): upgrade Lua version to fix CVE-2024-31449 and CVE-2025-49844 (#3435)\n\nUpgrade Lua version to fix CVE-2024-31449 and CVE-2025-49844.\nhttps://github.com/RocksLabs/lua/commit/c77781d0c23df021a903a9a6199d301ec559e9cd\n\n\nfix https://github.com/apache/kvrocks/issues/3434 fix\nhttps://github.com/apache/kvrocks/issues/3433"
    },
    {
      "commit": "b272b5c1b673385ca6e58cf5c595fce252782e22",
      "tree": "3387530d68a69520840dc878a161536070b5f37f",
      "parents": [
        "4aede367b72416a591623c2f04f176ab3e74c40a"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Thu Apr 09 09:01:42 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Apr 09 01:01:42 2026 +0000"
      },
      "message": "fix(set): propagate storage errors in Set instead of treating as NotFound (#3428)\n\nPreviously, when `storage_-\u003eGet()` returned a non-NotFound error (e.g.,\nI/O error or corruption) during SADD, the code fell through to the\n`batch-\u003ePut` path, incorrectly treating the error as \"member not found\"\nand adding the member. This could silently inflate `metadata.size` and\ninsert duplicate members on storage failures.\n\nAdd an explicit `!s.IsNotFound()` check to propagate real errors, which\nis consistent with how `Set::Remove` already handles the same pattern.\n\n---------\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "4aede367b72416a591623c2f04f176ab3e74c40a",
      "tree": "075663e5a753e4846ff0ef39f4d48a037b0f9984",
      "parents": [
        "797649012faa4ebf010e1558ba891df67d68cfc9"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Wed Apr 08 20:39:43 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 08 12:39:43 2026 +0000"
      },
      "message": "fix(string,hash): use compact float format in IncrByFloat to match Redis (#3427)\n\nPreviously, String::IncrByFloat and Hash::IncrByFloat used\nstd::to_string(double) to persist float values, which produces C-style\n%f format with 6 fixed decimal places (e.g., \"10.500000\"). Redis uses a\n    compact %g-like format that strips trailing zeros (e.g., \"10.5\").\n\n    This caused GET/HGET after INCRBYFLOAT/HINCRBYFLOAT to return values\nlike \"10.500000\" instead of \"10.5\", breaking Redis protocol\ncompatibility.\n\nReplace std::to_string with util::Float2String (which uses fmt {:.17g})\n    in both String::IncrByFloat and Hash::IncrByFloat. The INCRBYFLOAT\ncommand reply already used Float2String correctly; this fix aligns the\n    stored representation with both the reply format and Redis behavior.\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "797649012faa4ebf010e1558ba891df67d68cfc9",
      "tree": "492ada65c1960861df005c06ba20658114254c05",
      "parents": [
        "5f6d7b2053e0a0c514556a99aa66b06e30b76eaf"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Wed Apr 08 18:29:12 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 08 10:29:12 2026 +0000"
      },
      "message": "fix(zset): initialize *inter_cnt before early return in InterCard (#3421)\n\nWhen any input key is empty (mscores.empty()), InterCard returned OK\n    without ever assigning *inter_cnt, leaving callers with an\n    uninitialized value. Redis ZINTERCARD should return 0 in this case.\n\nFix by initializing *inter_cnt \u003d 0 at the function entry.\n\nAlthough the count at the caller layer is initialized to 0, which seems\nto be fortuitously safe, other potential callers (such as internal\ncalls, test code, and future refactoring) may not necessarily initialize\nit beforehand.\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "5f6d7b2053e0a0c514556a99aa66b06e30b76eaf",
      "tree": "20f92278845e66dc19e8b25cab791ffab5ae3285",
      "parents": [
        "c1f57aab7d0febbe40e6e38281e149a1d30de0e0"
      ],
      "author": {
        "name": "纪华裕",
        "email": "jihuayu123@gmail.com",
        "time": "Wed Apr 08 17:19:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 08 17:19:18 2026 +0800"
      },
      "message": "fix(ci): modify Redis build cache keys (#3430)\n\nUbuntu 22.04 incorrectly uses the cached redis-cli from Ubuntu 24.04,\ncausing go test to fail.\nUpdate the cache key to prevent this issue."
    },
    {
      "commit": "c1f57aab7d0febbe40e6e38281e149a1d30de0e0",
      "tree": "d0b4605e962eaf1566c4d4ced7a666852d983a43",
      "parents": [
        "fdcfd437fa835df6c919099aae9a3160d389ed11"
      ],
      "author": {
        "name": "纪华裕",
        "email": "jihuayu123@gmail.com",
        "time": "Wed Apr 08 15:19:56 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 08 07:19:56 2026 +0000"
      },
      "message": "chore(ci):  Update paths-filter and header action versions (#3426)\n\n\u003cimg width\u003d\"1996\" height\u003d\"284\" alt\u003d\"image\"\nsrc\u003d\"https://github.com/user-attachments/assets/fe2e4893-ba8c-46cb-bb37-bf801ab74991\"\n/\u003e"
    },
    {
      "commit": "fdcfd437fa835df6c919099aae9a3160d389ed11",
      "tree": "256a913c03e063ea55c2f11d25968ed22375d4b4",
      "parents": [
        "c7d91ed722ec91299d8e2caf439f7ffcf5db4c35"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Wed Apr 08 10:25:44 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 08 10:25:44 2026 +0800"
      },
      "message": "fix(stream): correct subkey prefix encoding in DestroyGroup (#3420)\n\nDestroyGroup was constructing scan prefixes using only\n    PutFixed64(group_name.size()) + group_name, which does not match the\nactual internal key format used by\n[internalKeyFromGroupName](https://github.com/apache/kvrocks/blob/da5e46307047b3e89753f0c9c02996430e758a5f/src/types/redis_stream.cc#L171),\n    internalKeyFromConsumerName, and internalPelKeyFromGroupAndEntryId.\n\nThe real keys are prefixed with PutFixed64(UINT64_MAX) + PutFixed8(type)\nbefore the group name length and name. The wrong prefix meant the scan\nrange could miss all group/consumer/PEL keys or match unrelated stream\n    entry keys, causing data leaks or corruption on XGROUP DESTROY.\n\nFix by iterating over the three subkey types (GroupMetadata,\nConsumerMetadata, PelEntry) and building the correct prefix for each,\n    consistent with the internal key encoding helpers.\n\nBesides, add two test cases verifying that DestroyGroup correctly cleans\nup all\ngroup-related subkeys (group metadata, consumer metadata, PEL entries):\n\n- DestroyGroupCleansUpConsumersAndPelEntries: verifies full cleanup\n      including that stream entries are preserved and the group can be\n      re-created cleanly.\n- DestroyGroupDoesNotAffectOtherGroups: verifies that destroying one\n      group does not affect another group\u0027s consumers or PEL entries."
    },
    {
      "commit": "c7d91ed722ec91299d8e2caf439f7ffcf5db4c35",
      "tree": "852c8de1564cd627c03b28db75fd3c10517407b9",
      "parents": [
        "784344e3c34db8d9df2065f42f998af46dae8d09"
      ],
      "author": {
        "name": "纪华裕",
        "email": "jihuayu123@gmail.com",
        "time": "Mon Apr 06 09:35:51 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Apr 06 09:35:51 2026 +0800"
      },
      "message": "fix(ci): add check-and-lint success as a merge condition (#3423)"
    },
    {
      "commit": "784344e3c34db8d9df2065f42f998af46dae8d09",
      "tree": "d2204233ecb9c17c64603c571ef46f6efe5150b2",
      "parents": [
        "c4934951e85476c15288b9771b3b5c8310cbaf7a"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Sun Apr 05 15:46:57 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Apr 05 07:46:57 2026 +0000"
      },
      "message": "fix(conf): cap proto-max-bulk-len to 4 GiB instead of UINT64_MAX  (#3419)\n\n Change proto_max_bulk_len to 4G so that bulk_len_+2 used for\nCRLF accounting in RESP parsing can never wrap around, see` if\n(evbuffer_get_length(input) \u003c bulk_len_ + 2) return Status::OK();` in\n[code](https://github.com/apache/kvrocks/blob/da5e46307047b3e89753f0c9c02996430e758a5f/src/server/redis_request.cc#L123).\n\n---------\n\nCo-authored-by: hulk \u003chulk.website@gmail.com\u003e"
    },
    {
      "commit": "c4934951e85476c15288b9771b3b5c8310cbaf7a",
      "tree": "0a29af8d8bead958e41395ccde2e669dc4748972",
      "parents": [
        "a841726d630e8565ba6e80d5f2fc63320f0b6277"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Sun Apr 05 06:07:17 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Apr 05 11:07:17 2026 +0800"
      },
      "message": "chore(ci): bump typos action to version 1.45.0 (#3422)\n\nBump typos action to version 1.45.0 (see:\nhttps://github.com/crate-ci/typos/releases/tag/v1.45.0)\n\n- Updated the dictionary with the\nhttps://github.com/crate-ci/typos/issues/1509 changes\n- Updated the dictionary with the\nhttps://github.com/crate-ci/typos/issues/1488 changes\n- Don\u0027t correct pincher\n- Adjust how typos are reported to github\n- Corrections for Python\n\n---------\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "a841726d630e8565ba6e80d5f2fc63320f0b6277",
      "tree": "cf7a9ab4f155767055625219b23723d96bb7d02b",
      "parents": [
        "da5e46307047b3e89753f0c9c02996430e758a5f"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Sat Apr 04 05:19:19 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Apr 04 10:19:19 2026 +0800"
      },
      "message": "chore(deps): bump jsoncons version to v1.6.0 (#3401)"
    },
    {
      "commit": "da5e46307047b3e89753f0c9c02996430e758a5f",
      "tree": "bd6092594868303618a1133a56f9fd9f92842372",
      "parents": [
        "833bf36a0571995fae7a18de4fa40e604dc27b39"
      ],
      "author": {
        "name": "Songqing Zhang",
        "email": "zhangsongqing164@163.com",
        "time": "Wed Apr 01 22:07:01 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 01 14:07:01 2026 +0000"
      },
      "message": "fix(server): data race when accessing the db scan infos in GetLatestKeyNumStats (#3414)\n\ndb_scan_infos_.find() was called without holding db_job_mu_, while\n    background threads mutate the map under that lock. Acquire the lock\n    before find() to match the pattern used in GetLastScanTime.\n\nCo-authored-by: hulk \u003chulk.website@gmail.com\u003e"
    },
    {
      "commit": "833bf36a0571995fae7a18de4fa40e604dc27b39",
      "tree": "552b6d25aa5e51555528ec8d9538c5e9cdce968b",
      "parents": [
        "96dd8cb2601b88314567ea6e253e73f01eed7c94"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Wed Apr 01 14:00:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 01 06:00:58 2026 +0000"
      },
      "message": "fix(ci): failure in macOS due to the unavailable cmake version (#3415)\n\nRelated CI logs:\nhttps://github.com/apache/kvrocks/actions/runs/23828447043/job/69456664463?pr\u003d3413\n\n```\nSome possibly relevant errors from pip install:\n    ERROR: Could not find a version that satisfies the requirement cmake\u003d\u003d3.31 (from versions: 0.1.0, 0.2.0, 0.4.0, 0.5.0, 0.6.0, 0.7.0, 0.7.1, 0.8.0, 0.9.0, 3.6.3.post1, 3.7.2, 3.8.2, 3.9.6, 3.10.3, 3.11.0, 3.11.4, 3.11.4.post1, 3.12.0, 3.13.0, 3.13.1, 3.13.2.post1, 3.14.3.post1, 3.14.4.post1, 3.15.3.post1, 3.16.3.post1, 3.16.5, 3.16.6, 3.16.7, 3.16.8, 3.17.0, 3.17.1, 3.17.2, 3.17.3, 3.18.0, 3.18.2.post1, 3.18.4.post1, 3.20.2, 3.20.3, 3.20.4, 3.20.5, 3.21.0, 3.21.1.post1, 3.21.2, 3.21.3, 3.21.4, 3.22.0, 3.22.1, 3.22.2, 3.22.3, 3.22.4, 3.22.5, 3.22.6, 3.23.3, 3.24.0, 3.24.1, 3.24.1.1, 3.24.2, 3.24.3, 3.25.0, 3.25.2, 3.26.0, 3.26.1, 3.26.3, 3.26.4, 3.27.0, 3.27.1, 3.27.2, 3.27.4.1, 3.27.5, 3.27.6, 3.27.7, 3.27.9, 3.28.1, 3.28.3, 3.28.4, 3.29.0.1, 3.29.2, 3.29.3, 3.29.5, 3.29.5.1, 3.29.6, 3.30.0, 3.30.1, 3.30.2, 3.30.3, 3.30.4, 3.30.5, 3.30.9, 3.31.0.1, 3.31.1, 3.31.2, 3.31.4, 3.31.6, 3.31.10, 4.0.0, 4.0.2, 4.0.3, 4.1.0, 4.1.2, 4.1.3, 4.2.0, 4.2.1, 4.2.3, 4.3.0, 4.3.1)\n    ERROR: No matching distribution found for cmake\u003d\u003d3.31\nError installing cmake from spec \u0027cmake\u003d\u003d3.31\u0027.\n```"
    },
    {
      "commit": "96dd8cb2601b88314567ea6e253e73f01eed7c94",
      "tree": "3ed366c7fa86bf806d7ace77e33286ba60d0638e",
      "parents": [
        "e61c81478c27a2309081d219b9dcb8f81b19d9aa"
      ],
      "author": {
        "name": "XYenon",
        "email": "register@xyenon.bid",
        "time": "Sat Mar 28 22:18:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Mar 28 22:18:19 2026 +0800"
      },
      "message": "fix(stream): accept `~` modifier in XADD and XTRIM (#3403)\n\nFixes https://github.com/apache/kvrocks/issues/3402\n\nXADD and XTRIM commands only recognized `\u003d` as the optional modifier for\nMAXLEN/MINID but not `~`, causing a parse error. Redis supports both\nmodifiers for compatibility."
    },
    {
      "commit": "e61c81478c27a2309081d219b9dcb8f81b19d9aa",
      "tree": "52ce3e5a7a323ab63b04da3d8d28899eca7dc91d",
      "parents": [
        "b7423c48042b272958d3f036b04f729c717fb7c4"
      ],
      "author": {
        "name": "chakkk309",
        "email": "chakk6870@gmail.com",
        "time": "Wed Mar 25 09:42:49 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Mar 25 01:42:49 2026 +0000"
      },
      "message": "feat(tdigest): implement TDIGEST.TRIMMED_MEAN command (#3312)\n\nCo-authored-by: Copilot \u003c175728472+Copilot@users.noreply.github.com\u003e\nCo-authored-by: Edward Xu \u003cxuxiangad@gmail.com\u003e"
    },
    {
      "commit": "b7423c48042b272958d3f036b04f729c717fb7c4",
      "tree": "f09a956a5737df31cd4575b52ba8e6faa70e2f3f",
      "parents": [
        "73e202dc96fafa068a2caab9cbe3793fd61c7a4d"
      ],
      "author": {
        "name": "Yatrik Solanki",
        "email": "yatriksolanki@gmail.com",
        "time": "Tue Mar 24 12:37:51 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Mar 24 16:37:51 2026 +0000"
      },
      "message": "chore(config): remove the deprecated configuration `rocksdb.max_background_{compactions,flushes}`  and set default to -1 (#3398)\n\nThis PR will:\n- update the default values of `rocksdb.max_background_compactions` and\n`rocksdb.max_background_flushes` from `2` to `-1`\n- unset them from `kvrocks.conf` and update comments to reflect\nRocksDB\u0027s decision logic for max background threads\n\nNOTE: This doesn\u0027t make it so that `rocksdb.max_background_compactions`\nis unsettable, like `rocksdb.max_background_flushes` currently is. This\nmay be desirable for people who do currently use the old overrides, but\nafaik it would lock people in to `max_background_flushes \u003d 2` - but\nthat\u0027s already the case as far as I can tell.\n\nI ran each of:\n```\n./x.py format (unrelated changes)\n./x.py build --unittest\n./x.py test cpp \n```\nTests all pass and formatting changes are unrelated.\n\nThis is effectively an addition to\nhttps://github.com/apache/kvrocks/issues/1665\nSee https://github.com/apache/kvrocks/discussions/3395 for more\nbackground.\n\n---------\n\nCo-authored-by: Yatrik S. \u003cyatrik@molniya.space\u003e\nCo-authored-by: Aleks Lozovyuk \u003caleks.raiden@gmail.com\u003e\nCo-authored-by: hulk \u003chulk.website@gmail.com\u003e"
    },
    {
      "commit": "73e202dc96fafa068a2caab9cbe3793fd61c7a4d",
      "tree": "19201420fc87bf3ed9ee460f7853141aecbb38e7",
      "parents": [
        "bf66a9e24ba3dd4b5740721d89526e3cd687f224"
      ],
      "author": {
        "name": "Edward Xu",
        "email": "xuxiangad@gmail.com",
        "time": "Tue Mar 24 23:21:32 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Mar 24 15:21:32 2026 +0000"
      },
      "message": "chore(ci): use git-hash in actions for ASF actions approval list (#3400)"
    },
    {
      "commit": "bf66a9e24ba3dd4b5740721d89526e3cd687f224",
      "tree": "102dbaa93abb5b7d300d9cbbb78033fa80e4b1c7",
      "parents": [
        "6f40a95bb66513c3c7fce6fa25370e9063ee8335"
      ],
      "author": {
        "name": "Twice",
        "email": "twice.mliu@gmail.com",
        "time": "Fri Mar 20 09:59:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Mar 20 09:59:03 2026 +0800"
      },
      "message": "chore(util): replace strtof/strtod with fast-float (#3394)\n\nIt closes #3344."
    },
    {
      "commit": "6f40a95bb66513c3c7fce6fa25370e9063ee8335",
      "tree": "8000613982be193ba14e3c31dcdaca6a82742100",
      "parents": [
        "8f56bf04ac5bdf1b7455167d14faffb2ccc94d9d"
      ],
      "author": {
        "name": "纪华裕",
        "email": "jihuayu123@gmail.com",
        "time": "Mon Mar 16 22:39:42 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 16 22:39:42 2026 +0800"
      },
      "message": "chore(ci): fix sonarcloud security hotspots (#3392)"
    },
    {
      "commit": "8f56bf04ac5bdf1b7455167d14faffb2ccc94d9d",
      "tree": "7b5b2b24943f9bee21109ee39913f50dad91d46a",
      "parents": [
        "3b02893fbcd1e30b707f6d2f09fda01e63394551"
      ],
      "author": {
        "name": "Sanjana",
        "email": "sanju250506@gmail.com",
        "time": "Mon Mar 16 07:24:31 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 16 09:54:31 2026 +0800"
      },
      "message": "chore: fix typos in README and redis_bitmap.cc (#3390)"
    },
    {
      "commit": "3b02893fbcd1e30b707f6d2f09fda01e63394551",
      "tree": "33f68e6e9c24fe05713c3d94062e99a0ac08bffa",
      "parents": [
        "f2058ceab287c49e2869ef0575480e52bbb1db82"
      ],
      "author": {
        "name": "Sanjana",
        "email": "sanju250506@gmail.com",
        "time": "Thu Mar 12 20:23:33 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 12 22:53:33 2026 +0800"
      },
      "message": "refactor: use stderr for CLI error output (#3372)\n\nI noticed that the CLI was printing error messages (like invalid\narguments or config load failures) to `stdout`, which isn\u0027t ideal for\nscripting or standard error handling. This PR redirects those critical\nerrors to `stderr`.\n\nI also enhanced the\n[PrintUsage](cci:1://file:///Users/sanjana./kvrocks/src/cli/main.cc:62:0-73:1)\nfunction to accept an output stream, so `-h`/`--help` still goes to\n`stdout` (as expected), but incorrect usage warnings go to `stderr`. The\nusage message itself has been slightly polished for better readability.\n\nChanges:\n- PrintUsage now takes an optional `std::ostream\u0026` argument (defaults to\n`cout`).\n- Invalid command-line arguments now print usage to `cerr` and return\nexit code 1.\n- Config loading and logger initialization errors now print to `cerr`.\n- Added `\u003ciostream\u003e` include for correctness.\n\n---------\n\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "f2058ceab287c49e2869ef0575480e52bbb1db82",
      "tree": "829c4712b41c55408bf84c7eb583fd9eecc99925",
      "parents": [
        "1a50c0bfa938714d370438098f9480280e505dc5"
      ],
      "author": {
        "name": "纪华裕",
        "email": "jihuayu123@gmail.com",
        "time": "Thu Mar 12 15:22:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 12 15:22:04 2026 +0800"
      },
      "message": "chore(ci): Use the lastest version of clang-format-18 \u0026 clang-tidy-18 (#3389)\n\nThe clang-format-18 provided by Ubuntu is version 18.1.3, while the\nlatest is 18.1.8. This discrepancy causes mismatches with the versions\nmany developers have installed locally. Pinning clang-format-18 to the\nlatest minor release of version 18 would significantly improve the\ndeveloper experience.\n\nRefer https://github.com/apache/kvrocks/pull/3372"
    },
    {
      "commit": "1a50c0bfa938714d370438098f9480280e505dc5",
      "tree": "a538c3bcb93f8d274d1ea9eccdeba6a60c5fdf49",
      "parents": [
        "e1de9414289f83adb3503f9ed22ef9c9a637d9d3"
      ],
      "author": {
        "name": "Ruifeng Guo",
        "email": "paragrf@163.com",
        "time": "Thu Mar 12 11:33:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 12 11:33:10 2026 +0800"
      },
      "message": "feat(cluster): propagate slave failure state via CLUSTER NODES fail flag (#3386)\n\nThis closes https://github.com/apache/kvrocks/issues/3385\n\n### Background\nTo maintain parity with Redis Cluster\u0027s behavior during slave node\noutages, this update enables Kvrocks to refresh its topology\naccordingly. This ensures clients stay synchronized with the server\nstate and helps mitigate the effects of node failures.\n\n### Implementation\nSupport the \"slave,fail\" role token in CLUSTERX SETNODES so that\ncontrollers can mark a downed slave in the cluster topology. Surviving\nnodes reflect the failed state as a \"fail\" flag in CLUSTER NODES output,\nallowing cluster-aware clients to update their routing tables without\nmanual intervention.\n\n---------\n\nCo-authored-by: paragrf \u003cguoruifeng@kanzhun.com\u003e\nCo-authored-by: 纪华裕 \u003cjihuayu123@gmail.com\u003e"
    },
    {
      "commit": "e1de9414289f83adb3503f9ed22ef9c9a637d9d3",
      "tree": "da59a6fb3c983aa3be2c5f541780a5ea5ff7146f",
      "parents": [
        "222711fd0e1a6e0f121b3713cacb63bb971b420a"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Tue Mar 10 14:47:59 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Mar 10 20:47:59 2026 +0800"
      },
      "message": "chore(ci): bump docker/build-push-action to v7 (#3384)\n\nBump docker/build-push-action to v7 (see:\nhttps://github.com/docker/build-push-action/releases/tag/v7.0.0)"
    },
    {
      "commit": "222711fd0e1a6e0f121b3713cacb63bb971b420a",
      "tree": "8076750b5472fb5a19f0011b07c7d8e716b97500",
      "parents": [
        "d09cdc12946803691fe949f76dbc916ad8cec86a"
      ],
      "author": {
        "name": "Paragrf",
        "email": "paragrf@163.com",
        "time": "Fri Mar 06 12:19:40 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Mar 06 12:19:40 2026 +0800"
      },
      "message": "feat(client): Add support for the CLIENT PAUSE/UNPAUSE commands to provide a temporary solution for failover (#3378)\n\n### Summary\nThis PR aims to provide a streamlined solution for graceful failover\nwithin the cluster. Previously, proposed failover schemes remained\nunmerged due to unresolved complexities and architectural concerns.\n\nTo address this, this modification introduces the CLIENT PAUSE and\nCLIENT UNPAUSE commands—capabilities that were previously missing in\nKvrocks. These commands provide the necessary primitives to temporarily\nsuspend client traffic, ensuring data consistency and a seamless\ntransition during the failover process.\n\n### Background\nBased on https://github.com/apache/kvrocks/issues/3377, this PR\nimplements two missing Redis protocols.\n\n- Implemented CLIENT PAUSE [timeout] [WRITE|ALL] to block client\nrequests.\n\n- Implemented CLIENT UNPAUSE to resume normal operations.\n\n### Implementation\nThe behavior of CLIENT PAUSE/UNPAUSE is consistent with Redis:\n\n- Blocking Mechanism: After executing CLIENT PAUSE, Kvrocks will block\nconnections attempting to run restricted commands.\n\n- Release/Error Handling: These commands are released once the timeout\nexpires or CLIENT UNPAUSE is called.\n\n- Role Transition: If a role change occurs (e.g., Master → Slave) during\nthe pause, any previously blocked write requests will return a READONLY\nerror upon resumption.\n\n- Exemption mechanism:master-slave replication, and the PAUSE/UNPAUSE\nprotocols themselves will not be blocked.\n\n- Testing:Comprehensive C++ unit tests and Go integration tests have\nbeen added\n\n---------\n\nCo-authored-by: paragrf \u003cguoruifeng@kanzhun.com\u003e\nCo-authored-by: hulk \u003chulk.website@gmail.com\u003e"
    },
    {
      "commit": "d09cdc12946803691fe949f76dbc916ad8cec86a",
      "tree": "13e0f62d5c3dd9fe77d3a021f013b17b5119fb23",
      "parents": [
        "792df3612c2d6bde2159cacbd104f12e0f73c6d5"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Thu Mar 05 04:35:51 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 05 10:35:51 2026 +0800"
      },
      "message": "chore(ci): bump all used actions to latest (#3383)\n\n"
    },
    {
      "commit": "792df3612c2d6bde2159cacbd104f12e0f73c6d5",
      "tree": "e14906809222e1bb56c6da9e60f28d6a1e0c0312",
      "parents": [
        "cc2bb3c7e3d77c6b88af5f1b42e9018e0bb31ec8"
      ],
      "author": {
        "name": "sryan yuan",
        "email": "sryan@qq.com",
        "time": "Tue Mar 03 16:32:27 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Mar 03 16:32:27 2026 +0800"
      },
      "message": "feat(info): add thread CPU time measurement for worker thread monitoring (#3379)\n\n## Summary\nThis PR introduces worker thread CPU time monitoring to identify\nbottlenecks and fixes precision issues in process CPU time calculations.\n\n## Problem Statement\n1. **Lack of granular thread monitoring**: The current `INFO` command\nprovides only overall process CPU time, which includes background\nthreads. This makes it difficult to identify bottlenecks in worker\nthreads specifically, as background thread activity can mask true worker\nthread utilization.\n\n2. **Precision loss in CPU time calculation**: The existing CPU time\ncalculation truncates microsecond values due to integer division\n(`tv_usec / 1000000`), causing millisecond data loss. This results in\ninaccurate reporting, especially for short operations where sub-second\nprecision matters.\n\n## Solution\n### 1. Worker Thread CPU Time Monitoring\n- Added new `worker_cpu_time` metric to track CPU usage per worker\nthread\n- Implemented per-thread CPU time collection using platform-specific\nAPIs\n- Formatted output with microsecond precision (6 decimal places) to\nmatch system precision\n- Sample output: `worker_cpu_time:[0.123456,0.456789,1.234567]`\n\n### 2. CPU Time Calculation Fix\n- Fixed precision loss in `used_cpu_user` and `used_cpu_sys`\ncalculations\n- Replaced integer division with floating point division:  \n  **Before**: `tv_usec / 1000000` → truncates to integer  \n**After**: `static_cast\u003cdouble\u003e(tv_usec) / 1e6` → preserves microseconds\n\n## Benefits\n- **Pinpoint worker thread bottlenecks**: Isolate worker thread CPU\nusage from background threads\n- **Accurate performance analysis**: Microsecond-precision timing\nenables precise performance profiling\n- **Better load diagnosis**: Distinguish between actual worker\nsaturation and background activity\n\n---------\n\nCo-authored-by: yxj25245 \u003cyxj25245@ly.com\u003e"
    },
    {
      "commit": "cc2bb3c7e3d77c6b88af5f1b42e9018e0bb31ec8",
      "tree": "d5145f03cc024146b9aa8bbe1908b37791b2e1c1",
      "parents": [
        "fa14a6bb12997702cd58fb9577652ffada2784c1"
      ],
      "author": {
        "name": "sryan yuan",
        "email": "sryan@qq.com",
        "time": "Fri Feb 27 13:41:53 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Feb 27 13:41:53 2026 +0800"
      },
      "message": "feat(command): add FLUSHSLOTS command to clear keys in specified slot ranges in cluster mode (#3375)\n\nAdd FLUSHSLOTS command to clear keys in specified slot ranges in cluster\nmode\n\nFLUSHSLOTS allows clearing keys from one or more cluster slots without\naffecting other slots.\nIt operates on the current connection\u0027s namespace (cluster mode does not\nsupport multiple namespaces).\n\nThe command returns an error if a slot migration is in progress to\nprevent conflicts.\n\nSlot ranges can be specified as:\n    - Single slot: FLUSHSLOTS 1234\n    - Range: FLUSHSLOTS 100-200\n    - Multiple ranges: FLUSHSLOTS “0 2 4 6-9”\n\nExample:\n    FLUSHSLOTS \"0 2 4 6-9\"\n\nUnit tests have been added to verify clearing multiple slots and\nensuring remaining keys match expectations.\n\n---------\n\nCo-authored-by: yxj25245 \u003cyxj25245@ly.com\u003e"
    },
    {
      "commit": "fa14a6bb12997702cd58fb9577652ffada2784c1",
      "tree": "83befc74c1c02e00fd8d6fabec79c3d3a90433c9",
      "parents": [
        "83afb41034d1a2821a7f5c14222a22c0c9d1aacf"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Fri Feb 27 09:57:22 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Feb 27 09:57:22 2026 +0800"
      },
      "message": "chore(.asf.yaml): add 2.15 into protected branches (#3376)\n\n"
    },
    {
      "commit": "83afb41034d1a2821a7f5c14222a22c0c9d1aacf",
      "tree": "65e75e0fd14225285eff8dc0c63bda682a74e7c8",
      "parents": [
        "818d4198013d4ef832265fcb650fe71afe941323"
      ],
      "author": {
        "name": "Cancai Cai",
        "email": "77189278+caicancai@users.noreply.github.com",
        "time": "Mon Feb 23 14:57:52 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Feb 23 14:57:52 2026 +0800"
      },
      "message": "chore: update copyright year in NOTICE (#3374)\n\n"
    },
    {
      "commit": "818d4198013d4ef832265fcb650fe71afe941323",
      "tree": "d0ab91a7bfbea840ffb11136c5391b71cb723ffa",
      "parents": [
        "90f51e7a6e08a2f17bd7d71d87ae2b769c81bed7"
      ],
      "author": {
        "name": "Aleks Lozovyuk",
        "email": "aleks.raiden@gmail.com",
        "time": "Sun Feb 22 13:47:27 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Feb 22 19:47:27 2026 +0800"
      },
      "message": "chore(ci): bump golang lint to v2.9.0 (#3370)\n\nBump golang lint to v2.9.0 (see:\nhttps://golangci-lint.run/docs/product/changelog/#290)\n\n**Key changes**:\n\n- go1.26 support\n- Update linters, bug fix\n- Emit an error when no linters enabled"
    },
    {
      "commit": "90f51e7a6e08a2f17bd7d71d87ae2b769c81bed7",
      "tree": "88e72616bde5f3bd19de52f1687da35d22324ec4",
      "parents": [
        "a10b6e1e6c7f6917de3b12731f75eaeafab83018"
      ],
      "author": {
        "name": "hulk",
        "email": "hulk.website@gmail.com",
        "time": "Thu Feb 12 14:14:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Feb 12 14:14:00 2026 +0800"
      },
      "message": "chore(docs): add AGENTS.md for AI coding agent guidance (#3369)\n\nAI coding agents like Claude Code, Cursor, and Codex are increasingly\nused by contributors.\nTo mitigate the issue of AI coding agents generating low-quality PR,\nwe could provide guidance to help them better understand Kvrocks.\n\n---------\nCo-authored-by: Twice \u003ctwice@apache.org\u003e"
    }
  ],
  "next": "a10b6e1e6c7f6917de3b12731f75eaeafab83018"
}
