# Wave 1 发现待 Neo 拍板 — 业务故事卡 > 日期:2026-05-04 / 来源:Wave 1 Day 1-4 实施过程中挖出的问题 > 用途:对齐 04a/b/c-feedback 风格,以业务上下文呈现,让 Neo 可读可判可拍 > 12 项总览 → P0 评估发现×5 / 项目治理×2 / 业务语义×5 > 注:本轮**不评估工时**,Neo 拍判定后主线自动安排到合适 Wave --- ## 第一组 P0 评估发现(5 项) ### F1-1. 批量 AI 任务 长事务无幂等(可能重复扣费) **关联页面/接口**: - admin-web 路由:`/ai/operations`(AI 手动操作页) - 后端端点:`POST /api/admin/ai/batch-run` + `POST /api/admin/ai/batch-run/confirm` - 后端代码:`apps/backend/app/routers/admin_ai.py`(批量任务创建/确认) - 数据库:`biz.ai_run_logs`、`biz.ai_run_costs`(token 计费) - 影响 AI 应用:全部 8 个 APP(因为批量入口通用) **业务背景**: admin-web `/ai/operations` 提供"批量触发"按钮,运维一次点击可以为多个 site 或多组合发起 AI 任务(典型场景:8 区域财务洞察并发跑)。后端做法:先 `POST /batch-run` 创建批次返回 batch_id,再 `POST /batch-run/confirm` 触发实际 dashscope 调用。 **问题描述**: - 整个流程**一个事务包了"创建批次 + 调 N 个 AI"** - 如果调用 dashscope 第 5 个时进程崩溃,前 4 次的 token 已经扣了(dashscope 计费),但事务回滚 → `ai_run_costs` 没记录这 4 次费用 - 运维不知道实际花了多少 → **预算追踪失真** - 重启后又重跑一遍,可能再扣 4 次费用 → **重复扣费** **业务联系**: - 上游:运维点"批量触发"按钮 - 下游:AI cache 写入 / `ai_run_costs` 计费 / 触发器统计 - 影响范围:每次批量 AI 任务都有这个风险,门店数 × 应用数越多风险越大 **修改影响**: - 数据层:`ai_run_costs` 写入策略改为"单次调用即写,不等批次完成" - 接口层:`/batch-run/confirm` 改为异步队列消费 + 单次幂等 - 展示层:admin-web `/ai/run-logs` 可能需要"部分完成"状态 **推荐选项**: 1. **A 拆事务 + 幂等 token**:每次 AI 调用前生成 idempotency_key,失败重启可幂等跳过 → 优:正确 劣:改造面广 2. **B 同步 → 异步队列**:`/batch-run` 入队,worker 单次消费,数据库做唯一约束防重 → 优:架构清晰 劣:引入队列基建 3. **C 仅打 audit log,不改架构**:崩溃后人工对账 → 优:最快 劣:依赖人,不可持续 **建议判定**:**[D Bug] 升级到 Wave 2(随 P1-7 admin API PRD 批 2)**,选 A(因为 Wave 2 已经会改 admin-ai 路由) --- ### F1-2. AI 运行日志 PII 跨租户泄露(super_admin 看到其他门店用户名) **关联页面/接口**: - admin-web 路由:`/logs/ai-run-logs` - 后端端点:`GET /api/admin/ai/run-logs`、`GET /api/admin/ai/run-logs/{log_id}` - 数据库:`biz.ai_run_logs`(含 user_id、site_id、prompt、response 字段) - 关联 Wave 0 决策:P0-5 致命 1+2 已修,但本项是新发现的另一处租户隔离 Bug **业务背景**: admin-web AI 运行日志页给运维看 AI 调用历史(谁触发的、prompt 是什么、token 用了多少、有没有失败)。其中 prompt 字段会**包含用户姓名 / 客户姓名 / 助教姓名**(因为 prompt 模板把这些注入了)。 **问题描述**: - 端点未加 `WHERE site_id = current_setting('app.current_site_id')` RLS 过滤 - super_admin 一旦切到任何 site,**能看到所有 site 的日志**(包括 prompt 里的客户姓名 / 手机号尾号 / 助教姓名) - 多租户上线后:租户 A 的运维查日志可能误看到租户 B 的客户 PII **业务联系**: - 上游:AI 调用产生日志写入 `biz.ai_run_logs` - 下游:admin-web `/logs/ai-run-logs` 列表 / 详情 - 法律影响:多租户场景下涉嫌"未授权访问个人信息",违反《个人信息保护法》第 51 条(责任主体的访问控制义务) **修改影响**: - 数据层:`biz.ai_run_logs` 加 RLS 策略(已有 site_id 列) - 接口层:`run-logs` 端点加 `SET LOCAL app.current_site_id` - 展示层:super_admin 跨 site 时显式切站才能看到对应日志(符合最小授权) - 兜底:勿动 prompt 字段(脱敏成本高) **业务联系**(进一步): - 与 P0-5 致命 1+2 同类(都是租户隔离),Wave 1 Day 1 已修 4 处 fdw_etl,这是第 5 处遗漏 - 与 P0-7 沙箱无直接冲突(沙箱影响时间不影响 site 隔离) **推荐选项**: 1. **A 加 RLS + 强制选 site**:类似 admin-runtime-context 行为,super_admin 必须先选 site → 优:最干净 劣:UX 多一步 2. **B 后端 query 强制带 site_id 参数**:不依赖 GUC,显式入参 → 优:简单 劣:跟全局一致性脱钩 3. **C 仅记 audit log,不限制访问**:运维知情同意 → 优:零改 劣:法律风险高 **建议判定**:**[D Bug 安全] 升级到 Wave 1(本 Wave 内修)**,选 A(与 admin-runtime-context UX 一致) --- ### F1-3. AI 批次 batch_id 生命周期未管理(数据库永久膨胀) **关联页面/接口**: - admin-web 路由:`/ai/operations` + `/logs/ai-run-logs` - 后端端点:`POST /api/admin/ai/batch-run` + `POST /confirm` - 数据库:`biz.ai_run_logs`(每次批次产生 N 行)、`biz.ai_run_costs`、可能还有 `biz.ai_batches`(批次主表) **业务背景**: 每次批量 AI 任务产生一个 batch_id,关联一组 ai_run_logs。一年下来如果每周跑一次 8 区域财务洞察预热,会产生 52 × 8 = 416 行 ai_run_logs(还没算其他 APP)。生产环境跑 1-2 年后,这张表会膨胀到几十万行。 **问题描述**: - `biz.ai_run_logs` **没有 retention / archive 策略** - 也没有 `cleanup_ai_run_logs_after_days` 类似配置 - admin-web 的 run-logs 列表查询可能从"快"变"慢" - 数据库备份大小持续上涨 **业务联系**: - 上游:每个 AI 调用都写 1 行 - 下游:列表查询 / 计费报表 / 异常排查 - 与沙箱关联:沙箱模式下也会写 run_logs 但带 `runtime_mode='sandbox'`,如果不区分清理会丢沙箱回放数据 **修改影响**: - 数据层:加 `cleanup_ai_run_logs.py` 定期任务(保留 N 天 / 归档前 M 天到对象存储) - 接口层:可选加 `GET /api/admin/ai/run-logs/archive` 查归档 - 展示层:admin-web 列表注明"最近 N 天",超出范围跳归档查询 **推荐选项**: 1. **A 简单 retention**:cron 每日删 90 天前的 live 日志,sandbox 日志保留 7 天 → 优:简单 劣:历史不可查 2. **B retention + 冷归档**:90 天后归档到对象存储(parquet / 或 cold table),admin-web 提供"查归档"入口 → 优:历史可查 劣:基建复杂 3. **C 仅打监控告警**:数据库行数 > 阈值时报警,不自动清理 → 优:零改 劣:被动响应 **建议判定**:**[P1] 留 Wave 4**(DWS / 数据正确性 Wave),选 A 起步,B 后续观察 --- ### F1-4. triggers/unified 权限过松(任意 admin 看全局) **关联页面/接口**: - admin-web 路由:`/triggers`(触发器统一管理页) - 后端端点:`GET /api/admin/triggers/unified`(P1-6 调研发现的第 3 个 API) - 数据库:跨表只读聚合(`biz.trigger_jobs` + ai_trigger_jobs + scheduled_tasks) **业务背景**: admin-web `/triggers` 顶部按 Tab 展示业务触发器 / AI 触发器,底部有个"统一视图"显示跨类型聚合。这个聚合数据来自 `/admin/triggers/unified` 端点。 **问题描述**: - 该端点只校验 `admin` 角色,**不校验 super_admin** - 任何 admin(含 site_admin)登录后能看**所有 site 的触发器**(因为 unified 是聚合视图,不按 site 过滤) - 多租户后:租户 A 的 site_admin 能看到租户 B 的触发器名称 / cron / status **业务联系**: - 上游:运维查"全局调度状态" - 下游:仅展示,不直接动数据 - 与 P1-6 关联:P1-6 已规划"扩展 /trigger-jobs PATCH + 业务触发器禁用守卫 + 保留 unified",**本项是 unified 的额外权限收紧**(原 P1-6 没覆盖) **修改影响**: - 接口层:`/admin/triggers/unified` 加 `super_admin` 守卫,或加 site_id 过滤 - 展示层:site_admin 看不到"统一视图" Tab(仅 super_admin 可见) **推荐选项**: 1. **A super_admin 才可见**:unified 是跨 site 的全局视图,符合 super_admin 职责 → 优:语义清晰 劣:site_admin 失去全局视图 2. **B 按当前 site_id 过滤**:站内 unified 视图 → 优:site_admin 仍可用 劣:与 unified 跨表语义冲突 3. **C 维持现状,文档警告**:零改 劣:租户隔离失效 **建议判定**:**[D Bug 安全] 升级到 Wave 2**(随 P1-6 合并修),选 A --- ### F1-5. 沙箱模式下批量 AI 任务未校验 runtime_context(切沙箱后仍按真实时钟跑) **关联页面/接口**: - admin-web 路由:`/ai/operations`(批量任务入口) - 后端端点:`POST /api/admin/ai/batch-run`、`POST /api/admin/ai/run/{app_type}` - runtime context:`biz.site_runtime_context`(P20 SPEC 主表) - 影响 AI 应用:全部 8 APP **业务背景**: P20 沙箱设计:切 sandbox 后,所有"读取业务数据"的查询应该按 sandbox_date 切片(看到历史日期当时的数据)。批量 AI 任务的 prompt 模板会嵌入"current_time" / "ref_date" 等字段,沙箱模式下这些应该是 sandbox_date,而不是真实今天。 **问题描述**: - `/api/admin/ai/batch-run` 创建批次时**没读 site_runtime_context** - prompt 模板里的"current_time"被设成 `datetime.now()`(真实今天) - 切沙箱回放 2026-03-01 时,AI 看到的"今天"还是真实日期(如 2026-05-04) - AI 输出的洞察文案会说"截至今天 5 月 4 日,本月营收..." → **跟沙箱数据(3 月)语义错位** **业务联系**: - 上游:运维切 sandbox + 触发批量预热 - 下游:AI 输出文案语义错位 → 沙箱演示效果失真 - 与 P0-3 看板沙箱关联:P0-3 已修小程序看板,但 AI 入口还没接(本项) - 与 P20 SPEC §10.2 关联:AI 提示词矩阵标了 X 已接入,但**这是 prompt builder 接入,不是 admin-web 触发入口接入** **修改影响**: - 接口层:`batch-run` / `run/{app_type}` 在创建任务前 `get_runtime_context(site_id)`,把 sandbox_date 传给 prompt builder - 数据层:`ai_run_logs.runtime_mode` + `sandbox_instance_id` 列(P20 已规划) - 展示层:admin-web `/ai/operations` 顶部条带显示当前 sandbox_date(如非 live) **推荐选项**: 1. **A 完整接入沙箱**:batch-run 读 runtime_context 传给 prompt + 写 ai_run_logs.runtime_mode → 优:沙箱主线达标 劣:Wave 1 工作量略增 2. **B 只 block 沙箱模式**:sandbox 时 batch-run 直接 422 拒绝(不允许沙箱跑批量)→ 优:简单 劣:沙箱演示功能受限 3. **C 留 Wave 2 处理**:Wave 1 不修,P20 §10.2 标"待补" → 优:不阻塞 Wave 1 劣:沙箱主线收口延后 **建议判定**:**[D Bug 沙箱主线] 升级到 Wave 1**(P0-7 沙箱收口主线,本 Wave 必修),选 A --- ## 第二组 项目治理(2 项) ### F2-1. OpenAPI 与代码不同步(本批 23 端点中 10 个不在 backend-api.json) **关联页面/接口**: - 项目级:`docs/contracts/openapi/backend-api.json`(OpenAPI 静态导出) - 抓取脚本:`tools/codex/...` 或类似(具体位置 Wave 1 没查到) - 影响:全部 admin-web API PRD 工作流 **业务背景**: admin-web API PRD(P1-7)的工作流是"自动生成 + 人工细化",依赖 backend-api.json 作为权威源。批 1 撰写时发现:**本批 23 端点中 10 个不在 OpenAPI 文件**,意味着每批 PRD 都可能漏 30%+ 端点。 **问题描述**: - `backend-api.json` 缺以下端点: - 全部 `/api/admin/runtime-context/*`(5 个) - `/api/admin/triggers/unified`(1 个) - `admin_ai` 后期扩展 4 个端点(`/run/{app_type}`、`/triggers` GET&PATCH、`/prewarm/progress`、`/trigger-event`) - 推测原因:OpenAPI 静态导出脚本未含某些后注册的 router,或抓取时服务未启动全部 router - backend-api.json 上次更新时间:Wave 0 迁移期(2026-04-XX)? **业务联系**: - 上游:后端 router 改动 → 应触发 OpenAPI 重抓 - 下游:admin-web 前端类型生成 / API PRD / 文档同步 - Wave 关联:批 2-5 会持续依赖 OpenAPI,如果不修,Wave 2-4 可能各漏 10-20% **修改影响**: - 工程层:修抓取脚本(确保启动包含所有 router 的服务) - 文档层:`backend-api.json` 重新生成 + 入仓 - 工作流:加 git pre-commit / CI 钩子检查 OpenAPI 与代码同步(可选) **推荐选项**: 1. **A Wave 2 提前修**(我推荐):批 2 撰写前先修脚本,避免后续批漏端点 → 优:止血最早 劣:Wave 2 多一项准备工作 2. **B Wave 5 文档收尾时统一修**:5 批合并时一次校核 + 修补 → 优:跟收尾节奏一致 劣:批 2-5 各漏端点时需手工补 3. **C 不修脚本,人工对照代码补 PRD**:每批主线手动 grep router 补漏 → 优:零基建 劣:容易漏 + 持续工作量 **建议判定**:**[C 待补] Wave 2 提前修**,选 A --- ### F2-2. tests/ 不入仓(.gitignore:71 排除测试代码) **关联页面/接口**: - 项目级:`.gitignore:71` `tests/` - 影响范围:**全部子项目**(backend / etl / miniprogram / admin-web / tenant-admin) - Wave 1 实例:W1-T4 audience 7 单测 + W1-T5 db_viewer 测试改动留本地 **业务背景**: Wave 1 Day 4 跑测试时发现:`apps/backend/tests/` 全部测试文件**从未被 tracked**(`git ls-files apps/backend/tests/test_auth_jwt.py` 返回空)。原因:`.gitignore:71` 写了 `tests/` 排除全部测试目录。 **问题描述**: - 测试代码不入仓 → CI 没法跑测试 → 测试可能 rot - 各子项目测试只在本地 → 不同开发者机器测试覆盖不一 - Wave 1 我加的 jwt audience 7 单测(75% 覆盖 W1-T4)留本地,无法保护后续 Wave 不破坏 audience 行为 - 这是项目级早期决策(可能是为了避开 venv / pytest_cache 误入仓) **业务联系**: - 上游:开发写测试(本地有效) - 下游:CI / 后续 Wave / 跨设备协作(都受影响) - 与 P1-13 tasks.md 撒谎对照:tasks.md 撒谎是"声明做了实际没做",tests 不入仓是"做了别人看不到" — 两者都侵蚀测试可信度 **修改影响**: - `.gitignore:71` 改为更精细的排除(如 `**/__pycache__/` `**/.pytest_cache/` `**/*.egg-info/`) - 全部子项目测试目录入仓 - CI 配置(可选,Wave 5 决议) - 注意:某些 tests 内可能含 fixtures / 测试库 dump,需要先脱敏 **推荐选项**: 1. **A 改 .gitignore + 入仓 + Wave 5 启 CI**(我推荐):彻底解决,CI 反馈 → 优:长期投资 劣:需要先扫一遍现有 tests/ 是否含敏感数据 2. **B 改 .gitignore + 入仓 + 不启 CI**:先解决"代码可见",CI 后续再说 → 优:渐进 劣:仍依赖人工跑 3. **C 维持现状**:接受 tests rot 风险 → 优:零改 劣:Wave 5 收尾时无法证明测试通过 **建议判定**:**[B 现状对 待优化] Wave 5 处理**,选 A(需先脱敏扫描) --- ## 第三组 批 1 PRD 业务语义待答(5 项) ### F3-1. AI cache 失效粒度 **关联**:`POST /api/admin/ai/cache/invalidate`、`biz.ai_cache` 表 **业务背景**: admin-web 提供"清空 AI 缓存"按钮,运维在 prompt 调优后清缓存让下次调用拿新版本。当前实现按 cache_key 整张表清,**可能误伤所有 site 的缓存**。 **冲突逻辑**: - 设计意图:某 site 的 prompt 改了 → 只清该 site 的缓存 - 实际实现:`DELETE FROM biz.ai_cache WHERE cache_key LIKE ?`,不带 site_id 过滤 **业务联系**: - 上游:运维改 prompt 后清缓存 - 下游:其他 site 缓存被误清 → 下次访问触发 AI 调用 → token 浪费 **修改影响**: - 接口层:加 `site_id` 参数(可选,不传则当前 site) - 数据层:无 schema 变更 - 展示层:admin-web 按钮加 site 选择器 **推荐选项**: 1. **A 按当前 site 清**:默认清当前 super_admin 选的 site → 优:安全 劣:运维需先切 site 2. **B 显式 ?scope=site|tenant|all**:运维选粒度,默认 site → 优:灵活 劣:UI 多按钮 3. **C 维持现状(全表清)**:简单粗暴 → 优:简单 劣:误伤 **建议判定**:**待 Neo 拍板**,我倾向 **B**(灵活 + 默认安全) --- ### F3-2. AI budget 单价是估算还是实际计费? **关联**:`GET /api/admin/ai/budget`、DashScope 计费 **业务背景**: admin-web 显示"本月 AI 预算 X 元 / 已用 Y 元"。Y 来自 `biz.ai_run_costs` 累计 token × 单价。但单价配置存哪里?DashScope 实际单价(qwen-max / qwen-turbo)是浮动的还是固定的? **冲突逻辑**: - 配置层:`config.AI_TOKEN_PRICE_*`(代码里硬编码?cfg 表?) - 计费层:DashScope API 返回 token usage,后端按单价转元 - 实际值:DashScope 控制台账单(权威) **业务联系**: - 上游:每次 AI 调用记 token - 下游:budget 展示 / 上线前预算估算 / 超额告警 - 上线门槛:P11 上线时 budget 准确性是验收点之一 **修改影响**: - 配置层:加 `cfg_ai_token_price`(SCD2 表,按 model + 时间切片) - 接口层:budget 端点改读 cfg 表 - 对账:每月与 DashScope 账单对账,误差 > 5% 报警 **推荐选项**: 1. **A 配置表 + 月度对账**:正确性最高 → 优:可审计 劣:对账自动化成本 2. **B 硬编码单价**:维持简单 → 优:0 改 劣:DashScope 调价后失准 3. **C 用 DashScope SDK 返回的实际计费值**:如果 SDK 返回 cost_yuan 字段,直接用 → 优:最准 劣:依赖 SDK **建议判定**:**待 Neo 答** — 你知道 DashScope SDK 是返 token 还是 cost,这影响选项 --- ### F3-3. 手动触发 AI 调用是否记 audit_log + 二次确认? **关联**:`POST /api/admin/ai/run/{app_type}`、admin-web `/ai/operations` **业务背景**: admin-web 提供"手动触发某 APP"按钮,运维点了直接调 dashscope。区别于 P0-6 clearAllTasks(那是清数据),这个是"花钱 + 不可撤销 + 可能产生 PII 写入"。 **冲突逻辑**: - 当前:点击直接调用,不记 audit - 期望:符合"可追溯 + 可控制成本"原则,应该记日志 + 弹窗确认 **业务联系**: - 上游:运维或测试人员手动触发 - 下游:dashscope 扣费 + 日志写入 + 可能影响小程序展示 - 与 P0-6 对照:P0-6 是清空(数据风险),F3-3 是调用(费用 + PII) **修改影响**: - 接口层:`/run/{app_type}` 加 audit_log 写入(`biz.admin_audit_log`,含 user / params / timestamp) - 展示层:admin-web 加二次确认弹窗(可选关闭) **推荐选项**: 1. **A 加 audit_log + 二次确认**(我推荐):标准做法 → 优:可追溯 + 防误操作 劣:UX 多一步 2. **B 仅加 audit_log,不加二次确认**:运维信任度高 → 优:UX 流畅 劣:误点风险 3. **C 维持现状**:零改 → 优:简单 劣:无追溯 **建议判定**:**待 Neo 答**,我倾向 A --- ### F3-4. runtime-context 切 sandbox 的"未来日期"边界 **关联**:`PATCH /api/admin/runtime-context`、admin-web `/settings/runtime-context` **业务背景**: admin-web 沙箱页可以切 sandbox_date。当前代码校验: ```python if sandbox_date > date.today(): raise HTTPException(422, "沙箱日期不能晚于今天") ``` **冲突逻辑**: - 设计:沙箱是"回放历史",上限 = today - 但 P20 SPEC §3.1 没明确写"sandbox_date 是否可以等于 today" - 边界:`> today` 拒绝,`= today` 允许(当前实现) - 问题:`= today` 时沙箱跟 live 几乎一致,有意义吗? **业务联系**: - 上游:运维切 sandbox 用于演示 / 调试 - 下游:全部读 sandbox_date 的逻辑 **修改影响**: - P20 SPEC §3.1 文字补充 - 后端校验逻辑(若需收紧) - admin-web 日期选择器 maxDate 配置 **推荐选项**: 1. **A 维持现状(`> today` 拒绝,`= today` 允许)**:今天也算合法回放(数据齐全)→ 优:零改 劣:沙箱意义弱 2. **B 严格 `< today`**:沙箱必须是历史 → 优:语义清晰 劣:今天演示需切 live 3. **C 提示 + 允许**:`= today` 时 admin-web 提示"今天数据可能不完整(实时更新中)" → 优:体验好 劣:UI 多一项 **建议判定**:**待 Neo 答**(产品决策),我倾向 A 或 C --- ### F3-5. triggers/unified 是否需要分页 **关联**:`GET /api/admin/triggers/unified`、admin-web `/triggers` **业务背景**: unified 端点跨表聚合返回所有触发器(含 biz / ai 两类)。当前**全表返回,不分页**。 **冲突逻辑**: - 当前实现:全量返回(预计 < 100 条) - 真实场景:门店多 + AI 触发器多 → 100-500 条 - 极端场景:多租户 + 50 门店 × 10 触发器 = 500 条 - 单 row JSON 估 200 bytes → 100KB(可接受)~ 1MB(慢)~ 10MB(慢且占带宽) **业务联系**: - 上游:运维浏览触发器 - 下游:列表渲染 / 筛选 **修改影响**: - 接口层:加 `?page=&page_size=` - 展示层:admin-web 列表加分页器 - 跟 P1-6 关联:P1-6 合并方案保留 unified,可顺带加分页 **推荐选项**: 1. **A 加分页(默认 page_size=50)**:标准做法 → 优:任意规模可承受 劣:Wave 2 改造时多一项 2. **B 全量 + 前端分页**:后端简单 → 优:简单 劣:1000+ 触发器时仍卡 3. **C 维持现状**:门店少时无问题 → 优:零改 劣:多租户后必爆 **建议判定**:**待 Neo 答**,我倾向 A,**留 Wave 4**(数据/性能 Wave),不阻塞 Wave 2 P1-6 合并主线 --- ## 总览决策清单 | # | 简述 | 我的建议 | Wave | |---|---|---|---| | F1-1 | 批量 AI 长事务无幂等 | D Bug 选 A | Wave 2 | | F1-2 | run-logs PII 跨租户泄露 | D Bug 选 A | **Wave 1** | | F1-3 | batch_id 数据库膨胀 | P1 选 A | Wave 4 | | F1-4 | triggers/unified 权限过松 | D Bug 选 A | Wave 2 | | F1-5 | 沙箱 batch-run 未读 runtime | D Bug 选 A | **Wave 1** | | F2-1 | OpenAPI 不同步 | C 待补 选 A | Wave 2 提前修 | | F2-2 | tests/ 不入仓 | B 待优化 选 A | Wave 5 | | F3-1 | AI cache 失效粒度 | 待 Neo 答 (B 倾向) | Wave 2 | | F3-2 | AI budget 单价来源 | 待 Neo 答 | Wave 2-4 | | F3-3 | 手动触发 audit + 确认 | 待 Neo 答 (A 倾向) | Wave 2 | | F3-4 | sandbox_date 边界 | 待 Neo 答 (A/C 倾向) | Wave 5 文档 | | F3-5 | unified 分页 | 待 Neo 答 (A 倾向) | Wave 4 | --- > 等 Neo 在每条卡上写斜体反馈(类似 04a/b/c),主线接斜体即按判定走 Wave。