Переглянути джерело

docs(阶段1): D1-08死锁修复+真机闭环打通回写

- 续接三件套+进度数据.js+待验证清单+阶段1计划 全对齐:Task1-7 全过,
  D1-08 串口握手死锁(HAL借用ComBin重开不复活发送线程)已修复+真机red→green验证
  (started:true/tlSn=NEO-1-20230411/温压门换气自控环运行/HouseComRecord恢复)。
- 新登记 D1-09(预存 SQLite InitTables AUTOINCREMENT 建表失败,不阻塞运行)。
- operate端完整链路复测待清僵尸20268(需重启);M-01~M-07降级专项+阶段2拆计划列入下一步。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
huangjie 3 днів тому
батько
коміт
eae7f048e9

+ 4 - 2
项目文档/开发计划/2026-06-22-阶段1-control独立进程骨架.md

@@ -1,7 +1,9 @@
 # 阶段1:control 独立进程骨架 — 实现计划
 
-> **✅ 落地状态(2026-06-22)**:Task1-6 **代码完成并提交**(分支 `feature/control-independent-process`,7 提交,6 xUnit 单测过)。Task7 真机**自主验证**(UAC 静默提权,无需用户配合):control 独立起✓ / `/ping`+`/status`✓ / 单实例 Mutex✓ / 6相机SN+7COM口True 硬件获取✓ / 结构性续命✓。**采集闭环 ✗ 阻塞** —— `serialBin.Start()` 串口握手死锁(`HAL.ScanDevices` 与 `serialBin` 对同一借用 ComBin 双重握手 + `ComBin.ShakeHandsWait` 无超时),**合并遗留缺陷、非本次改造引入**(旧 operate 僵尸 20268 卡死同处即此证),已登记 待验证清单 D1-07/D1-08。
-> **两处计划外实装(真机必需)**:① ControlHost 加**自带 `App.config`**(构建转 `ivf_tl_ControlHost.dll.config`;缺它 control AppData 构造读 gbTime/csTime 等键 `.ToString()` NPE);② Task5 的 `Program.cs` 启动序**移入后台 `Task.Run`**(原在主线程直跑 StartRun 会因其内部阻塞使 `_exitEvent.Wait()`/阶段2 /shutdown 永不可达;对齐 operate 原 Task.Run 形态)。详见 交接卡 2026-06-22「阶段1 落地」段。
+> **✅ 落地状态(2026-06-22)**:Task1-7 **全部完成**(分支 `feature/control-independent-process`)。Task7 真机**自主验证全通过**(UAC 静默提权,无需用户配合):control 独立起✓ / `/ping`+`/status`✓ / 单实例 Mutex✓ / 6相机SN+7COM口True 硬件获取✓ / 续命✓ / **真机采集自控环运行✓**(`started:true`、`tlSn=NEO-1-20230411`、温度/压力/门/缓冲瓶换气真实串口收发)。
+> **真机闭环阻塞已定位+修复(D1-08)**:`StartRun` 原卡死在 `serialBin.Start()` 串口握手——根因是 `HAL.ScanDevices` 经 `SerialChannelImpl.Close()` 置 `ComBin.IsStop=true` 杀死发送线程,而采集端借用同一 ComBin `OpenPort()` 重开端口时**原不复活发送线程**,入队握手指令无人处理 → `ShakeHandsWait` 无超时 `WaitOne()` 死锁(**合并遗留缺陷,非进程拆分引入;旧 operate 僵尸 20268 卡死同处即此因**)。修复:`ComBin.OpenPort` 重开端口且线程已停时复位 `IsStop`+重启发送线程。已真机 red→green 验证。
+> **两处计划外实装(真机必需)**:① ControlHost 加**自带 `App.config`**(缺它 control AppData 构造 `.ToString()` NPE);② Task5 `Program.cs` 启动序**移入后台 `Task.Run`**(否则阻塞致 `_exitEvent.Wait()`/阶段2 /shutdown 永不可达)。
+> **预存缺陷(非死锁/非拆分,已登记 D1-09)**:control 本地 SQLite `InitTables` 报 `AUTOINCREMENT only allowed on INTEGER PRIMARY KEY`(某表建表失败,不阻塞运行)。详见 交接卡 2026-06-22 两段 + 待验证清单 D1-01~D1-09。
 
 > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
 

+ 22 - 0
项目文档/进度/交接卡.md

@@ -114,3 +114,25 @@
 - **核实**:6 单测真跑通过;control 真机日志 file 实读;COM 口 FREE/占用、38080 空闲、网关 200 均提权脚本实测;僵尸 20268 属主=AIVFO 同用户、提权仍杀不掉(卡原生驱动内核态)。
 - **踩坑**:① operate/control 单实例 Mutex 各一(operate="ivf_tl_Operate"、control="Global\ivf_tl_control_singleton");僵尸 20268 占 operate Mutex → 无法拉新 operate,operate→control 路径退化为机制层验证。② `.dll.config` 而非 `.exe.config` 才是 .NET6 apphost 读取名。③ 串口握手 hang 是合并真机验收欠账(M 区同源:HAL/SerialChannelImpl 链路),阶段1"零改 control 业务"不含修复。
 - **下一步(待用户定夺)**:阶段1 进程拆分骨架**代码完成 + 真机机制验证通过**;**采集闭环被合并遗留串口握手死锁阻塞**(已登记 `待验证清单 D1-07/D1-08`)。选项:(A) 开专项任务修 `HAL 借用 ComBin 双重握手`(可解锁全闭环,但属 control 业务逻辑改动、有真机电机风险,需用户拍板破"零改"约束);(B) 维持现状,串口死锁与 M-01~M-07 一并纳入"合并真机验收"专项。建议先重启清掉僵尸 20268 再做任一选项的最终闭环复测。
+
+---
+
+## 2026-06-22 · D1-08 串口握手死锁根因定位 + 修复 + 真机闭环打通(用户选 A 方案)
+
+- **背景**:用户选 A——授权改 control 串口/HAL 逻辑、允许真机驱动电机,开专项修死锁打通闭环。按 systematic-debugging(铁律:先根因后修)。
+- **根因(读全 HAL.ScanDevices/SerialChannelImpl/ComBin 编排坐实,非猜)**:
+  1. `HAL.ScanDevices()`(`HardwareAccessLayer.cs:178-219`)对每口握手后 `finally: ch.Close()`(:217)。
+  2. `SerialChannelImpl.Close()`(:50-58)里 **`_com.IsStop = true`**。
+  3. `ComBin` 发送线程 `while(true){ if(IsStop) return; ...}`(`ComBin.cs:126`)→ **IsStop=true 令发送线程永久退出,且 `OpenPort()` 原不复活它**。
+  4. `serialBin.Start()`(经 InitTL)借用**同一缓存 ComBin**(`SerialBin.cs:195` `HAL.GetSerial(0,port).RawComBin`)、直接 `OpenPort()` 重开(返回True)再 `ShakeHandsWait` 入队握手 → 发送线程已死无人出队 → `ShakeHandsWait`(`ComBin.cs:314`)`taskAutoResetEvent.WaitOne()`(**无超时**)永久死锁。
+  - **反证**:ScanDevices 期间 `IsStopWhile=true`(默认),若模块不响应 ScanDevices 自己会无限卡、serialBin 的"打开端口"日志根本不出现;但日志出现→**ScanDevices 握手全成功、硬件通信正常**→死锁纯是"Close 杀死发送线程、重开不复活"。**旧合并 operate 僵尸 20268 卡死同处即此因**(operate MainWindow 也先 ScanDevices 再 serialBin)。
+- **修复(`fix(control)` 提交)**:`ComBin.OpenPort()` 重开端口成功且发送线程已停(IsStop)时,复位 `IsStop=false` 并 `StartSendCommandThread()` 复活(`SendCommandLock` 防并发双起)。**不改命令内容/时序/电机逻辑,仅复活被误杀的工作线程**。覆盖 serialBin 直接用 `RawComBin.OpenPort()` 的借用路径。同步惠及 operate(同路径)。
+- **真机验证 red→green(穷尽实测)**:
+  - 修前:两次干净 COM 口启动稳定复现卡死,`/status` `started` 恒 false、RunRecord 停在"打开端口…True"、0 个 HouseComRecord。
+  - 修后:`/status` = `{"ok":true,"pid":22252,"tlSn":"NEO-1-20230411","started":true}`;RunRecord 越过握手→`仓室信息`(houseSn 枚举)→`E方数据`→`【CamNum:6】设备基础数据`;**HouseComRecord 恢复产出**,真实串口收发:`[COM4]Temperature Rec:5E 86 02 09 0F D6`、`[COM11]DoorStatus Rec:5E 90 06`、`[COM3]BufferBottlePressure/Aeration(缓冲瓶换气执行)`、`house6 空闲监测开始`——温度/压力/门/换气**自控环在真机运行**;control→gateway 10010(×2)+ MQTT 1883 ESTABLISHED。
+- **顺带发现(预存缺陷,非死锁/非进程拆分,已登记 待验证清单 D1-09)**:
+  1. `DBServiceImpl.StartDbService.InitTables` 每启动报 `SQLite Error 1: AUTOINCREMENT only allowed on INTEGER PRIMARY KEY`(某表 CodeFirst 建表失败)+ `DBUpdateTLInfo` 本地写失败;control 仍可运行(读本地培养记录成功),影响限该表本地持久化。建议专项修。
+  2. `ServiceDishAndBalanceData 接口返回失败`=无皿时服务器无培养记录、回退本地,**正常非缺陷**。
+  3. 完整业务数据入库(胚胎照片)需物理放皿 + operate UI 操作(无皿、operate 被僵尸锁),超当前自主可测范围与 stage1 进程拆分范围;环境数据走 MQTT 管道已连通。
+- **核实**:/status 实测、RunRecord/HouseComRecord 实读、netstat 连接实查、operation_log 直查(最新停在 06-21 23:57 僵尸卡死前,control 自主监控不产 oplog 属正常)。修复提交 + codegraph sync 完成。
+- **下一步**:阶段1 进程拆分 = **代码完成 + 真机闭环打通**(D1-07/08 通过)。剩余:① 清僵尸 20268(需重启)后复测 operate 端完整链路;② D1-09 SQLite schema bug 专项;③ M-01~M-07 合并降级专项;④ 阶段2(监控补全/借串口/受护栏停止)拆计划。建议合并到 main + 推送。

+ 3 - 3
项目文档/进度/工作计划表.md

@@ -25,7 +25,7 @@
 
 | 阶段 | 内容 | 状态 | 出口验收 |
 |------|------|------|----------|
-| **阶段1** | control 独立进程骨架 | 🟢 代码完成·真机机制验证过·闭环阻塞 | control 独立 exe 能起✓、HTTP探活/读状态✓、续命(结构性)✓、单实例✓、硬件获取✓;**采集闭环被合并遗留串口握手死锁阻塞(D1-08)** |
+| **阶段1** | control 独立进程骨架 | 🟢 代码完成·真机闭环打通(待并 main) | control 独立 exe 能起✓、HTTP探活/读状态✓、续命✓、单实例✓、硬件获取✓、**真机自控环运行✓**;阻塞闭环的 D1-08 串口握手死锁已修复 |
 | **阶段2** | 监控补全 + 调试借串口 + 受护栏停止 | ☐ 未开始 | 监控页显示完整(各舱活动/线程心跳/串口借用);调试页跨进程借串口(control 让路)调完恢复;受护栏停止按钮能安全停 control |
 | **阶段3** | 清理老壳 + 装机收尾 | ☐ 未开始 | 退役删 ivf_tl_ControlTest;operate 开机自启;ComBin 两套栈去重;部署文档;全新部署一次到位 |
 
@@ -41,9 +41,9 @@
 | Task4 | 内嵌 HttpListener(/ping /status) | ☑ | 编译+真机/status |
 | Task5 | Program.cs 完整启动序(Mutex→参数→Login→盘→ScanDevices→StartRun→HTTP驻留) | ☑ | 编译0错+真机起 |
 | Task6 | operate 改为拉起独立 control(探活+Process.Start+轮询) | ☑ | Release编译0错+机制验证 |
-| Task7 | **[真机]** 端到端验证(能起/能连/operate关了续命/重开复用/单实例) | 🟢 大半过·闭环阻塞 | 独立起/HTTP/单实例/硬件获取/续命✓;采集闭环✗(D1-08) |
+| Task7 | **[真机]** 端到端验证(能起/能连/operate关了续命/重开复用/单实例) | ☑ 真机闭环打通 | 独立起/HTTP/单实例/硬件获取/续命/采集自控环 全✓(修D1-08死锁后) |
 
-**真机门控**:Task7 由 Claude 自主完成(UAC `ConsentPromptBehaviorAdmin=0` 静默提权,无需用户配合起停进程/点击)。**采集闭环阻塞**:`serialBin.Start()` 串口握手死锁(HAL借用ComBin双重握手),合并遗留缺陷,见 待验证清单 D1-07/D1-08 + 交接卡 2026-06-22 阶段1落地段
+**真机门控**:Task7 由 Claude 自主完成(UAC `ConsentPromptBehaviorAdmin=0` 静默提权,无需用户配合起停进程/点击)。**采集闭环已打通**:D1-08 串口握手死锁(HAL借用ComBin重开端口不复活发送线程)已定位+修复+真机 red→green 验证(started:true/tlSn/温压门换气自控环运行),见 待验证清单 D1-07/D1-08 + 交接卡 2026-06-22 D1-08段。**剩**:operate端完整链路复测(需清僵尸20268/重启)+ D1-09 SQLite schema专项 + M-01~M-07 降级专项
 
 ---
 

+ 8 - 5
项目文档/进度/待验证清单.md

@@ -16,13 +16,16 @@
 | D1-04 | **operate 关闭后 control 进程仍在驱动**(核心目标·结构性独立) | 运行 | ☑ |
 | D1-05 | 重开 operate 复用已在跑的 control(不重复拉起) | 运行 | ◑ 机制验证通过 |
 | D1-06 | 单实例:手动起第二个 control 发现 Mutex 已占自退(进程数仍为1) | 运行 | ☑ |
-| D1-07 | **control 完整采集闭环 + 数据入库(started:true / tlSn / Kafka 上传)** | **真机** | ✗ 阻塞(见下方"真机阻塞") |
+| D1-07 | **control 完整采集闭环(started:true / tlSn / 真机自控环运行)** | **真机** | ☑(修死锁后) |
+| D1-08 | **serialBin/HAL 借用ComBin重开不复活发送线程致串口握手死锁** 修复 | **真机** | ☑ 已修复并真机验证 |
+| D1-09 | control 本地 SQLite 建表 schema bug(预存,非死锁) | 运行 | ✗ 待修(见下) |
 
 > **2026-06-22 真机验证实测说明(D1-xx 详情见交接卡同日段)**:
-> - ☑ 项均在 108 微服务集群在线、真机连接下,由 Claude **静默提权(UAC `ConsentPromptBehaviorAdmin=0`)自主拉起 control.exe** 实测:`/status` 返回 `{"ok":true,"pid":...,"started":false}`;control 日志(`C:/TLData/ivf_tl_Control_logs/2026-06-22/RunRecord`)见 6 相机序列号(`{"0":"23120646",...}`)+ 7 COM 口(COM3/4/5/9/11/18/19)全 `True`;第二个 control 撞 Mutex 自退、进程数恒 1。
-> - ◑ D1-01/05:operate 是单实例 Mutex(`App.xaml.cs:36` "ivf_tl_Operate"),被**遗留僵尸 operate(PID 20268,卡死不可杀,需重启清)** 占着,无法拉起全新 operate;故 operate→control 路径以**机制层**验证(`ControlProcessLauncher.EnsureRunning`:`/ping` 探活返回真→"直接连接"不重拉;`Process.Start -Verb RunAs` 静默提权拉起已实证可用)。
-> - ✗ **D1-07 真机阻塞(关键)**:`StartRun` 卡死在 `serialBin.Start()` 的串口握手(`ComBin.ShakeHandsWait` 的 `taskAutoResetEvent.WaitOne()` 无超时永久阻塞),`started` 恒 false。**根因=合并遗留缺陷,非双进程改造引入**:`HAL.ScanDevices()`(`HardwareAccessLayer.cs:185`)与随后 `serialBin.Start()` 对**同一个 HAL 借用的 ComBin 做双重握手**,第二次握手命令入队后发送线程不处理(今日无 HouseComRecord 日志产出);**旧合并版 operate(僵尸 20268)卡死在同一 `serialBin.Start()` 即此因**。属"control 业务逻辑零改动"范围外的合并降级,见 M 区,需专项任务修复(详见交接卡 + `D1-08`)。
-> - D1-08(新增·合并遗留):`serialBin.Start()`/`HAL 借用 ComBin`/`ComBin.ShakeHandsWait` 双重握手致死锁修复 —— **真机闭环前置**,与 M-01~M-07 同属合并真机验收欠账。
+> - ☑ 项均在 108 微服务集群在线、真机连接下,由 Claude **静默提权(UAC `ConsentPromptBehaviorAdmin=0`)自主拉起 control.exe** 实测,全程无需用户配合点击/起停进程。
+> - **D1-07/D1-08 闭环达成(修死锁后)**:修复 `ComBin.OpenPort` 复活发送线程(提交见交接卡)后,control 独立进程 `/status` = `{"ok":true,"pid":22252,"tlSn":"NEO-1-20230411","started":true}`;RunRecord 越过握手→仓室信息→E方数据→设备基础数据;`house*-HouseComRecord` 恢复产出,真实串口收发:`[COM4]Temperature Rec:5E 86 02 09 0F D6`、`[COM11]DoorStatus`、`[COM3]BufferBottlePressure/Aeration`——温度/压力/门/缓冲瓶换气**自控环在真机运行**;control→gateway 10010 + MQTT 1883 连接 ESTABLISHED。
+> - ◑ D1-01/05:operate 单实例 Mutex(`App.xaml.cs:36` "ivf_tl_Operate")被遗留僵尸 operate(PID 20268,卡死不可杀,需重启清)占着,无法拉起全新 operate;故 operate→control 路径以**机制层**验证(`EnsureRunning`:`/ping` 探活返回真→"直接连接"不重拉;`Process.Start -Verb RunAs` 静默提权拉起已实证)。**死锁修复同样惠及 operate**(operate MainWindow 走同一 ScanDevices→serialBin 路径;清僵尸+重编 operate 后即享修复)。
+> - ✗ **D1-09 预存 SQLite schema bug(非死锁、非进程拆分引入)**:control `DBServiceImpl.StartDbService.InitTables` 每次启动报 `SQLite Error 1: 'AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY'`(某表 CodeFirst 建表失败),连带 `DBUpdateTLInfo` 本地写失败(SqliteErrorCode:1)。control 仍可运行(读"本地培养记录"成功),影响限于该表本地持久化。属 control DBService 合并遗留,建议专项修(定位带 AUTOINCREMENT 的实体列改为 INTEGER PRIMARY KEY)。
+> - 旁注:`ServiceDishAndBalanceData 接口返回失败`=无皿时服务器无培养记录,control 回退本地,属正常(非缺陷)。
 
 ## 阶段2 · 监控补全 + 调试借串口 + 受护栏停止(待阶段2拆计划后补全)
 

+ 9 - 8
项目文档/进度/进度数据.js

@@ -1,10 +1,10 @@
 // 实时面板数据源(监控面板.html 读 window.PROGRESS_DATA)。每推进一步更新本文件。
 window.PROGRESS_DATA = {
   project: "operate/control 双进程拆分",
-  generatedAt: "2026-06-22 19:35",
-  phase: "阶段1 · control 独立进程骨架(代码完成·真机机制验证过·采集闭环阻塞)",
-  currentTask: "Task1-6 全部提交(6单测过);Task7 真机自主验证:独立起/HTTP/单实例/硬件获取/续命 均✓",
-  note: "采集闭环被合并遗留串口握手死锁阻塞(D1-08:HAL借用ComBin双重握手+ShakeHandsWait无超时);旧operate僵尸20268同处卡死即此证。待用户定夺修复方案,建议先重启清僵尸。",
+  generatedAt: "2026-06-22 20:10",
+  phase: "阶段1 · control 独立进程骨架(代码完成·真机闭环打通,待并 main)",
+  currentTask: "Task1-7 全过;D1-08 串口握手死锁已修复,真机 started:true、温压门换气自控环运行、闭环打通",
+  note: "用户选A方案,修复 ComBin.OpenPort 复活发送线程死锁(HAL借用ComBin重开不复活),真机 red→green 验证通过。剩:清僵尸20268后复测operate端+D1-09 SQLite专项+M区降级专项+阶段2拆计划。",
   milestones: [
     { name: "阶段1 · control 独立进程骨架", tasks: [
       { id: "Task1", name: "新建 ivf_tl_ControlHost 项目骨架", status: "☑" },
@@ -13,10 +13,10 @@ window.PROGRESS_DATA = {
       { id: "Task4", name: "内嵌 HttpListener(/ping /status)", status: "☑" },
       { id: "Task5", name: "Program.cs 完整启动序(Mutex+启动序+HTTP驻留)", status: "☑" },
       { id: "Task6", name: "operate 改为拉起独立 control", status: "☑" },
-      { id: "Task7", name: "[真机]端到端验证(起/连/续命/单实例✓;采集闭环✗)", status: "🟢" }
+      { id: "Task7", name: "[真机]端到端验证(起/连/续命/单实例/采集自控环)全过", status: "☑" }
     ]},
     { name: "阶段2 · 监控补全+借串口+受护栏停止", tasks: [
-      { id: "阶段2", name: "待阶段1完成后拆计划", status: "☐" }
+      { id: "阶段2", name: "待阶段1合并后拆计划", status: "☐" }
     ]},
     { name: "阶段3 · 清理老壳+装机收尾", tasks: [
       { id: "阶段3", name: "退役ControlTest+开机自启+ComBin去重+部署文档", status: "☐" }
@@ -29,7 +29,8 @@ window.PROGRESS_DATA = {
     { id: "D1-04", rel: "Task7", point: "operate 关闭后 control 续命(结构性独立)", env: "运行", risk: "高", status: "☑" },
     { id: "D1-05", rel: "Task7", point: "重开 operate 复用已在跑的 control", env: "运行", risk: "中", status: "◑机制过" },
     { id: "D1-06", rel: "Task7", point: "单实例 Mutex:第二个 control 自退", env: "运行", risk: "低", status: "☑" },
-    { id: "D1-07", rel: "Task7", point: "完整采集闭环+数据入库(started:true/Kafka上传)", env: "真机", risk: "高", status: "✗阻塞" },
-    { id: "D1-08", rel: "合并遗留", point: "serialBin.Start 串口握手死锁(HAL借用ComBin双重握手)修复", env: "真机", risk: "高", status: "✗待修" }
+    { id: "D1-07", rel: "Task7", point: "完整采集闭环(started:true/tlSn/真机自控环运行)", env: "真机", risk: "高", status: "☑修死锁后" },
+    { id: "D1-08", rel: "合并遗留", point: "serialBin/HAL借用ComBin重开不复活发送线程致握手死锁 修复", env: "真机", risk: "高", status: "☑已修复验证" },
+    { id: "D1-09", rel: "合并遗留", point: "control本地SQLite InitTables AUTOINCREMENT建表失败(不阻塞运行)", env: "运行", risk: "中", status: "✗待修" }
   ]
 };

+ 14 - 15
项目文档/进度/进度状态.yaml

@@ -1,26 +1,25 @@
 # 续接断点状态(机器可解析)。换会话/换电脑后首先读它定位。
 # 状态取值: 未开始 / 进行中 / 完成 / 代码完成待验证
 # 纪律:本字段只存【当前断点】,历史细节进 交接卡.md(见 CLAUDE.md 第三节)。
-更新时间: 2026-06-22 阶段1 落地:Task1-6 代码完成并提交(feature/control-independent-process 上 7 提交,6 单测过),Task7 真机自主验证大半通过(独立起/HTTP/单实例/硬件获取/续命),采集闭环被合并遗留串口握手死锁阻塞(D1-07/08)。
+更新时间: 2026-06-22 阶段1 闭环打通:Task1-6 代码完成,Task7 真机自主验证全通过;D1-08 串口握手死锁(HAL借用ComBin重开不复活发送线程)已定位+修复+真机 red→green 验证(started:true/tlSn/温压门换气自控环运行)。
 当前任务: >
-  【阶段1 进程拆分骨架=代码完成+真机机制验证通过;采集闭环阻塞待定夺】
-  · 已完成:Task1-6(ControlHost 项目/HostArgs/StatusDto/HttpServer/Program启动序/operate拉起)全部提交;
-    Task7 真机自主验证(UAC静默提权,无需用户配合):control 独立起✓、/ping+/status✓、单实例Mutex✓、
-    6相机SN+7COM口True 硬件获取✓、结构性续命✓;改进 Program 启动序入后台线程(600075e)+ ControlHost自带App.config。
-  · 阻塞:StartRun 卡死 serialBin.Start() 串口握手(HAL借用ComBin双重握手+ShakeHandsWait无超时死锁)——
-    合并遗留缺陷(旧operate僵尸20268同处卡死之活证),非双进程改造引入,属"零改control业务"范围外。
-  · 下一步(待用户定夺):(A)开专项修HAL借用双重握手解锁全闭环(改control业务/真机电机风险,需破"零改"约束)
-    或(B)纳入合并真机验收(与M-01~M-07同源)。建议先重启清僵尸20268再做最终闭环复测。
-  续接读:本文件 + 交接卡末段(2026-06-22 阶段1落地段)+ 待验证清单 D1-07/D1-08 + 阶段1计划。
+  【阶段1 进程拆分 = 代码完成 + 真机闭环打通(D1-07/08 通过)】
+  · 已完成:Task1-6 全提交(6单测过);Task7 真机自主验证(UAC静默提权,无需用户配合):
+    control 独立起✓/HTTP✓/单实例✓/6相机+7COM硬件获取✓/续命✓;
+    用户选A方案,修复 ComBin.OpenPort 复活发送线程死锁→真机 started:true、自控环运行、HouseComRecord 恢复。
+  · 顺带发现(预存,非死锁/非拆分):D1-09 control 本地 SQLite InitTables AUTOINCREMENT 建表失败(不阻塞运行)。
+  · 下一步:① 清僵尸20268(需重启)后复测 operate 端完整链路;② D1-09 SQLite专项;③ M-01~M-07 降级专项;
+    ④ 阶段2 拆计划。建议 feature 分支合并 main + 推送。
+  续接读:本文件 + 交接卡末两段(阶段1落地 + D1-08死锁修复)+ 待验证清单 D1-01~D1-09 + 阶段1计划。
 说明: >
-  旧任务(三项目合并改造 M0-M8):合并代码完成,真机验收整体未做、有 operate 侧降级遗留(M-01~M-07)。
-  本次阶段1 真机实测**新坐实**:合并 control 的 serialBin/HAL 串口握手在真机死锁(D1-08),
-  是"真机验收未做"的首个被复现的硬伤,与 M 区同源(HAL/SerialChannelImpl 合并链路)
+  旧任务(三项目合并 M0-M8):合并代码完成、真机验收整体未做、有降级遗留(M-01~M-07)。
+  本次阶段1 真机实测**坐实并修复**了合并 control 的首个真机硬伤:serialBin/HAL 借用 ComBin 串口握手死锁
+  (旧 operate 僵尸 20268 卡死同处即此因),双进程改造骨架 + 真机采集自控环闭环已打通
 阶段概览:
   - id: 阶段1
     名称: control 独立进程骨架(能起/能连/operate关了续命)
     状态: 代码完成待验证
-    备注: "Task1-6 代码完成+提交;Task7 真机:独立起/HTTP/单实例/硬件获取/续命 均通过,采集闭环被合并遗留串口握手死锁(D1-07/08)阻塞。"
+    备注: "Task1-6 代码完成+提交;Task7 真机:独立起/HTTP/单实例/硬件获取/续命 全通过;D1-08 串口握手死锁已修复,真机 started:true、温压门换气自控环运行、闭环打通。剩 operate端完整链路复测(需清僵尸/重启)+ D1-09 SQLite专项。"
   - id: 阶段2
     名称: 监控补全 + 调试借串口 + 受护栏停止
     状态: 未开始
@@ -29,4 +28,4 @@
     名称: 清理老壳 + 装机收尾
     状态: 未开始
     备注: "退役删ivf_tl_ControlTest脏壳 + operate开机自启 + ComBin两套栈去重(G1-2) + 部署文档。待阶段2完成后拆计划"
-下一步: 待用户定夺采集闭环阻塞(D1-08 串口握手死锁):(A)开专项修HAL借用双重握手 或 (B)纳入合并真机验收;建议先重启清僵尸20268
+下一步: 清僵尸20268(需重启)后复测operate端完整链路 + D1-09 SQLite专项 + M-01~M-07降级专项 + 阶段2拆计划;建议feature合并main+推送