# Nova Agent 工程规则

本文件是所有人类开发者与 Coding Agent 的**强制入口**。开始任何修改前，必须先阅读本文件；涉及架构、状态、公共契约、兼容或跨模块改动时，还必须阅读 [`engineering-rules.md`](engineering-rules.md)。修改测试、测试基础设施或 Renderer/Electron 生命周期时，还必须阅读 [`tests/AGENTS.md`](tests/AGENTS.md)。

在系统与平台约束之下，规则优先级为：任务明确要求 > 本文件 > 适用的目录级规则与详细工程规则 > 全局默认规则 > 现有代码惯例。目录规则细化对应领域，不能隐式放宽架构、安全或授权边界；同一版本已完整读取的材料无需机械重读。现有代码不因存在已久而自动成为正确范例。

## 任务适用范围与完成

- 解释、检查、审查和诊断默认只读，以有证据的结论完成，不因发现问题自动修复；“检查并修复”等明确请求包含相应实施授权。
- 对已授权且范围明确的修改，自主完成必要调查、实施和适度验证，不把计划当作最终交付，也不逐步重复请求确认。只有缺少会实质影响结果且调查无法确定的信息，或下一步超出授权时才询问。
- 下文的 Owner、契约、并发和生命周期要求用于涉及这些概念的改动，不要求文档或局部静态修改虚构对应流程。开发检查清单按实际影响核对，不适用项可略过。
- 中文交流、模型与子代理角色偏好沿用有效的全局或任务要求；日常工作不因此强制使用多模型、子代理、独立计划文档或全量测试。
- 完成意味着约定范围已交付、适用验证已执行且结果如实报告；受阻时按停止条件处理，不擅自缩减需求，也不无限扩展到无关问题。

---

## 强制写作规范（必须遵守）

以下三条对所有 Agent **一律强制**，不得以「便于追踪」「方便以后看」为由放宽。

### 1. 严禁任务编号与过程痕迹

注释、commit message、PR 说明、代码文档中**严禁**出现：

- 任务编号、阶段号、PR 编号（如 `P0`/`P1`/`P4`、`Phase 6`、`#1853`）
- 临时方案名、验收项编号、内部工单号
- 「完成了某任务」「修复了某 Bug」「按某某计划」这类过程汇报

这些内容应留在 Git 历史之外的任务系统里；写进仓库会污染可读性。

### 2. Commit message：像软件更新说明

Commit 面向「读 changelog 的人」，写**优化了什么、改进了什么、重写了什么**，不要写成技术实现流水账。

**要求：**

- 标题：`type(scope): 一句话概括用户/产品侧变化`（conventional commits）
- 正文：若干短 bullet，每条说清一项可感知的变化
- 用产品语言：体验、观感、行为、能力；少提具体组件名、类名、文件名、API、CSS 选择器
- 不要列「改了哪个文件」「删了哪个函数」

**推荐写法：**

```text
feat(chat): 优化输入体验与代码块观感

- 输入框改用官方 Composer，去掉自研包壳
- 技能斜杠补全改走官方菜单
- 发送被拒时保留草稿，不被误清空
- 技能菜单限制宽度，长描述不再撑破边界
- 回到底部改为清晰的悬浮小箭头
- 代码块配色与羊皮纸主题统一，深浅色均可辨认
- 补充输入相关契约测试
```

**禁止写法（难读、过技术）：**

```text
feat(chat): 接入官方 Composer，并打磨技能菜单与代码块观感

- 输入框改用 Astryx ChatComposerInput，去掉自研 textarea 包壳
- slash 技能补全改为官方 trigger，删除旧 SkillAC 浮层
- Enter 仍由产品层控制，编排忙/拒发时保留草稿不被清空
- ...
```

后者堆砌实现名词，读起来像补丁说明，不像产品更新。

### 3. 注释要短：概括「做什么 / 用什么」，不要写说明书

- 默认少写注释；命名与结构能说清的，不要再写一段。
- 需要注释时：一两句概括职责、关键不变量、为何不能改成别的写法即可。
- **禁止**给每个函数写大段 AI 式说明、逐步复述代码、堆叠背景故事。
- 注释只解释长期成立的「为什么」（并发、安全、协议、边界）；不写修改历史、任务过程、阶段标签。

---

## 不可破坏的边界

1. **一项职责，一个 Owner**
   - 每个模块的核心职责必须能用一句话说明。
   - 每项可变状态必须只有一个写入 Owner；其他模块只能查询、订阅或请求 Owner 修改。
   - Facade、Coordinator、Service 和 Store 不得成为承接无关功能的万能容器。

2. **Agent kernel 保持纯粹**
   - Agent Loop 只负责「调用模型 → 执行工具 → 写回结果 → 判断继续或停止」的循环。
   - 权限、持久化、上下文压缩、协议适配、Skill、Workflow、产品路由、UI 与 Electron 生命周期必须由独立 Owner 管理。
   - kernel 不得直接依赖产品执行器、Renderer、Electron 或具体持久化实现。

3. **依赖只能朝允许方向流动**
   - `shared` 不依赖其他应用层；runtime 的 core/domain 只依赖 `shared`、同层公共契约和显式端口；`main` 负责装配 Electron、基础设施与 runtime；`preload` 只暴露类型化桥接；`renderer` 只依赖自身与 `shared`。
   - 禁止跨层反向 import、循环依赖、从 barrel 或相对路径绕过边界、直接访问其他模块内部文件。
   - 现有 import boundary 测试是最低门禁；不得用宽泛 allowlist 放行新债务。

4. **契约必须显式且唯一**
   - 跨模块命令、事件和数据使用唯一来源的类型化契约。
   - 禁止 `any`、松散 payload、复制相似类型、未校验的类型断言。
   - 外部输入先以 `unknown` 接收并在边界校验；transport DTO、领域状态、持久化模型和诊断信息不得混成一个无结构对象。

5. **目录表达领域和职责**
   - 实现按业务领域放入子目录；测试应镜像或紧邻对应领域，能够直接定位。
   - 禁止新增职责模糊的 `utils`、`helpers`、`common` 垃圾桶。
   - 新工具必须位于 `src/runtime/tools/<tool-name>/` 并由该目录的 `index.ts` 导出。
   - 不按行数机械拆文件；只有存在独立概念、独立契约或独立生命周期时才拆分。
   - 文档分层：用于技术说明与架构文档等给仓库读者看的就直接置于 `docs/`；本地的草稿、过程调研、任务规划文档等用于当前开发的一律置于 `docs/Local_Docs/`（不纳入 Git 追踪）。
   - 评估归档：性能、效果及方案对比等可用于面试讲述的量化评估，交付前必须按日期和主题归档至 [`docs/Local_Docs/评估报告/`](docs/Local_Docs/评估报告/)，记录问题、方案、版本与环境、样本与指标口径、基线/结果、复现方式及原始证据；保留负向结果和未验证边界，区分实测、推断与统计显著性，不含凭据。

6. **修改必须最小且完整**
   - 一次修改只处理一个主要目标。动手前明确目标、范围、非目标、不变量和验收方式；小改动可在任务中简述，不要求额外文档或等待批准。跨模块、迁移或高风险改动再补充必要的设计说明。
   - 在最早破坏约束的位置修根因；禁止在多个下游重复打补丁、创建平行状态或复制主路径。
   - 禁止让新旧两套主路径长期并存。兼容代码必须写明兼容对象、存在原因、删除条件和保护测试。
   - 不借局部任务大规模重构，不修改与目标无关的稳定行为。

7. **测试要保护风险，不追求数量**
   - 测试应保护用户行为、关键状态、容易回归的边界，以及事件顺序、终态唯一性、取消/失败清理、状态写入权限、协议兼容和依赖方向。
   - **不要默认给每个改动新增测试，也不强制机械执行 TDD。** 新测试必须能说明它在防止什么真实回归；优先扩展或复用现有测试。
   - 禁止重复 assertion、只断言非空、只断言 mock 被调用、过度 mock 状态 Owner、放宽断言或吞错来制造假绿。没有独立保护价值的测试应合并或删除。
   - 开发循环只运行受影响的最小测试集合；当前行为完成后运行相关回归。不得每编辑一行就机械跑全量测试；完整 suite、fault/stress 和打包门禁交给 CI / nightly / release。
   - Renderer 的卡死、跨会话污染、reload、重复 reload 后的 listener 重绑定、IPC 生命周期等真实用户体验问题，优先使用真实 Electron E2E 验证，不能用全 mock 的组件测试冒充完整链路。
   - 源码变更至少运行相关测试、`npm run typecheck` 和仓库已配置的 lint；build/架构门禁按改动风险执行。纯文档检查内容、链接/路径、格式和 diff。若所需门禁尚未配置或无法执行，必须明确报告，不能声称验证完成。
   - 已通过的适用检查不因收尾而重复运行；只有新修改、失败或未解决风险才增加验证。付费真实 API、外部副作用和发布操作仍须处于明确授权范围内。

8. **保护工作区与安全边界**
   - 不读取、输出或硬编码密钥和凭据。
   - 不覆盖、删除或回退无关改动；未经要求不 commit、push、rebase、reset、clean 或强制 checkout。
   - 不新增依赖、不改变公共 API、持久化格式、默认值或错误语义，除非目标明确要求且迁移与回退已设计。
   - 提交时由当前仓库配置的用户身份完成；不要附加与本仓库无关的 bot / co-author 信息。

9. **基于源码事实，严禁凭空盲写**
   - 描述或修改项目行为前，读取支撑该结论的源码、调用链、公共契约和相关测试；区分实现事实、设计目标和本轮实际验证结果。纯规则或文档任务读取相关规则与材料，不要求遍历业务源码。
   - 严禁凭借模糊印象或未经核验的记忆输出项目结论。局部任务从相关入口向外追踪，以能解释目标行为和受影响边界为止；用户明确要求完整模块盘点时，先列出该范围文件并逐项覆盖，才可声称完整。证据不足则继续定向调查或明确未覆盖范围。

---

## Coding Agent 停止条件

仅对当前目标或拟修改链路判断以下条件。先做授权范围内的只读定位、复现及必要验证准备；若仍无法消除阻碍，暂停依赖该决策的实现并报告事实、风险、可选方向和最小决策点，继续不受影响的已授权工作：

- 调查后仍无法确定相关状态的唯一 Owner，或多个写入者的收敛需要超出授权的改造；
- 相关公共契约互相冲突，且无法在已授权范围内依据权威来源收敛；
- 目标要求跨越禁止的依赖方向；
- 只能靠新增第二条主路径、长期兼容层或重复状态完成；
- 高风险重构无法用测试证明行为保持一致；
- 任务范围、数据安全、公开接口或不可逆操作存在关键歧义。

已有缺陷本身不是停止调查的理由。若任务已明确授权修复该缺陷，且可在上述边界内完成，就推进修复与验证。无关历史债务按需报告，不为消除全部债务而扩大任务，也不因此停止当前工作。检查失败时先区分本次回归、既有失败和环境阻塞，不用无依据的重试或兜底绕过。

---

## 开发检查清单

以下清单用于核对受影响的职责和门禁，不要求逐项输出、创建新文档或申请批准。

### 修改前

- [ ] 已阅读本文件；必要时已阅读详细工程规则；修改测试或 Electron/Renderer 生命周期时已阅读 `tests/AGENTS.md`。
- [ ] 已查看真实调用方、被调用方、公共类型、相邻实现和相关测试，严禁凭印象脑补。
- [ ] 已写明目标、范围、非目标、不变量和验收方式。
- [ ] 已确认职责 Owner、状态 Owner、依赖方向和兼容边界。
- [ ] 已检查工作区，确认不会覆盖无关改动。

### 修改中

- [ ] 变更位于最接近根因和正确 Owner 的位置。
- [ ] 未新增跨层 import、重复状态、松散契约、万能容器或垃圾桶目录。
- [ ] 未保留无删除条件的旧主路径或兼容分支。
- [ ] 测试没有因“代码有改动”而机械新增，也没有重复已有保护或把关键 Owner mock 掉。
- [ ] 注释克制：无任务编号、无过程痕迹、无函数说明书式长注释。

### 完成前

- [ ] 已识别本次风险；需要自动化保护的行为有有效测试，不值得维护的重复/表面测试没有继续堆积。
- [ ] 已按变更类型执行适用验证：源码的相关测试、typecheck、已配置 lint 及风险触发的架构/build；纯文档的内容、路径、格式和 diff。
- [ ] 已检查错误、取消、并发、恢复和清理路径。
- [ ] 已检查 diff、tracked/untracked 文件和生成物边界。
- [ ] 若需要 commit：message 像产品更新说明，无任务编号、无实现流水账。
- [ ] 未验证项、剩余风险和兼容删除条件已如实报告。
