Skip to content

Architecture Decisions

AceGuru-mjh edited this page Oct 1, 2026 · 4 revisions

架构决策记录(ADR 索引)

🏗️ 架构 · 🏠 首页 › Architecture-Decisions

Home Version Kotlin Modules Tools License

Architecture-Decisions

📑 本页目录

本项目用交付报告 + ADR 记录"为什么这样决定"。本页汇总跨任务的关键决策。 原文:docs/T76_ADR.md、docs/T81_ARCHITECTURE_ASSESSMENT.md、docs/T82_FINAL_REPORT.md、 docs/terminal/TERMUX_CAPABILITY_MATRIX.md §15。

1. T76:长任务运行时

# 决策 理由 / 否决项
D-1 文件式 JSON + 原子 rename 存储 checkpoint 频率远超 SharedPreferences 的 O(n) 模型;否决 SharedPreferences(非原子)、Room(第二数据库)、DataStore(收益有限)
D-2 TaskRuntime 作为叠加层(组合而非替换 AgentEngine 绑定) 审计修正:VM 有 15 处 (agentEngine as? ApexAgentEngine) cast,替换绑定会让全部 cast 静默失效;最终改经 AgentTaskStatusController 转发(3 处一行改动)
D-3 恢复触发 = ViewModel init 时确定性发现 可测、零后台依赖;不复活 platform:persistence 死代码;WorkManager expedited 恢复列为 v1.1 可选
D-4 taskId 一等公民 + v1 单活跃执行 存储 schema 不含单任务假设;不为 T76 先造第二套 Session 系统
附加 悬空 toolCall 合成 ToolResult(R-5) 否则重启后 OpenAI 兼容 API 返回 400,整条历史不可用

2. T81:终端执行基础设施 2.0

# 决策 内容
D-1 Native 并发 IO 方法改"锁内拷贝 shared_ptr → 锁外执行",mutex_ 只保护 map 结构 → 从全局串行变 per-session 串行
D-2 Job 终止语义 统一走 TimeoutController 三级(SIGTERM → grace → SIGKILL);信号目标从"整个 session 进程组"收窄为前台进程组(tcgetpgrp)+ shell 组,shell 优先保留;exitCode/signal 如实上报(不再编 130/0)
D-3 Job 完成检测 InputWaitingDetector 补齐真实 PS1 正则并与 PromptDetector 对齐;JobManager 合成退出仅在 native exit code 不可得时使用
D-4 事件系统收敛 TerminalEventLogImpl 加 per-session 上限(默认 500);SessionManagerImpl.close 调 eventLog.drop + eventBus.drop;bus subscribe 改"先建 live channel 再查历史"
D-5 持久化真原子 tmp 写 + fsync + rename(与 T76 同模式);RuntimeRecoveryService.recover 完整实现;恢复的 session 一律 EXITED/BROKEN,不伪造 RUNNING;isPidAlive 改 /proc/<pid> 存在性检查(不再 fork kill -0)
D-6 LinuxExecutionContext 统一构造点(rootfs + workspace + home + env + arch + proot + cwd)供所有 Linux 侧组件复用;env 基线单一来源
D-7 Capability 真接线 基于 ProotExecutor 的轻量真实探测(which X / X --version,带超时 + 缓存)→ 产出 EnvironmentSnapshot
附加 Shutdown 设计 TerminalRuntime.shutdown() 幂等(AtomicBoolean):停新请求 → cancel 全部 job → 停 pump → close session → scope.cancel → nativeCloseAll 兜底

处置原则(T81 §50-12)

三套"规格先行、实现未接线"的平行层(observation v2、process2、reliability/RecoveryCoordinator) 与两套仅测试引用的状态机一律不删除;接线优先于新写。

3. T82:Ubuntu 产品生命周期

# 决策 内容
1 状态派生而非复制 derivePhase(hasRootfs, rootfsState, bootstrapState) 纯函数(11 组合矩阵测试),底层单一事实源不动
2 函数端口而非接口 bootstrap / probe / repair 以 suspend (…) -> … 注入(T81 禁令:不建第二套类抽象)
3 超时 = IN_PROGRESS 与 install 工具同语义:断点续传 + stageEvidence 续跑,进度永不丢失
4 probe 失败不否定 READY 环境可用性与诊断快照分离
5 RECOVERING 是过程态 refreshState 一律派生事实终态,不残留
6 细粒度工具全保留 ensure 是聚合入口,不是替代

4. 死层判决(跨 T81/T82 一致)

判决 原则
死层(~5000 行 PR#55–#67 平行层)不接线、不删除 能力由生产路径实现(exit code → JobManager;fs → GuestFilesystem)
P60 api 层是唯一例外 以 TerminalSdk 适配器落地(文档已宣称冻结契约,不能让文档与现实割裂)
每命令 PID 身份 marker 携带 jobId(shell 级关联);/proc 级 PID 追踪仍属 process2 死层(已记录)
keep-alive / reattach 设计记录(TerminalSupervisorService 草案)不实现 —— 无法在本环境验证进程死亡矩阵,拒绝发布未验证的生命周期服务

5. 有意延迟(NOT silently skipped,7 项)

  1. 会话跨 App 死亡保活(需 supervisor service + 进程死亡矩阵);
  2. guest 内 sshd(暴露面,需安全评审);
  3. X11 / VNC GUI(独立产品面);
  4. 内置 rootfs(原为 APK 体积产品决策 —— T83 已落地);
  5. ARM32(无 Ubuntu armhf base 镜像);
  6. 鼠标上报(需先有 UI 手势层);
  7. 物理 Gradle 模块拆分(尚无第二消费方)。

6. 跨文档的"数字纠偏"

Important

以审计文为准,而不是 README:

  • 实际注册工具 ≈80 个(73 无条件 + 7 GitHub 条件;browser 15、terminal v2 16、terminal legacy 4、cs-mem 3)—— 既不是 README 的 35,也不是 ToolModule 注释的 53;
  • 行数门禁 main ≤1200 / test ≤1600;写 T76 时 ApexAgentEngine 已 1057 行、AgentChatViewModel 已 1123 行 → 几乎不能再往这两个文件加代码。

7. CI 盲区登记(跨文档反复出现)

盲区 现状
:core:llm-adapter:test(69 用例) 不在 CI
:app:test(37 用例) 不在 CI;app 模块无 androidTest
:app:compileDebugKotlin continue-on-error
gradle wrapper 仓库无 wrapper,CI 现场生成 8.10
lint CI 无 lintDebug 任务(审计建议补充)
括号平衡检查 按原始字符计数 → 产生 \x28 类绕行写法(见 流水线输出 UI)

8. 相关页面

footer

🏠 返回首页 · 📚 文档索引 · ❓ FAQ · 🔧 故障排查 · 🗺️ 路线图 · 🐛 提 Issue

Android Guru Agent · v1.4.4 · Kotlin 2.0.21 · Compose · PRoot · Room

Clone this wiki locally