dev-manager-tauri/.blueprint/modules/architecture-evolution.md
lanrtop d1b9b0564e
All checks were successful
Push & PR Check / check (push) Successful in 1m2s
Push & PR Check / check (pull_request) Successful in 59s
feat(onboard/parity): 客户端适配器注册表与三端结构化注入结果,onboard 模块投影无关适应度测试(P8b、A1a)
一键接入(P8)编排前置:Claude local 与 DSH 托管块的成败原来只写日志,inject_mcp
笼统回「已配置 Codex 与 Claude」,失败会被报成成功(R4)。

- 新增 src-tauri/src/onboard/:ClientId、ClientOutcome(converged/applied/refreshed/
  removed/manual_kept/other_project/not_installed/skipped/missing/unavailable/
  needs_human/failed)、ClientAdapter(detect/static_status/apply)与 registry();
  适应度测试 onboard_module_is_projection_free 机器校验本体不依赖投影层
- 三端适配器实现在 mcp_inject,注册表反向接入;注入经 registry() 逐端 apply,
  新增 inject_project_mcp_report,inject_project_mcp 签名与「Codex 失败即整体失败」
  语义不变
- sync_claude_local / ensure_dsh_patch 抽出依赖注入版,每条分支返回结构化结果,
  日志类别与文案不变;upsert_codex_mcp_config 返回 converged/applied/manual_kept
- verify_onboarding(MCP)附加 clients 只读三端状态,不计入 checks、不影响 pass;
  inject_mcp 回执逐端列出实际结果
- 行为变化(有意):Codex 手写同名 server 改记 manual_kept 不再阻断 Claude/DSH;
  WSL 项目 Claude local 记 skipped 不再起 CLI
- 新增 9 条测试(假 CLI 覆盖 Claude 全部分支、临时 DSH 目录四态);cargo test
  295 passed;契约同步 project-context.yaml,AGENTS.md 架构速查补 onboard/

Feature-Confirmed: true
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 08:25:04 +09:00

70 lines
6.4 KiB
Markdown
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.

---
id: architecture-evolution
name: 炼境架构演进
status: planned
progress: 0
---
## 概述
2026-10-01 评估结论:现有技术栈(Tauri v2 + Rust + React/TS + SQLite)适合「管家 / agent 客户端兼容层」方针,不换栈。常驻托盘服务、凭据安全、单文件分发、cargo test 快速回归都是 Rust/Tauri 的强项;真正的难点在 Windows 与各客户端自身机制(cmd 引号与 %VAR% 展开、CRLF、Claude 配置作用域、DSH !!js、Node 拒绝直接执行 .cmd),与语言无关。Electron 全 Node 栈(与三家客户端同生态、JSON/YAML 顺手)因常驻内存大、凭据需原生模块且须整体重写而否决;Go、Python 无明显收益。
本模块收集比「换语言」更影响实现效率的结构性改进,按收益排序。
## 任务拆解
### 📋 A1 — 本体与投影分离(2026-10-03 改写为三段:A1a / A1b / A1c)
- status: todo
- complexity: L(已拆,见下)
- 原卡:core crate + CLI——「业务逻辑位于不依赖 Tauri 的 core crate;同一 exe 或独立 cli 在炼境界面未运行时可执行 onboard / probe / diagnostics」。原「为什么」:核心逻辑写在 Tauri 应用内,炼境不运行时 agent 与脚本无法调用;拆分后 Tauri 界面、MCP 服务、命令行成为同一本体的三个投影。
- 改写理由(2026-10-03 agent-client-parity P8 设计评审,`docs/tasks/2026-10-03-p8-onboarding-oneclick-design.md` §5):
1. P8 与 P4 的验收载体是 Tauri command 和 MCP,本来就跑在炼境进程里;探针测的是「客户端连上运行中的炼境 MCP」,炼境离线时无物可测——「界面不运行也能用的 CLI」对它们没有用例。
2. 离线写入有实际危害:MCP_OP_LOCK、DSH_PATCH_LOCK 与凭据存储的锁只在进程内有效,~/.claude.json(经 claude CLI)、~/.dsh/cordis.patch.yml、Credential Manager、SQLite 会被两个进程竞争写;agent 从 MSIX 客户端里调用时 AppData 写入可能被重定向(P3 已实证)。
3. 真正的耦合是全局 pool()(约 293 处、43 个文件)和进程内静态锁,拆 crate 解决不了;A1 是 L 级,会与 A4、P6 大面积冲突,把 P8 推迟数周。
4. 复用主 exe 做 CLI 还要处理控制台挂接(release 为 windows_subsystem="windows")和 single-instance,那是拆 crate 时才需要解决的设计问题。
结论:P8 需要的是 A1 的原则(本体不依赖投影),不是 crate 拆分。
### ✅ A1a — onboard/ 模块的投影无关约束(随 agent-client-parity P8b 落地)
- status: done
- verification: "2026-10-03(分支 feat/agent-client-parity-p8):src-tauri/src/onboard/mod.rs 内 onboard_module_is_projection_free 逐个读取 onboard/*.rs,出现 tauri::、db::pool(、#[tauri::command] 即失败(模式拼接书写,测试自身不命中);当前 mod.rs 与 clients.rs 通过。ProcessRunner、ClientLocator 尚未引入(P4d 引入时同受此约束);三端适配器实现暂在 mcp_inject(需其私有辅助函数),按绞杀者模式在 P8d 起逐步迁入。"
- complexity: S
- depends: agent-client-parity P8b
- acceptance: "agent_verify: [cargo test] onboard_module_is_projection_free——src-tauri/src/onboard/ 下的源码不含 tauri::、db::pool(、#[tauri::command];连接、CredentialStore、ProcessRunner、ClientLocator 都由调用方注入,结果一律是 serde 结构体。"
- 说明:由 P8b 承载实现,P8b ✅ 时本卡同步 ✅。存量代码不扩散旧写法,旧入口按绞杀者模式逐步改成薄包装;A1-ready 由测试机器校验,而不是靠约定。
### 📋 A1b — CLI 薄客户端(按需)
- status: todo
- complexity: M
- acceptance: "agent_verify: [CLI] 由真实需求定义;探针场景已由 agent-client-parity P4e 的 pnpm probe:clients(调用全局 MCP 的薄脚本,不新增协议面)覆盖。"
- 触发:「会话启动时 MCP 没连上、需要第二通道」被证明是常态时,再做 Rust console 版 lianjing.exe 与 skill 降级说明(需升接入包版本、全部子项目重新分发)。
### 📋 A1c — core crate 拆分(触发式,届时先 /architect)
- status: todo
- complexity: L(先 /architect 再拆)
- acceptance: "agent_verify: [cargo test] 业务逻辑位于不依赖 Tauri 的 core crate;具体验收在触发后的 /architect 设计中定义。"
- 触发条件(满足任一即启动):① 需要在没有 Tauri/WebView 的环境(例如 Linux CI)里跑本体;② 确实需要离线写入,并且跨进程锁和包上下文检测已经具备;③ cargo test 的编译时延成为主要的反馈延迟;④ 出现第三个独立的消费者。
### 📋 A2 — 前后端类型契约自动生成
- status: todo
- complexity: M
- files: src-tauri/src/commands/、src/lib/commands.ts
- acceptance: "agent_verify: [pnpm typecheck] commands.ts 的参数与返回类型由 Rust 定义生成(tauri-specta 或 ts-rs),新增 command 不再手抄类型;删改 Rust 字段时 typecheck 报出所有受影响处。"
- 为什么:现由规则 R01 要求手动同步 commands.ts,易漏;对应四支柱「可推理」。
### 📋 A3 — 配置文本生成模板化
- status: todo
- complexity: M
- files: src-tauri/src/mcp_inject.rs、src-tauri/resources/
- acceptance: "agent_verify: [cargo test] Codex 托管块、DSH 托管块、shim 等由模板(如 minijinja)渲染,并有「渲染结果是合法 YAML/TOML/JSON」测试。"
- 为什么:2026-10-01 实现 P1 时在 Rust 中手拼 YAML/JS,出现缩进被字符串续行吞掉、转义少一个反斜杠两个缺陷(均被测试拦下)。模板能从写法上避免这类问题。
### 📋 A4 — MCP 协议改用官方 Rust SDK(rmcp)
- status: todo
- complexity: M
- files: src-tauri/src/mcp_server.rs、src-tauri/src/mcp_tools.rs
- acceptance: "agent_verify: [cargo test + 三端无头探针] 换用 rmcp 后 scoped 路由、敏感读取认证、SSE 与 streamable HTTP 行为不变,三端 A–F 矩阵不回退。"
- 为什么:现为手写 JSON-RPC + SSE。各客户端对 MCP 的支持持续演进(streamable HTTP、认证、服务器说明等),自维护协议细节的成本会上升。
### 附:调用外部进程的 Tauri command 统一 async
- 同步 Tauri command 跑在主线程,内部调用 claude CLI 等外部进程会卡界面;agent-client-parity 审查已两次发现此类问题。新增此类 command 默认 async,存量随相关改动迁移,不单独立卡。