回溯只移动指针
像 git checkout,不是 git reset --hard。回到 20 分钟前不该毁掉那 20 分钟。
架构
这一页写的每一条都能在代码里定位到文件和行号。 读完之后你应该能自己验证,或者推翻我们。
standard 是宪法层:纯 stdlib,外部依赖只有 github.com/google/uuid。这不是声称,是 go list -deps 能数出来的。
cmd / tui / web / desktop
│
▼
internal/app (组合根 · 唯一允许装配 provider)
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
agent/runtime wire/server wire/rpc
│ │ │
├──── model/capability ──── 只读能力聚合 │
│ │ │
│ context/ · session/ · store/ │
│ │ │
└──── tools/ · platform/ · a2a/ ────────────┘
│
▼
foundation/standard ← 纯 stdlib
▲
│
全部单向依赖,standard 不反向依赖任何业务模块测试遍历全仓非测试 .go 文件,并且断言必须命中 >0 个文件——否则直接失败,防止目录层级变化导致豁免规则静默失效。
arch_test.go:87除 cmd/、internal/app/、internal/model/ 外,任何文件不得 import openai / anthropic / bedrock / google / azure adapter 或官方 SDK
arch_test.go:119runtime / context / session / tools / memory / tui / config 不得 import pal/internal/model/*
arch_test.go:132extension/mcp、agent/memory、platform/sandbox 不得 import pal/internal/agent/runtime
arch_test.go:214gotreesitter 只有 platform/syntax/tsengine 能 import
arch_test.go:189agent/、tools/、wire/ 不得直接读 App.WorkspaceDir
Turn 可以跑数小时。每个 Cycle 重新冻结一次执行环境,整份 snapshot 序列化后作为 EventCycleStarted 落库——所以「当时用的是哪个模型、哪些工具」是可回溯的事实,不是猜测。
cycleEngine.Run
────────────────────────────────────────────────────────────
1 processSteering 消费排队的 steering
2 读 session projection progress / task / goal / scope / model
3 CreateCycleSnapshot ★ 冻结 provider·model·tools·skills
4 合并·排序·收窄 scope 应用 ExecutionPolicy 覆盖
5 compactAtSafePoint 压缩在建请求之前发生
6 BuildRequest system sections + 动态段 + tools
7 EventCycleStarted 落库 ★ 整份 snapshot 序列化后持久化
8 openProviderStream 重试阶梯
9 媒体超额 → 降级重试 上限 1 次
10 streams.Consume
11 usage·成本·校准·append ObserveUsage 回流校准 token 估算
12 ExecuteBatch 或全部拒绝
13 EventCycleCompleted 落库
14 ObserveCycle → Transition
15 pal.finalize ★ 强制 snapshot.Tools = nil每一条都是「选了 A 弃了 B」,附代码位置。
像 git checkout,不是 git reset --hard。回到 20 分钟前不该毁掉那 20 分钟。
代码注释直书 "exact text matching, no vectors"。内置打分维度 0 个,排序交给插件——不装 ranker 就返回空,不假装。
标准层是宪法。厂商 SDK 升 v4 时,runtime / session / context / memory / tui 一行不用改。
收尾时强制 Tools=nil——工具集被清空这件事本身也是审计记录。
MCP 是纯客户端。外部 server 返回的内容一律标注 untrusted,不因为它自称可信就降级。
正文只在模型自己发起 read 时才加载。技能多了不烧 token。
CI 故意排除 L6(真实付费 provider)和 L8(soak 时长测试),其余在 Linux / macOS / Windows 三个平台跑 gofmt + vet + build + -race。
| 层 | 内容 | CI |
|---|---|---|
| L0–L3 | Unit / Component / Wire / Runtime Integration | ● 跑 |
| L4 | Local E2E | ● 跑 |
| L5 | Failure / Crash 注入 | ● 跑 |
| L6 | Real Provider(付费网络) | ○ 排除 |
| L7 | Platform E2E | ● 跑 |
| L8 | Soak(墙钟) | ○ 排除 |
| L9 | Eval / Release | ● 跑 |
| L10 | UI E2E(拟人驱动 herdr / browser-use) | ○ 手动 |