)]}'
{
  "log": [
    {
      "commit": "6af75bbe23b79974900997b85f9629d7c1623311",
      "tree": "516c9ff2b65297c537095f0e58b805efa70f5324",
      "parents": [
        "890c95e12a7fe0cec50d5cbeadbbaf20c3d351c7"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jiwonpark@apache.org",
        "time": "Wed Oct 21 15:07:40 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 21 14:07:40 2026 +0800"
      },
      "message": "[AMORO-4451][Build] Discontinue Hadoop 2 support (#4452)\n\n* [AMORO-4451][Build] Discontinue Hadoop 2 support\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e\n\n* [AMORO-4451][Build] Remove one-off Flink image verification files\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e\n\n---------\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e"
    },
    {
      "commit": "890c95e12a7fe0cec50d5cbeadbbaf20c3d351c7",
      "tree": "a7be72c4cade176155254501ade9b02bd8df3727",
      "parents": [
        "734b96a1c62b1a5326a6c1b8fd7c7c13bdb1aa8a"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jiwonpark@apache.org",
        "time": "Wed Oct 21 00:31:17 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 20 16:31:17 2026 +0100"
      },
      "message": "[Hotfix][CI] Fix optimizer Docker image latest tag conditions (#4454)\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e"
    },
    {
      "commit": "734b96a1c62b1a5326a6c1b8fd7c7c13bdb1aa8a",
      "tree": "1eb491709fefe126dd7bd2b44f83325e5d696391",
      "parents": [
        "6d3cd428c1c7d6c2f16ca9b3ac2d37171c580480"
      ],
      "author": {
        "name": "Congxian Qiu",
        "email": "qcx978132955@gmail.com",
        "time": "Mon Oct 19 10:25:06 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 19 10:25:06 2026 +0800"
      },
      "message": "Add the licences introduced by postgresql-42.7.2.jar into LICENSE-binary (#4449)"
    },
    {
      "commit": "6d3cd428c1c7d6c2f16ca9b3ac2d37171c580480",
      "tree": "fd93f66448389b5f223fb432fe96142483e5ee76",
      "parents": [
        "28c0a57846d22b64bf093227a97c6709440dfd1f"
      ],
      "author": {
        "name": "hutiefang76",
        "email": "137664623+hutiefang76@users.noreply.github.com",
        "time": "Fri Oct 16 19:21:09 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 17 11:21:09 2026 +0900"
      },
      "message": "[AMORO-4423][Common] Escape Spark SQL literals in table-operation history (#4424)\n\nEscape Spark SQL literals in table-operation history\n\nCo-authored-by: Jiwon Park \u003cjiwonpark@apache.org\u003e"
    },
    {
      "commit": "28c0a57846d22b64bf093227a97c6709440dfd1f",
      "tree": "7c1164e8c9a2ae8b2bee51c48438de2da02a9eb7",
      "parents": [
        "abf3b40131057d614c073d29cfc0c2274645808a"
      ],
      "author": {
        "name": "hutiefang76",
        "email": "137664623+hutiefang76@users.noreply.github.com",
        "time": "Fri Oct 16 18:07:31 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 17 10:07:31 2026 +0900"
      },
      "message": "[AMORO-4426][AMS] Preserve timestamp without time zone in Spark type display (#4428)\n\nPreserve timestamp without time zone in Spark type display\n\nCo-authored-by: Jiwon Park \u003cjiwonpark@apache.org\u003e"
    },
    {
      "commit": "abf3b40131057d614c073d29cfc0c2274645808a",
      "tree": "4a044e84fd30de4e699c69c9c0a609f0c2dacead",
      "parents": [
        "169c7445c30a5300040db6639aa4fe78c5c02897"
      ],
      "author": {
        "name": "hutiefang76",
        "email": "137664623+hutiefang76@users.noreply.github.com",
        "time": "Fri Oct 16 18:07:05 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 17 10:07:05 2026 +0900"
      },
      "message": "[AMORO-4419][Common] Correct nullability in table-operation DDL (#4421)\n\nCorrect nullability in table-operation DDL\n\nCo-authored-by: Jiwon Park \u003cjiwonpark@apache.org\u003e"
    },
    {
      "commit": "169c7445c30a5300040db6639aa4fe78c5c02897",
      "tree": "ca33cfe15b01d7f3d909ed71f31be777e42e9b2f",
      "parents": [
        "43af0c9d68d584503457ca2430093c251aaad5b9"
      ],
      "author": {
        "name": "hutiefang76",
        "email": "137664623+hutiefang76@users.noreply.github.com",
        "time": "Fri Oct 16 09:13:19 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 17 01:13:19 2026 +0900"
      },
      "message": "[AMORO-4412][AMS]Validate table pagination parameters (#4415)\n\n[AMS] Reject invalid pagination parameters in table APIs"
    },
    {
      "commit": "43af0c9d68d584503457ca2430093c251aaad5b9",
      "tree": "2ff6a48a15316b01d1c5238789ce3c91d7d6cca1",
      "parents": [
        "a38c4ba3b50e46cc1486fdf767fbac8fa854734e"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jiwonpark@apache.org",
        "time": "Thu Oct 15 14:46:03 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 15 14:46:03 2026 +0900"
      },
      "message": "[AMORO-4441][AMS] Close optimizing processes with incompatible persisted task outputs (#4442)\n\n[AMS] Close optimizing processes with incompatible persisted task outputs\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e"
    },
    {
      "commit": "a38c4ba3b50e46cc1486fdf767fbac8fa854734e",
      "tree": "b94a8008975288fd95af2ce644cdb8c48016af57",
      "parents": [
        "6a55a5f5d9dbd4ffe34b9d0ade37859ebd379133"
      ],
      "author": {
        "name": "Sivakumar Mahalingam",
        "email": "36898056+sivakumar-mahalingam@users.noreply.github.com",
        "time": "Wed Oct 14 11:48:48 2026 +0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 14 15:48:48 2026 +0800"
      },
      "message": "[AMORO-4439][AMS] Fix wrong placeholder usage in Preconditions messages (#4440)\n\nfix wrong placeholder usage in Preconditions messages"
    },
    {
      "commit": "6a55a5f5d9dbd4ffe34b9d0ade37859ebd379133",
      "tree": "0bc72661938fe19d8654a0282979c2c4120bb5ad",
      "parents": [
        "afdcd19bdd1accb8960d82967d2b9f56e60f8226"
      ],
      "author": {
        "name": "yaolei",
        "email": "leisure2001@163.com",
        "time": "Tue Oct 13 21:04:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 13 22:04:10 2026 +0900"
      },
      "message": "[AMORO-4435] Fix typos and grammar in error messages and comments (#4436)\n\nCo-authored-by: yaolei \u003cyaolei@cmss.chinamobile.com\u003e"
    },
    {
      "commit": "afdcd19bdd1accb8960d82967d2b9f56e60f8226",
      "tree": "ec0bcf2c85ff5032d289f5d86610e03161fa8caa",
      "parents": [
        "70bb50451e74596e84195457a6865c47bfe63e88"
      ],
      "author": {
        "name": "Sivakumar Mahalingam",
        "email": "36898056+sivakumar-mahalingam@users.noreply.github.com",
        "time": "Tue Oct 13 13:50:54 2026 +0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 13 17:50:54 2026 +0800"
      },
      "message": "[AMORO-4437][AMS] Fix dashboard API error response status (#4438)"
    },
    {
      "commit": "70bb50451e74596e84195457a6865c47bfe63e88",
      "tree": "362b029de3262dcae990010e76ac89043daab3b2",
      "parents": [
        "6eba347f0bde52de25899fb8b486eef61e607fe6"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Sat Oct 10 16:45:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 10 16:45:10 2026 +0800"
      },
      "message": "fix: clarify bundled dashboard license location (#4433)"
    },
    {
      "commit": "6eba347f0bde52de25899fb8b486eef61e607fe6",
      "tree": "ba61f15953f8617b074f9299e6d14c3f8b1ef62a",
      "parents": [
        "ac9a343df0fb873a184815e31ddd9bb40afe10f1"
      ],
      "author": {
        "name": "hutiefang76",
        "email": "137664623+hutiefang76@users.noreply.github.com",
        "time": "Fri Oct 09 04:45:29 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 19:45:29 2026 +0800"
      },
      "message": "[AMORO-4407][Hudi]Preserve long Hudi snapshot file sizes (#4408)\n\n[Hudi] Preserve snapshot file sizes as long\n\nGenerated-by: DeepSeek v4 Flash via Reasonix 1.39.4"
    },
    {
      "commit": "ac9a343df0fb873a184815e31ddd9bb40afe10f1",
      "tree": "d330e553123eca6de81ed6a7847340b7b5e9eb20",
      "parents": [
        "342d83e63459a20c8ba040496579f96b8097d8de"
      ],
      "author": {
        "name": "Nikita Ryanov",
        "email": "ryanov.nikita@gmail.com",
        "time": "Fri Oct 09 14:45:13 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 19:45:13 2026 +0800"
      },
      "message": "[hotfix][postgres] Fix org.postgresql.util.PSQLException: ERROR: column name must be qualified (#4396)"
    },
    {
      "commit": "342d83e63459a20c8ba040496579f96b8097d8de",
      "tree": "7929cf52869f81f8830a3530244a871f6a4f6f09",
      "parents": [
        "2c85dcbabbf2c14532acb1ad697e5de04164bb15"
      ],
      "author": {
        "name": "ZhouJinsong",
        "email": "zhoujinsong0505@163.com",
        "time": "Fri Oct 09 11:26:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 11:26:33 2026 +0800"
      },
      "message": "[HOTFIX] Add amoro-web npm dependencies to LICENSE-binary and NOTICE-binary (#4430)\n\n* Add amoro-web npm dependencies to LICENSE-binary and NOTICE-binary\n\n- Add a \u0027npm packages bundled into the dashboard (amoro-web)\u0027 section to\n  LICENSE-binary covering all bundled frontend libraries (MIT and Apache-2.0)\n- Add NOTICE-binary entries for the Apache-2.0 bundled packages\n  (echarts, swagger-ui)\n- Ship the amoro-web/licenses directory inside the dashboard jar so the\n  third-party license texts are distributed with the artifacts\n- Sync the licenses directory with package.json: add missing entries\n  (vue-virtual-scroller, @vue/devtools-api, swagger-ui, swagger-ui-dist,\n  vite-plugin-vue-devtools) and remove stale ones (@tsconfig/node18, babel,\n  unplugin-auto-import, vue-draggable-plus)\n\n* Address review: fix resources override, cover transitive deps, correct qs license\n\n- Restore src/main/resources as a \u003cresource\u003e entry: declaring \u003cresources\u003e\n  silently dropped the default directory and the built jar shipped no\n  static assets (60 files were missing). Verified the jar now packages\n  both static assets and the licenses directory.\n- Collect licenses for transitive npm dependencies actually present in\n  the dashboard bundle (verified by scanning built assets): zrender,\n  tslib, clipboard, react, react-dom, react-redux, redux,\n  react-copy-to-clipboard, react-debounce-input, react-syntax-highlighter,\n  prop-types, classnames, immutable, reselect, serialize-error, randexp,\n  js-yaml, dompurify, remarkable, zenscroll, swagger-client, sha.js,\n  async-validator, @emotion/hash, @emotion/unitless, shallow-equal,\n  @intlify/core-base, @intlify/shared, marked, nearley, @ctrl/tinycolor\n  (detected via its color-name table, e.g. \u0027aliceblue\u0027)\n- Add NOTICE entry for swagger-client (upstream NOTICE exists)\n- Move qs (BSD-3-Clause) from the MIT group to the BSD 3-Clause group\n- Group transitive deps by their actual licenses: zrender/qs -\u003e BSD-3,\n  tslib -\u003e 0BSD, zenscroll -\u003e Unlicense, dompurify -\u003e MPL-2.0 OR Apache-2.0,\n  swagger-client -\u003e Apache-2.0, sha.js noted as MIT AND BSD-3-Clause\n\n* Collect complete license coverage for all npm packages in the dashboard bundle\n\nSwitch from string-pattern scanning (which missed packages) to an\nauthoritative extraction: build the dashboard with sourcemaps and\nenumerate every module from the sourcemap \u0027sources\u0027 field, resolving\neach to its exact pnpm-installed version.\n\nThe bundle contains 137 distinct packages. Compared to the previous\nround this adds ~90 missing declarations, including the ones spotted\nin review (@babel/runtime, buffer, ieee754, redux-immutable,\nhighlight.js) plus the @swagger-api/apidom-* family, ramda,\ncore-js-pure, safe-buffer, scheduler, lodash*, and the es-shims\ncall-bind family.\n\n- LICENSE-binary: regroup all npm declarations by actual license and\n  split into direct/transitive sections (MIT 107, Apache-2.0 19,\n  BSD-3-Clause 6 incl. qs, BSD-2-Clause 1, 0BSD 1, Unlicense 1,\n  MPL-2.0 OR Apache-2.0 1)\n- NOTICE-binary: add entries for ApiDOM (SmartBear, with pointer to\n  the full upstream NOTICE shipped in the jar),\n  openapi-path-templating and openapi-server-url-templating\n  (Vladimír Gorej) whose upstream NOTICE files exist\n- licenses/: collect texts for all bundled packages; for packages\n  that ship no license file (@swagger-api/apidom-*, css.escape,\n  format, short-unique-id, toggle-selection, @ant-design/icons-svg)\n  fetch from upstream repositories or reconstruct with provenance\n  notes; remove the swagger-ui-dist-only leftovers\n\nVerified: the dashboard jar contains 92 static assets and 155 license\nfiles; RAT check passes.\n\n* Add embedded-code notices for bundled npm packages\n\nAddress the remaining items from the completed recheck: attributions\nfor code embedded inside bundled packages that their top-level license\nfiles do not cover.\n\n- @swaggerexpert/json-pointer: ship the upstream NOTICE, which\n  attributes the bundled RFC 6901 ABNF grammar to the IETF Trust\n  (Simplified BSD License) in addition to Vladimír Gorej\n- monaco-editor: ship ThirdPartyNotices.txt; base/common/path.js is\n  the nodejs path library (Copyright Joyent, Inc. and other Node\n  contributors, MIT) and its attribution was missing\n- echarts: ship LICENSES/LICENSE-d3 (BSD-3-Clause, Mike Bostock) for\n  the retained d3 quantile implementation\n- fast-json-patch: preserve the embedded fast-deep-equal MIT notice\n  (Copyright 2017 Evgeny Poberezkin) from module/core.mjs, whose\n  _areEquals implementation is bundled while the package LICENSE only\n  credits Joachim Wester\n\nAll four texts are added to NOTICE-binary and packaged in the\ndashboard jar under licenses/ (now 159 entries, together with 92\nstatic assets; RAT passes).\n\n* Update amoro-web/licenses/LICENSE-fast-deep-equal\n\nCo-authored-by: Xu Bai \u003ctocreationbai@gmail.com\u003e\n\n---------\n\nCo-authored-by: Xu Bai \u003ctocreationbai@gmail.com\u003e"
    },
    {
      "commit": "2c85dcbabbf2c14532acb1ad697e5de04164bb15",
      "tree": "470822394ba0b259bb1d666017ca943ec5999cb5",
      "parents": [
        "13364ef2f2aab6e2b897ce848bdaeca0ee5b0de4"
      ],
      "author": {
        "name": "Xu Bai",
        "email": "tocreationbai@gmail.com",
        "time": "Thu Oct 08 20:00:01 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 20:00:01 2026 +0800"
      },
      "message": "[HOTFIX] Include ICU license in Flink JARs (#4429)\n\nHotfix: append LICENSE file and update pom.xml for org/apache/amoro/flink/lookup/ByteArrayWrapper.java"
    },
    {
      "commit": "13364ef2f2aab6e2b897ce848bdaeca0ee5b0de4",
      "tree": "b3b439504d1c7c99ad47598b0527328c5d28b58b",
      "parents": [
        "061eb724e93592fe87cf44b61af34c1d799f5db6"
      ],
      "author": {
        "name": "Sivakumar Mahalingam",
        "email": "36898056+sivakumar-mahalingam@users.noreply.github.com",
        "time": "Thu Oct 08 09:36:52 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 14:36:52 2026 +0800"
      },
      "message": "fix(ams): reject non-positive optimizer parallelism (#4398)\n\nCo-authored-by: Xu Bai \u003ctocreationbai@gmail.com\u003e"
    },
    {
      "commit": "061eb724e93592fe87cf44b61af34c1d799f5db6",
      "tree": "466bd18f617c91b2a31b573f98494074f49dabbd",
      "parents": [
        "eeaf68154125f4619aee417e72a7914ba5573a6e"
      ],
      "author": {
        "name": "hutiefang76",
        "email": "137664623+hutiefang76@users.noreply.github.com",
        "time": "Sat Oct 03 06:35:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 07:35:19 2026 +0900"
      },
      "message": "[AMORO-4405][AMS]Report total file size for Iceberg snapshots (#4406)\n\n[AMS] Report total size for table snapshots\n\nGenerated-by: DeepSeek v4 Flash via Reasonix 1.39.4"
    },
    {
      "commit": "eeaf68154125f4619aee417e72a7914ba5573a6e",
      "tree": "d09ed4b3b741fcd0d36322c6489ebe84ad18f73f",
      "parents": [
        "488b2e34c48d0160af4638478958406d29416870"
      ],
      "author": {
        "name": "hutiefang76",
        "email": "137664623+hutiefang76@users.noreply.github.com",
        "time": "Sat Oct 03 06:35:07 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 07:35:07 2026 +0900"
      },
      "message": "[AMORO-4401][AMS]Validate optimizer list pagination parameters (#4404)\n\n* [AMS] Validate optimizer list pagination parameters\n\nGenerated-by: DeepSeek v4 Flash via Reasonix 1.39.4\n\n* [AMS] Cover optimizer pagination boundaries\n\nGenerated-by: DeepSeek v4 Flash via Reasonix 1.39.4"
    },
    {
      "commit": "488b2e34c48d0160af4638478958406d29416870",
      "tree": "2a06c64b42861b0ab2a43352b2e4c01bee9b24af",
      "parents": [
        "9442f8c0fe86f3199c77c21b730e1d9cf6cfe984"
      ],
      "author": {
        "name": "hutiefang76",
        "email": "137664623+hutiefang76@users.noreply.github.com",
        "time": "Sat Oct 03 06:34:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 07:34:54 2026 +0900"
      },
      "message": "[AMORO-4400][AMS]Keep dashboard optimizing quota positive (#4403)\n\n[AMS] Keep dashboard optimizing quota positive\n\nGenerated-by: DeepSeek v4 Flash via Reasonix 1.39.4"
    },
    {
      "commit": "9442f8c0fe86f3199c77c21b730e1d9cf6cfe984",
      "tree": "c99e06bb5cee2689af2003be33ab8fa2864f5511",
      "parents": [
        "dd77868ee172604dbade9502b05f7774bf9aea27"
      ],
      "author": {
        "name": "Sivakumar Mahalingam",
        "email": "36898056+sivakumar-mahalingam@users.noreply.github.com",
        "time": "Tue Sep 29 08:04:03 2026 +0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 29 13:04:03 2026 +0900"
      },
      "message": "[AMORO-4393][AMS] Fix shared state between AMS test classes (#4394)\n\nAMS test classes share one AMS instance and Derby database, so state left by one test class broke others depending on execution order.\n\n- TestIcebergV3OptimizingPlanning: delete only rows for tables it created instead of truncating the shared database; initialize DerbyPersistence only when run standalone.\n- TestInternalMixedCatalogService: drop residual tables and test_ns before each test; assert on test_ns presence instead of an empty catalog.\n- TestInternalIcebergCatalogService: reload through REST and reapply the catalog update if the background catalog scan overwrote it."
    },
    {
      "commit": "dd77868ee172604dbade9502b05f7774bf9aea27",
      "tree": "8ba2489e9e5da1426a0cfc38e20ec84ecd07e6d0",
      "parents": [
        "65b24e102cadaaec889ea0589929a29bdf490c55"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Wed Sep 23 12:41:02 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 12:41:02 2026 +0800"
      },
      "message": "[AMORO-4388] Complete LICENSE and LICENSE-binary third-party attribution (#4389)\n\nSource distribution LICENSE:\n- Add ICU license attribution for ByteArrayWrapper.java, derived from\n  com.ibm.icu.util.ByteArrayWrapper in ICU4J (binding -1 item from the\n  0.9.0-rc10 IPMC vote)\n- List the v3.4 SparkInternalRowWrapper.java under the Iceberg section\n  (v3.3/v3.5 were already listed)\n- List ThreadLocalCache.java (copied from Flink 1.18)\n- List the Spark-derived MixedFormatParserUtils.scala and\n  MixedFormatSqlExtensionsParser.scala for v3.3/v3.4/v3.5\n- Remove a duplicated Projection.java line\n\nBinary distribution LICENSE-binary:\n- Add javax.transaction:jta (CDDL 1.0) and javax.xml.bind:jaxb-api\n  (CDDL 1.1), both bundled in the binary distribution\n- Move org.javassist:javassist from the BSD section to the Apache\n  License 2.0 section (tri-licensed MPL/LGPL/ALv2)"
    },
    {
      "commit": "65b24e102cadaaec889ea0589929a29bdf490c55",
      "tree": "b7279c4c9d734d893d72d8d8a67d90a9eae8d9c6",
      "parents": [
        "9e63e8ebda0f9664b3efa1b4075a2ec695609893"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Wed Sep 23 11:58:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 11:58:04 2026 +0800"
      },
      "message": "[AMORO-4387] Exclude macOS AppleDouble entries from the source release archive (#4390)\n\nThe 0.9.0-rc10 source tarball shipped 3,119 AppleDouble (._*) entries:\nmacOS bsdtar serializes extended attributes as ._\u003cname\u003e sidecar members,\nand on Linux the build failed because Checkstyle parsed ._*.java files\nas Java sources (binding -1 in the IPMC vote).\n\nProtection layers in create_source_release.sh:\n\n- export COPYFILE_DISABLE\u003d1 so bsdtar/rsync stop emitting AppleDouble data\n- rsync additionally excludes ._*\n- tar additionally excludes ._ * and .DS_Store\n- after creating the archive, inspect the raw entry names with Python\u0027s\n  tarfile module and abort before signing if any ._*, __MACOSX or\n  .DS_Store entry is found (macOS `tar -t` hides ._ entries by folding\n  them back into metadata, so it cannot be used for this check)\n- verify python3 (stdlib tarfile) is available before any side effects,\n  so a missing interpreter cannot leave a half-built release directory\n  or a blocking temporary clone"
    },
    {
      "commit": "9e63e8ebda0f9664b3efa1b4075a2ec695609893",
      "tree": "e89decefed4e537bdbd8c1024ada8e35027c9fd2",
      "parents": [
        "ed4623f8597e2cbcd96ab818c2f044ad96af471a"
      ],
      "author": {
        "name": "Sivakumar Mahalingam",
        "email": "36898056+sivakumar-mahalingam@users.noreply.github.com",
        "time": "Tue Sep 22 10:30:48 2026 +0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 22 14:30:48 2026 +0800"
      },
      "message": "[AMORO-4232][common] Improve AmsThriftUrl parsing and validation (#4372)\n\nfix: improve AmsThriftUrl parsing and validation"
    },
    {
      "commit": "ed4623f8597e2cbcd96ab818c2f044ad96af471a",
      "tree": "fcb1285f109490a788cabcf8c2a66f3a92b7369a",
      "parents": [
        "3cf72b7069dbe2d65311a0f4ab8b4f0e22a4c3ba"
      ],
      "author": {
        "name": "Wang Tao",
        "email": "wtrunwolf@gmail.com",
        "time": "Tue Sep 22 14:27:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 22 14:27:10 2026 +0800"
      },
      "message": "[AMORO-4384]add jdk version check and add more add-opens (#4385)\n\n* fix# 4384 add jdk version check and add more add-opens\n\n* fix\n\n* fix according to the comment"
    },
    {
      "commit": "3cf72b7069dbe2d65311a0f4ab8b4f0e22a4c3ba",
      "tree": "427816a62f6c6494fd5c9a10c8a4b1fde4090592",
      "parents": [
        "0b79c70b71c4074f0e154287e92f4742ac03c3c6"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jiwonpark@apache.org",
        "time": "Sun Sep 20 16:29:26 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 20 15:29:26 2026 +0800"
      },
      "message": "Explain dynamic resource allocation (DRA) for optimizer groups (#4383)\n\nAdd a Dynamic resource allocation subsection to the Optimizer group\nguide covering how scale-up/scale-down are triggered, constraints,\nand a config example. Also drop the AIP-5 reference from the\ndynamic-allocation.enabled property row for consistency with the\nrest of the page, which doesn\u0027t cite proposal numbers.\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e"
    },
    {
      "commit": "0b79c70b71c4074f0e154287e92f4742ac03c3c6",
      "tree": "978256ff94db89611a59aeaafdedddd1a5fa7102",
      "parents": [
        "06d0b9e8e874b26e32c3a2292adbf21257eda2a6"
      ],
      "author": {
        "name": "Aakash",
        "email": "142689316+aakashofficial-k01@users.noreply.github.com",
        "time": "Sun Sep 20 12:57:21 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 20 15:27:21 2026 +0800"
      },
      "message": "[AMORO-4379][Iceberg] Fix OS-dependent File.separator in table URI path resolution (#4380)"
    },
    {
      "commit": "06d0b9e8e874b26e32c3a2292adbf21257eda2a6",
      "tree": "bae2b21f3cef4a2f61a8c1af3517656c6e699543",
      "parents": [
        "1909b950b0733fdfec5d5bc7532f3a4b6a86e5e7"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jiwonpark@apache.org",
        "time": "Sun Sep 20 16:00:44 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 20 15:00:44 2026 +0800"
      },
      "message": "[AMORO-4381] Fix and extend third-party license documentation in LICENSE-binary (#4382)\n\nCross-checked every jar in a built binary distribution against\nLICENSE-binary using each jar\u0027s embedded license metadata (LICENSE\nfiles, pom.xml, MANIFEST). Found one misclassification and roughly\ntwo dozen missing entries across Apache 2.0, EPL 2.0, CDDL 1.0/1.1,\nMIT, and BSD.\n\n- Move Jersey\u0027s containers group from Apache 2.0 to EPL 2.0; add its\n  core/inject groups\n- Add CDDL 1.0/1.1 sections for previously undocumented javax.*\n  dependencies; rename orphaned LICENSE.jaxb to LICENSE.javax.json\n- Fix a commons-compile/commons-compiler typo\n- Add previously undocumented Apache 2.0, MIT, and BSD dependencies\n- Elect the Apache 2.0 option of jsqlparser\u0027s dual license, per ASF\n  policy\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e"
    },
    {
      "commit": "1909b950b0733fdfec5d5bc7532f3a4b6a86e5e7",
      "tree": "efe0c3383d74812e867903d0bc200488e8d5cce7",
      "parents": [
        "e697eb3a32f777b0435230fb405a3861fe383e8e"
      ],
      "author": {
        "name": "csurong",
        "email": "csurong1@gmail.com",
        "time": "Tue Sep 15 21:20:52 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 15 21:20:52 2026 +0800"
      },
      "message": "[AMORO-4350][catalog] Fix Hive view handling in table management (#4351)\n\n* Fix Hive view filtering in table management\n\n* Fix Hive view type compatibility across versions\n\n* Simplify Hive view lookup and avoid redundant metastore calls\n\n---------\n\nCo-authored-by: caosurong \u003csurong.cao\u003e\nCo-authored-by: ConradJam \u003cjam.gzczy@gmail.com\u003e"
    },
    {
      "commit": "e697eb3a32f777b0435230fb405a3861fe383e8e",
      "tree": "b091201aa228f9debe8d0b8eb5bde2861788759b",
      "parents": [
        "bdd5f5816676f7938c379c24fad449bec19454a6"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jiwonpark@apache.org",
        "time": "Mon Sep 14 20:04:32 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 14 19:04:32 2026 +0800"
      },
      "message": "[AMORO-4375][Iceberg] Prevent automatic changes to unsupported V3 tables (#4376)\n\n* [AMORO-4375][Iceberg] Prevent automatic changes to unsupported V3 tables\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e\n\n* [AMORO-4375] Move optimizing close overloads to interface defaults\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e\n\n---------\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e"
    },
    {
      "commit": "bdd5f5816676f7938c379c24fad449bec19454a6",
      "tree": "d99c5ed52d0ca751e69c8ca19cb2c054adf1c57c",
      "parents": [
        "fc2a158f44f1915aa8a1330b97371870f8ea69e2"
      ],
      "author": {
        "name": "csurong",
        "email": "csurong1@gmail.com",
        "time": "Fri Sep 11 15:01:37 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Sep 11 15:01:37 2026 +0800"
      },
      "message": "[AMORO-4368][Dashboard] Fix Tables menu navigation after viewing Hive tables (#4369)\n\n[Bugfix][Dashboard] Return to the table list from the Tables menu"
    },
    {
      "commit": "fc2a158f44f1915aa8a1330b97371870f8ea69e2",
      "tree": "c7720223e7cc8147c442dab223cacc7508bde4d7",
      "parents": [
        "7f97dca0cbbfa9752444e13cae0f8df22db2907f"
      ],
      "author": {
        "name": "Sivakumar Mahalingam",
        "email": "36898056+sivakumar-mahalingam@users.noreply.github.com",
        "time": "Fri Sep 11 06:29:53 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Sep 11 11:29:53 2026 +0800"
      },
      "message": "[AMORO-4353] Set standby node state to FOLLOWER after base services start (#4371)\n\nfix: set standby AMS state to follower after startup"
    },
    {
      "commit": "7f97dca0cbbfa9752444e13cae0f8df22db2907f",
      "tree": "eb6e164318b8e2bced61684a0624e373cd1d8454",
      "parents": [
        "cf99b07762995230b65a9ebe4c46e74454330c21"
      ],
      "author": {
        "name": "Akeron",
        "email": "Luckilyaf@qq.com",
        "time": "Thu Sep 10 20:18:29 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 20:18:29 2026 +0800"
      },
      "message": "[AMORO-4357][Docs] Document the table. prefix requirement for catalog-level table properties (#4358)\n\n* Document the table prefix requirement for catalog-level table properties\n\n* Add link to Table configurations page in managing-catalogs doc\n\nCo-authored-by: CodeFree \u003ccodefree@chinatelcom.cn\u003e\n\n---------\n\nCo-authored-by: zhukeke \u003cakeron@qq.com\u003e\nCo-authored-by: CodeFree \u003ccodefree@chinatelcom.cn\u003e"
    },
    {
      "commit": "cf99b07762995230b65a9ebe4c46e74454330c21",
      "tree": "19209f03df46668fdf43b7b3cbf7c708d2c45073",
      "parents": [
        "75a0b2a40fd5f65c8c92c5fa3d4550b54ab75d1e"
      ],
      "author": {
        "name": "ZhouJinsong",
        "email": "zhoujinsong0505@163.com",
        "time": "Thu Sep 10 19:08:34 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 19:08:34 2026 +0800"
      },
      "message": "[Hotfix] Rmove NOTICE/LICENSE filter from shade filters (#4370)\n\nRmove NOTICE/LICENCE filter from shade filters"
    },
    {
      "commit": "75a0b2a40fd5f65c8c92c5fa3d4550b54ab75d1e",
      "tree": "49ded8801e9cffcc7b21173241b9a177cd603ced",
      "parents": [
        "c4c0aef95e09c28768a491515b98b79b9593d998"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Thu Sep 10 17:48:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 17:48:38 2026 +0800"
      },
      "message": "[web-console][dependency] Upgrade frontend to Vue 3.5 and Vite 8 toolchain, lazy-load monaco (#4340)\n\n* [web-console][dependency] Upgrade frontend to Vue 3.5 and Vite 8 toolchain, lazy-load monaco\n\nRuntime dependencies:\n- vue 3.4.27 -\u003e 3.5.41, vue-router 4.3.3 -\u003e 5.2.0, pinia 2.1.7 -\u003e 4.0.3\n  (+ @vue/devtools-api peer), vue-i18n 9.13.1 -\u003e 11.4.9\n- ant-design-vue 4.2.3 -\u003e 4.2.6, dayjs/axios/swagger-ui minor bumps\n- echarts 5.5.0 -\u003e 6.1.0 with the official v5 compatibility theme\n  registered to keep the current chart appearance\n- vue-virtual-scroller 2.0.0-beta.8 -\u003e 3.0.5 (stable); CSS entry moved\n  to index.css, RecycleScroller usage unchanged\n\nmonaco-editor 0.49.0 -\u003e 0.56.0:\n- on-demand imports (editor.api + SQL language definition + curated\n  editor features) replace the full entry that bundles ~90 languages\n- setupMonaco() loads monaco lazily when the SQL editor mounts, so the\n  ~1MB gzip monaco assets no longer load on app startup\n- unreferenced language-service worker bundles (~9.3MB) dropped at\n  build time\n\nBuild toolchain:\n- vite 5.2.13 -\u003e 8.2.2 (Rolldown), @vitejs/plugin-vue 6.0.8,\n  vite-plugin-vue-devtools 8.2.1\n- manualChunks -\u003e codeSplitting.groups with the same 8 vendor groups;\n  the monaco group sets includeDependenciesRecursively:false so a\n  shared util cannot leak into it and re-create a static entry\n  dependency that would defeat the lazy loading\n- Node v18.18.0 -\u003e v22.23.2 (pom.xml frontend-maven-plugin, README,\n  package.json engines); typescript ~5.9.3 + vue-tsc 3.3.11 restore\n  the type check that previously crashed on @vue/language-core 2.x;\n  new \"typecheck\" script\n\nMeasured (vs the pre-upgrade build):\n- build time 15.88s -\u003e ~1.7s; dist 7.8MB -\u003e 7.1MB; 114 -\u003e 30 JS chunks\n- monaco removed from the startup path; ~90 unused language chunks\n  eliminated\n\nVerified: mvnw package -pl amoro-web (frontend-maven-plugin with the\npinned Node 22: pnpm install + vite build + gen:license) passes;\neslint clean on all changed files; vue-tsc runs with no new errors\n(remaining findings are pre-existing in untouched files); vite dev\nwith mock server smoke-tested.\n\nKnown follow-ups: manual browser check of the SQL terminal editor\n(completion / format / theme) and chart visuals; pre-existing\ntype-check and lint findings are unchanged and left for separate\ncleanup.\n\n* hotfix: fix reload page error\n\n---------\n\nCo-authored-by: ZhouJinsong \u003czhoujinsong0505@163.com\u003e"
    },
    {
      "commit": "c4c0aef95e09c28768a491515b98b79b9593d998",
      "tree": "1e8b31689a4dfa7eace5a3eea344122542d4aca0",
      "parents": [
        "e8fde484d57c945a95e10dce06728521387fa335"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Thu Sep 10 11:21:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 11:21:58 2026 +0800"
      },
      "message": "[hotfix][Metrics] Iterate a locked table-runtime snapshot in gauges (#4326)\n\n* [hotfix][Metrics] Iterate a locked snapshot of tracked tables in group gauges\n\nOptimizerGroupMetrics\u0027 five table-count gauges streamed over\nSchedulingPolicy\u0027s live HashMap on scrape threads without tableLock;\nconcurrent addTable/removeTable (table onboarding, group migration)\nthrew ConcurrentModificationException mid-scrape. getTableRuntimeMap()\nis @VisibleForTesting yet was the production access path.\n\nAdd tableRuntimesSnapshot() (locked copy, same pattern as\ntableIdentifiersSnapshot) and point the gauges at it. Churn regression\ntest: with the lock temporarily removed it fails 2 of 3 runs with CME;\nlocked it is stable.\nFix record: docs/fix-records/2026-08-16-fix-17-gauge-snapshot-cme.md\n\n* [hotfix][Metrics] Verify table gauges use runtime snapshots\n\nExercise the registered optimizer-group gauges directly and fail deterministically if they read SchedulingPolicy\u0027s live runtime map. This replaces the snapshot-only test that did not cover the production metric path."
    },
    {
      "commit": "e8fde484d57c945a95e10dce06728521387fa335",
      "tree": "0da72edc12ba744d50da3e148279987ffcf1132d",
      "parents": [
        "15cb08da63d85c6783a3f4441b4e006c4501850f"
      ],
      "author": {
        "name": "wangxianghu",
        "email": "wxhjsxz@126.com",
        "time": "Thu Sep 10 07:19:31 2026 +0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 11:19:31 2026 +0800"
      },
      "message": "[AMORO-4359][AMS] Support AWS Secrets Manager as a ConfigShade (#4360)"
    },
    {
      "commit": "15cb08da63d85c6783a3f4441b4e006c4501850f",
      "tree": "5ec4ef7c3b66abd76c77cf2ddf266d928cdec7bd",
      "parents": [
        "a10adb00ccb480157769ab121551b6a856bb3e39"
      ],
      "author": {
        "name": "Aakash",
        "email": "142689316+aakashofficial-k01@users.noreply.github.com",
        "time": "Tue Sep 08 12:18:04 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 14:48:04 2026 +0800"
      },
      "message": "[AMORO-4363][ams] Support HEAD route for namespaces in Iceberg REST catalog (#4364)"
    },
    {
      "commit": "a10adb00ccb480157769ab121551b6a856bb3e39",
      "tree": "22990c34a40508f67a91dded6b48efbc87619035",
      "parents": [
        "e0640e67a457c21ff7aabad3eca91e24d275e6d1"
      ],
      "author": {
        "name": "Xu Bai",
        "email": "tocreationbai@gmail.com",
        "time": "Tue Sep 08 14:46:50 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 14:46:50 2026 +0800"
      },
      "message": "[Hotfix][Release] Update NOTICE copyright years for 2026 (#4365)\n\nUpdate copyright years in NOTICE files and pom.xml"
    },
    {
      "commit": "e0640e67a457c21ff7aabad3eca91e24d275e6d1",
      "tree": "c0dbe6aa25998a1369ae5cf9c56f5269985c0765",
      "parents": [
        "cc0ef839a9efc3071c5db5e304efdabc8cd90948"
      ],
      "author": {
        "name": "Xu Bai",
        "email": "tocreationbai@gmail.com",
        "time": "Tue Sep 08 14:08:06 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 14:08:06 2026 +0800"
      },
      "message": "[Hotfix][Release] Exclude site from source package (#4366)\n\nExclude site from source release package"
    },
    {
      "commit": "cc0ef839a9efc3071c5db5e304efdabc8cd90948",
      "tree": "c75f13ebcb6ae53c0749906152d6cf9fba4c9e95",
      "parents": [
        "f3685c959d4c9830a21ad7bd82842d56ed1f9583"
      ],
      "author": {
        "name": "WenLingzhang",
        "email": "1298877813@qq.com",
        "time": "Tue Sep 08 11:57:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 11:57:28 2026 +0800"
      },
      "message": "[Hotfix] improve REST+Lance catalog correctness (#4341)\n\n* Enforce REST+Lance exclusivity on catalog metadata update\n\n* Fetch all tables and databases across pages via pageToken in LanceRestCatalog\n\n* keep entered Iceberg storage/auth values when switching to Lance and back\n\n* fixup style"
    },
    {
      "commit": "f3685c959d4c9830a21ad7bd82842d56ed1f9583",
      "tree": "2f0a493872df652d081d789f1d4d60726c9d5466",
      "parents": [
        "2c64571f99b6ea41fc2f214612dc34100ebb780d"
      ],
      "author": {
        "name": "Xu Bai",
        "email": "tocreationbai@gmail.com",
        "time": "Mon Sep 07 11:09:24 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 07 11:09:24 2026 +0800"
      },
      "message": "[AMORO-4354] Improve process identification in logs (#4355)\n\n[AMORO-4354][common] Improve process identification in logs"
    },
    {
      "commit": "2c64571f99b6ea41fc2f214612dc34100ebb780d",
      "tree": "6218a350820447437df104a00f1df3f9f2d65b57",
      "parents": [
        "dc126a34cfe8950dc63a42a9e4774b9af9297603"
      ],
      "author": {
        "name": "Aakash",
        "email": "142689316+aakashofficial-k01@users.noreply.github.com",
        "time": "Mon Sep 07 08:38:35 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 07 11:08:35 2026 +0800"
      },
      "message": "[AMORO-4361][ams] Fix Iceberg REST catalog table creation collision to return 409 Conflict (#4362)\n\n* [AMORO-4361][ams] Fix Iceberg REST catalog table creation collision to return 409 Conflict\n\n* [AMORO-4361][ams] Address review comments: trim upfront checks and map exception codes"
    },
    {
      "commit": "dc126a34cfe8950dc63a42a9e4774b9af9297603",
      "tree": "84deead21bb986e35ecba28e0c46847d94298890",
      "parents": [
        "bbec598aeda42b051bbc2dce7299086cbf565f22"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Mon Sep 07 10:54:56 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 07 10:54:56 2026 +0800"
      },
      "message": "[ams] Fix optimizing status metrics never updated and reset on restart (#4356)\n\nThe table optimizing status metrics (table_optimizing_status_in_* and\ntable_optimizing_status_*_duration_mills) have been broken since the\nTableRuntime storage refactor in AMORO-3747:\n\n1. TableOptimizingMetrics#statusChanged is never invoked, so the status\n   gauges stay at their initial values (idle) for the whole process\n   lifetime and non-idle durations are always zero.\n2. The runtime is not seeded with the persisted status code and update\n   time when constructed, so durations restart from zero after an AMS\n   restart.\n3. Same-status status-code writes (e.g. setPendingInput on a non-idle\n   table) refresh status_code_update_time, restarting the persisted\n   duration clock used by the dashboard.\n\nThe fix:\n- seed TableOptimizingMetrics from the persisted status code and\n  status_code_update_time when constructing DefaultTableRuntime\n- notify the metrics from the status-change handler after the update\n  is committed to the store\n- skip status-code updates that don\u0027t change the value, so no-op\n  writes no longer refresh status_code_update_time or fire redundant\n  status-change notifications"
    },
    {
      "commit": "bbec598aeda42b051bbc2dce7299086cbf565f22",
      "tree": "056ce86b857b9d8ad2daed45b7c42af5e6a62caa",
      "parents": [
        "05c0efe346c50b438d3e00e2a2636a347fbd4d9a"
      ],
      "author": {
        "name": "wangxianghu",
        "email": "wangxianghu@apache.org",
        "time": "Fri Sep 04 12:24:20 2026 +0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Sep 04 16:24:20 2026 +0800"
      },
      "message": "[Hotfix][AMS] Fix optimizer registration failure under database HA mode (#4352)"
    },
    {
      "commit": "05c0efe346c50b438d3e00e2a2636a347fbd4d9a",
      "tree": "12bf072de808225371511f37df7cdb9623d16607",
      "parents": [
        "cf5c5aaa957a0a3e904d732a1c74bc4ce482c32a"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jiwonpark@apache.org",
        "time": "Wed Sep 02 23:59:20 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 02 22:59:20 2026 +0800"
      },
      "message": "[AMORO-4348] Fix infinite retry loop for failed table processes (#4349)\n\n* [AMORO-4348] Fix infinite retry loop for failed table processes\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e\n\n* [AMORO-4348] Make the failing test engine throw from submitTableProcess\n\nSigned-off-by: Jiwon Park \u003cjiwonpark@apache.org\u003e"
    },
    {
      "commit": "cf5c5aaa957a0a3e904d732a1c74bc4ce482c32a",
      "tree": "d65eb8c7445950a51fd9050fafe56b40a05566db",
      "parents": [
        "fc0c2e8e3f6fd4e9966b405e709e7735c44a5cc9"
      ],
      "author": {
        "name": "csurong",
        "email": "csurong1@gmail.com",
        "time": "Wed Sep 02 13:30:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 02 13:30:58 2026 +0800"
      },
      "message": "[AMORO-4345][Iceberg] Fix catalog table listing isolation (#4346)\n\nFix catalog table listing isolation\n\nCo-authored-by: caosurong \u003csurong.cao\u003e"
    },
    {
      "commit": "fc0c2e8e3f6fd4e9966b405e709e7735c44a5cc9",
      "tree": "c28bcdd8dc85d06a7c8dab718e2c26386360e529",
      "parents": [
        "5d976fc71445690bb557e495d4787357040a1e8d"
      ],
      "author": {
        "name": "csurong",
        "email": "csurong1@gmail.com",
        "time": "Mon Aug 31 19:35:51 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 31 19:35:51 2026 +0800"
      },
      "message": "[AMORO-4343][ams] Fix runtime creation for unsupported table formats (#4344)\n\nFix runtime creation for unsupported table formats\n\nCo-authored-by: caosurong \u003csurong.cao\u003e"
    },
    {
      "commit": "5d976fc71445690bb557e495d4787357040a1e8d",
      "tree": "091d4da122e464970682558d2684216ee7362d64",
      "parents": [
        "52ef6b19020b133eae6309490b701976674ede79"
      ],
      "author": {
        "name": "ZhouJinsong",
        "email": "zhoujinsong0505@163.com",
        "time": "Mon Aug 31 17:01:31 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 31 17:01:31 2026 +0800"
      },
      "message": "[Refactor] Unify the main process of amoro service container (#4339)\n\n* Unify the main process of amoro service container\n\n* Fix checkstyle issus\n\n* Stop leader service first in dispose path"
    },
    {
      "commit": "52ef6b19020b133eae6309490b701976674ede79",
      "tree": "f2e67af4c72240b303dbd48f629ea4f790de7044",
      "parents": [
        "18859a662cddb9bb74066e6f27cf2821f15f705c"
      ],
      "author": {
        "name": "ZhouJinsong",
        "email": "zhoujinsong0505@163.com",
        "time": "Mon Aug 31 16:59:13 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 31 16:59:13 2026 +0800"
      },
      "message": "[Hotfix] Remove slf4j classes from kyuubi-hive-jdbc-shaded (#4342)\n\nFix slf4j dependency conflicts"
    },
    {
      "commit": "18859a662cddb9bb74066e6f27cf2821f15f705c",
      "tree": "8e4d0b8603b84f9df346d9ecdc2ee0aac6e879c4",
      "parents": [
        "f4e73310b58b56bac325cbb5665fd509b59cc188"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jpark92@outlook.kr",
        "time": "Wed Aug 26 20:30:07 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 26 19:30:07 2026 +0800"
      },
      "message": "[AMORO-4337] Upgrade Iceberg dependency to 1.8.1 (#4338)\n\n* [AMORO-4337] Upgrade Iceberg dependency to 1.8.1\n\nBump iceberg.version from 1.7.2 to 1.8.1. The only API removal affecting\nAmoro is FlinkAvroReader, removed in Iceberg 1.8.0: RowDataFileScanTaskReader\nin amoro-mixed-flink-common-iceberg-bridge is a copy of the Iceberg class of\nthe same name, so mirror the change Iceberg 1.8 made to its own copy\n(FlinkPlannedAvroReader via createReaderFunc, and path() to location()).\nAlso refresh the Iceberg download links in the Flink CDC ingestion doc.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4337] Fix pos-delete read schema in IcebergRewriteExecutorTest\n\nThe test projected position-delete files with the virtual metadata columns\n_file/_pos (MetadataColumns.FILE_PATH/ROW_POSITION), while the files actually\nstore file_path/pos (DELETE_FILE_PATH/DELETE_FILE_POS) with different field\nids. Iceberg 1.7 tolerated the mismatch by synthesizing row positions and\nignoring the missing _file column, so the assertions passed by accident.\nIceberg 1.8 rejects projections of required fields that are absent from the\nfile (Missing required field: _file). Project with the delete-file schema so\nthe test reads the values actually written.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4337] Update dependency manifests for Iceberg 1.8.1\n\nRegenerated with ./dev/dependencies.sh --replace: iceberg artifacts move to\n1.8.1 and the transitive httpclient5/httpcore5 move to 5.4.1/5.3.1.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n---------\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e"
    },
    {
      "commit": "f4e73310b58b56bac325cbb5665fd509b59cc188",
      "tree": "d7d9297c51401aa842bc77dae3543b50c84f32e8",
      "parents": [
        "505a66e1e454a4706caca6857e84d4e7f7a39282"
      ],
      "author": {
        "name": "ZhouJinsong",
        "email": "zhoujinsong0505@163.com",
        "time": "Wed Aug 26 16:23:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 26 16:23:18 2026 +0800"
      },
      "message": "[Hotfix] Change log4j impl dependency to `log4j-slf4j2-impl` (#4336)\n\n* Change log4j impl to log4j-slf4j2-impl\n\n* Fix dependencies information\n\n* Fix mixed-trino ci issue\n\n* Fix log4j dependency conflicts\n\n* Fix log4j dependencies\n\n* Change enforcer to verify phase\n\n* Fix checkstyle issue in pom\n\n* Fix unit test issues for spark 3.3\n\n* Fix log4j conflicts in mixed trino\n\n* Fix log dependency conflicts in hudi moduel"
    },
    {
      "commit": "505a66e1e454a4706caca6857e84d4e7f7a39282",
      "tree": "80a5caf27749293ca43f87029e887eb6b988d607",
      "parents": [
        "4f26c4574c5200d4904822408db7a96f4f59326c"
      ],
      "author": {
        "name": "WenLingzhang",
        "email": "1298877813@qq.com",
        "time": "Wed Aug 26 11:04:02 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 26 11:04:02 2026 +0800"
      },
      "message": "[AMORO-4280] Add support for Lance format on REST metastore (#4334)\n\n* Add support for Lance format on REST metastore\n\n* skip TableMetaStore auth build for REST + Lance-only catalog\n\n* fixup style"
    },
    {
      "commit": "4f26c4574c5200d4904822408db7a96f4f59326c",
      "tree": "19c8d98e6a45faf015f69f158fffb32b988156f3",
      "parents": [
        "1c894691bcb761774901c11ed46f1e454bdad1d3"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Wed Aug 26 10:53:22 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 26 10:53:22 2026 +0800"
      },
      "message": "[hotfix][Optimizer] Preserve keeper visibility on lookup failure (#4325)\n\n[hotfix][Optimizer] Volatile optimizer touch time; keep groups watched on container lookup failure\n\ntouchTime is written by thrift heartbeat threads and read by the keeper\nthread without a shared lock - a plain long field is a JMM data race\n(stale reads can expire live optimizers; word tearing on 32-bit JVMs).\nDeclare it volatile.\n\nOptimizerGroupKeeper.processTask called Containers.get outside the\ntry/finally whose finally-block re-queues the group via keepInTouch.\nAn unknown container name threw IllegalArgumentException straight into\nAbstractKeeper.run\u0027s swallow-all catch, permanently removing the group\nfrom scale-out monitoring until restart. Move the lookup and the cast\ninside the try.\n\nRegression test testUnknownContainerKeepsGroupWatchedAndResetsMinParallelism\n(red before: min-parallelism stayed 2, group silently dropped).\nFix record: docs/fix-records/2026-08-16-fix-15-keeper-visibility-and-container-lookup.md"
    },
    {
      "commit": "1c894691bcb761774901c11ed46f1e454bdad1d3",
      "tree": "3abeb49a338bbfb42e0cb8a12d780070986c1f60",
      "parents": [
        "72a7729860e284c88206479ffec1ff751751d463"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Tue Aug 25 14:21:36 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 25 14:21:36 2026 +0800"
      },
      "message": "[hotfix][Optimizer] Guard invalid fragment ratio and target quota (#4324)\n\nself-optimizing.fragment-ratio and self-optimizing.quota do not enforce positive values, so zero or negative values may already exist in persisted table properties.\n\nNormalize fragment ratios to at least one in OptimizingConfig.setFragmentRatio(), keep the configured default value of 8 in TableProperties, and make CommonPartitionEvaluator reuse OptimizingConfig.maxFragmentSize(). This prevents division by zero in the actual planner while leaving persisted properties unchanged.\n\nClamp quota limits to at least one so invalid target quotas neither corrupt quota weights nor starve tables of schedulable slots.\n\nTests: TestOptimizingConfig, TestCommonPartitionEvaluator, and TestOptimizingQueue#testQuotaSchedulePolicy."
    },
    {
      "commit": "72a7729860e284c88206479ffec1ff751751d463",
      "tree": "37a7fd7e1c89eed5541cbcdaebd2c10450efd2fb",
      "parents": [
        "7333642cfb92e391fc4280553f673ea9829c6644"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Tue Aug 25 14:21:12 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 25 14:21:12 2026 +0800"
      },
      "message": "[hotfix][Optimizer] Remove zero-valued in-flight task counters (#4328)\n\n[hotfix][Optimizer] Remove per-table in-flight task counters at zero\n\noptimizingTasksMap kept a zero-count AtomicInteger entry forever after\na table\u0027s last task completed: poll created entries via\ncomputeIfAbsent, acceptResult decremented but always returned the\nholder, and neither releaseTable nor dispose cleaned up. Every table\nthat ever had a polled task (including deleted tables and tables that\nmoved groups) permanently occupied one map slot.\n\nSwitch acceptResult to an atomic compute that removes the entry at zero\n(keeping the \u003e0 decrement guard; late accepts on a removed entry are\nno-ops instead of resurrecting it), and clear the entry in\nreleaseTable/dispose.\n\nRegression test testTasksMapEntryRemovedAfterTaskCompletes (red before:\nmap size stayed 1). Full TestOptimizingQueue 47/47 green.\nFix record: docs/fix-records/2026-08-16-fix-19-optimizing-tasks-map-leak.md"
    },
    {
      "commit": "7333642cfb92e391fc4280553f673ea9829c6644",
      "tree": "b34789c4f1747b4494fc859ca218d6126893241f",
      "parents": [
        "96a4d781aac60c4080b3f4a41322848e2308649a"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Tue Aug 25 11:23:26 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 25 11:23:26 2026 +0800"
      },
      "message": "[hotfix][AMS] Clean up orphan optimizer records at startup (#4320)\n\n* [hotfix][AMS] Clean up orphan optimizer records at startup instead of NPE\n\nAn optimizer row referencing a resource group that no longer exists\n(e.g. group dropped while AMS was down, or the canDeleteResourceGroup\ncheck-then-act race) made loadOptimizingQueues throw an NPE during\ninitHandler and prevented AMS from starting, with no self-healing path.\n\nExtract registerOptimizers(): register when the group exists, otherwise\nWARN and remove the orphan row via the existing unregisterOptimizer\ncleanup, mirroring the tolerant handling already present in the\nfollower-sync path (registerOptimizerWithoutPersist).\n\nVerified by new test testOrphanedOptimizerRecordMustNotBreakInitialization\n(red: NPE reproduced on old behavior; green: 26/26 in TestDefaultOptimizingService).\nFix record: docs/fix-records/2026-08-15-fix-01-orphan-optimizer-startup-npe.md\n\n* [hotfix][AMS] Prevent optimizer resource group races in HA mode"
    },
    {
      "commit": "96a4d781aac60c4080b3f4a41322848e2308649a",
      "tree": "082cd90d213785e3224aeb1e69107d3710be4357",
      "parents": [
        "de6205c0e92bbf3139e25067d735f61ba95b7f41"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Sat Aug 22 12:02:59 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 22 12:02:59 2026 +0800"
      },
      "message": "[hotfix][Optimizer] Recognize CLOSED optimizing processes (#4331)\n\n[hotfix][Optimizer] Make isClosed() recognize the CLOSED status\n\nclose() sets ProcessStatus.CLOSED while isClosed() only compared\nagainst KILLED - a status never assigned in this class - so the\npredicate was permanently false and acceptResult\u0027s\nOptimizingClosedException guard against late results on a closed\nprocess could never fire (downstream isProcessing conditions happened\nto contain the fallout).\n\nCheck both CLOSED and KILLED. Reachability analysis in the fix record:\nclose(false) cancels tasks so late completes fail earlier with\nIllegalTaskStateException, and the partial-commit path legitimately\naccepts late results; no public-API path drives the guard today, so\nthis lands as an intent fix verified by the full queue regression\n(47/47) rather than a behavioral red test.\nFix record: docs/fix-records/2026-08-16-fix-22-is-closed-status-mismatch.md"
    },
    {
      "commit": "de6205c0e92bbf3139e25067d735f61ba95b7f41",
      "tree": "df85042fbc49d9718a1d51a5ec653c9f0ead8cc4",
      "parents": [
        "6ab54c515f9eb698812b95589fed60e2325d65ad"
      ],
      "author": {
        "name": "Power John",
        "email": "johntomcat7408@gmail.com",
        "time": "Tue Aug 18 15:35:53 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 15:35:53 2026 +0800"
      },
      "message": "[AMORO-4264][AMS] Use a shared pool for Iceberg maintenance planning (#4311)\n\n* [AMORO-4264][AMS] Isolate snapshot expiration planning\n\n* [AMORO-4264][AMS] Use a shared pool for Iceberg maintenance planning\n\n---------\n\nCo-authored-by: ZhouJinsong \u003czhoujinsong0505@163.com\u003e"
    },
    {
      "commit": "6ab54c515f9eb698812b95589fed60e2325d65ad",
      "tree": "6598d9a58e40b8b2df6092185033f2fdd2fcb27a",
      "parents": [
        "4c141b393d52f37becb3c719e6cc3366fa08d22f"
      ],
      "author": {
        "name": "seoyeon",
        "email": "41140596+seoyoniee@users.noreply.github.com",
        "time": "Tue Aug 18 15:14:57 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 14:14:57 2026 +0800"
      },
      "message": "[AMORO-4316][AMS] Support monthly period for auto-creating Iceberg tags (#4317)\n\n[AMORO-4316] add monthly auto-create tag\n\nCo-authored-by: seoyoniee \u003cseoyonie22@gmail.com\u003e\nCo-authored-by: ZhouJinsong \u003czhoujinsong0505@163.com\u003e"
    },
    {
      "commit": "4c141b393d52f37becb3c719e6cc3366fa08d22f",
      "tree": "eae6803205213727b92c5ba539664c96fb1a2ad8",
      "parents": [
        "f5098f8d0de4fa3f9900f1e69d89213cef959b93"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jpark92@outlook.kr",
        "time": "Tue Aug 18 12:01:37 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 11:01:37 2026 +0800"
      },
      "message": "[AMORO-4318] Add mixed Flink 1.20 support (#4319)\n\n* [AMORO-4318] Compile amoro-mixed-flink-common against Flink 1.20\n\nBump the common module to Flink 1.20.3 with iceberg-flink-1.20 and\npaimon-flink-1.20. Adapt two test utilities to Flink 1.20 test API\nchanges: MockEnvironment gained jobName/JobType constructor parameters,\nand RexNodeToExpressionConverter no longer takes a session time zone.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4318] Add mixed Flink 1.20 modules\n\nAdd v1.20/amoro-mixed-flink-1.20 and v1.20/amoro-mixed-flink-runtime-1.20\nmirroring the v1.19 modules. The runtime module overrides\nflink-connector-kafka to 3.4.0-1.20, the latest connector release\ntargeting Flink 1.20, since the parent\u0027s 3.2.0-1.18 line has no\nFlink 1.20 variant.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4318] Document mixed Flink 1.20 support\n\nAdd Flink 1.20.x to the supported engine matrix and the Flink\nget-started and logstore version tables.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n---------\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e"
    },
    {
      "commit": "f5098f8d0de4fa3f9900f1e69d89213cef959b93",
      "tree": "5e810c4f8b3aaddb637b260c570db81421887dba",
      "parents": [
        "072560927f30f2429d361a2383800608ddabdbb3"
      ],
      "author": {
        "name": "ConradJam",
        "email": "jam.gzczy@gmail.com",
        "time": "Tue Aug 18 10:31:30 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 10:31:30 2026 +0800"
      },
      "message": "[hotfix][Process] Preserve recovery failure context (#4321)\n\n[hotfix][Process] Include recovery context in markRecoverFailed message\n\nThe fail_message persisted for an un-recoverable process only carried the\nraw cause text; processId/tableId/action/engine/externalIdentifier lived\nonly in the server log. testRecoverProcessesShouldSkipFailedRecovery\n(added in f0cd29e80) already asserted the richer message but production\ncode never implemented it, leaving the test red on a clean tree.\n\nFix record: docs/fix-records/2026-08-15-fix-03-recover-fail-message-context.md"
    },
    {
      "commit": "072560927f30f2429d361a2383800608ddabdbb3",
      "tree": "e4cba3757d40de56862b6c207791a4d4f54c27a8",
      "parents": [
        "56c34f61ece921d83ab6d32ca0a8f6715f0447fd"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jpark92@outlook.kr",
        "time": "Tue Aug 18 11:02:38 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 10:02:38 2026 +0800"
      },
      "message": "[Hotfix][AMS] Stabilize optimizer scale-down floor test (#4332)\n\ntest: stabilize optimizer scale-down floor test\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e"
    },
    {
      "commit": "56c34f61ece921d83ab6d32ca0a8f6715f0447fd",
      "tree": "c5ef270973684a3fa90f1ccbaaf6ca2f378e913c",
      "parents": [
        "219550114c60c888de8783766a46a117e5b075b1"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jpark92@outlook.kr",
        "time": "Mon Aug 17 12:46:58 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 17 11:46:58 2026 +0800"
      },
      "message": "[AMORO-4313] AIP-5 Phase 5: observability metrics for dynamic allocation (#4314)\n\n* [AMORO-4313] Expose backlog duration from DynamicAllocationState for the backlog gauge\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4313] Add per-group dynamic allocation metrics with source-backed gauges and scale counters\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4313] Wire dynamic allocation metrics into the scale keeper watch lifecycle\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4313] Add idle-optimizer and config-invalid gauges to the optimizer group metrics\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4313] Document dynamic allocation metrics in the metrics table\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n---------\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e"
    },
    {
      "commit": "219550114c60c888de8783766a46a117e5b075b1",
      "tree": "410caf3b5d9f05dd688d8828d87a648a48469d3a",
      "parents": [
        "1b094b4105ee84f77587bbc0f2e602d0471f2b1e"
      ],
      "author": {
        "name": "OctoBored",
        "email": "sgirard+github@insa-rouen.fr",
        "time": "Fri Aug 14 07:13:16 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 14 13:13:16 2026 +0800"
      },
      "message": "[Docs] Fix the broken Star History chart in the README (#4315)\n\nThe Star History chart in the README is broken because the upstream chart no longer works reliably. Point the chart to a working mirror so the project\u0027s star history is displayed correctly again.\n\nCo-authored-by: OctoBored \u003c212877535+OctoBored@users.noreply.github.com\u003e"
    },
    {
      "commit": "1b094b4105ee84f77587bbc0f2e602d0471f2b1e",
      "tree": "e75c228dca40f0e0e594a9898e64510afe029954",
      "parents": [
        "9f2a45e88ca97864b6de0bbb843e3ae9dd201577"
      ],
      "author": {
        "name": "Xu Bai",
        "email": "tocreationbai@gmail.com",
        "time": "Wed Aug 12 14:53:21 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 14:53:21 2026 +0800"
      },
      "message": "[Hotfix][AMS] Unify authentication handling for dashboard requests (#4312)\n\nRemove single page token validation and related utility methods"
    },
    {
      "commit": "9f2a45e88ca97864b6de0bbb843e3ae9dd201577",
      "tree": "d5b30f6410f209529a7238b2147b2dd0cefd2aa8",
      "parents": [
        "287f4586b2357097e472de2e4868c8f59b8cc412"
      ],
      "author": {
        "name": "seoyoniee",
        "email": "41140596+seoyoniee@users.noreply.github.com",
        "time": "Tue Aug 11 21:01:49 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 20:01:49 2026 +0800"
      },
      "message": "[AMORO-4139] Delete resource and optimizer atomically when releasing optimizer (#4310)\n\n[AMORO-4139] Delete resource and optimizer atomically when releasing an optimizer\n\nCo-authored-by: seoyoniee \u003cseoyonie22@gmail.com\u003e\nCo-authored-by: ConradJam \u003cjam.gzczy@gmail.com\u003e\nCo-authored-by: ZhouJinsong \u003czhoujinsong0505@163.com\u003e"
    },
    {
      "commit": "287f4586b2357097e472de2e4868c8f59b8cc412",
      "tree": "1b781a0c2ed58c8c1659054932e617d11e63f78e",
      "parents": [
        "c26fd6e787dc4cdfc5e54601426d9595320923ad"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jpark92@outlook.kr",
        "time": "Tue Aug 11 20:10:52 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 19:10:52 2026 +0800"
      },
      "message": "[AMORO-4295] AIP-5 Phase 3+4: idle-driven scale-down with graceful drain for dynamic allocation groups (#4296)\n\n* [AMORO-4295] Expose per-token in-flight counts in the dynamic allocation load snapshot\n\nScale-down needs to know which optimizer instances are busy, not only how\nmany threads are. Aggregate SCHEDULED/ACKED task counts per optimizer token\nin the same scan collectDynamicAllocationLoad() already performs, so one\nsnapshot supplies both scale directions. Recovered tasks keep their token\nacross an AMS restart, which makes the very first snapshot after a restart\naccurate without any rebuild step.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4295] Add snapshot-derived idle observation and the scale-down decision\n\nTrack per-token idle time by observation instead of event counters: each\nkeeper round feeds the task snapshot into observe(), which refreshes busy\ntimestamps, seeds first-seen tokens as idle (an instance that never\nreceives a task must still become removable), and prunes unregistered\nones. Event-maintained counters were rejected because three existing\npaths reclaim assigned tasks without any service-level decrement hook\n(queue-internal stale-ACKED resets, ack/exec-timeout reclaims of live\noptimizers, and process close), each silently inflating a counter until\nthe instance can never look idle again.\n\ncomputeScaleDown picks at most one candidate per round: the longest-idle\ninstance past executor-idle-timeout, rate-limited by scale-down-cooldown,\nwhose removal keeps registered-minus-draining threads at or above\nmin-parallelism. Draining threads count as already gone so consecutive\nremovals cannot pass the floor check together and land below the floor\nonce they all complete.\n\nvalidate() now also requires sustained-backlog-timeout to be at most half\nof executor-idle-timeout: the keeper cadence is the observation\nresolution, and sampling slower than that misjudges an instance that\nworked between samples as continuously idle.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4295] Add graceful drain plumbing: poll blocking and optimizer removal\n\nA draining optimizer\u0027s token enters a pending-removal set consulted twice\nin pollTask: once on entry, and once after the queue poll returns, because\nthe entry check cannot stop a thread already parked in the queue\u0027s\nlong-poll — it may fetch a task after the drain began, and that task is\nhanded back (PLANNED again) instead of being assigned. touch/ack/complete\nstay open so in-flight tasks finish normally.\n\nexecuteRemoval releases the container resource, deletes the persisted row,\nand unregisters. A missing resource row is handled by releasing through\nthe optimizer instance itself (it extends Resource and carries the\ncontainer identity): a pod that self-registered after a persist failure\nhas no row and never will, so treating that as a retryable error would\ndrain-block it forever while its heartbeat keeps it registered. A failed\ncontainer release keeps the drain state and retries on a later round —\nKubernetes deletion is idempotent.\n\nThe mock container used by the keeper tests now records released\nresources and can simulate release failures.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4295] Integrate scale-down and drain progress into the scale keeper round\n\nEach round now runs in a fixed order. Drain progress first and\nunconditionally — a drain that completed or hit its deadline converts to\na removal even in rounds that scale up, or a busy drain would linger to\nits full timeout while backlog persists. Draining instances are then\naccounted as already gone on both sides of the demand math: leaving\ntheir threads in the capacity undercounts demand by up to their thread\ncount, and leaving their tasks in the load keeps the future-demand\nsignal (busy \u003e\u003d effective) from ever firing mid-drain. Idle observation\nruns every round including scale-up ones, so an instance busy through a\nburst does not come out of it looking idle since before the burst began.\n\nScale-down runs only in rounds with no demand signal at all — including\ndemand still held back by the backlog gate, which computeScaleUp now\nexposes: removing a warm instance right before the gate opens would\nfree exactly the capacity the next round re-requests. A selected victim\nbegins a graceful drain and is removed in the same round only if a\nsnapshot taken after the token entered the pending-removal set shows it\nidle; the pre-insert snapshot may miss a task fetched by a long-poll\nracing the drain start.\n\nThe keeper tests drive rounds with injected times because the validated\nminimum executor-idle-timeout (30s) puts real idle waits beyond sane\ntest durations.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4295] Clear drain state on unregistration and on dynamic allocation disable\n\nTwo lifecycle paths could strand a token in the pending-removal set. An\noptimizer that dies mid-drain is unregistered by heartbeat expiry, and\nits token can never be matched again (the replacement pod registers\nunder a fresh one), so unregisterOptimizer now clears the drain state.\nAnd a group whose dynamic allocation is disabled mid-drain returns to\nthe legacy floor keeper, where a leftover drain block would starve the\nstill-running pod forever — unwatching the group re-admits its tokens\nto task assignment.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4295] Fix concurrent optimizer unregistration\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4295] Document scale-down and drain behavior in the optimizer group property table\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n---------\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\nCo-authored-by: ZhouJinsong \u003czhoujinsong0505@163.com\u003e"
    },
    {
      "commit": "c26fd6e787dc4cdfc5e54601426d9595320923ad",
      "tree": "add5348a1ff4ff20a65e18a3afacd7c8d3913589",
      "parents": [
        "7c791a5f5dbfb509eabffc8a46a42a18791d439b"
      ],
      "author": {
        "name": "Xu Bai",
        "email": "tocreationbai@gmail.com",
        "time": "Mon Aug 10 14:19:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 14:19:28 2026 +0800"
      },
      "message": "[AMORO-4266] Introduce Amoro MCP server (#4285)\n\n(cherry picked from commit 5a0f93774e09a10cbb3585e395335fab363540df)\n\nCo-authored-by: ConradJam \u003cjam.gzczy@gmail.com\u003e"
    },
    {
      "commit": "7c791a5f5dbfb509eabffc8a46a42a18791d439b",
      "tree": "06cadf353d09bccf23203a814da5d2c412442442",
      "parents": [
        "4953d9c90d378d0f031bad3a1bc879a0dc16512c"
      ],
      "author": {
        "name": "Xin Sun",
        "email": "ddupgs@gmail.com",
        "time": "Mon Aug 03 20:05:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 03 20:05:58 2026 +0800"
      },
      "message": "[AMORO-4308][lance] Remove redundant getTables call (#4309)\n\nChange-Id: I8ced8b818e8b77f2757f737df7df4a0a425d07e7"
    },
    {
      "commit": "4953d9c90d378d0f031bad3a1bc879a0dc16512c",
      "tree": "910936b045bedef3e1c1576a566519c9a9b23c86",
      "parents": [
        "7e9f9a7697a2a7cfef6ff6362235153a3bf39035"
      ],
      "author": {
        "name": "Power John",
        "email": "johntomcat7408@gmail.com",
        "time": "Mon Aug 03 20:04:49 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 03 20:04:49 2026 +0800"
      },
      "message": "[AMORO-4303][AMS] Stabilize optimizer heartbeat tests (#4307)"
    },
    {
      "commit": "7e9f9a7697a2a7cfef6ff6362235153a3bf39035",
      "tree": "57075aafaac2db7d63862d8a8f00f5f32502d66f",
      "parents": [
        "a0640e0c988b8ad9784ca4658e395a5d9989fec4"
      ],
      "author": {
        "name": "Xu Bai",
        "email": "tocreationbai@gmail.com",
        "time": "Mon Aug 03 20:02:34 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 03 20:02:34 2026 +0800"
      },
      "message": "[Hotfix][tools] Include Helm chart in change-version script (#4306)"
    },
    {
      "commit": "a0640e0c988b8ad9784ca4658e395a5d9989fec4",
      "tree": "df1fddaec7a6fd5ce3745ecaab8c457699e9259f",
      "parents": [
        "efbedc396fa178abe39ec24071f91f24163d8c9a"
      ],
      "author": {
        "name": "Xu Bai",
        "email": "tocreationbai@gmail.com",
        "time": "Mon Aug 03 20:01:44 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 03 20:01:44 2026 +0800"
      },
      "message": "[AMORO-2099][amoro-web] Remove default Glue lock configuration (#4305)\n\n[amoro-web] Remove default Glue lock configuration"
    },
    {
      "commit": "efbedc396fa178abe39ec24071f91f24163d8c9a",
      "tree": "1715c81d5a58e5ff0961825fe1c5369e2efc32d0",
      "parents": [
        "acb9a49a493fc0708e186a7da6bac9634deef895"
      ],
      "author": {
        "name": "csurong",
        "email": "csurong1@gmail.com",
        "time": "Thu Jul 30 21:39:30 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 30 21:39:30 2026 +0800"
      },
      "message": "[AMORO-4301][ams] Fix Kubernetes executor label prefix (#4302)\n\nUse Spark\u0027s executor label prefix for optimizer executor pods and add regression coverage for both driver and executor labels.\n\nCo-authored-by: caosurong \u003csurong.cao@thinkingdata.cn\u003e\nCo-authored-by: ZhouJinsong \u003czhoujinsong0505@163.com\u003e"
    },
    {
      "commit": "acb9a49a493fc0708e186a7da6bac9634deef895",
      "tree": "c8046c3caf28829ff54bc4e60749db1b65cf765e",
      "parents": [
        "38b2b49e72676cc5623264ce6f5d0dd94d3e414c"
      ],
      "author": {
        "name": "Xu Bai",
        "email": "tocreationbai@gmail.com",
        "time": "Thu Jul 30 19:11:45 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 30 19:11:45 2026 +0800"
      },
      "message": "[AMORO-4300] Recover active processes after table ownership transfer (#4304)\n\n[AMORO-4300][ams] Recover active processes after table ownership transfer\n\nCo-authored-by: ZhouJinsong \u003czhoujinsong0505@163.com\u003e"
    },
    {
      "commit": "38b2b49e72676cc5623264ce6f5d0dd94d3e414c",
      "tree": "cd42bbd10c39642abb761fbc6a64c9019e3eacd1",
      "parents": [
        "b7bf0d39de9bb085446f1b06da2cb1810ac5cb26"
      ],
      "author": {
        "name": "Power John",
        "email": "johntomcat7408@gmail.com",
        "time": "Thu Jul 30 17:57:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 30 17:57:15 2026 +0800"
      },
      "message": "[AMORO-4240][AMS] Support staged table creation in REST catalog (#4284)\n\n* [AMORO-4240][AMS] Support staged table creation in REST catalog\n\n* [AMORO-4240][AMS] Address staged create review comments"
    },
    {
      "commit": "b7bf0d39de9bb085446f1b06da2cb1810ac5cb26",
      "tree": "9e790acfe129f3696c80c37462bd30e94c3088ed",
      "parents": [
        "ec28554a2eaab45c402d6c5a1a1c14ab36d769a1"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jpark92@outlook.kr",
        "time": "Thu Jul 30 15:21:11 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 30 14:21:11 2026 +0800"
      },
      "message": "[AMORO-4297][AMS] Persist failure reasons in task quota history (#4298)\n\nfix: persist task quota failure reasons\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e"
    },
    {
      "commit": "ec28554a2eaab45c402d6c5a1a1c14ab36d769a1",
      "tree": "b44bd75445ab5dccc7a10b1b9420e918642fb1de",
      "parents": [
        "ea4ea4cd31ecab35a3d8b7ebf39571d266cac472"
      ],
      "author": {
        "name": "ZhouJinsong",
        "email": "zhoujinsong0505@163.com",
        "time": "Wed Jul 29 11:58:32 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 29 11:58:32 2026 +0800"
      },
      "message": "[Hotfix] Change the docker action version to match ASF policy (#4299)\n\nChange the docker action version to match ASF policy"
    },
    {
      "commit": "ea4ea4cd31ecab35a3d8b7ebf39571d266cac472",
      "tree": "4913eb6bde9a1763395d01309e1e332bbb096285",
      "parents": [
        "436a3173b992cf049112b0ea47cb83f38a2afc6f"
      ],
      "author": {
        "name": "ZhouJinsong",
        "email": "zhoujinsong0505@163.com",
        "time": "Mon Jul 27 21:47:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 27 21:47:28 2026 +0800"
      },
      "message": "[Hotfix] Pin all external actions to the specific git hash (#4294)\n\n* Pin all external actions to the specific git hash\n\n* Update action version"
    },
    {
      "commit": "436a3173b992cf049112b0ea47cb83f38a2afc6f",
      "tree": "17fd86e099361a73165ac9216b803c6cf586d4d9",
      "parents": [
        "0dfaa4b159728d470f90e22e0cede8a3ef441fc6"
      ],
      "author": {
        "name": "ZhouJinsong",
        "email": "zhoujinsong0505@163.com",
        "time": "Mon Jul 27 17:40:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 27 17:40:28 2026 +0800"
      },
      "message": "[AMORO-4286]Change process status to failed when recover from AMS restarting (#4288)\n\n* Change process status to failed when recover from unknown status\n\n* Fix the checkstyle errors"
    },
    {
      "commit": "0dfaa4b159728d470f90e22e0cede8a3ef441fc6",
      "tree": "c8dfce1f0d57c03e4535a193b437dfda83adb959",
      "parents": [
        "7be0710b3e134f889ce1f970604428663c0ca97b"
      ],
      "author": {
        "name": "huangjc7",
        "email": "43225006+huangjc7@users.noreply.github.com",
        "time": "Mon Jul 27 17:31:45 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 27 17:31:45 2026 +0800"
      },
      "message": "[AMORO-4290][AMS] Propagate internal Iceberg table commit failures (#4291)\n\nLog internal commit errors and propagate CommitFailedException to REST clients instead of swallowing failures. Add unit tests for failure propagation and metadata cleanup errors."
    },
    {
      "commit": "7be0710b3e134f889ce1f970604428663c0ca97b",
      "tree": "cf3e5199d66d7cca441ec61148e4f9e64049e41c",
      "parents": [
        "eee2e3573180ae943adfa867018bdf310027efdf"
      ],
      "author": {
        "name": "Wang Tao",
        "email": "wtrunwolf@gmail.com",
        "time": "Fri Jul 24 15:45:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 24 15:45:39 2026 +0800"
      },
      "message": "[AMORO-4277] imporove expire_snapshots performance (#4278)\n\n* optimize expire snapshots\nfix: logical error\nremove some comments\n\n* remove duplicate class and move test case to amoro-format-iceberg\n\n* Update amoro-format-iceberg/src/main/java/org/apache/amoro/utils/TableFileUtil.java\n\nCo-authored-by: Xu Bai \u003ctocreationbai@gmail.com\u003e\n\n* fix review comment\n\n---------\n\nCo-authored-by: Xu Bai \u003ctocreationbai@gmail.com\u003e"
    },
    {
      "commit": "eee2e3573180ae943adfa867018bdf310027efdf",
      "tree": "5f406b2c9d2892048b789753ab5c98f047344c2f",
      "parents": [
        "da51a2d582deedab65b36c9c831e3a3f566caab0"
      ],
      "author": {
        "name": "csurong",
        "email": "csurong1@gmail.com",
        "time": "Fri Jul 24 11:49:22 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 24 11:49:22 2026 +0800"
      },
      "message": "[AMORO-4126][ams] Default waitAppCompletion\u003dfalse for Spark optimizer on Kubernetes (#4289)\n\n[AMORO-4126][ams] Default waitAppCompletion to false on Kubernetes\n\nCo-authored-by: caosurong \u003csurong.cao@thinkingdata.cn\u003e"
    },
    {
      "commit": "da51a2d582deedab65b36c9c831e3a3f566caab0",
      "tree": "db63b6097a091841c23f6a1bbae2b2bc105f0245",
      "parents": [
        "0704a1ee92df82bd923074d6714cb7612b45d964"
      ],
      "author": {
        "name": "Power John",
        "email": "johntomcat7408@gmail.com",
        "time": "Thu Jul 23 14:15:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 23 14:15:19 2026 +0800"
      },
      "message": "[AMORO-4240][AMS] Support namespace properties in REST catalog (#4283)"
    },
    {
      "commit": "0704a1ee92df82bd923074d6714cb7612b45d964",
      "tree": "1d4585c548604451f45cef7a6ece9984fbbaf52b",
      "parents": [
        "0cb625072686a58d32af00939d919569a7185586"
      ],
      "author": {
        "name": "ZhouJinsong",
        "email": "zhoujinsong0505@163.com",
        "time": "Wed Jul 22 19:28:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 22 19:28:00 2026 +0800"
      },
      "message": "[AMORO-4281]Fix cleanning process trigger issue for mixed format tables (#4282)\n\n* Fix expire process trigger issue\n\n* Add some method to reuse some codes\n\n* Fix some issues of comments\n\n---------\n\nCo-authored-by: baiyangtx \u003cxiangnebula@163.com\u003e"
    },
    {
      "commit": "0cb625072686a58d32af00939d919569a7185586",
      "tree": "8e2464935d51aac673646326a6c0bb93bc017b8a",
      "parents": [
        "d29cbf4bcfba2ee60b24c0708aa5e7a1962205b0"
      ],
      "author": {
        "name": "byungnam",
        "email": "lbn0216@gmail.com",
        "time": "Wed Jul 22 16:06:48 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 22 15:06:48 2026 +0800"
      },
      "message": "[AMORO-4274] Remove Roaring64Bitmap.isEmpty() check in CombinedDelete… (#4275)\n\n[AMORO-4274] Remove Roaring64Bitmap.isEmpty() check in CombinedDeleteFilter\n\npositionMap is populated only via computeIfAbsent(...).add(...) while reading\nposition-delete files, so any stored value is a non-empty Roaring64Bitmap.\npositionMap.get(...) therefore returns null or a non-empty bitmap, never an\nempty one, making the isEmpty() branch unreachable.\n\nRoaring64Bitmap.isEmpty() is backed by getLongCardinality(), which traverses\nall containers, so calling it once per scanned record wastes CPU on the hot\npath. Drop the check and keep only the null guard; behavior is unchanged.\n\nClose #4274"
    },
    {
      "commit": "d29cbf4bcfba2ee60b24c0708aa5e7a1962205b0",
      "tree": "424b3b8d584e19fc7e2e28463a65c32e0a5d8f62",
      "parents": [
        "cbd7d65652226f9f7b259924b3d2164b5ea8d7a5"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jpark92@outlook.kr",
        "time": "Wed Jul 22 16:06:17 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 22 15:06:17 2026 +0800"
      },
      "message": "[AMORO-4271] AIP-5 Phase 2: demand-driven scale-up for dynamic allocation groups (#4272)\n\n* [AMORO-4271] AIP-5 Phase 2: add dynamic-allocation.executor-parallelism config\n\nThe scaling unit of dynamic allocation is one homogeneous K-thread\noptimizer instance (the Spark executor model). K is configured by the\nnew dynamic-allocation.executor-parallelism property (default 1).\n\nvalidate() rejects K \u003c 1 and K \u003e max-parallelism: a single K-thread\ninstance already exceeding the cap could never be created, which would\nleave an enabled group as a silent no-op.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4271] AIP-5 Phase 2: pure demand accounting (serviceable planned, thread occupancy)\n\nserviceablePlannedCount implements quota-mode-aware demand counting:\na proportional quota (targetQuota \u003c\u003d 1) scales with availableCore, so\nthe whole backlog is serviceable; an absolute quota (\u003e 1) is a fixed\nlimit that scaling cannot raise, so only free slots count.\n\noccupiesThread counts SCHEDULED as occupying: a thread is busy from\nassignment (pollTask), not from ack; counting only ACKED would\noverestimate headroom during the poll-to-ack window.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4271] AIP-5 Phase 2: computeScaleUp scale-out decision\n\nPer-group decision state (backlog timer, cadence, exponential ramp)\nwith injected time, so every scenario is deterministic.\n\nOrdered checks:\n- min-parallelism floor: enforced immediately, no timing gate.\n- Immediate demand (busy + serviceable \u003e effective): exponential ramp\n  (1, 2, 4, 8) clamped to the actual need; the ramp resets when the\n  clamp binds (Spark addExecutors semantics) or when demand clears.\n- Future demand (pending tables while all threads are busy, including\n  the zero-optimizer cold start where nothing polls and planning never\n  runs): a single probe instance. Pending tables are not quantified\n  demand before planning, so no exponential growth on this signal.\n\nDemand must persist for scheduler-backlog-timeout before the first\nscale-out; later rounds are spaced by sustained-backlog-timeout, so a\ntrickle drained between rounds never accumulates toward a scale-out.\nThe max-parallelism cap always wins.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4271] AIP-5 Phase 2: pending registration accounting with boot deadline\n\nRegistration is optimizer-driven (the pod self-registers after boot),\nso scale-up counts requested-but-unregistered capacity to avoid\nduplicate scale-outs during the boot window. Entries carry their own\nboot deadline: a request that never registers (image pull failure,\nexhausted ResourceQuota, crash loop) is pruned instead of freezing\nscale-up below real demand forever. Heartbeat expiry cannot cover this\nwindow because it only starts after registration.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4271] AIP-5 Phase 2: dedicated scale keeper for dynamic-allocation groups\n\nDRA-enabled groups are taken over from the legacy floor keeper, whose\nmin-parallelism-check cadence (minutes, multiplied by consecutive\nattempts) would render the DRA backlog timeouts (seconds) physically\nunreachable. OptimizerScaleKeeper reuses the AbstractKeeper\ninfrastructure (HA leader gating, DelayQueue, lifecycle) and evaluates\neach group at its own sustained-backlog-timeout; the legacy keeper\nkeeps watching DRA groups only to resume floor duty if DRA is disabled\nlater.\n\nScale-outs are executed in executor-parallelism-thread instance units\n(computeScaleUp), with requested-but-unregistered capacity counted via\nPendingRegistrations so a booting pod is not re-requested every round;\na synchronous request failure is dropped immediately and retried.\nGroups are watched on create, startup load, and update (covering\nenabling DRA on an existing group at runtime); deleted or disabled\ngroups drop out of the watch set on their next evaluation.\n\nOptimizingQueue.collectDynamicAllocationLoad() snapshots the demand\nside: busy threads (SCHEDULED and ACKED), quota-mode-aware serviceable\nPLANNED tasks, and PENDING tables - the only signal observable on a\ncold group with zero optimizers.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4271] AIP-5 Phase 2: warn when a group is planning-bound instead of scaling\n\nIdle threads while tables wait as PENDING and no PLANNED tasks\nmaterialize means the bottleneck is the serialized planning\n(optimizer.max-planning-parallelism), not thread capacity: scaling out\nwould only add more idle threads. The scale keeper surfaces this as an\nedge-triggered warning naming the config to raise, and does not scale.\nA cold group (zero threads) stays the future-demand case.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4271] AIP-5 Phase 2: distinguish the scale keeper\u0027s failure modes\n\nThe keeper\u0027s drop-out path treated every irregularity the same way,\nwhich conflates situations that need opposite handling:\n\n- A transient group-read failure (e.g. a database hiccup) is not a\n  deletion: there is no periodic re-watch, so dropping the group there\n  would silently disable its dynamic allocation until the next config\n  change. Keep the task alive and retry shortly.\n- After unwatching a disabled group, re-read it once: an update\n  re-enabling DRA concurrently would have had its watch() call\n  swallowed by the still-present watched-set entry, orphaning the\n  group until its next change.\n- An enabled group whose queue is momentarily absent (a delete/create\n  racing the config watcher) is transient too; unwatch-plus-rewatch\n  there would spin a delay-0 hot loop of DB reads.\n- A scale-out that fails after requestResource succeeded has started a\n  real pod; erasing its boot-window entry would re-request a duplicate\n  next round. Only a failure before the request is dropped and retried.\n- Disabling DRA keeps the boot-window accounting (re-enabling within\n  the window must not re-request the same capacity); deleting the\n  group drops everything immediately, so a same-name group created\n  before the next evaluation does not inherit phantom capacity.\n- The planning-bound warning now counts registered threads only (a\n  booting pod\u0027s phantom capacity is not idle threads) and requires the\n  condition to persist across two consecutive evaluations, since a\n  single snapshot can hold transiently while planning is in flight.\n\nAlso pins in the integration test that registration clears the\nboot-window accounting: double-counted capacity would suppress demand\nscaling.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4271] AIP-5 Phase 2: keep floor handling consistent across validation and scaling\n\nTwo floor edge cases:\n\n- A floor unreachable in executor-parallelism units (e.g. min\u003d5, max\u003d6,\n  K\u003d4: covering the floor needs 2 instances \u003d 8 threads \u003e max) passed\n  validation and then sat permanently below its floor with no signal -\n  the same silent no-op the validation rules exist to prevent. Reject\n  it up front; the keeper-side cap clamp stays as defense in depth for\n  configs persisted before this rule.\n- A floor deficit (optimizers died, or a new group) now resets the\n  demand-phase state: previously a demand phase before the deficit\n  left a passed cadence gate and a grown ramp behind, so the first\n  demand after recovery fired immediately and oversized instead of\n  re-proving backlog persistence.\n\nAlso pins that a fractional absolute quota truncates like the poll\ngate does ((int) 2.5 \u003d 2 slots), keeping the two accountings aligned.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4271] AIP-5 Phase 2: snapshot table runtimes under the scheduling lock\n\nSchedulingPolicy\u0027s table runtime map is a plain HashMap whose\ncanonical accesses all hold tableLock; the dynamic-allocation load\nsnapshot iterated it lock-free from the scale keeper thread, so a\nconcurrent addTable/removeTable could throw\nConcurrentModificationException and skip that whole evaluation round.\nAdd a snapshot accessor that copies the runtimes under the lock and\nuse it for the load snapshot.\n\nAlso covers collectDynamicAllocationLoad with a queue-level test on a\nreal table: the PENDING table is the only demand signal before any\npoll (the cold-start case), and a polled task occupies its thread from\nSCHEDULED on.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4271] AIP-5 Phase 2: document the dynamic-allocation group properties\n\nAdd the dynamic-allocation.* properties to the optimizer group\nproperty table, mark the flat min-parallelism row deprecated in favor\nof the namespaced key, and recommend executor-parallelism 4-8 for\nKubernetes groups so per-pod JVM overhead is shared across threads.\nThe scale-down-related properties are documented as landing in a later\nrelease.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n---------\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\nCo-authored-by: ZhouJinsong \u003czhoujinsong0505@163.com\u003e"
    },
    {
      "commit": "cbd7d65652226f9f7b259924b3d2164b5ea8d7a5",
      "tree": "65ea4dcea6380c78f0421e956accf932d106fb7c",
      "parents": [
        "6318c408471847e4a6628104dc68764395bf1b19"
      ],
      "author": {
        "name": "WenLingzhang",
        "email": "1298877813@qq.com",
        "time": "Tue Jul 21 15:50:08 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jul 21 15:50:08 2026 +0800"
      },
      "message": "[hotfix] Fix S3 credentials not vended when loading Lance table (#4279)\n\nfixup bug\n\nCo-authored-by: 张文领 \u003czhangwl9@chinatelecom.cn\u003e"
    },
    {
      "commit": "6318c408471847e4a6628104dc68764395bf1b19",
      "tree": "c17f97d4dd83326b6f0e7ee34d2464855c09c535",
      "parents": [
        "27ae8d55f2d300acb0d123602d90928ab7349b6b"
      ],
      "author": {
        "name": "Xu Bai",
        "email": "tocreationbai@gmail.com",
        "time": "Mon Jul 20 11:36:07 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 20 11:36:07 2026 +0800"
      },
      "message": "[AMORO-4269] Refactor Iceberg thread pool initialization and scope (#4270)\n\n* Refactor Iceberg thread pool initialization and usage for improved configuration management\n\n* Fix Iceberg thread pool initialization in tests\n\n* Restore Iceberg thread pool API compatibility\n\n* Make Iceberg thread pool methods public for enhanced accessibility\n\n* Document Iceberg thread pool fallback\n\n* Remove unused fallback warning set from Iceberg thread pool implementation"
    },
    {
      "commit": "27ae8d55f2d300acb0d123602d90928ab7349b6b",
      "tree": "98a3326b28edc4e74ae07710ca3ac3fd5a581ada",
      "parents": [
        "8b03fec1105aa4b29b5f4d09815c62628187c115"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jpark92@outlook.kr",
        "time": "Thu Jul 16 00:21:04 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 15 23:21:04 2026 +0800"
      },
      "message": "[AMORO-4235] Recognize stale optimizer responses on the AMS side (#4261)\n\n* [AMORO-4235] Recognize stale optimizer responses on the AMS side\n\nWhen the OptimizerKeeper (or resetStaleTasksForThread on re-poll) resets a\ntask that is still executing, the optimizer\u0027s in-flight ack/complete arrives\nafter the task\u0027s token has been cleared. TaskRuntime.validThread then threw\n\"Task has been reset or not yet scheduled\", surfacing as an ERROR; for\ncompletion it also broke the SCHEDULED -\u003e SUCCESS transition\n(IllegalTaskStateException).\n\nThe AMS now recognizes stale responses by (token, threadId, status):\n- ack: rejected outside the transaction so the optimizer skips the obsolete\n  round, without the misleading \"failed to commit transaction\" error.\n- complete: ignored gracefully, since the reported run belongs to a\n  torn-down round.\n\nThis fixes the rejection of valid optimizer responses. The permanent-stuck /\nuncancelable symptom in the issue could not be reproduced from the excerpt\nlogs and may need the full log to confirm -- hence \"Relates to\" rather than\n\"Close\".\n\nTests:\n- TestOptimizingQueue: unit reproductions via the pollTask path (multi-task\n  stale ack, single-task stale completion).\n- TestDefaultOptimizingService: end-to-end reproduction driving the real\n  OptimizerKeeper ack-timeout reset of a live optimizer\u0027s task.\n\nRelates to #4235\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4235] Fix testAckAndCompleteTask for absorbed stale completion\n\nCompleting a task before ack now produces no exception (the AMS absorbs it\nas a stale response, indistinguishable from a completion for a task reset\nand re-scheduled to the same thread), so assert the task stays SCHEDULED\ninstead of expecting IllegalTaskStateException.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4235] Apply spotless formatting\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4235] Lower test ack-timeout and poll for status instead of sleeping 35s\n\nAddress review feedback: testAckTimeoutResetThenLateAckRejected relied on the\ndefault 30s optimizer.task-ack-timeout and a fixed Thread.sleep(35000).\n\n- Override OPTIMIZER_TASK_ACK_TIMEOUT to 5s in AMSServiceTestBase. It must\n  stay above optimizer.polling-timeout (3s): a blocking pollTask waiting out\n  its full timeout would otherwise pick up the task the keeper reset by\n  ack-timeout in the meantime (this broke testPollTaskThreeTimes at 2s).\n- Replace the fixed sleep with waitForTaskStatus polling every 100ms, so the\n  test finishes right after the keeper reset lands (~6s instead of 35s).\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4235] Stamp an attempt id on schedule and ignore completions of previous attempts\n\nA completion delayed until the same task has been reset, re-scheduled to\nthe same optimizer thread and re-acked matches (token, threadId, status)\nand was accepted as the result of the new attempt.\n\nEvery schedule now stamps a monotonically increasing attempt id into the\ntask properties (reaching the optimizer via the existing\nOptimizingTask.properties map), the optimizer echoes it back in the\nresult summary, and complete() ignores a completion whose echoed attempt\nid does not match the current one. Results from older optimizers carry\nno attempt id and fall back to the previous checks.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n---------\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\nCo-authored-by: ConradJam \u003cjam.gzczy@gmail.com\u003e"
    },
    {
      "commit": "8b03fec1105aa4b29b5f4d09815c62628187c115",
      "tree": "2fbd8d474d4889af852ee3256041c41366f40aa1",
      "parents": [
        "498ea2716df26ce0677e53401fb8d5c3058aa2c6"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jpark92@outlook.kr",
        "time": "Fri Jul 10 12:22:05 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 10 11:22:05 2026 +0800"
      },
      "message": "[AMORO-4253] AIP-5 Phase 1: dynamic allocation configuration and validation (#4254)\n\n* [AMORO-4253] AIP-5 Phase 1: dynamic allocation configuration and validation\n\nFirst implementation phase of AIP-5 (Dynamic Resource Allocation for\nOptimizer, #4191). Configuration foundation only; no runtime scaling\nbehavior. Dynamic allocation is opt-in and disabled by default, so\nexisting groups are unaffected.\n\n- OptimizerProperties: declare the dynamic-allocation.* constants (with\n  @since); deprecate the flat min-parallelism in favor of the namespaced\n  dynamic-allocation.min-parallelism, still honored as a fallback.\n- DynamicAllocationConfig: parse(ResourceGroup) + validate() enforcing\n  the AIP-5 constraints only when enabled (max-parallelism mandatory,\n  min \u003c\u003d max \u003c\u003d 1024, executor-idle-timeout \u003e\u003d 30s, positive durations,\n  reject the external container). resolveMinParallelism centralizes the\n  namespaced -\u003e legacy -\u003e 0 resolution.\n- OptimizerGroupController: reject an invalid DRA config with HTTP 400 on\n  create/update before persisting.\n- DefaultOptimizingService: startup load is fail-safe (invalid config\n  logs a warning and falls back to DRA-disabled instead of crashing AMS);\n  the keeper min-parallelism auto-reset is skipped when DRA is\n  effectively enabled, and otherwise writes the key the group actually\n  reads (fixing an endless no-op loop for namespaced groups).\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4253] Strictly validate min-parallelism on opted-in DRA groups\n\nresolveMinParallelism() is intentionally lenient (unparsable -\u003e 0) for the\nkeeper hot path and legacy compatibility, but validate() reused that leniency\nfor opted-in groups: an enabled group with \u0027dynamic-allocation.min-parallelism\u0027\nset to a non-numeric value silently degraded to 0, and a negative value passed\nthe max \u003e\u003d min check unchecked. This was asymmetric with max-parallelism, which\nis parsed strictly and rejected with HTTP 400.\n\nRetain the raw min-parallelism string at parse time so validate() can tell\n\"explicitly configured but unparsable\" from \"unset\" (the resolved int collapses\nboth to 0). When DRA is enabled, an explicitly configured min-parallelism that\nis unparsable or negative is now rejected. The keeper hot path stays lenient.\n\nAlso document the getMaxParallelism() unboxing precondition (nullable until\nvalidated) and leave a TODO for realistic lower bounds on the polling timeouts.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4253] Unify min-parallelism with max-parallelism as nullable Integer\n\nDrop the dual int/String representation of min-parallelism in favor of a\nsingle nullable Integer, mirroring max-parallelism: the value is strictly\nparsed in parse() (a malformed numeric throws there, honoring parse()\u0027s\ncontract, instead of being silently degraded to 0 by the lenient keeper\nresolver), and null encodes \"unset\". validate() then only checks the\nsemantic bounds (non-negative, max \u003e\u003d min).\n\nAlso align the trim semantics of the lenient resolveMinParallelism() path\nwith the strict one so a whitespace-padded value (e.g. \" 5 \") that\nvalidate() accepts resolves to the same floor the keeper reads, instead of\nsilently degrading to 0 at runtime.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4253] Cite the actually-used key in the min-parallelism parse error\n\nWhen min-parallelism is configured only via the deprecated flat key, a\nmalformed value reported the namespaced \u0027dynamic-allocation.min-parallelism\u0027\nthe user never set. Pick the value and its source key together so the error\nnames the key the value actually came from, folding the former\nrawMinParallelism helper into parseMinParallelism.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO-4253] Drop the inert DRA validation block from queue loading\n\nThe startup validate/fallback block in loadOptimizingQueues was\nbehaviorally inert: the disable is already implicit (isEffectivelyEnabled()\ntreats an invalid config as disabled wherever DRA is consumed), and in\nPhase 1 nothing strictly parses DRA config at load, so there was no crash\nto guard against. Validating inside the queue loader also mixed an unrelated\nconcern into it. Surfacing invalid configs as an alertable signal belongs\nwith the metric that lands in the observability phase.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n---------\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e"
    },
    {
      "commit": "498ea2716df26ce0677e53401fb8d5c3058aa2c6",
      "tree": "39fa4efa49514f56ee09517f7c52ebdc03dfdb15",
      "parents": [
        "89d27bcd67541a6d3cc3a983cd9fe09a6e9c5cfb"
      ],
      "author": {
        "name": "WenLingzhang",
        "email": "1298877813@qq.com",
        "time": "Wed Jul 08 19:41:59 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 08 19:41:59 2026 +0800"
      },
      "message": "[AMORO-4263] Persist cleanup operation metrics for Dashboard display (#4265)\n\n* Persist cleanup operation metrics for Dashboard display\n\n* fixup  metric\n\n---------\n\nCo-authored-by: 张文领 \u003czhangwl9@chinatelecom.cn\u003e\nCo-authored-by: ConradJam \u003cjam.gzczy@gmail.com\u003e"
    },
    {
      "commit": "89d27bcd67541a6d3cc3a983cd9fe09a6e9c5cfb",
      "tree": "c638dc44055c9b631a209b1032c48253b6166301",
      "parents": [
        "d1dca2749a5c36a37c450734b6e826f07f272929"
      ],
      "author": {
        "name": "Jiwon Park",
        "email": "jpark92@outlook.kr",
        "time": "Mon Jul 06 13:46:37 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 06 12:46:37 2026 +0800"
      },
      "message": "[AMORO-4198][optimizer] Support graceful shutdown for in-progress tasks (#4197)\n\n* [AMORO][optimizer] Support graceful shutdown for in-progress tasks\n\nOn SIGTERM the optimizer flips its stopped flag and returns immediately,\nso in-flight task results are silently dropped (completeTask is gated by\nisStarted). On K8s this is compounded by `sh -c` swallowing SIGTERM, a\n30s default grace period, and Hadoop\u0027s FileSystem cache cleanup racing\nJVM shutdown hooks.\n\n- Optimizer.stopOptimizing: join executors with a deadline, force\n  interrupt only on timeout; keep toucher alive so AMS heartbeats\n  continue while tasks drain.\n- OptimizerExecutor.completeTask: best-effort direct call after stop so\n  the in-flight result still reaches AMS.\n- SparkOptimizer / StandaloneOptimizer: register on Hadoop\n  ShutdownHookManager (priority above FS_CACHE / SparkContext) with an\n  explicit per-hook timeout.\n- OptimizerConfig: new -st / --shutdown-timeout-ms (default 600s).\n- KubernetesOptimizerContainer: `sh -c \u0027exec \u003cargs\u003e\u0027` and an explicit\n  terminationGracePeriodSeconds derived from -st + 30s buffer; user\n  podTemplate values are respected.\n- optimizer.sh start-foreground: exec $CMDS so java gets PID 1.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO][optimizer] Wire shutdown-timeout-ms group property to -st startup arg and K8s grace period\n\nThe -st/--shutdown-timeout-ms option was parsed by the optimizer but AMS\nnever emitted it into the startup args, so the configured shutdown timeout\nwas unreachable for AMS-spawned optimizers and the K8s grace period was\npinned at the default.\n\n- Emit \u0027-st \u003cvalue\u003e\u0027 in buildOptimizerStartupArgsString when the optimizer\n  group sets the shutdown-timeout-ms property (same pattern as -hb), which\n  wires all containers sharing the args builder.\n- Derive terminationGracePeriodSeconds from the same resource property that\n  drives the -st arg via PropertyUtil, instead of re-parsing the rendered\n  CLI string, and remove parseShutdownTimeoutMs. Reading from one source\n  guarantees the pod\u0027s SIGKILL deadline can never fall below the shutdown\n  timeout the optimizer JVM actually honors.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO][optimizer] Add graceful drain to Flink optimizer on job cancellation\n\nFlinkExecutor.close() previously interrupted the executor thread after a\nhardcoded 5s join, killing in-progress tasks on job cancellation and\nsilently ignoring the -st/--shutdown-timeout-ms option on the Flink engine.\n\n- close() now stops the executor first, waits up to the configured\n  shutdown timeout for the in-progress task to complete (so its result is\n  reported to AMS), and only then force-interrupts.\n- The drain absorbs interrupts of the thread running close(): Flink\u0027s\n  cancellation machinery (TaskCanceler/TaskInterrupter) interrupts the\n  task thread to unblock I/O, which must not abort the drain early.\n- The drain budget is capped safely below Flink\u0027s cancellation watchdog\n  (task.cancellation.timeout, default 180s), which would otherwise fail\n  the whole TaskManager; operators wanting longer drains must raise both\n  settings, as documented.\n- Document the shutdown-timeout-ms group property, the -st option for\n  Flink/Spark external optimizers, and the interaction with\n  task.cancellation.timeout.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO][optimizer] Harden the shutdown drain so finished task results survive\n\nFixes several defects in the graceful-shutdown paths that could still lose\nthe result of a task that completed during the drain, or leave the process\nin a bad state:\n\n- Optimizer.startOptimizing published the executorThreads array before\n  filling its elements; a concurrent shutdown hook could observe null\n  elements and skip joining executor threads that were already running\n  tasks. Build the array fully, then publish, then start the threads.\n- The force-interrupt pass in stopOptimizing interleaved interrupt with\n  per-thread 1s joins: when the stopping thread was itself interrupted\n  (e.g. the shutdown-hook watchdog cancelling a timed-out hook), join()\n  threw instantly and executor threads after the first were never\n  interrupted; the per-thread joins also overshot the deadline by up to N\n  seconds. Interrupt all survivors first, then await them against one\n  shared deadline, restoring the caller\u0027s interrupt status only after\n  cleanup completes.\n- waitAShortTime restored the interrupt flag unconditionally, but no\n  caller loop ever clears it: a stray interrupt while still running turned\n  every subsequent sleep into an instant return, busy-spinning the\n  poll/retry loops. Preserve the flag only once the operator is stopped.\n- completeTask checked isStarted() once at entry and fell back to a single\n  best-effort call after stop, so a result finishing during shutdown was\n  dropped on a stop/report race or one transient AMS error. It now retries\n  through callAuthenticatedAmsWithDrain: a bounded window anchored at the\n  moment shutdown is observed, reusing the existing transient-error and\n  auth handling, aborted early by the shutdown force-interrupt. The mock\n  AMS gains transient-failure injection to cover this.\n- The toucher stays alive during the drain for heartbeats, but scale-down\n  unregisters the optimizer before the pod receives SIGTERM; the resulting\n  auth error made the toucher re-register a ghost optimizer and rotate the\n  executors\u0027 token so their final completeTask was rejected. Drain mode\n  now skips re-registration once the token becomes invalid.\n- The graceful-shutdown test timed stop() with fixed sleeps against the\n  poll cadence (~0.5s margins on CI); slow test tasks now signal a latch\n  when execute() begins so the test stops the optimizer deterministically.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n* [AMORO][optimizer] Keep the optimizer registration alive during the Flink drain\n\nFlink cancels the FlinkToucher source before downstream operators, so\nheartbeats stop the moment the drain in FlinkExecutor.close() begins. AMS\nthen expires the optimizer after optimizer.heart-beat-timeout (default\n1 min) and, in the same sweep, unregisters it and resets its in-flight\ntasks — so any task finishing later than that lost its result even though\nthe drain was still waiting, capping the effective drain window at the\nheartbeat timeout instead of the configured shutdown timeout.\n\nThe drain loop now sends a best-effort touch with the existing token\nbetween join slices, at the configured heartbeat interval. Touching keeps\nthe registration and the task assignment alive for exactly as long as the\ndrain runs; it never re-registers (consistent with the drain-mode\ntoucher), and once close() returns the touches stop and AMS cleans up\nthrough the normal expiration path.\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e\n\n---------\n\nSigned-off-by: Jiwon Park \u003cjpark92@outlook.kr\u003e"
    },
    {
      "commit": "d1dca2749a5c36a37c450734b6e826f07f272929",
      "tree": "ab6b601687bb964b03c5f25dfa642633bfb23938",
      "parents": [
        "2b3027d9c95e37fc329eeec7fb6d04f2963284b3"
      ],
      "author": {
        "name": "nathan.ma",
        "email": "majin1102@gmail.com",
        "time": "Thu Jun 25 14:54:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 25 14:54:58 2026 +0800"
      },
      "message": "[AMORO-3837] Integrate lance format (#4051)\n\n* Add Lance format support\n\n* Align Lance Arrow dependencies\n\n* Fix Lance CI dependency checks\n\n* Fix catalog refresh properties\n\n* Restore catalog refresh behavior\n\n* Fix Lance catalog exception handling\n\n* Avoid exposing Lance catalog credentials\n\n* Fix Lance catalog storage handling\n\n* Fix Lance OSS endpoint catalog config\n\n* Fix Lance database discovery semantics\n\n* Fix Lance load table fallback semantics\n\n---------\n\nCo-authored-by: majin.nathan \u003cmajin.nathan@bytedance\u003e\nCo-authored-by: ConradJam \u003cjam.gzczy@gmail.com\u003e"
    },
    {
      "commit": "2b3027d9c95e37fc329eeec7fb6d04f2963284b3",
      "tree": "ecbfe92ed8468644c2cb3d1c4008430d936fcc57",
      "parents": [
        "9126f7318adbe70e6d30dacfc5994e2f28f4e32e"
      ],
      "author": {
        "name": "Nikhil Ujjwal",
        "email": "67941788+NikhilUjjwal7@users.noreply.github.com",
        "time": "Wed Jun 24 21:33:27 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 25 00:03:27 2026 +0800"
      },
      "message": "[AMORO-4211] Fix legacy Flink config loading (#4249)\n\nFix legacy Flink config loading\n\nCo-authored-by: nujjwal \u003cnujjwal@cisco.com\u003e"
    },
    {
      "commit": "9126f7318adbe70e6d30dacfc5994e2f28f4e32e",
      "tree": "958cea2a223e6c57a123139ad79f6d2e78c7281b",
      "parents": [
        "bc83f0834d0f7c88d43f8add0312d29555aa063e"
      ],
      "author": {
        "name": "Xu Bai",
        "email": "tocreationbai@gmail.com",
        "time": "Wed Jun 24 18:51:50 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 24 18:51:50 2026 +0800"
      },
      "message": "[AMORO-3853] Support Java 17 build for Amoro (#4244)\n\n* Refactor flink module for JDK 17 support\n\nAdd JDK 17 compatibility\n\n* Update SLF4J dependency to version 2.0.17 and adjust README for JDK compatibility\n\n* Fix CI configuration to properly format JDK matrix in core-hadoop3-ci.yml\n\n* Fix CI configuration to properly format JDK matrix in core-hadoop3-ci.yml\n\n* Stabilize continuous optimizing tests on Java 17\n\n* Update TestAutomaticLogWriter to use truncated LocalDateTime for consistency in time calculations\n\n* Remove reflective invocation of emitPeriodicWatermark in MixedFormatSourceReader\n\n* use FlinkWriteResult for consistency\n\n* Add locality exposure in IcebergClassUtil and implement tests for file committer\n\n* Remove Java 17 from CI build matrix and update wrapKrb method to accept nullable startSnapshotId\n\n* spotless\n\n* address"
    },
    {
      "commit": "bc83f0834d0f7c88d43f8add0312d29555aa063e",
      "tree": "7a047419c087b326f4a66e920944299efd01f773",
      "parents": [
        "675c222c3c3e208a1603415b1696704cc9de4621"
      ],
      "author": {
        "name": "felixhzhu",
        "email": "43262022+felixhzhu@users.noreply.github.com",
        "time": "Wed Jun 24 11:07:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 24 11:07:18 2026 +0800"
      },
      "message": "Fix expireSnapshots fails with IllegalArgumentException on object-store-backed tables (#4259)\n\n[AMORO-4237][Iceberg] Fix expireSnapshots fails with IllegalArgumentException on object-store-backed tables\n\nWhen the underlying FileIO is an object store (S3FileIO/OSSFileIO/GCSFileIO), deleteEmptyDirectory() calls asFileSystemIO() which throws IllegalArgumentException because supportFileSystemOperations() returns false.\n\nFix: 1) Add early-return in TableFileUtil.deleteEmptyDirectory() when !supportFileSystemOperations() 2) Guard the parent directory cleanup loop in RollingFileCleaner with supportFileSystemOperations() check 3) Move buffer clear() into finally block to prevent re-submission on failure\n\nfix #4237\n\nCo-authored-by: felixhzhu \u003cfelixhzhu@tencent.com\u003e"
    },
    {
      "commit": "675c222c3c3e208a1603415b1696704cc9de4621",
      "tree": "ef721ee6ab44fb04a5c773a7428701a92b27302d",
      "parents": [
        "b3bf85ab5b74f553f5d63c79d25e3d1b14347c12"
      ],
      "author": {
        "name": "felixhzhu",
        "email": "43262022+felixhzhu@users.noreply.github.com",
        "time": "Wed Jun 24 11:03:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 24 11:03:38 2026 +0800"
      },
      "message": "[AMORO-4257][AMS] Fix duplicate process ID caused by multiple SnowflakeIdGenerator instances (#4258)\n\nConsolidate multiple independent SnowflakeIdGenerator instances into a single global singleton (SnowflakeIdGenerator.INSTANCE) to prevent ID collisions when two instances generate IDs in the same 10ms time window with the same machineId\u003d0.\n\nfix #4257\n\nCo-authored-by: felixhzhu \u003cfelixhzhu@tencent.com\u003e"
    },
    {
      "commit": "b3bf85ab5b74f553f5d63c79d25e3d1b14347c12",
      "tree": "153d092a5fe5e859a4fdf7d26f4897ce84f652ac",
      "parents": [
        "374ed06bdb3d2de20856f6e2f13b4a5c49cc4757"
      ],
      "author": {
        "name": "WenLingzhang",
        "email": "1298877813@qq.com",
        "time": "Wed Jun 24 11:03:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 24 11:03:19 2026 +0800"
      },
      "message": "[hotfix] Cleanup empty columns from Cleanup and Profiling pages (#4260)\n\nCleanup empty columns from Cleanup and Profiling pages\n\nCo-authored-by: 张文领 \u003czhangwl9@chinatelecom.cn\u003e"
    },
    {
      "commit": "374ed06bdb3d2de20856f6e2f13b4a5c49cc4757",
      "tree": "6aae6f7a0801162b5adb43fc16c3b8345d2661b0",
      "parents": [
        "acf8ef47a3d9305ef217399a9aeb8c6d312bbe75"
      ],
      "author": {
        "name": "ZhouJinsong",
        "email": "zhoujinsong0505@163.com",
        "time": "Mon Jun 15 10:56:17 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 15 10:56:17 2026 +0800"
      },
      "message": "Revert \"[AMORO-4246] Refactor process data expiring via ProcessFactory plugin\" (#4252)\n\nRevert \"[AMORO-4246] Refactor process data expiring via ProcessFactory plugin…\"\n\nThis reverts commit acf8ef47a3d9305ef217399a9aeb8c6d312bbe75."
    }
  ],
  "next": "acf8ef47a3d9305ef217399a9aeb8c6d312bbe75"
}
