# PROGRESS — 多 Agent 协同任务台账 > 多 agent 共享的**唯一协同入口**。开工前读这里 + `memory/`;认领任务、尊重依赖、完成即更新。 > 完整任务定义见 `DEV_PLAN.md`;本台账只展开**当前阶段**,进入新阶段时再把该阶段任务拉进来。 > 协同规则见 `CLAUDE.md` →「多 Agent 协同」。 **状态图例**:⬜ 待办 · 🔵 进行中(注明 @skill + 日期) · ✅ 完成 · ⛔ 阻塞(注明等什么) --- ## 进行中:AI 对话(聊天记录)持久化 · develop 上新功能 > **背景**:[2026-07-09] 用户要求把作者↔AI 每轮往复(refine/rewrite/clarify/continue/工具箱生成器)**落库为聊天记录**,每章一个「AI 对话」抽屉展示。多 agent(4 学科起草→4 视角交叉评审→合稿)产出实施计划 `docs/design/ai-chat-history-plan.md`。**决策全 A**:clarify buffer-until-concluded / v1 只记 5 类交互 / append-only 不删。 > **契约与不变量纪律**:@db 建表(契约 C2 扩)→@backend 端点(C3 扩)→@frontend gen:api+接线→@qa E2E,逐级等上游契约「稳定」。守 #1/#3/#8:聊天记录是**旁路留痕**(同 `usage_ledger` 物种),前端**显式 append**、生成端点**保持只读不变**、**绝不**喂 `assemble`/prompt(计划 §8 有围栏 + code-review 守卫)。 | 任务 | 状态 | 负责 | 依赖 | 备注 | |---|---|---|---|---| | AC-1 `ai_messages` 表 + 迁移 | ⬜ | @db | — | 计划 §2 canonical DDL | | AC-2 repo + append/list 端点 + schema + 契约 | ⬜ | @backend | AC-1 | 计划 §3;批级 append 信封、newest-first 分页 | | AC-3 gen:api + AiConversationDrawer + useAiConversation + 接线 5 处交互 | ⬜ | @frontend | AC-2 | 计划 §4;本章对话 + 项目级生成两段 | | AC-4 E2E + repo/端点/hook 测试 | ⬜ | @qa | AC-3 | 计划 §6 | --- ## 已完成阶段:QA-CR · 全项目 Code Review 整改批(全 ✅) > **背景**:[2026-06-26] 对全仓做了一次**七维度 Code Review**(后端 Python 规范 / LangGraph 最佳实践 / 后端 FastAPI 架构 / 前端编程规范 / 前端架构 / 应用安全 / 依赖时效),6 个专科 reviewer 并行 + 依赖自查。绿门禁下仍揪出 **2 CRITICAL + 13 HIGH + 一批 MEDIUM/LOW**——再次证伪「测试过=没问题」。架构本身成熟、不变量纪律强(provider 中立 / HITL accept 单写 / checkpoint 仅控制流 / SecretStr 全覆盖);**确认无虞**:SSRF(`base_url` 仅来自硬编码 `_PROVIDER_BASE_URLS`,无用户 URL 入网)/ SQL 注入(全 ORM 参数化)/ XSS(无 `dangerouslySetInnerHTML`/`eval`)/ 错误信封不泄栈密钥 / Kimi 用 RFC 8628 device flow 无 CSRF 面。 > **整改 DoD**:CRITICAL + HIGH 全部 ✅ 且各自补回归测试;MEDIUM 择批清理;门禁全绿(后端 ruff/format/mypy/pytest + alembic 无漂移;前端 lint/tsc/vitest/build)。**守 §Definition of Done**:每项 TDD 先红后绿、完成即小步 commit。 > **落地顺序**:① 本周 CR-C1/C2 + 两资源泄漏(H1/H2)+ Fernet key(H8);② 合并前 计费两项(H3)+ request_id(H4)+ max_length(H9)+ 前端三 HIGH(H10/H11/H12);③ MEDIUM/LOW 技术债批。 > **依赖纪律**:CR-C1(升 Next)须 `pnpm install` 重锁 + `pnpm build` 验证、**升级后轮换全部应用密钥**(与 CR-H8 Fernet key 联动)。CR-H4/H9 改 schema → 若动 OpenAPI 形参须 `pnpm gen:api` + `memory/contracts.md` 记一笔。无 DB 迁移预期。 | 任务 | 状态 | 负责 | 依赖 | 备注 | |---|---|---|---|---| | CR-C1 🔴 升级 Next.js 修 RCE + React 补丁 | ✅ | @frontend | — | `f4c2c4e` next 15.1.3→**15.5.20**(registry backport 线,避 16.x 大迁移)、react/react-dom 19.0.0→**19.2.7**、eslint-config-next/@types 同步;`pnpm install` 重锁 + `pnpm build` 绿;`pnpm audit` next/react/react-dom 无 high/critical;新 `lib/security/dependencyFloors.ts` 版本下界守卫。**⚠️ 运维待办(用户执行)**:CVE 号无法对真库核验(升级后 `pnpm audit`/GitHub advisory 复核)+ 升级后轮换全部应用密钥 | | CR-C2 🔴 多章链设 `recursion_limit` | ✅ | @backend | — | `ed0a679` **前提证伪**:langgraph 1.2.5 默认上限=10007(非 25)、count≤50→~200 步,**无实活崩溃**;仍加显式**顶层** `recursion_limit=count*4+10`(防御硬化);测断言 config 键(行为「跑长链完成」测会 vacuous) | | CR-H1 🟠 Kimi OAuth 轮询不占 DB 会话 | ✅ | @backend | — | `ca8fbc8` 轮询移出会话:`_poll_for_token`(无会话)+`_run_kimi_oauth_poll`,仅最终 persist 走 run_job 短会话;`job_runner` 未动(与 style_learn 共享) | | CR-H2 🟠 修 `httpx.AsyncClient` 泄漏 | ✅ | @backend | — | `5dd336b`+`26f10d0` 请求级依赖改 `_http_client` 生成器(`async with`→`aclose`);两处测 override 跟随改,堵住 E2E 误触真网 | | CR-H3 🟠 Anthropic 结构化输出记真实 usage | ✅ | @llm | — | `cb8fddf` 改 `create_with_completion` 取 `raw.usage`,弃硬编码 0(修计费腐蚀) | | CR-H4 🟠 `request_id` 贯通网关日志 | ✅ | @llm | — | `51fe9f4`+`e08b01a` LlmRequest 加可选 `request_id` + **条件透传**(仅非 None,否则覆盖 contextvars 反退化 sync/SSE 追踪);`llm_call`+两处 `llm_provider_failed` 全锁测。契约 C1-扩 | | CR-H5 🟠 `thinking` 字段:实现或删除 | ✅ | @llm | — | `afeac51` 删死字段 `LlmRequest.thinking`(YAGNI);保 `Capabilities.thinking`(异名活字段);回写 ARCH/contracts | | CR-H6 🟠 流式路径加 per-provider 重试 | ✅ | @llm | — | `8a2b1b0` `_stream_with_retry` 对称 run:仅首 token 前重试,mid-stream 失败照抛(不变量 §4.5) | | CR-H7 🟠 `TOOLBOX` 注册表不可变 | ✅ | @backend | — | `25d48b7` `Final[Mapping]=MappingProxyType(_TOOLBOX_BY_KEY)`(仿 SPECS) | | CR-H8 🟠 `.env.example` 移除可用 Fernet key | ✅ | @devops | — | `baa41d3` 换不可用占位符(Fernet 拒绝→照抄即启动失败)+ 轮换提示。**⚠️ 真 key 仍在 git 历史,曾用该 key 的环境须轮换(用户)** | | CR-H9 🟠 API 文本输入加 `max_length` | ✅ | @backend | — | `e1a24a2`+`d6b53d0` 全请求文本字段加上限(api_key≤512/brief≤1e4/final_text≤2e5/segment≤2e4/directive≤2e4/instruction≤2e3…)+ **2 MiB body 中间件 413 兜底** + `PAYLOAD_TOO_LARGE`。契约 C3;`gen:api` 无漂移 | | CR-H10 🟠 前端 `errorCode` 去重 | ✅ | @frontend | — | `5665cc9` `lib/style/{useRefine,useStyleLearn}` 统一 import 自 `generation/cards` | | CR-H11 🟠 Drawer 关闭还原焦点 | ✅ | @frontend | — | `6e2b478` 行为本分支早已修;提取 `lib/a11y/useRestoreFocus` + renderHook 回归测试 + DRY(Drawer/ContextDrawer 共用) | | CR-H12 🟠 RefineView 取消在途 refine | ✅ | @frontend | — | `5c02792` useRefine 暴露 `abort`(setState-free)+ AbortController + aborted 守卫弃迟到响应;RefineView cleanup 调用 + 真 deps | | CR-M1 🟡 后端架构整改批 | ✅ 大部 | @backend | — | `c596a8d` outline volume 下推 DB WHERE(Protocol/Sql/fake 加 keyword `volume`);`bf3dabe` 角色/世界观入库 N+1→`create_many`(世界观 add_all;角色一次 IN 查+一次 flush 保 upsert 幂等/批内去重;单条 create 薄封装);`1392830` jobs 读端点裸 ORM→JobRepo;`0892ff6` projects/templates 列表加分页(`ww_api.pagination` limit∈[1,200]/offset≥0,越界 422,下推 LIMIT/OFFSET)。**item#4 provider_deps `_client`→已由 @llm 交付**(`832ab7d` `OpenAICompatAdapter.probe_connection()` 公开探测 + provider_deps 改调,删私有 `_client` 反手 + `type:ignore`/`noqa:SLF001`;isinstance 收窄兜非 OpenAI 兼容)。**item#6 assemble 并行→SKIP**:8 查询共享同一注入 AsyncSession,`gather` 会腐蚀(ledger 警告属实);安全化须把 session 工厂穿透 assemble + 8 repo 各独立 session + 并发正确性测,对单用户几 ms 收益不值该回归风险 | | CR-M2 🟡 网关/adapters 整改批 | ✅ 大部 | @llm | — | `32451a9` pricing 未知 model 发 `pricing_unknown_model` warning(成本仍 0、照常记账);`9439b97` 三 adapter 瞬时错误消息经 `provider_error_summary(exc)` 只留类名+status(不泄 vendor 响应体)。**item `is_open()` CQS→SKIP**:冷却过读时半开清态是**故意的惰性转移**(唯一转半开点),拆 CQS 需两处调用方各先发命令、漏发则熔断永不复位(更差),风格分不值动熔断语义 | | CR-M3 🟡 LangGraph 链健壮性 | ✅ 大部 | @llm | — | `ec91c8f` runner 改用公开 `graph.aget_state(config).interrupts` 判暂停(弃私有 `__interrupt__`;SpyGraph 测同步补 aget_state 透传);`6a739ca` review 节点五审 `asyncio.gather` 并行扇出(复用主图 add-only 记账并发范式 T3.8,collect 仍一次落库;并发峰值测 + 五审落齐测)。**item `run_overdue_scan` 幂等→SKIP**:`scan_overdue` 本已幂等(单条 `UPDATE...RETURNING` + `status NOT IN [CLOSED,OVERDUE]` + commit-only-if-changed,原子无部分空洞),且下一章扫描 current+1 自愈漏标;再动会触碰验收事务边界,单用户零收益 | | CR-M4 🟡 前端 key/a11y/cleanup 批 | ✅ | @frontend | — | `47d5558` ARIA(NavDrawer `aria-controls` + Drawer `id` + ForeshadowCard 语义化 `
/
/
`)+ `125908e` ReviewReport `flashMark` setTimeout 卸载清理(ref 存句柄)。**核实为无需改/已具备**:index-key(三处均 replace-all/append-only 静态展示、无天然稳定 id,index 安全;卡名可编辑作 key 更糟)、`stop`(经查**非**服务端 SSE 帧、是客户端 AbortController 动作,加则处理不存在事件)、AppShell nav label(`