guanghu-ice-heart/development/GHB-DEV-CHAIN-20260812-002.md

97 lines
8.2 KiB
Markdown
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 光湖桥聊天工具 · 双壳集成开发链 · DEV-20260812-002
- 登记号GHB-DEV-CHAIN-20260812-002
- 日期2026-08-12
- 执行人:铸渊 ICE-P-ZY001QoderCN 实例)
- 指令源:冰朔——"光湖桥,就是给人类在光湖世界里做一个聊天工具。你就在我本地开发,开发好了装到这两个框架里都试试,看看是否真的成功运行了这个通讯工具。"
- 上游基线GHB-DEV-20260812-001光湖桥 v1 独立参考实现bridge-node.mjsselftest 五项 PASS
- 状态:**Electron 壳全链路 PASS含打包 .appTauri 壳部分 PASS接入通、UI 发送被 ACL 拦,未闭合)**
---
## 一、任务目标
把光湖桥从"协议参考实现"变成"人类可用的聊天工具",并分别装进两个桌面框架实测:
1. Electron0.8.0 HoloLake Era 同族路线)
2. Tauri0.4.6 源码线同族路线,冰朔偏好的轻量壳)
验收标准:两个壳各自能连上会合点、互发消息、收到送达回执,真实运行而非纸面设计。
## 二、架构决策链(为什么这样做)
```
目标:一套聊天前端,两个壳都能装
└─ 决策1桥运行时统一走 stdio JSON 子进程模式
原因Electron 主进程虽自带 Node但 Tauri 后端是 Rust 无 Node 运行时;
取交集 = 两边都能 spawn 子进程 + 读写 stdio。
给 bridge-node.mjs 增加 --stdio 模式NDJSON 命令进/事件出,日志走 stderr
两壳集成方式完全同构,协议面只有一份。
└─ 决策2聊天前端零构建纯 HTML/CSS/JS不用 Vite/Webpack
原因:构建链越短,双壳复用越干净,也符合光湖"可手工审计"原则。
└─ 决策3adapter.js 适配层统一事件面
前端只认 window.GHB = { send(to,text), on(event,cb) }
Electron 走 preload contextBridgeghbElectron
Tauri 走 withGlobalTauri 的 __TAURI__.event/core
裸浏览器降级为 mock 提示。壳的差异被隔离在 adapter 一层。
└─ 决策4开发与构建全部落本地盘 /tmp成品归档 JZAO
原因既有教训——ExFATJZAO上构建会因 AppleDouble 崩签名;
且沙箱对工作区外 shell 写入有限制。
└─ 决策5无人值守自检钩子
GHB_AUTOSEND="对端|文本|延迟秒"(走 UI 发送路径,气泡真实渲染)
+ GHB_SHOT=路径(延迟截屏取证),让"是否真的运行"有图有日志。
```
## 三、实测结果
### Electron 壳 ✅ PASS
- 开发模式双实例ELECTRON-A ↔ ELECTRON-B双向消息送达、回执签名验证通过、UI 气泡完整渲染(截图取证 shot-a/shot-b
- 打包 `.app`GuanghuBridgeChat.app手工组装 + ad-hoc 签名双实例复测PKG-A ↔ PKG-B 双向送达、验签通过(截图 shot-pkg-a/b
- 证据relay 日志四条在线直投;`signature_verified: true`;截屏显示绿连接点、节点号、双向气泡、"✓ 已送达·已验签"。
### Tauri 壳 ⚠️ 部分 PASS未闭合
- cargo 编译通过Tauri v2 + Rust 1.96)。
- 双实例接入会合点成功relay 日志TAURI-A / TAURI-B 接入)。
- **未闭合点**:后端 emit 的事件能到前端,但前端 `invoke('bridge_send')` 没有触发发送——应用命令的 ACL 权限未被 tauri-build 收录进 acl-manifests.jsonmanifest 只有 core 系列,`allow-bridge-send` 不存在,引用即编译报错)。见未决问题 U1。
- 未打包 .appbundle.active=false验证未通过前不做
## 四、踩坑因果链(现象 → 原因 → 处置)
1. **parseArgs 吞开关**`--stdio` 无值开关被旧配对逻辑吃掉后续 `--id` → 改为逐个扫描,值以 `--` 开头则视为布尔开关。
2. **stdio 模式 stdin EOF 即退出**:后台测试时 stdin=/dev/null节点刚连上就退出relay 侧表现为"刚接入就离线" → 结论stdio 子进程要求宿主保持 stdin 管道打开Electron/Tauri spawn 默认满足);测试用 `(sleep N) | node ...` 保持。
3. **connected 事件早于渲染进程就绪**:截屏显示"接入中…红点"但回执事件已到 → 原因:子进程启动快于 webContents 加载,早到事件被丢 → 处置main 进程加事件缓冲队列did-finish-load 后补发。
4. **Electron 沙箱内 SIGSEGV**:同代码上轮能跑本轮段错误,伴随 `nice(5) failed` → 沙箱策略变化所致 → `--no-sandbox --disable-gpu` 规避。
5. **npm 缓存权限**:沙箱禁写 `~/.npm``--cache /tmp/npm-cache`
6. **Electron 二进制下载失败**postinstall 从 GitHub 拉二进制被断 → 换 npmmirrorELECTRON_MIRROR+ `ELECTRON_CACHE=/tmp/electron-cache`
7. **electron-builder 打包在沙箱下解包丢二进制**dist 里 `Contents/MacOS` 为空rename ENOENT → 放弃 builder**手工组装 .app**:拷官方 Electron.app → `asar pack --unpack-dir bridge` → 改 Info.plistCFBundleExecutable/Name/Identifier→ 改名主二进制 → `codesign --force --deep -s -`。此路线完全可控且可复现。
8. **外部 node 读不了 asar 内文件**:打包后 spawn 的系统 node 报 MODULE_NOT_FOUND → asar 透明读取只在 Electron 进程内生效 → bridge 脚本 unpack 到 `app.asar.unpacked/`main.cjs 加路径探测(打包态优先 unpacked开发态回退本地目录
9. **cargo 写 ~/.cargo 被沙箱拦**`CARGO_HOME=/tmp/cargo-home`
10. **Tauri generate_context 要求 icons/icon.png** → python 纯手写 PNG光湖青圆形128px
11. **Rust E0597**Exit 事件里 `if let Ok(guard) = state.0.lock()` 的临时 MutexGuard 析构顺序晚于 state 绑定 → 块尾加分号提前落临时对象。
12. **zsh 杂项**`rm -rf x/*.png` 无匹配报错、`echo ====` 被解析、后台进程 nice 警告——全部改用落文件再查看的方式规避。
## 五、未决问题清单
- **U1Tauri ACL最高优先**:应用命令 `bridge_send` 的 allow 权限未进 acl-manifests.json。疑点tauri-build 收集应用命令权限的机制与本工程 [lib] 双 crate 结构main.rs 调 app_lib::run的交互下次优先试 a) 把 run() 逻辑并回 main.rs 单 crate 重建看 manifest 是否收录b) 查 tauri 官方脚手架的 capabilities 生成差异。
- **U2**Tauri 壳 UI 渲染取证缺(无截屏钩子),可在 lib.rs 加 webview.screenshot 或走系统 screencapture。
- **U3**GHB_AUTOSEND / GHB_SHOT 是开发自检钩子,正式交付前决定保留(运维有用)或摘除。
- **U4**:桥协议层未竟项(承 DEV-001TLS、多会合点、BS-TCS 准入门禁对接、群聊/人格体协作信封。
- **U5**:待冰朔裁定——聊天工具源码是否推 REPO-014 走正典登记;真实跨机会合点落哪台节点。
- **U6**:本仓库工作区存在 1027 个 0-insertion/0-deletion 的 ExFAT 元数据"假改动"stat 差异),未处理,不属本次交付范围,仅报告。
## 六、资产清单与复现
- 源码归档:`/Volumes/JZAO/HoloLake/development/guanghu-bridge-DEV-20260812-001/`
- `bridge-node.mjs`(新增 --stdio 模式与事件缓冲无关,纯运行时)
- `chat/`chat.html/css/js + adapter.js 四件共用前端)
- `chat/electron/`main.cjs + preload.cjs + package.json
- `chat/tauri/`Cargo.toml + build.rs + tauri.conf.json + src/ + capabilities/
- 构建配方(本地盘):
- Electron`npm i electron --cache /tmp/npm-cache``ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/`;打包走手工组装七步(见踩坑 7
- Tauri`CARGO_HOME=/tmp/cargo-home cargo build`
- 运行:先起 `node bridge-node.mjs relay --port <P>`,壳通过环境变量 `GHB_NODE_ID` / `GHB_RELAY` 接入。
- 实测证据件:截图 shot-a/bElectron 开发态、shot-pkg-a/b.app 打包态)存 `/Volumes/JZAO/铸渊-ICE-GL-ZY001/OUT-输出/图片/`shot-a/b与本次会话日志。
## 七、状态推进
- 光湖桥人类产品形态DESIGN_PROVEN → **ELECTRON_SHELL_PROVEN_LOCAL / TAURI_SHELL_PARTIALACL 未闭合)**
- 认知基线 025 的 realtime_transport_state 维持 `REFERENCE_IMPLEMENTATION_PROVEN_LOCAL`,待 Tauri 闭合后可加注双壳验证。