git:20260814.57453a3 to git:20260815.3a6942a

17 added, 12 removed. Audit A to A.

# Team: Coding Agent
> 本包是 Coding Agent 的产品组合层。所有修改必须同时服从仓库根 `AGENTS.md`;本文件只补充本包的架构与长期演进约束。
## 架构定位
- `@vetta/coding-agent` 上接 CLI、Desktop、IM 和 SDK 等宿主,下接 AI、Agent Core 与各 Runtime 能力域。它负责把稳定合同和独立能力组合成 Coding Agent 产品,但不拥有这些能力的通用底层实现。
+ `@vetta/coding-agent` 定义 Coding Agent 产品:它下接 AI、Agent Core 与各 Runtime 能力域,向平台
+ Runtime 和应用提供产品 Feature、策略、默认配置和稳定产品 API 映射。它不是通用 Runtime Host,也
+ 不是最终平台 Composition Root。
本包拥有:
- - 产品级 Runtime Composition Root 与默认 Profile。
- - Session 创建、恢复、切换、提交、回滚和释放的产品编排。
- - Prompt、Skill、MCP、Plugin、Memory、Compaction 和工作状态的产品策略与能力装配。
- - Runtime 事件、Port 与宿主服务之间的产品适配。
- - SDK、RPC、历史会话等稳定产品入口。
+ - 默认 Profile、Prompt、Mode 与产品 Feature 集合。
+ - Todo、Memory、Knowledge、Skill、Plugin、IM、Compaction 和上下文的产品规则与策略。
+ - 产品 Feature 与 Session Extension 定义,以及产品事件和稳定产品 API 的语义映射。
+ - Coding Agent 历史数据格式的显式读取与迁移边界。
本包不拥有:
- 模型 Provider 协议与流式实现,属于 `@vetta/ai`。
- Agent Kernel、Turn Pipeline 和通用 Port,属于 `@vetta/runtime-core` / `@vetta/agent-core`。
+ - Session 创建、恢复、切换、Queue、Snapshot、生命周期事务和通用事件路由,属于 `@vetta/runtime-core`。
- Coding Tool 协议与纯逻辑属于 `@vetta/runtime-tools`;Node Tool 实现属于 `@vetta/runtime-node`。
- Conversation Repository 端口属于 `@vetta/runtime-storage`;Node 文件/内存实现属于 `@vetta/runtime-node`。
- MCP 协议与通用生命周期属于 `@vetta/runtime-mcp`;Node transport、文件和 OAuth 实现属于 `@vetta/runtime-node`。
- 通用知识库、Subagent 和观测实现,属于对应 `@vetta/runtime-*` 包。
- CLI、Desktop 或 IM 自身的进程入口、UI 和传输协议。
+ - Node/Desktop 环境实现和最终平台 Composition Root,属于现有平台 Runtime 或应用宿主。
## 依赖方向
- Apps 只能依赖本包在 `package.json#exports` 中声明的公开入口,不得深度导入 `src/`。
- 本包可以依赖 `@vetta/runtime-*`、`@vetta/ai` 和 `@vetta/agent-core`;Kernel、协议包和 `runtime-node` 不得反向依赖本包,平台 Composition Root(例如 `runtime-desktop`)可以组合本包。
- - 当前本包是 Node 产品组合,可以选择 `@vetta/runtime-node` 默认实现;非 Node 产品必须在独立 Composition Root 注入对应平台实现,不得让协议包兼容 Node I/O。
+ - 产品 Feature 不得选择 `@vetta/runtime-node` 默认实现;具体实现只允许在现有平台 Composition Root
+ 中选择。迁移期间保留的 Node 接线必须登记并按纵向切片移除。
- `runtime-contracts/`、`composition/contracts/` 和其他合同文件不得依赖 Composition、Host、Adapter 或 Public API 实现。
- 产品能力域不得依赖 `composition/` 实现、`adapters/` 或 Public API facade。
- Adapter 可以依赖稳定合同,但不得反向控制 Composition,也不得复制 Runtime 域实现。
- `src/core/`、`src/compat/` 和旧执行入口属于退役架构,不得恢复。
- 历史格式兼容只能位于 `sessions/legacy/` 等明确的数据边界,不得成为活动 Agent 执行路径。
## 关键目录
- - `src/composition/`:产品 Composition Root、Session 装配和生命周期事务。
+ - `src/composition/`:产品定义和默认 Feature/策略集合;通用 Session 装配与生命周期应迁入 Runtime。
- `src/composition/contracts/`、`src/runtime-contracts/`:稳定产品合同与依赖倒置边界。
- `src/sessions/`:会话产品语义、投影、迁移和历史格式隔离。
+ - `src/features/`:Todo 等完整产品能力,按领域共同放置状态、Tool、Extension 和产品策略。
- `src/extensions/`、`src/plugins/`、`src/resources/`:扩展、Plugin、Skill 和 Prompt 的产品域。
- - `src/model-context/`、`src/compaction/`、`src/memory/`、`src/work-state/`:产品级上下文与工作状态策略。
+ - `src/model-context/`、`src/compaction/`、`src/memory/`:待按产品能力或策略继续收敛的现有领域。
- `src/mcp/`:Coding Agent 的 MCP 路径、OAuth 和宿主组合;通用 MCP 实现仍属于 `runtime-mcp`。
- - `src/adapters/`、`src/host/`:Runtime Port 的产品适配和有副作用的宿主实现。
+ - `src/adapters/`、`src/host/`:迁移中的混合区域;只允许保留产品语义映射,通用机制和环境实现应迁出。
- `src/public-api/`:稳定公开入口;入口文件只导出,不承载业务实现。
## 编码前必须分析
非平凡修改不得直接开始写实现。先完成以下分析,并在工作计划或实施说明中给出结论:
1. **目标与不变量**:明确要改变的行为、必须保持的旧功能、错误/取消/并发/释放语义,以及可验证的完成标准。
2. **职责所有者**:确认代码应属于 Coding Agent 产品策略、Runtime 通用能力、Host Adapter 还是具体 App;位置不对时先调整设计,不在错误层级补丁式实现。
3. **变化点**:识别真正可能变化的维度,例如 Provider、存储、策略算法、宿主环境或动态能力,而不是假设所有代码未来都会替换。
4. **候选方案**:至少比较当前直接方案与一个合理替代方案,说明依赖方向、复杂度、兼容风险和测试成本;优先选择能满足当前需求的最简单方案。
5. **抽象与模式**:说明是否需要设计模式。使用时写清它解决的变化点;不使用时保持直接、局部和可读的实现。
6. **验证策略**:在编码前确定单元、合同、差分或宿主测试分别验证什么,行为修改必须先有可运行的失败场景或明确基线。
若需求存在多个会显著改变合同或用户行为的解释,应先向用户说明,不得静默选择。若只是局部、无分支、无外部边界的简单修改,可以简化上述记录,但仍须确认职责位置和验证方式。
## 设计原则
### 面向长期迭代
- 围绕稳定职责组织模块,不围绕一次需求、页面或临时调用者组织代码。
- 稳定合同与易变实现分离;业务语义通过领域类型表达,不使用通用 `Record`、字符串约定或共享 metadata 隐藏依赖。
- 组合优于继承。具体实现只在 Composition Root 选择,领域代码依赖窄 Port。
- 动态 Tool、MCP、Skill、Plugin、Prompt 与模型策略在 Turn admission 绑定同一个不可变 generation;普通外部更新只对后续 Turn 可见,不得在同一 Turn 的模型调用、工具执行或 Hook dispatch 中读取新的 current revision。
- Model Call 仍可观察本 Turn 自己产生的消息、工具结果、Todo、usage 与 deferred activation;不要把该 Turn-local state 误当成外部 generation,也不要把 snapshot 固定到整个 Session。
- ConversationDocument 和持久化事件是 canonical 事实;上下文裁剪、图片预算和 microcompact 应优先实现为模型调用视图的纯投影。
- 公共合同按兼容方式演进;需要破坏性变化时,使用显式版本和迁移器,不以双执行路径或永久 Adapter 掩盖迁移。
- 一次架构修改只解决一个清晰问题。不要顺带重写无关模块或改变用户可观察功能。
### 可维护性与易读性
- 一个文件只承担一个可描述的职责;入口文件保持薄,只做注册、导出和装配。
- 当文件要求读者同时理解多个独立状态、协议或副作用时,按职责拆分,而不是仅按代码行数机械拆分。
- 使用能表达领域含义的文件和类型名称,避免新的 `Manager`、`Service`、`Helper`、`Utils` 或 `Common` 大杂烩。
- 控制函数和构造参数规模。配置项属于哪个对象就由哪个对象拥有,不把所有依赖汇总成不断增长的 Options 对象。
- 副作用集中在 Adapter/Host 边界;选择、校验、状态转换和投影逻辑尽量保持纯函数并独立测试。
- 错误使用稳定类型或判别联合表达;不要依赖解析自然语言错误文本决定控制流。
- 不通过注释解释混乱结构。先改善命名、职责和控制流,只为非显然约束保留简短注释。
## 设计模式使用准则
设计模式是解决已识别结构问题的工具,不是代码质量指标。只有当模式能减少耦合、明确所有权或稳定真实变化点时才使用。
适合本架构的常见模式:
- **Strategy**:Compaction、上下文裁剪、重试、Tool Result 投影等存在可替换产品策略时使用。
- **Ports and Adapters / Adapter**:隔离文件系统、进程、网络、模型、存储、MCP SDK、Legacy 格式和宿主 API。
- **Composition Root / Factory**:集中选择具体实现、组装依赖和定义资源所有权;Factory 不得隐藏全局状态。
- **State Machine**:Session、Turn、取消、切换、关闭和资源生命周期存在合法状态迁移时使用。
- **Typed Pipeline**:固定的 Turn 阶段需要有序编排时使用;不要开放可任意修改共享上下文的万能 Middleware。
- **Repository**:会话持久化需要原子追加、版本、分支和恢复等领域语义时使用,不退化为通用键值存储。
- **Registry/Catalog**:动态能力需要注册、撤销、revision 和在途执行仲裁时使用;读取面与修改面应分离。
- **Decorator**:在不改变 Tool/Port 核心实现的前提下增加 Hook、观测、权限或结果策略时使用。
- **Observer**:观察已发生事件且失败不得影响主流程时使用;Observer 不得修改 Turn 结果。
- **Anti-Corruption Layer**:适配旧格式或第三方协议时使用,转换结果必须进入当前稳定领域合同。
以下情况通常不要引入模式或接口:
- 只有一个实现、没有外部边界且测试不需要替换的局部逻辑。
- 简单计算、规范化、排序或状态转换可以由命名清晰的纯函数完成。
- 只是为了减少几行重复,或为了“以后可能需要”而增加 Factory、Builder、事件总线或插件系统。
- 用抽象隐藏尚未理解的业务差异,或让调用者依赖大量可选参数和运行时约定。
新增抽象后必须能够回答:它稳定了哪个合同、隔离了哪个变化点、删除它会造成什么真实耦合。无法回答时,使用更直接的实现。
## 执行与动态能力约束
- Turn 使用固定阶段的 Typed Pipeline;Tool Loop 是 Execution 阶段内的循环,不得伪装成一次性线性 Stage。
- 不引入公开的 `next()` Middleware 让任意 Feature 修改 messages、tools、instructions 或终止结果。
- 新上下文来源使用 Context Provider;模型调用级动态能力使用 Contribution Provider;上下文预算使用 Context Strategy;权限使用 Tool Policy;非关键后处理使用 Observer。
- Feature 不得持有可变 Session 内部对象,不得通过共享对象互相通信,不得静默覆盖同名 Tool 或资源。
- 注册、移除或替换动态能力默认从下一 Turn 可见;普通 retirement 允许持有旧 generation lease 的在途调用完成,只有携带 reason 与审计信息的 hard revoke 可以在安全检查点立即拒绝或取消。
- 失败、取消和关闭必须沿 `AbortSignal` 与生命周期合同传播;资源创建与释放必须成对并可在部分初始化失败时回滚。
## 功能兼容与数据边界
- 当前工作是架构演进,不是功能重写。Tool Schema、描述、结果、错误、副作用、路径语义和事件顺序必须保持,除非用户明确批准行为变化。
- 不得通过删除功能、降低校验、吞掉错误或回退旧执行路径修复架构问题。
- 旧实现只能作为行为 Oracle 或显式数据迁移输入,不能被新生产代码调用。
- 来自模型、磁盘、网络、MCP、Plugin、Extension 或 RPC 的数据必须在首次进入领域边界时运行时校验。
- Tool 参数和需要发送给 Provider 的 JSON Schema 使用 TypeBox;复杂外部配置在确有 preprocess/transform 需求或既有约定时使用 Zod;已经校验的内部对象只使用 TypeScript 合同,不重复维护两套 Schema。
- Schema 只验证结构,Session 身份、事件顺序、版本和权限等领域不变量由明确代码验证。
## 测试要求
- 行为修改必须随代码提供测试;架构重构必须通过现有行为测试或差分测试证明功能未变。
- 纯策略、选择、校验和状态转换优先使用表驱动单元测试。
- Port、协议、Schema、公开 API、持久化事件和 Tool 输入输出使用合同测试。
- Session、Composition 和生命周期修改至少覆盖成功、失败、中止、部分初始化回滚和最终释放。
- 动态能力修改至少覆盖新增、删除、替换、未变化、在途执行和下一模型调用可见性。
- 跨 CLI、Desktop、IM 的真实环境行为使用现有 Agent Host 验证入口,不新增临时执行路径或硬编码超时绕过问题。
- 测试断言可观察合同,不锁定私有类、文件布局、偶然调用顺序或实现细节。
从仓库根目录执行:
```bash
bun run check:quick
- bunx vitest --run <相关测试文件>
+ bun scripts/quality/run-vitest.mjs --run <相关测试文件>
bun run check
```
`bun run check` 不运行测试;定向测试和完整质量门禁都必须单独执行。文档或注释修改无需为了形式新增测试,但必须运行适当的格式和链接检查。
## 完成前审查
提交结果前逐项确认:
- 代码是否位于正确所有者,依赖方向是否单向。
- 是否存在更简单且同样满足需求的实现。
- 使用的抽象或设计模式是否对应真实变化点,而非形式化包装。
- 是否引入重复事实源、隐藏全局状态、万能 Options 或新的大文件职责混合。
- 是否保持原有功能、动态能力语义和数据兼容性。
- 测试是否覆盖本次决策和失败路径,而不只是覆盖代码行。
- `bun run check:quick`、相关测试和代码变更后的 `bun run check` 是否全部通过。
- 固定重写目标见 [`REWRITE-CHARTER.md`](../../docs/agent/coding-agent/05-greenfield-rewrite/08-implementation-log/REWRITE-CHARTER.md)。架构守卫以 `scripts/quality/check-coding-agent-architecture.mjs` 和包边界守卫为准。
+ 固定重写目标见 [`REWRITE-CHARTER.md`](../../docs/agent/coding-agent/05-greenfield-rewrite/08-implementation-log/REWRITE-CHARTER.md),三层所有权以 ADR-0077 为准。架构守卫以 `scripts/quality/check-coding-agent-architecture.mjs` 和包边界守卫为准。