Created
July 12, 2026 07:42
-
-
Save AGDholo/abea4fc6fdc3056c6faf4566a606f211 to your computer and use it in GitHub Desktop.
agd-bug-repro-fix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| name: agd-bug-repro-fix | |
| description: Yanlee 的真实缺陷复现、强制最小 demo 隔离、证据驱动根因定位、分阶段暂停汇报、真实代码修复和真实浏览器复测工作流。用于 TransferAI/Luni/app shell 中用户要求先复现、用 Codex 内置浏览器验证、做 demo 页面复现、只报告根因后再修、或处理登录态、权限、缓存、状态流、默认值、降级策略等跨层缺陷。 | |
| --- | |
| # AGD Bug Repro Fix | |
| ## 核心 | |
| 把用户报告当症状,不当结论。先复现,再用证据定位 owner 和事实源,最后只在真实代码里修根因。 | |
| 根因必须由真实证据支持:Codex 内置 `@浏览器` 的真实操作、页面可见状态、请求、日志、埋点、数据库或本地状态。读代码只能提出假设,不能单独当根因结论。 | |
| 禁止把“让症状暂时消失”当修好。延时、忽略下一次事件、拖拽后删 class、重复写状态、临时开关和调用点拦截都属于补丁信号;一旦出现,必须停止实现并重新检查职责、事件顺序和状态所有权。 | |
| ## 工作流 | |
| 1. 读规则和真实代码。 | |
| - 先读仓库 `AGENTS.md`、`agd-user-preferences`、相关子目录说明和本次涉及的 route、feature、component、hook、store、API。 | |
| - 需要浏览器时先用 Codex 内置 `@浏览器` 真实复现,不用其他浏览器通道或脚本浏览器替代。 | |
| - 需要第三方库当前行为时,先确认锁文件中的真实版本和本机安装源码,再按官方文档、官方源码、GitHub issue / discussion / PR、社区成熟实践的顺序取证。 | |
| - 对照官方实现时,不只比较函数名;必须比较 DOM 层级、事件触发时机、受控状态、portal、focus、owner 和清理责任。 | |
| 2. 复现真实问题。 | |
| - 用用户给的真实 URL、账号、操作顺序和可见页面状态复现。 | |
| - 记录页面可见状态、请求、日志、埋点、缓存、登录态和失败条件。 | |
| - 复现不了就说清差哪一步,别靠截图猜。 | |
| 3. 做最小 demo。 | |
| - demo 必须复用真实组件、hook、store、policy 或 API,不写一套假逻辑。 | |
| - UI / 视觉类 demo 不能看截图手写假页面、假遮挡、假 opacity、假 z-index、假 mask。必须复用真实组件、真实样式、真实 DOM 层级、真实 portal container、真实滚动/裁切/层叠关系。 | |
| - 浮层、菜单、popover、modal、tooltip、滚动 fade、mask、overflow、z-index、position、pseudo element 这类问题,demo 必须搬运真实 owner 的触发器和内容组件,并复刻真实 portal 宿主、兄弟顺序和 stacking context。只要菜单内容、尺寸、层级或遮挡形态和真实页面不同,就算 demo 失败。 | |
| - 有 `ref` 参与 portal container 时,demo 必须等 ref 挂载后再渲染触发器或让真实组件完成一次同等重渲染;ref 为空导致 portal fallback 到 body 的 demo 无效。 | |
| - demo 必须只暴露当前问题的最小状态切换和最少输入。 | |
| - 先让 demo 稳定复现失败。 | |
| - demo 复现完成后必须停下来汇报:复现步骤、证据、根因判断、怀疑的 owner、下一步 demo 修复计划。 | |
| - 等用户明确继续后,才修 demo。 | |
| - demo 修好后必须再次停下来汇报:改了哪里、为什么能证明根因、demo 复测结果、准备如何映射到真实代码。 | |
| - 等用户明确继续后,才把同一个根因修复落到真实代码。 | |
| - 真实代码修好后删除临时 demo 和路由,除非用户明确要保留。 | |
| 4. 把症状抽象成可迁移的根因。 | |
| - 先写一句通用根因假设,再用证据验证或推翻它。 | |
| - 优先看运行证据:真实浏览器状态、控制台错误、网络请求、服务端日志、客户端日志、埋点事件、存储和数据库状态。 | |
| - 读代码用于解释证据链,不要靠“看起来像”直接下结论。 | |
| - 按 `route -> page -> feature -> component -> hook/store -> shared policy/API` 追到最上游 owner。 | |
| - 改 owner 前,用 `rg` 查所有调用方和兄弟入口。 | |
| - 强制做主路径复用审计:找到同能力最成熟、已稳定运行的入口,对照状态 owner、控制面、请求字段、transport、错误/停止/成功终态和持久化边界。输出一张复用表,明确“直接复用”“共享层抽取”“允许分叉”;缺少这张表时不得给修复方案。 | |
| - 新入口与成熟入口只允许在用户意图、业务上下文、输出合同和展示层分叉。模型、推理、权限、计费、请求规范化、重试、错误转换和终态收口必须复用,不得各自维护。 | |
| - 优先修共享事实源;只有局部入口独有时,才在局部修。 | |
| - 写出参与方的契约表:谁接收原始事件、谁拥有状态、谁提交终态、谁负责清理。两个参与方不得同时拥有同一个事件或状态。 | |
| - 浏览器事件冲突必须记录真实事件顺序。例如 `mousedown -> dragstart -> drop -> dragend -> click` 中,不能在后置事件里修补前置事件已经写错的状态。 | |
| - 第一版修法若需要再加延时、事件屏蔽或额外布尔值才能通过,视为根因判断失败;撤回实验修法,回到官方契约和 owner 重新定位。 | |
| 5. 修真实代码。 | |
| - 从 owner 和职责边界根治:让每个库只管理自己的契约。例如拖拽库管理拖拽源和生命周期,菜单库只管理明确的菜单触发,不让两者争用同一个原始手势。 | |
| - 优先把缺陷入口接回成熟主路径的共享控制面和运行时契约;不要复制主路径代码,也不要靠后端默认值掩盖入口缺失字段。后端默认只做校验、归一化和安全兜底。 | |
| - 实现前再次核对复用表。若改动仍新增第二套 transport、模型/推理状态、错误监听或完成条件,说明方案未根治,停止实现并重新抽取共享层。 | |
| - 正式修法必须能解释为什么错误状态不再产生,而不是解释错误产生后如何被清掉。 | |
| - 优先恢复或适配官方结构,删除影子状态、双写、兼容分支和症状清理;不要为了缩小 diff 保留错误架构。 | |
| - 状态边界要显式建模:未知、未登录、无权限、已登录、有权限不能共用同一份派生数据。 | |
| - 权限和产品规则要有单一事实源:客户端只能展示、禁用或表达用户意图,不能自作主路径裁决。 | |
| - 默认值必须满足最低权限用户;高权限值只能由权限事实源显式放行。 | |
| - 降级必须保留语义:可降级才降级,不可用就切到允许的 fallback。 | |
| - 缓存只能加速事实源,不能在边界变化后继续当事实源。 | |
| - 产品常量写代码事实源,不为不变规则新增环境变量。 | |
| 6. 验证最小但真实。 | |
| - 先跑 demo 验证,再跑真实页面验证。 | |
| - 用 Codex 内置 `@浏览器` 看页面可见状态,不只看 URL。 | |
| - UI / 视觉类缺陷必须用真实浏览器截图确认“肉眼同款失败”,不能只用 DOM 结构、computed style 或代码推断宣称复现成功。 | |
| - 浮层/层叠类缺陷还要记录 `getBoundingClientRect`、ancestor chain、`position`、`overflow`、`z-index`、`mask-image`、pseudo element 样式和 `elementsFromPoint`;这些证据用于解释截图,不替代截图。 | |
| - 权限、状态机、共享 policy 要补定点测试;纯 UI 视觉不硬补测试。 | |
| - 路由变更跑路由生成;共享契约改动跑相关测试;不要默认全量 build。 | |
| - 测试失败若是无关旧问题,要给出具体文件、行号和错误。 | |
| 7. 汇报。 | |
| - 先说是否修好。 | |
| - 点名根因函数、证据来源和真实修复文件。 | |
| - 列出真实复现、demo 复现、demo 复测、真实复测和命令验证。 | |
| - 说明 demo 是否已删除、是否提交、是否推送。 | |
| ## 暂停点 | |
| 必须暂停两次: | |
| 1. demo 复现后暂停。只汇报证据和根因,不修 demo,等待用户继续。 | |
| 2. demo 修好后暂停。只汇报 demo 修复和证据,不修真实代码,等待用户继续。 | |
| 用户明确说继续、修 demo、修真实代码、完全落地,才进入下一阶段。 | |
| ## 例子 | |
| ### 认证缓存泄漏 | |
| 症状:退出登录后,页面或 sidebar 还显示上一个用户的数据。 | |
| 泛化根因:未授权状态仍消费授权缓存。 | |
| demo:复用真实 workspace hook,做一个登录态切换页;切到未登录时,旧项目仍显示即复现成功。 | |
| 修法:修派生状态或 shared hook,让未登录状态硬切空;不要只在 sidebar 里隐藏。 | |
| ### 权限默认值漂移 | |
| 症状:免费用户默认拿到高权限模型、套餐、工具或能力,菜单虽然显示限制,但运行时仍可用。 | |
| 泛化根因:默认值、菜单状态、服务端 normalize 和运行时准入没有共用同一个权限事实源。 | |
| demo:复用真实模型列表、权限 policy 和选择器;用免费用户打开后,默认值或可选项越权即复现成功。 | |
| 修法:修共享权限 policy;默认值选最低权限可用项;UI、API 和 runtime 都消费同一个 policy。 | |
| ### 浮层被 fade 或 mask 盖住 | |
| 症状:菜单、model picker、permission popover 等浮层在真实页面里被一条横向渐变、滚动 mask、composer 背景或 pseudo element 盖住。 | |
| 泛化根因:浮层 portal 宿主、滚动容器、兄弟顺序和 stacking context 与触发器所在区域耦合;只看菜单组件本身或重写一个静态菜单会漏掉真实遮挡层。 | |
| demo:复用真实触发器、真实菜单内容、真实 dropdown/popover 基础组件和真实 `scroll-edge-fade-*` / `scroll-fade-*` 样式;portal container 必须和真实页面同层级。如果 demo 里列表缺项、整体被裁切、遮挡位置不对、或者靠手写白带才像截图,都算复现失败。 | |
| 修法:先在 demo 中用最小层级改动证明是 portal 宿主或 stacking context 问题,再把同一个 owner 的修复映射回真实代码;不要在每个菜单调用点各写一个 z-index 补丁。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment