This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch branch-catalog-spi
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-catalog-spi by this 
push:
     new b8d64260e0c update P5 handoff and fix compile issue
b8d64260e0c is described below

commit b8d64260e0c80776d2b7bc42c2905102e1c36375
Author: morningman <[email protected]>
AuthorDate: Tue Jun 9 17:49:22 2026 +0800

    update P5 handoff and fix compile issue
---
 .../datasource/maxcompute/MCTransactionTest.java   |  54 --------
 .../maxcompute/MaxComputeExternalCatalogTest.java  | 146 ---------------------
 plan-doc/HANDOFF.md                                |  53 ++++++++
 plan-doc/PROGRESS.md                               |  36 +++--
 4 files changed, 75 insertions(+), 214 deletions(-)

diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/maxcompute/MCTransactionTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/maxcompute/MCTransactionTest.java
deleted file mode 100644
index e76f192a858..00000000000
--- 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/maxcompute/MCTransactionTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.doris.datasource.maxcompute;
-
-import org.apache.doris.common.UserException;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import java.util.Optional;
-
-public class MCTransactionTest {
-    @Test
-    public void testBeginInsertRejectsOdpsExternalTable() {
-        assertBeginInsertRejectsUnsupportedOdpsTable("mc_external_table");
-    }
-
-    @Test
-    public void testBeginInsertRejectsOdpsLogicalView() {
-        assertBeginInsertRejectsUnsupportedOdpsTable("mc_logical_view");
-    }
-
-    private void assertBeginInsertRejectsUnsupportedOdpsTable(String 
tableName) {
-        MaxComputeExternalCatalog catalog = 
Mockito.mock(MaxComputeExternalCatalog.class);
-        MaxComputeExternalTable table = 
Mockito.mock(MaxComputeExternalTable.class);
-        Mockito.when(table.isUnsupportedOdpsTable()).thenReturn(true);
-        Mockito.when(table.getDbName()).thenReturn("default");
-        Mockito.when(table.getName()).thenReturn(tableName);
-
-        MCTransaction transaction = new MCTransaction(catalog);
-
-        UserException exception = Assert.assertThrows(UserException.class,
-                () -> transaction.beginInsert(table, Optional.empty()));
-        Assert.assertTrue(exception.getMessage().contains(
-                "Writing MaxCompute external table or logical view is not 
supported: default." + tableName));
-        Mockito.verify(catalog, 
Mockito.never()).getOdpsTableIdentifier(Mockito.anyString(), 
Mockito.anyString());
-    }
-}
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/maxcompute/MaxComputeExternalCatalogTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/maxcompute/MaxComputeExternalCatalogTest.java
deleted file mode 100644
index dfe22f136b5..00000000000
--- 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/maxcompute/MaxComputeExternalCatalogTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.doris.datasource.maxcompute;
-
-import org.apache.doris.common.DdlException;
-import org.apache.doris.common.maxcompute.MCProperties;
-import org.apache.doris.datasource.ExternalCatalog;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class MaxComputeExternalCatalogTest {
-    @Test
-    public void testSplitByteSizeErrorMessage() {
-        Map<String, String> props = new HashMap<>();
-        addRequiredProperties(props);
-        props.put(MCProperties.SPLIT_STRATEGY, 
MCProperties.SPLIT_BY_BYTE_SIZE_STRATEGY);
-        props.put(MCProperties.SPLIT_BYTE_SIZE, "1048576");
-
-        MaxComputeExternalCatalog catalog = new MaxComputeExternalCatalog(1L, 
"mc_catalog", null, props, "");
-
-        DdlException exception = Assert.assertThrows(DdlException.class, 
catalog::checkProperties);
-        Assert.assertTrue(exception.getMessage().contains(
-                MCProperties.SPLIT_BYTE_SIZE + " must be greater than or equal 
to 10485760"));
-        
Assert.assertFalse(exception.getMessage().contains(MCProperties.SPLIT_ROW_COUNT));
-    }
-
-    @Test
-    public void testCheckWhenCreatingSkipsValidationByDefault() throws 
DdlException {
-        Map<String, String> props = createRequiredProperties(true);
-        TestMaxComputeExternalCatalog catalog = new 
TestMaxComputeExternalCatalog(props);
-
-        catalog.checkWhenCreating();
-
-        Assert.assertNull(catalog.checkedProjectName);
-        Assert.assertNull(catalog.checkedNamespaceSchemaProjectName);
-    }
-
-    @Test
-    public void testCheckWhenCreatingValidatesProjectWhenValidationEnabled() 
throws DdlException {
-        Map<String, String> props = createRequiredProperties(false);
-        props.put(ExternalCatalog.TEST_CONNECTION, "true");
-        TestMaxComputeExternalCatalog catalog = new 
TestMaxComputeExternalCatalog(props);
-
-        catalog.checkWhenCreating();
-
-        Assert.assertEquals("mc_project", catalog.checkedProjectName);
-        Assert.assertNull(catalog.checkedNamespaceSchemaProjectName);
-    }
-
-    @Test
-    public void 
testCheckWhenCreatingValidatesSchemaWhenNamespaceSchemaEnabled() throws 
DdlException {
-        Map<String, String> props = createRequiredProperties(true);
-        props.put(ExternalCatalog.TEST_CONNECTION, "true");
-        TestMaxComputeExternalCatalog catalog = new 
TestMaxComputeExternalCatalog(props);
-
-        catalog.checkWhenCreating();
-
-        Assert.assertNull(catalog.checkedProjectName);
-        Assert.assertEquals("mc_project", 
catalog.checkedNamespaceSchemaProjectName);
-    }
-
-    @Test
-    public void testCheckWhenCreatingReportsInaccessibleProject() {
-        Map<String, String> props = createRequiredProperties(false);
-        props.put(ExternalCatalog.TEST_CONNECTION, "true");
-        TestMaxComputeExternalCatalog catalog = new 
TestMaxComputeExternalCatalog(props);
-        catalog.projectExists = false;
-
-        DdlException exception = Assert.assertThrows(DdlException.class, 
catalog::checkWhenCreating);
-
-        Assert.assertTrue(exception.getMessage().contains("Failed to validate 
MaxCompute project 'mc_project'"));
-        Assert.assertTrue(exception.getMessage().contains("does not exist or 
is not accessible"));
-        Assert.assertNull(catalog.checkedNamespaceSchemaProjectName);
-    }
-
-    @Test
-    public void testCheckWhenCreatingReportsInaccessibleNamespaceSchema() {
-        Map<String, String> props = createRequiredProperties(true);
-        props.put(ExternalCatalog.TEST_CONNECTION, "true");
-        TestMaxComputeExternalCatalog catalog = new 
TestMaxComputeExternalCatalog(props);
-        catalog.threeTierModel = false;
-
-        DdlException exception = Assert.assertThrows(DdlException.class, 
catalog::checkWhenCreating);
-
-        Assert.assertTrue(exception.getMessage().contains("Failed to validate 
MaxCompute project 'mc_project'"));
-        Assert.assertTrue(exception.getMessage().contains("schema list is 
accessible"));
-    }
-
-    private static Map<String, String> createRequiredProperties(boolean 
enableNamespaceSchema) {
-        Map<String, String> props = new HashMap<>();
-        addRequiredProperties(props);
-        props.put(MCProperties.ENABLE_NAMESPACE_SCHEMA, 
Boolean.toString(enableNamespaceSchema));
-        return props;
-    }
-
-    private static void addRequiredProperties(Map<String, String> props) {
-        props.put(MCProperties.PROJECT, "mc_project");
-        props.put(MCProperties.ENDPOINT, 
"http://service.cn-beijing.maxcompute.aliyun-inc.com/api";);
-        props.put(MCProperties.ACCESS_KEY, "access_key");
-        props.put(MCProperties.SECRET_KEY, "secret_key");
-    }
-
-    private static class TestMaxComputeExternalCatalog extends 
MaxComputeExternalCatalog {
-        private boolean projectExists = true;
-        private boolean threeTierModel = true;
-        private String checkedProjectName;
-        private String checkedNamespaceSchemaProjectName;
-
-        private TestMaxComputeExternalCatalog(Map<String, String> props) {
-            super(1L, "mc_catalog", null, props, "");
-        }
-
-        @Override
-        protected boolean maxComputeProjectExists(String projectName) {
-            checkedProjectName = projectName;
-            return projectExists;
-        }
-
-        @Override
-        protected void validateMaxComputeNamespaceSchemaAccess(String 
projectName) {
-            checkedNamespaceSchemaProjectName = projectName;
-            if (!threeTierModel) {
-                throw new RuntimeException("schema list is not accessible");
-            }
-        }
-    }
-}
diff --git a/plan-doc/HANDOFF.md b/plan-doc/HANDOFF.md
index 1bb74163a0d..3b46b6cf5b1 100644
--- a/plan-doc/HANDOFF.md
+++ b/plan-doc/HANDOFF.md
@@ -5,6 +5,57 @@
 
 ---
 
+# 🔥 第 19 次 handoff(2026-06-09,覆盖)— 🎉 P4 maxcompute 全部完成并合入;下一 session = P5 
paimon 迁移 kickoff
+
+> **本 session**:用户确认「P4(maxcompute)已完成、HANDOFF 中所有 maxcompute TODO 
已做完」,要求同步交接文档(PROGRESS + HANDOFF)并为下一 session 启动 **P5 paimon 迁移**做准备。**本 
session 仅文档同步,0 产线代码。**
+
+## ✅ P4 完成核实(code-grounded,本 session 亲核)
+- **翻闸已合入**:`max_compute` ∈ `CatalogFactory.SPI_READY_TYPES`(PR **#64253** "P4 
maxcompute connector full adoption + live cutover (T01–T06)")。
+- **legacy 已删 + odps-free**:`fe-core/.../datasource/maxcompute/` 不存在;`grep 
com.aliyun.odps fe-core/src/main/java`=∅(PR **#64300** "remove legacy subsystem 
+ make fe-core odps-free (T07–T09)",HEAD `e96037cf6aa`)。
+- **#64119 校验迁移已合入**:连接器含 
`validateMaxComputeConnection`/`checkOperationSupported`;`git log -S 
validateMaxComputeConnection` 证其随 **#64300** squash 合入 —— 即上一次(第 18 次)handoff 的 
10 文件工作已落地,无悬空。
+- **分支干净**:当前 `branch-catalog-spi`,HEAD=`e96037cf6aa`(#64300);`git status` 
仅未跟踪 
scratch(`.audit-scratch/`/`conf.cmy/`/`*.bak`/`.claude/scheduled_tasks.lock`)。
+- ⚠️ 仍有遗留 stash `stash@{0}`("WIP on branch-catalog-spi: ... #64253")—— 本 
session 未动;如确认无用可由用户 `git stash drop stash@{0}`。
+
+## ✅ 本 session 已完成(文档同步)
+- **PROGRESS.md**:§header(P4 完成→P5 待启动 + 进度统一 ~32%);§一(P4 100%✅ / P5 
标「下一阶段」);§二看板(maxcompute 100%);§三(P4 收尾为「已合入 #64253+#64300」+ **新增 P5 kickoff 
块**:范围/风险/材料);§四(加 2026-06-09 P4 完成里程碑);§六(决策计数 25→**36**、偏差 12→**22** 纠正,此前严重 
stale);§七(session 状态)。
+- **HANDOFF.md**:本第 19 次 + 折叠第 18 次(标注「已随 #64300 合入」)。
+
+## 🎯 下一 session = P5 paimon 迁移 kickoff(用户定)
+> **策略 = full adopter + 翻闸**(复用 P4 样板,非 P3 hybrid)。P4 已交付可复用的**写/事务 
SPI**(`ConnectorTransaction`/`ConnectorWritePlanProvider`/`PluginDrivenTransaction`/`PluginDrivenInsertExecutor`)+
 full-adopter + cutover 流程范本。
+
+**kickoff 步骤**(沿用 P2/P3/P4:recon → 设计 → 用户签字 → 分批实现):
+1. **code-grounded recon**(多 Agent + 亲核,Rule 8)—— 产 
`research/p5-paimon-migration-recon.md`:
+   - 连接器模块 `fe-connector-paimon/` 现状(10 文件:scan/predicate/handle 
完整;`ConnectorMetadata` 部分实现;catalog flavor / MVCC / vended / sys-tables 缺)。
+   - fe-core footprint:`datasource/paimon/`(22 顶层 + source/5 + profile/2);**反向 
instanceof 10 处**(`PhysicalPlanTranslator` 的 `PAIMON_EXTERNAL_TABLE` 分支等)。
+   - **6 个 catalog flavor**(HMS/DLF/REST/File/Base/Factory)—— 连接器内工厂重组 
`PaimonConnectorProvider.create()` 按 properties 实例化 paimon `Catalog`。
+   - **复用面**:P0 已建 `ConnectorMvccSnapshot`(E5) / vended-creds(E6) / 
sys-tables(E7) SPI —— **paimon 是首个真正消费 E5/E6/E7 的 adopter**(MC 未用,无先例,须重点核)。BE 
经 JNI 调 paimon-reader,序列化 `Table` 经 
`ConnectorScanPlanProvider.getSerializedTable` 已支持。
+   - **P1-T02 推迟项**:fe-core 重复 `PaimonPredicateConverter`(**仍在** 
`datasource/paimon/source/PaimonPredicateConverter.java:43`,连接器侧另有一份)—— P5 删 
fe-core 版。
+2. **写设计 + 批次计划** `tasks/P5-paimon-migration.md`(连接器档约定「P5 待启动时建」)。
+3. **用户签字** → 分批落地、独立 commit、每批守门。
+
+**已知特殊性 / 风险**(master §3.6 line 218 + 连接器档 + risks):
+- **R-004**(classloader 隔离打破 SDK 单例,**paimon 明列**)+ **R-007**(FE/BE 共享 jar 
冲突)+ **R-012**(snapshotId 类型)—— P5/P6 触发窗口,recon 须评估(auto-memory 
[[catalog-spi-be-java-ext-shared-classpath]] 有共享类路径模型)。
+- **关联决策**:D-005(HMS flavor 走 `tableFormatType`,P3-T08 已细化 per-table 
`getScanPlanProvider`)、D-006(cache 放连接器内)。
+- paimon-HMS-flavor 复用 `fe-connector-hms`(P3 已建、稳定)。
+
+**起点材料**:[paimon 连接器档](./connectors/paimon.md)、master plan 
[§3.6](./00-connector-migration-master-plan.md)、[P4 task 
档](./tasks/P4-maxcompute-migration.md)(full-adopter 样板)、写 SPI RFC 
`tasks/designs/connector-write-spi-rfc.md`、[AGENT-PLAYBOOK](./AGENT-PLAYBOOK.md)。
+
+## ⚙️ 操作须知(复用)
+- maven 必绝对 `-f /mnt/disk1/yy/git/wt-catalog-spi/fe/pom.xml` + `-pl 
:<artifact> -am` + `-Dmaven.build.cache.enabled=false`;改连接器 
`:fe-connector-paimon`、改 SPI `:fe-connector-api`(须 -am 连带 rebuild)、改 fe-core 
`:fe-core`。读真实 `Tests run:`/`BUILD`,勿信后台 echo 
exit([[doris-build-verify-gotchas]])。
+- 连接器**禁 import fe-core**(import-gate `bash 
tools/check-connector-imports.sh`)—— 需 fe Config/session 值经 session-property 
透传([[catalog-spi-connector-session-tz-gotcha]])。
+- 连接器测试模块**无 mockito**(纯 seam / child-first 
loader,[[catalog-spi-fe-core-test-infra]])。
+- 分支 `branch-catalog-spi`(HEAD #64300);P5 建议 off 最新 upstream 起新分支。未跟踪 scratch 
勿提交。
+
+## 🧠 给下一个 agent 的 meta
+- **P4 是 full-adopter + cutover 的完整样板** —— P5 复用其写 SPI + 流程;但 paimon 多了 **6 
catalog flavor 工厂** + **首次真正用 E5/E6/E7(MVCC/vended/sys-tables)**,recon 
须重点核这两块(MC 无先例)。
+- **live e2e 仍是翻闸真正完成门**(CI 跳)—— P5 翻闸前同样需用户真实 paimon 环境验证。
+- **翻闸时 GSON 三注册须 atomic 
齐迁**(catalog+db+table,[[catalog-spi-gson-migrate-all-three]],漏 db 致 
ClassCastException);**每个 full-adopter 都要补 FE 分发缺口**(DROP TABLE / CREATE·DROP DB 
/ SHOW PARTITIONS / partitions TVF,[[catalog-spi-cutover-fe-dispatch-gap]])。
+- auto-memory:连接器禁 import 
fe-core([[catalog-spi-connector-session-tz-gotcha]]);测基建无 fe-core/无 
mockito([[catalog-spi-fe-core-test-infra]]);clean-room 
对抗复审偏好([[clean-room-adversarial-review-pref]]);构建坑([[doris-build-verify-gotchas]])。
+
+---
+
+<details><summary>📅 历史:第 18 次 handoff(2026-06-09)— PR #64119 MaxCompute 校验迁移 
SPI DONE(10 文件已随 #64300 合入)</summary>
+
 # 🔥 第 18 次 handoff(2026-06-09,覆盖)— PR #64119(MaxCompute test_connection 校验 + 
外表/视图 read·write 拒绝)迁移 SPI DONE,连接器 UT 全绿
 
 > **本 session**:用户要求把 upstream PR apache/doris#64119(`[fix](fe) Improve 
 > MaxCompute catalog validation`,11 文件/+422)的功能完整迁移到 SPI 框架,并跑通其 3 个单元测试。PR 改的 
 > fe-core 
 > 类(`MaxComputeExternalCatalog`/`MaxComputeExternalTable`/`MCTransaction`/`MaxComputeScanNode`)在本
 >  fork 已于 P4 删除→连接器化,故为真迁移。**用户定夺**:① 范围 = surgical(补 A + 加 C,B/D 已在不动);② 测试 
 > = fold 进现有连接器测试文件。
@@ -38,6 +89,8 @@
 - maven 绝对 `-f .../fe/pom.xml -pl :fe-connector-maxcompute -am test [-Dtest=X] 
-Dmaven.build.cache.enabled=false`;**必带 -am**;读真实 `Tests run:`/`BUILD`,勿信后台 
echo exit。
 - 分支 `catalog-spi-06`。未跟踪 `.audit-scratch/`(本 session 测试 
log)/`conf.cmy/`/`*.bak`/`scheduled_tasks.lock`(勿提交)。
 
+</details>
+
 ---
 
 <details><summary>📅 历史:第 17 次 handoff(2026-06-09)— 老 MaxCompute 代码移除 DONE(3 
commit,全门绿)</summary>
diff --git a/plan-doc/PROGRESS.md b/plan-doc/PROGRESS.md
index 203565b1a13..a5acbbd78dd 100644
--- a/plan-doc/PROGRESS.md
+++ b/plan-doc/PROGRESS.md
@@ -1,6 +1,6 @@
 # 📊 项目进度仪表盘
 
-> 最后更新:**2026-06-09** | 当前阶段:**P4 maxcompute·scope=C(翻闸完成)**——写/事务 SPI RFC 
已批准;**W-phase(W1–W7)全部落地** ✅;**P4 adopter 设计已批准**([D-023],5 批/11 task);**Batch 
A+B 全完成**(T01–T04,gate 关 dormant);**Batch C 翻闸完成**(T05 image-compat + T06a 
写接线/UT + **T06b flip ✅** `CatalogFactory.SPI_READY_TYPES += "max_compute"`,gate 
全绿 [D-027]);**Batch D 删除完成 ✅**(2026-06-09,分支 `catalog-spi-06` off upstream 
`9ed49571b20`/#64253:删 20 fe-core 文件 + 21 反向引用清理 + MCUtils 下沉 
be-java-ext,fe-core 依赖树**彻底无 odps**;`7a4db3511 [...]
+> 最后更新:**2026-06-09** | 当前阶段:**P4 maxcompute 完成 ✅(已合入),P5 paimon 待启动(下一 
session)**——P4 full-adopter 迁移 + live 翻闸 + legacy 删除全部完成并合入 
`branch-catalog-spi`:**#64253**(T01–T06 连接器全适配 + 
`CatalogFactory.SPI_READY_TYPES += "max_compute"`)+ **#64300**(T07–T09 删 20 
fe-core 文件 + 清反向引用 + MCUtils 下沉 be-java-extensions,fe-core 依赖树**彻底无 odps**,HEAD 
`e96037cf6aa`);upstream PR **#64119**(MaxCompute 连接校验)功能已迁连接器 SPI 并随 #64300 
合入。前序 P0/P1/P2(#63582/#63641/#64096)+ P3 hybrid(#64143)均已合入。**下一阶段 = P5 paimon  
[...]
 > [README](./README.md) · [Master 
 > Plan](./00-connector-migration-master-plan.md) · [SPI 
 > RFC](./01-spi-extensions-rfc.md) · [Decisions](./decisions-log.md) · 
 > [Deviations](./deviations-log.md) · [Risks](./risks.md) · [Agent 
 > Playbook](./AGENT-PLAYBOOK.md) · [Handoff](./HANDOFF.md)
 
 ---
@@ -13,13 +13,13 @@
 | **P1** | scan-node 收口 + 重复清理 | 1 周 | ▰▰▰▰▰▰▰▰▰▰ 100% | ✅ 完成(PR 
[#63641](https://github.com/apache/doris/pull/63641) squash-merged 
`778c5dd610f`;T1 推迟 P8;T2 推迟 P4/P5)| 
[tasks/P1](./tasks/P1-scan-node-cleanup.md) |
 | **P2** | trino-connector 迁移 | 2 周 | ▰▰▰▰▰▰▰▰▰▰ 100% | ✅ 已合入 
`branch-catalog-spi`(#64096,squash `0793f032662`;T12 回归推迟 DV-003)| 
[tasks/P2](./tasks/P2-trino-connector-migration.md) |
 | P3 | hudi 迁移 | 2 周 | ▰▰▰▰▰▱▱▱▱▱ 45% | ✅ hybrid(D-019)批 A–D 已合入 
`branch-catalog-spi`(**#64143** squash `5c240dc7a34`);批 E(live cutover)并入 P7 | 
[tasks/P3](./tasks/P3-hudi-migration.md) |
-| P4 | maxcompute 迁移 | 2 周 | ▰▰▰▰▰▰▰▰▱▱ 80% | 🚧 **W-phase 全落地** ✅;**Batch A+B 
完成**(T01–T04 dormant);**Batch C 翻闸完成**(T05 + T06a + **T06b flip ✅** 
[D-027]);**Batch D 删除完成 ✅**(legacy 删 + odps 
依赖彻底移除,`7a4db351100`+`409300a75b8`,全门绿);剩 push/PR | 
[tasks/P4](./tasks/P4-maxcompute-migration.md) |
-| P5 | paimon 迁移 | 3 周 | ▱▱▱▱▱▱▱▱▱▱ 0% | ⏸ 待启动 | — |
+| **P4** | maxcompute 迁移 | 2 周 | ▰▰▰▰▰▰▰▰▰▰ 100% | ✅ 完成并合入 
`branch-catalog-spi`(**#64253** T01–T06 适配+翻闸 + **#64300** T07–T09 删 
legacy/odps-free;含 #64119 校验迁移)| [tasks/P4](./tasks/P4-maxcompute-migration.md) 
|
+| **P5** | paimon 迁移 | 3 周 | ▱▱▱▱▱▱▱▱▱▱ 0% | 🔜 **下一阶段**(本 session 
后启动;recon+设计先行)| —(kickoff 时建 tasks/P5)|
 | P6 | iceberg 迁移 | 5 周 | ▱▱▱▱▱▱▱▱▱▱ 0% | ⏸ 待启动 | — |
 | P7 | hive (+HMS) 迁移 | 6 周 | ▱▱▱▱▱▱▱▱▱▱ 0% | ⏸ 待启动 | — |
 | P8 | 收尾清理 | 2 周 | ▱▱▱▱▱▱▱▱▱▱ 0% | ⏸ 待启动 | — |
 
-**全局进度:12%**(25 周计划中 P0+P1 共 3 周完成)
+**全局进度:~32%**(25 周计划中已完成约 7.9 周:P0+P1+P2+P4 满 + P3 hybrid 45%;统一 header 
与本行此前不一致的 38%/12% 旧值,改按 §一 进度条加权)
 
 ---
 
@@ -33,7 +33,7 @@
 | **es** | ✅ | ✅ 100% | ✅ | ✅ | ✅ | **100%** | [详情](./connectors/es.md) |
 | trino-connector | ✅ | ✅ 100% | ✅ | ✅ | ✅ | **100%** | 
[详情](./connectors/trino-connector.md) |
 | hudi | 🟡(D-005 区分符 + D-020 模型 dispatch 已设计;实现批 E)| 🟨 55%(读路径 dormant + 批 C 
测试基线)| ❌(gate 关)| ❌ | 0/0(寄生 hms)| **25%** | [详情](./connectors/hudi.md) |
-| maxcompute | 🟡 | ✅ 100%(翻闸 + legacy 删除完成)| ✅ **翻闸 T06b** | ✅(Batch D 已删)| ✅ 
0/0(已清)| **95%** | [详情](./connectors/maxcompute.md) |
+| maxcompute | ✅ | ✅ 100% | ✅ **已合入 #64253** | ✅ **#64300 已删** | ✅ 0/0 | 
**100%** | [详情](./connectors/maxcompute.md) |
 | paimon | 🟡 | 🟨 50% | ❌ | ❌ | 0/10 | **20%** | [详情](./connectors/paimon.md) |
 | iceberg | 🟡 | 🟥 10% | ❌ | ❌ | 0/19 | **5%** | [详情](./connectors/iceberg.md) |
 | hive (+hms) | 🟡 | 🟥 20% | ❌ | ❌ | 0/31 | **10%** | 
[详情](./connectors/hive.md) |
@@ -44,7 +44,14 @@
 
 > 状态非 ✅ 的项,按阶段聚合。详细见各阶段 task 文件。
 
-### P4 — maxcompute 迁移(🚧 full adopter;**设计已批准** [D-023],5 批/11 task;Batch 
A+B+C ✅(翻闸完成),下一步 Batch D(删 legacy + drop odps 依赖,待 live 验证))
+### P5 — paimon 迁移(🔜 下一 session 启动:recon + 设计先行)
+
+> 策略 = **full adopter + 翻闸**(复用 P4 样板,非 P3 hybrid)。kickoff = code-grounded 
recon → 设计 + 批次计划(`tasks/P5-paimon-migration.md`)→ 用户签字 → 分批实现 + 独立 commit。详见 
[HANDOFF 第 19 次](./HANDOFF.md) + [paimon 连接器档](./connectors/paimon.md) + master 
plan [§3.6](./00-connector-migration-master-plan.md)。
+>
+> **已知范围**(master §3.6 + 连接器档,待 recon 校正):① port 
`PaimonMetadataOps`→`PaimonConnectorMetadata`(注意 partitionStatistics / 
bucketing);② **6 个 catalog 
flavor**(HMS/DLF/REST/File/Base/Factory)连接器内工厂重组(`PaimonConnectorProvider.create()`);③
 MVCC(E5 `PaimonMvccSnapshot`)/ vended creds(E6 
`PaimonVendedCredentialsProvider`)/ sys-tables(E7 `PaimonSysExternalTable`)承接 
P0 新增 SPI —— **paimon 是首个真正消费 E5/E6/E7 的 adopter**(MC 未用);④ 删 fe-core 重复 
`PaimonPredicateConverter`(**P1-T02 推迟项,仍在** `datasource/pai [...]
+> **前置风险**:R-004(classloader 打破 SDK 单例,paimon 明列)、R-007(FE/BE 共享 jar 
冲突)、R-012(snapshotId 类型)。**关联决策**:D-005(HMS flavor 走 
`tableFormatType`)、D-006(cache 放连接器内)。
+
+### P4 — maxcompute 迁移(✅ 已完成并合入:**#64253** T01–T06 适配+翻闸 + **#64300** T07–T09 
删 legacy/odps-free;含 #64119 校验迁移)
 
 > 策略 = **full adopter + 翻闸**([D-023],非 P3 hybrid);前置 W-phase(W1–W7)✅。批次计划 + 完整 
 > task 表见 [tasks/P4](./tasks/P4-maxcompute-migration.md)。
 
@@ -52,9 +59,9 @@
 |---|---|---|---|---|
 | A | 连接器 DDL + 分区 parity | 🔒 关 | P4-T01 ✅ / T02 ✅ | ✅ T01 DDL + T02 分区 
listing 完成(gate 全绿:compile + checkstyle 0 + import-gate)|
 | B | 写/事务 SPI(`ConnectorTransaction`/`WriteOps` + 
`WritePlanProvider`→`TMaxComputeTableSink`)| 🔒 关 | P4-T03 ✅ / T04 ✅ | ✅ T03 
写/事务 SPI(`MaxComputeConnectorTransaction`+`beginTransaction`)+ T04 
写计划(`MaxComputeWritePlanProvider.planWrite`,OQ-2=Approach A)完成,gate 全绿 |
-| C | 翻闸(`SPI_READY_TYPES` + GSON + `getEngine`;含 R-004 防御测)| 🔓 **live** | 
P4-T05/T06 | ✅ **翻闸完成**(T05 image-compat + T06a 写接线/UT + **T06b flip**,gate 全绿 
[D-027]);R-004 part-2 live 待用户跑 |
-| D | 清 ~30 反向引用 + 删 legacy 子系统(20 文件,收口 P1-T02)+ **drop fe-core odps 依赖** + 
**下沉 MCUtils/删 fe-common odps**(方案A §8)| 🔓 live | P4-T07/T08/T09 | ⏳ 方案已 
finalize + @HEAD 校验(20 文件全在、linchpin residual=∅,2026-06-09);执行后 fe-core 
依赖树**彻底无 odps**;**执行待用户 live ODPS 
验证后**([D-027],[设计](./tasks/designs/P4-batchD-maxcompute-removal-design.md))|
-| E | 连接器测试基线 + PR | — | P4-T10/T11 | ⏳ |
+| C | 翻闸(`SPI_READY_TYPES` + GSON + `getEngine`;含 R-004 防御测)| 🔓 **live** | 
P4-T05/T06 | ✅ **已合入 #64253**(T05 image-compat + T06a 写接线/UT + T06b flip;+ T06c 
FE 分发补接 + T06e 红线 gap campaign G0/G2/G5/G6/G7/GC1/F9 等)|
+| D | 清反向引用 + 删 legacy 子系统(20 文件,收口 P1-T02 的 Mc 部分)+ **drop fe-core odps 依赖** 
+ **下沉 MCUtils/删 fe-common odps**(方案A §8)| 🔓 live | P4-T07/T08/T09 | ✅ **已合入 
#64300**(删 20 fe-core 文件 + 清反向引用 + MCUtils 下沉 
be-java-extensions;`dependency:tree \| grep odps`=∅;含 DV-021/DV-022)|
+| E | 连接器测试基线 + PR | — | P4-T10/T11 | ✅ 连接器 UT 全绿(含 #64119 迁移测,101 run/0 
fail/1 skip);PR #64253 + #64300 已合入 |
 
 ### P3 — hudi 迁移(🚧 hybrid,批 A–D 全部 in-scope 完成:T02/T04/T05/T07 ✅ + T06/T08 
决策;T03→批 E;剩批 E→P7,**P3 已合入 #64143 `5c240dc7a34`**;批 E live cutover 并入 P7)
 
@@ -140,6 +147,7 @@
 
 > 倒序,新内容置顶;超过 14 天的条目移除(git log 保留历史)。
 
+- **2026-06-09(阶段里程碑 · P4 完成)** ✅ **P4 maxcompute 迁移全部完成并合入 
`branch-catalog-spi`** —— **#64253**(T01–T06 连接器 full 适配 + live 翻闸 
`SPI_READY_TYPES += "max_compute"`)+ **#64300**(T07–T09 删 20 fe-core legacy 文件 
+ 清反向引用 + MCUtils 下沉 be-java-extensions,`fe-core dependency:tree | grep 
odps`=∅,HEAD `e96037cf6aa`)。upstream PR **#64119**(MaxCompute 连接校验)功能已迁连接器 
SPI(`validateMaxComputeConnection`/`checkOperationSupported`,连接器 UT 
101/0/0/1)并随 #64300 squash 合入(`git log -S` 证)。fe-core **彻底无 odps**(代码 + [...]
 - **2026-06-06(实现 ⑧·P4-T05)** ✅ **P4 Batch C 启动 — P4-T05 
翻闸接线完成**(dormant、gate-green、**待 commit**,用户定时机):GsonUtils 三 GSON 注册(catalog 
`:397` / **db `:452`** / table `:472`)atomic 迁 
`registerCompatibleSubtype`→`PluginDriven*` + 删 3 unused `maxcompute.*` 
import;`PluginDrivenExternalTable.getEngine`/`getEngineTableTypeName` 加 `case 
"max_compute"`(返 `MAX_COMPUTE_EXTERNAL_TABLE.toEngineName()`=null / 
`.name()`,**核 legacy 行为等价**);`legacyLogTypeToCatalogType` 仅加注释(默认分支已出 
`"max_compute"`,不加 case) [...]
 - **2026-06-06(设计 ⑤·Batch C)** ✅ **P4 Batch C 翻闸设计完成 + 用户签字 
[D-026]**(design-only,零代码):用户选 "Design Batch C first"。4 路 Explore re-verify 
recon 锚点 + 主线核读 executor/txn 生命周期,出 
[翻闸设计](./tasks/designs/P4-T05-T06-cutover-design.md)(verified file:line + 5 gap 
G1–G5 + 写生命周期顺序 + R-004 两分测 + ordered TODO)。**3 决策签字**:D-1 capability signal=新增 
`ConnectorWriteOps.usesConnectorTransaction()` flag(MC=true,否决 
writePlanProvider 代理/复用 ConnectorWriteType);D-2 两 commit、flip 末(`[P4-T06a]` 接线 
dormant + `[P4-T06 [...]
 - **2026-06-06(实现 ⑦·P4-T04)** ✅ **P4 Batch B 收尾 — P4-T04 连接器写计划完成 = Batch A+B 
全完成**(gate 关、dormant、零 live 风险):新建 `MaxComputeWritePlanProvider implements 
ConnectorWritePlanProvider`,`planWrite` 走 **OQ-2 = Approach A**(finalizeSink 
一处:建 ODPS Storage API 写 session → 
`session.getCurrentTransaction()`→`MaxComputeConnectorTransaction.setWriteSession`
 绑事务 → 盖 `TMaxComputeTableSink` 静态字段 + `static_partition_spec` + 
`partition_columns`(ODPS 表列) + `write_session_id` + `txn_id`;**无运行期注入 
hook**,lega [...]
@@ -202,8 +210,8 @@
 
 | 类型 | 总数 | 最新条目 | 文档 |
 |---|---|---|---|
-| **决策**(D-NNN) | 25 | D-025(P4-T04 写计划 5 决策:OQ-2=Approach A / D-2a seam fill 
/ D-3 抽 `getSettings()` / D-4 `supportsInsert` / D-5 静态分区 map);D-024(P4-T03 两 
fork)| [decisions-log.md](./decisions-log.md) |
-| **偏差**(DV-NNN) | 12 | DV-012(P4-T04 `partition_columns` 取 ODPS 
表列,源不同值同);DV-011(P4-T03 block 上限常量)| [deviations-log.md](./deviations-log.md) |
+| **决策**(D-NNN) | 36 | D-036(P4-T06e FIX-CAST-PUSHDOWN:MC 关 CAST 谓词下推 + 剥壳抑制 
source LIMIT,修 F9 静默丢行回归);D-035(FIX-BATCH-MODE-SPLIT 通用 batch SPI 
路径);D-034(FIX-POSTCOMMIT-REFRESH swallow)| 
[decisions-log.md](./decisions-log.md) |
+| **偏差**(DV-NNN) | 22 | DV-022(P4-T09 fe-common 去 odps 暴露隐藏传递依赖→显式补 
netty/protobuf);DV-021(Batch-D 删后 4 条 Tier-3 接受项 GAP3/4/9/10)| 
[deviations-log.md](./deviations-log.md) |
 | **风险**(R-NNN) | 14 | R-014(thrift sink 选择灵活性) | [risks.md](./risks.md) |
 
 ---
@@ -212,9 +220,9 @@
 
 > 当本项目通过 Claude Code 这类 LLM agent 推进时,跟踪当前 session 状态、handoff 状况和 context 健康度。
 
-- **本 session 已完成**:**P4-T04 连接器写计划**(Batch B 收尾 = A+B 全完成,gate 关、dormant、零 
live 风险)——新建 `MaxComputeWritePlanProvider.planWrite`(**OQ-2=Approach 
A**:finalizeSink 一处建写 session + `setWriteSession` 绑 txn + 盖 
`txn_id`/`write_session_id`,无运行期注入)+ 
`MaxComputeDorisConnector.getSettings()`/`getWritePlanProvider()` + 
`supportsInsert()`=true + fe-core seam(`bindViaWritePlanProvider(insertCtx)` + 
`PluginDrivenInsertCommandContext.staticPartitionSpec`)。5 决策 [D-025];偏差 
[DV-012](partition_columns 源)。守 [...]
-- **下一个 session 应做**:**Batch C 翻闸**(唯一 live 切点;前置 = A+B 全绿 ✅ + R-004 ODPS 
classloader 防御测)——P4-T05 GsonUtils `registerCompatibleSubtype` + 
`PluginDrivenExternalTable.getEngine`/`legacyLogTypeToCatalogType` 加 
`max_compute`;P4-T06 `SPI_READY_TYPES += "max_compute"` + 删 `CatalogFactory` 
case + **executor 接线**(`beginTransaction`→`begin(connectorTx)` + 置 
`ConnectorSessionImpl.setCurrentTransaction`)+ 
`GlobalExternalTransactionInfoMgr` 注册 + binding 期填 
`PluginDrivenInsertCommandContext` overwri [...]
-- **是否需要 handoff**:**是**——本场已 rewrite [HANDOFF.md](./HANDOFF.md)(P4-T04 完成 + 
Batch C 翻闸首步锚点 + dormant→live 接线清单 + 守门坑沿用)
+- **本 session 已完成**:**交接文档同步(P4 完成里程碑)** —— 核实 P4 全部合入(#64253 T01–T06 + #64300 
T07–T09,含 #64119 校验迁移;fe-core 代码 + 依赖树彻底无 odps;分支 `branch-catalog-spi` 干净)后,更新 
PROGRESS(§header / §一 P4→100% + P5 标「下一阶段」/ §二看板 maxcompute 100% / §三 P4 收尾 + 
**新增 P5 kickoff 块** / §四里程碑 / §六 D-036·DV-022 计数纠正 / §七)+ rewrite HANDOFF(第 19 
次)。**无产线代码改动。**
+- **下一个 session 应做**:**P5 paimon 迁移 kickoff** —— code-grounded recon(连接器模块现状 / 
fe-core footprint / 6 catalog flavor / MVCC·vended·sys-tables 即 E5/E6/E7 / 10 
处反向 instanceof / 复用 P4 写 SPI)→ 写 `tasks/P5-paimon-migration.md`(设计 + 批次计划)→ 
用户签字 → 分批实现。起点材料见 [HANDOFF 第 19 次](./HANDOFF.md) + [paimon 
档](./connectors/paimon.md) + master 
[§3.6](./00-connector-migration-master-plan.md)。
+- **是否需要 handoff**:**是**——本场已 rewrite [HANDOFF.md](./HANDOFF.md)(第 19 次:P4 
完成确认 + P5 kickoff 起点 + paimon 范围/风险/材料清单)。
 - **协作规范**:[AGENT-PLAYBOOK.md](./AGENT-PLAYBOOK.md)(context 预算、subagent 
使用、handoff 触发条件)
 
 ---


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to