etaf/AGENTS.md

161 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ETAF 开发约束
本文件适用于 ETAF 及其联调范围内的 `etaf-ui`、`ebox`、`tp`、
`etaf-sqlite`、`etaf-playground`。实现与性能优化必须从最终产品目标倒推,
不得用局部完成、容易通过的替代目标缩小原始范围。
## 项目自动化入口
- GUI 与性能自动化先查 `scripts/README.md`、`scripts/emacs-gui-verifier.el`
及既有 Makefile 入口;公共机制归 `scripts/`,具体业务场景归示例仓库。
- 现有 Emacs 的截图与录像默认保留用户当前应用焦点,使用已登记的窗口捕获
入口;后台视觉证据须检查内容更新,后台耗时与前台输入到显示延迟分别报告。
- 交互回调测量使用 `etaf-gui-verifier-measure-action`,按 scripts/README.md
固定场景、计时边界与前后台条件;保留全部样本,阶段记录按 observer runtime ID
隔离,不能用可复用的 buffer 名隔离。该入口不证明 compositor 已呈现。
- 连续 resize 使用 `scripts/benchmark-ebox-resize.el`
`ebox-resize-benchmark-start`,适用于现有 ETAF 或独立 Ebox buffer。
按 README 选择范围、轮数和新证据文件;先验证前台与已加载版本,保留全部样本,
检查 `:valid``:within-limit`,同时比较内容规模,不能只比较 p95。
- 遇到重复的渲染、交互、resize 或验证需求,优先扩展已登记入口。稳定的通用
操作应主动固化为带参数、验证和说明的仓库工具,随后更新工具索引及本节路由。
- `.omx/` 中的临时诊断是历史调查材料,不是日常运行入口。不要从中复制新的
示例专用脚本,也不要把项目逻辑放进通用 Emacs 技能。
## 最终目标驱动
开始工作前先明确最终可观察结果、硬性指标、不可牺牲的功能、权威验证方式
和停止条件。架构、算法、缓存、预编译与局部优化都只是达到目标的手段,不能
反过来成为交付物本身。
ETAF 当前性能工作的最终结果是:通用性能工具能解释每次操作跨包各阶段的
耗时;固定真实场景在功能、文本属性、身份、生命周期和回滚语义不缩水的前提
p95 与 max 都不超过 50ms。
## 架构与抽象准则
- 先从复杂现象中识别最小、稳定、可命名的领域模型及其不变量,再写代码;
不把偶然的调用顺序、示例名称或当前数据形状伪装成抽象。
- 一个模块只拥有一项完整职责,并为这项职责提供少量、精确、正交的接口。
接口之间通过明确数据契约组合,不读取彼此的内部状态,不复制彼此的规则。
- 用户心智成本是公共 API 的硬指标。同一能力只能有一个规范名称和一条推荐路径;
内部算法、后端节点、兼容别名和便捷 wrapper 不得伪装成并列公共概念。常用路径
只要求学习最小模型,高级能力通过逐层展开获得,不能让用户先理解包内部实现。
- 区分语义身份、视觉槽位、布局坐标、绘制层和发布权限。只有模型本身允许时
才能合并概念;不能为了减少代码把不同生命周期的身份混在一起。
- 复杂系统通过小模块的组合与复用逐步形成。新增能力应优先扩展已有模型的
输入域或组合方式,不平行创建第二套状态、第二条渲染链或只服务一个例子的
特殊协议。
- 架构必须满足性能可组合性。每层只处理变化集合,成本应为 `O(changed)` 或有
明确上界的小常数;模块增加时,总成本应接近各层小常数之和,不能因每层都
重新扫描 `O(all)` 而相乘。
- 上一层输出的稳定身份、坐标、依赖、布局证书和绘制贡献就是下一层的输入。
下游不得丢弃这些中间产物后重新推导;一次事务中的同一全量遍历最多发生
一次,多个模块应组合在同一遍历或直接消费保留状态。
- 数据只 materialize 一次。跨层优先传递不可变中间产物、稳定句柄或精确操作
批次;重复建树、重复复制文本、重复合并属性和重复证明都必须有独立收益证据。
- 每个模块都要有独立性能预算和基准。模块单独合格但组合后超标,说明接口
泄漏了重复工作,必须修正边界,不能把额外耗时解释为“架构层数的正常代价”。
- 每条快速路径都必须是普通正确路径的严格子集:入口条件可判定、保留状态可
验证、失败可精确回退、提交与回滚仍由原有权限边界控制。
- 代码量不是进度。没有清晰模型、独立测试和真实收益的辅助层、兼容分支、
预留接口、重复证明与缓存都属于 slop应删除而不是继续包装。
## 纵向最小可运行版本
面对架构级任务,先选择一个真实、代表性强、可以端到端运行的最小切片。这个
切片必须同时经过“输入 → 核心机制 → 运行时消费 → 用户可见结果 → 验证”,
不能只交付数据结构、接口空壳、设计文档或与真实应用脱节的玩具示例。
例如 App 预编译应先打通一个真实 View编译阶段产生中间 blueprint运行时
只填动态洞,不支持的语法精确回退,真实应用实际使用该产物。只有这个闭环
可运行、结果等价且确有性能收益,才扩展语法和覆盖面。
## 最小验证循环
每个实现假设都采用下面的短循环:
1. 写出本次最小假设以及它应改善的一个可测指标。
2. 只实现证明该假设所需的最小代码,不提前铺设后续层次。
3. 立即运行最小但有判定力的验证:可运行、结果等价、目标指标改善。
4. 验证通过才保留并扩展;失败则先定位原因,无法证明价值的实验立即完整撤掉。
5. 每次只扩大一个维度,例如一种语法、一个组件或一个缓存层,然后重复验证。
最小验证不能偷换最终目标。微基准只能证明局部机制;真实跨包场景和完整门禁
仍是最终证据。
## 可验证的小赌注与反馈控制环
不要把一次无法控制、无法快速证伪的“大赌注”当作工程推进方式。任何跨包、
跨阶段或“国民级应用”尺度的大 gap都必须拆成一组彼此有清晰因果关系、能够
独立验证和独立回退的小 gap。每个小 gap 只承载一个主要假设,并在扩大范围前
得到新鲜证据。
这不是三条孤立技巧,而是一条完整的反馈控制环:
- **拆解**缩短因果距离:一次只改变一个可命名机制,使失败能直接指向假设,
不让多个变量同时变化后再靠猜测定位;
- **验证**限制错误传播定向测试、静态编译、CI、事务回滚和真实 GUI 门禁必须
放在对应边界上,不能等到最终集成时才第一次发现问题;
- **迭代**提高反馈频率:小步实现、立即运行最小有判定力的检查,通过后才扩大
一个维度,并在完整子目标证明后及时提交 Git 基线。
工程目标不是假装“零错误”,而是让错误出现得早、扩散得不远、定位有证据、
回退代价低。一个实验若不能快速回答“假设是否成立”,就说明切片仍然过大;
一个门禁若失败后不能指出责任边界,就说明验证粒度仍然过粗。不得用继续堆代码、
增加兼容分支或推迟集成来掩盖反馈环已经失效。
凡目标涉及用户可观察的 Emacs 界面、文本属性、交互或性能,只有在目标版本的
真实 GUI Emacs 中实际渲染并执行对应操作所得的视觉结果、动态过程和耗时数据,
才称为反馈。batch ERT、静态编译、CI、mock、结构检查和微基准只是进入 GUI 前的
预检或定位工具,不能替代 GUI 反馈,也不能据此宣称功能正确、视觉合格或性能收敛。
GUI 反馈失败时,以 GUI 为当前事实,回到最小假设重新定位;不得用逻辑测试绿色
反驳用户实测。
## 控制变更规模
- 避免一次编写大段跨层代码后才首次运行测试。
- 优先提交或保留小而完整的纵向切片;每个切片都应可独立解释、回退和验证。
- 新抽象必须服务于当前已验证的下一步,不为尚未证明的未来需求预建框架。
- 不因已有方案投入较多就继续扩建;数据否定假设时及时收缩或删除。
- 同一轮不要同时改变编译协议、Runtime 语义、Ebox 发布算法和 TP 权限边界,
除非最小闭环确实无法拆分,并且有逐层验证点。
## Git 基线与完成提交
- 每个完整目标在新鲜验证通过后、开始下一个目标前,必须提交所有受影响仓库,
让已证明正确的状态成为可比较、可回退的基线;工作树中“已经完成但未提交”
不算真正收敛。
- 提交只包含当前已经完成并验证通过的目标。下一目标的失败测试、实验代码、
临时诊断和未验证实现必须与基线提交分离,不能为了清空工作树混进同一提交。
- 多仓库目标按依赖顺序分别提交,每个仓库使用与其实际改动相符的 message
不用 `update`、`changes`、`work` 一类无法说明结果的含糊描述。
- commit message 应以可观察结果或稳定的架构能力为中心,例如
`perf: retain native frame updates across ETAF commits`,而不是罗列实现步骤。
- 提交前至少运行该目标约定的定向测试、静态检查和最终门禁;验证失败时继续修复,
不得通过提交把失败状态包装成完成。
- 完成汇报列出各仓库 commit hash、验证证据和仍未提交的下一目标改动确保后续
性能对比能够明确指出基准版本。
## 性能优化纪律
- 先用通用记录面板确认真实热区,再选择架构或算法改动。
- 一次优化只绑定一个主要瓶颈和一个预期收益,记录优化前后的相同口径数据。
- 根因确认后按全局 Root-cause follow-through 规则检查同类路径;在当前证据记录中
列出各路径的触发场景、正确性边界、实测影响与修复状态,不能用候选清单代替闭环。
- 不用示例名称或业务概念污染通用工具、编译器和底层包协议。
- 不以关闭校验、减少功能、弱化文本属性、破坏身份或回滚语义换取数字。
- 缓存和预编译提示不能自行授权快速路径;运行时仍负责验证和精确回退。
- 如果最小切片没有改善真实目标场景,不继续实现持久化、原生后端或更复杂缓存。
## 每轮汇报格式
进度更新应明确说明:最终目标、当前最小切片、已经验证的证据、未通过的指标、
下一次只准备验证的一个假设。不得把普通字节编译、局部优化或设计计划描述成
尚未实现的 App 预编译能力。
## 完成条件
只有当前工作树中的真实实现和新鲜验证同时证明最终要求,任务才算完成。计划、
部分测试、单个微基准、一次偶然的低耗时或“没有发现错误”都不是完成证据。