架构演进主线
同步引擎、单驾驶员、门禁、文档极简等关键阶段。
Claude Chat Mobile 今天的系统形态来自长期的渐进式决策与真实痛点驱动,每一条主线都伴随着对假设的推翻与对不变量的坚守。
核心演进历程与分期
第一阶段
桥接层打通(2026-06)
放弃自造 LLM 编排器,通过 Agent SDK 建立双向流,确立终端等价性立场。
第二阶段
双通道与单驾驶员(2026-07)
确立「单驾驶员模型」,引入磁盘轮询镜像引擎与读写互斥锁,彻底杜绝数据分叉。
第三阶段
测试安全重构与沙箱防线(2026-08)
经历变异测试误伤数据的教训,确立容器隔离 HOME、宿主机命令白名单与 S0–S7 执行槽分层。
第四阶段
配置与网络拓扑重构(2026-08 末 ~ 2026-09)
从松散 .env 升级为结构化 ccm.config.json;确立 ACCESS_PROFILE 三候选拓扑,支持无 Cloudflare 部署。
第五阶段
SDK 升级与活体感知深化(2026-09)
升至 SDK 0.3.263,接入 applyFlagSettings 运行时调参;完善终端等待态感知与 tail attribution 归因。
近期重大关键决策与事故教训
| 事件与时间 | 表象与问题根因 | 形成的防线与架构决策 |
|---|---|---|
| 8/2 删库事故与沙箱防线 | mutate 测试在改坏源码时把路径函数算成空串,误打在宿主机真实 ~/.claude/projects 上造成数据清除。 | 宿主机仅跑白名单命令(guard-host-tests.js);所有可能造成破坏的测试一律在容器中跑(容器内 HOME 为一次性沙箱)。 |
| 8/14 插件化提案被否决 | 曾提案将系统扩展插件化、允许动态加载外部模块。 | 坚决不做插件化。插件出仓库会导致 import 边界、双向事件契约与静态门禁彻底失明,扩展全走 CLI 原生 MCP/Skills。 |
| 8/26 计数失明与长轮次 | 模型输出数分钟无 token 刷新,被误判为卡死。 | 确立以 transcript 字节增长作为真实死活判据;避免基于静态超时武断终止活跃长工具执行。 |
| 9/1 拓扑重构与三候选落地 | 原网络判定过度与 Cloudflare 绑定,纯反代或局域网部署难以通过健康检查。 | 落地 ACCESS_PROFILE(cloudflare, reverse-proxy, lan),将非 Cloudflare 部署正式升为一等支持路径。 |
| 9/3 运行时 effort 动态切换 | 历史实现认为 SDK 无法动态改 effort,切档必须重启实例。 | 实证实测推翻旧假设:SDK 原生支持 applyFlagSettings({effortLevel}) 运行时生效,改掉低效的实例置换。 |
| 9/6-8 终端活体识别与归因修复 | 桌面端写活体条目但不写 status;Web 续接后误将已结束的 pending 归因于桌面端。 | 深化活体与终端等待态(terminalWaiting)感知;严格区分锁判定(宁可误锁)与列表展示(宁可少报)的相反判定方向。 |
组装根与代码演进约束
在历史重构中,曾考虑将组装根 app/src/server/app.js 完全拆散。但实测表明:镜像同步(Mirror)、历史追平(Catch-up)、实例调度与网络路由在业务上有极强的生命周期相关性。当前仓库要求:
- 新状态严格受限。前端新状态进
app/public/js/app/域模块;后端新状态进所属领域模块,不得再向app.js顶层堆积全局可变状态。 - 纯逻辑下沉 logic/。任何能够独立计算的状态判据必须写成
app/public/js/logic/中的纯函数,两侧共用,禁止副作用污染。 - 决策留痕于 Commit。项目明确不保留一次性提案文档;重大决策必须通过 Git Commit Message 的结构化 Trailer(
Constraint:,Rejected:,Tested:,Not-tested:)永久固化。