Files
writer-work-flow/PROGRESS.md
Yaojia Wang 68f194a043 feat: M2 — 写→审(一致性)→裁决→验收(事务);未决冲突禁验收
- 续审 Agent 声明(AgentSpec) + 结构化输出契约(ContinuityReview/Conflict 五类)
- LangGraph 并行审子图(可扩四审) + collect 落 chapter_reviews 留痕 + review SSE(section/conflict)
- 验收-side Repository:章节 accepted 版本晋升 + digest append-only + 审稿留痕/裁决
- API:review(SSE) + reviews 历史 + accept(单原子事务:晋升 version + 终稿 digest + 裁决留痕)
- 冲突 gate:未决裁决拦截(CONFLICT_UNRESOLVED);digest 从终稿提炼(不变量#4)
- 前端:审稿报告页 + 冲突就地标注 + 裁决(采纳/忽略/手改) + 未决禁验收 + 「本次将更新」清单
- M2 E2E:真实 DB + 多档位 mock 网关零 token 走通 写→审→裁决→验收→摘要入库
- 多 agent 协同台账(PROGRESS.md) + 共享记忆(memory/contracts·decisions·gotchas)
2026-06-18 11:38:28 +02:00

73 lines
15 KiB
Markdown
Raw 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.

# PROGRESS — 多 Agent 协同任务台账
> 多 agent 共享的**唯一协同入口**。开工前读这里 + `memory/`;认领任务、尊重依赖、完成即更新。
> 完整任务定义见 `DEV_PLAN.md`;本台账只展开**当前阶段**,进入新阶段时再把该阶段任务拉进来。
> 协同规则见 `CLAUDE.md` →「多 Agent 协同」。
**状态图例**:⬜ 待办 · 🔵 进行中(注明 @skill + 日期) · ✅ 完成 · ⛔ 阻塞(注明等什么)
---
## 当前阶段Phase 2 (M2) · 一致性 + 验收
> 目标:写 → 审(一致性) → 裁决 → 验收(事务写回)**未决冲突禁验收**。**契约先行**C6 续审 AgentSpec + 结构化输出 schema → C4 扩(并行审图/SSE) → C3 扩(review/accept/reviews)。
> 执行波次依赖驱动A(T2.1‖T2.3) → B(T2.2) → C(T2.4+T2.5) → D(T2.6) → E(T2.7)。
> 计划已定的设计决策(见变更日志 + `memory/decisions.md` 待 Wave A 落地后回写):
> **R2** digest 提炼在事务外做、原子事务只写库(不在持开事务里跨网络调 LLM
> **R3** accept 为确定性事务代码、读领域表(`chapters`/`chapter_reviews`)重建真相checkpoint 仅控制流句柄(不变量 #5
> **R4** accept 取该章 `max(version)+1` 晋升 `status='accepted'`,草稿行保留;
> **R5** 裁决清单每个 conflict 必须 采纳/忽略/手改 之一,缺判决 → `CONFLICT_UNRESOLVED`。
| 任务 | 状态 | 负责 | 依赖 | 契约 | 备注 |
|---|---|---|---|---|---|
| T2.1 续审 AgentSpec + 结构化输出契约 + 网关 instructor 接线 | ✅ @llm 2026-06-18 | @llm | T1.1✅ | C6✅稳定 | `packages/agents/`+`packages/llm_gateway/``ContinuityReview/Conflict`(五类枚举)+`continuity_spec`(只读)`Gateway.run` 经 instructor 填 `parsed`(改 C1)25 tests 绿 |
| T2.2 LangGraph 并行审 + collect 留痕 + review SSE | ✅ @llm 2026-06-18 | @llm | T1.3✅, T2.1✅ | C4✅扩稳定 | `orchestrator/``build_review_graph`(continuity 并行,可扩四审)+`collect_reviews``chapter_reviews`+`normalize_review`(section/conflict)accept 接线留 T2.415 新测;只 flush 不 commit |
| T2.3 摘要/审稿留痕 Repository + 章节 version | ✅ @backend 2026-06-18 | @backend | T0.2✅ | — | `core/ww_core/domain/``chapter_repo`(promote_to_accepted/max_version/latest_accepted)+`digest_repo`(append-only)+`review_repo`(record/list/set_decisions);纯 fake 17 新测;只 flush 不 commit交 T2.4 事务);唯一约束 DB 级→T2.7 E2E 覆盖 |
| T2.4 验收事务 + 冲突 gate | ✅ @backend 2026-06-18 | @backend | T2.2✅, T2.3✅ | C3✅扩 | `accept_service`(冲突 gate+R3/R4 单事务)+`digest_extraction`(R2 事务外提炼,light)`POST .../accept`缺判→409 `CONFLICT_UNRESOLVED`+missing_indices |
| T2.5 review API + 历史 | ✅ @backend 2026-06-18 | @backend | T2.2✅ | C3✅扩 | `POST .../review`(SSE section/conflict/done)+`GET .../reviews`(新→旧)analyst 网关;流耗尽 commit+9 测全仓 112 passed |
| T2.6 审稿报告页 + 冲突裁决 + 验收 gate | ✅ @frontend 2026-06-18 | @frontend | T2.4✅, T2.5✅ | — | `app/projects/[id]/review`+`components/review/*`+`lib/review/*`gen:api 纳三端点;就地标注(R6 段级锚点)+裁决+「将更新」清单+未决禁验收vitest 45(+21) |
| T2.7 M2 E2E | ✅ @qa 2026-06-18 | @qa | T2.6✅ | — | `tests/test_m2_e2e.py` 2 用例真跑过(非 skip);闭环 + 零冲突直通DB 真源断言(accepted v2 / digest 来自终稿#4 / 裁决留痕 / 三档位 ledger);无新 bug |
**M2 出口DoD✅ 全部达成**:写→审(一致性)→裁决→验收(事务)未决冲突禁验收。后端门禁绿ruff / mypy **90 文件** / pytest **114 passed** / alembic **无漂移**前端门禁绿gen:api / lint / tsc / vitest **45** / buildE2E 真实 DB + mock 网关零 token 走通 写→审→裁决→验收→摘要入库DB 真源逐项断言。**M2 完成。** 下一阶段 M3伏笔 + 节奏)见 DEV_PLAN进入时拉入本表。
---
## 已归档阶段
<details><summary>Phase 1 · 写章闭环骨架 (M1) — ✅ 全部完成2026-06-18</summary>
T1.1 LLM 网关接口+DeepSeek 适配器+usage_ledger 记账C1✅稳定@llm · T1.2 记忆 assemble 确定性选择C5✅稳定@backend · T1.3 LangGraph 写章节点+Postgres checkpointer+SSEC4✅稳定@llm · T1.4 立项+写章 draft(SSE)+PUT 自动保存C3✅稳定@backend · T1.5 AppShell+作品库+5 步立项向导 @frontend · T1.6 写作工作台(三栏+流式打字机+注入透明面板+自动保存)@frontend · T1.7 提供商凭据管理Fernet 加密+测试连接)@backend · T1.8 设置页(档位路由+凭据行)@frontend · T1.9 M1 E2E真实 DB+mock 网关零 token暴露并修复 ledger 提交 bug@qa
出口达成后端门禁绿ruff / mypy 68 / pytest 57 / alembic 无漂移前端门禁绿gen:api / lint / tsc / vitest 24 / buildE2E 闭环走通。
M2 起可补的 M1 占位:本章助手/注入透明面板、向导主角/世界观字段、档位路由可写。
</details>
<details><summary>Phase 0 · 基建与栈修订 — ✅ 全部完成2026-06-18</summary>
T0.1 monorepo 骨架 ✅ @devops · T0.2 16 MVP 表迁移无漂移users stub@db · T0.3 FastAPI 骨架 + config + 错误信封(带 request_id) + OpenAPI + `GET /jobs/:id` + structlog ✅ @backend · T0.4 前端骨架 + 纸感 token + OpenAPI→TS gen:api ✅ @frontend · T0.5 CI含 pg service + alembic 漂移校验)✅ @devops · T0.6 架构栈修订回写规格 ✅ @docs
出口达成backend 门禁绿、frontend 门禁绿、API 实跑 200 带 `x-request-id`
</details>
---
## 变更日志append-only最新在最上
> 格式:`- [YYYY-MM-DD] @skill 完成/进展 Txx — 一句话结果 + 影响的契约/文件`
- [2026-06-18] @orchestrator**🎉 M2 完成**Wave ET2.7✅)。`tests/test_m2_e2e.py` 真实 pg + 多档位 mock 网关(零 token真跑通过 2 用例:主用例串 立项→写章 SSE→自动保存→**审稿 SSE(section/conflict)**→GET 历史→**残缺裁决触发 409 `CONFLICT_UNRESOLVED`+missing_indices(gate 事务前拦截未写库)**→全量裁决+终稿验收(200, accepted v2)→**DB 真源逐项断言**chapters draft v1 留存 + accepted v2(content==final_text)、`chapter_digests.facts` 追溯终稿标记(证 #4 digest 从终稿非草稿)、`chapter_reviews.decisions` 写回、`usage_ledger` 三档位(writer/analyst/light)各落一条且事务已 commit补充用例验证零冲突直通。**无新 bug**M1 曾暴露的 ledger 提交 bug 在 M2 三档位无复发——review 流末 + accept 事务末均 commit。最终全收口门禁绿ruff/format 干净、mypy **90 文件**、pytest **114 passed**、**alembic 无漂移**M2 全程零建表迁移。M2 出口 DoD 全达成。下一阶段 **M3伏笔+节奏)**
- [2026-06-18] @orchestrator**Wave D 完成**T2.6✅)。审稿报告页落地:`app/projects/[id]/review`RSC 取历史)+ `components/review/*`(报告卡/就地标注/AcceptPanel+ `lib/review/*`SSE reducer/裁决完整性/请求体组装,纯逻辑单测)。`pnpm gen:api` 纳入 review/accept/reviews 三端点类型不手写SSE 沿用 `useDraftStream` 的 fetch+ReadableStream 范式;五类冲突就地朱砂锚点(R6 段级降级)+裁决(采纳/忽略/手改)+**未决禁验收 gate**+409 missing_indices 高亮+「本次将更新」清单。前端门禁绿gen:api/lint/tsc/**vitest 45(+21)**/build。memory +1 decision +2 gotchas。下一步 **Wave ET2.7 M2 E2E**(@qa 真实 DB + mock 网关零 token)。
- [2026-06-18] @orchestrator**Wave C 完成**T2.4✅ + T2.5✅C3 扩稳定,单 @backend agent 顺序做)。三端点入 OpenAPI`POST .../review`(SSE section/conflict/done) + `GET .../reviews`(新→旧) + `POST .../accept`。验收:冲突 gate裁决 `conflict_index` 须覆盖 review.conflicts 全下标缺判→409 `CONFLICT_UNRESOLVED`+missing_indices→ 终稿 digest 提炼在事务外(R2light 档)→ 单原子事务 promote(R4)+digest.append(#4)+set_decisions、末尾一次 commit、失败全回滚(R3)。`build_gateway_for_tier` 统一多档位网关注入。全仓门禁绿ruff/format 干净、mypy **83 文件**、pytest **112 passed**+9。memory 登记 C3 扩 + 1 decision + 2 gotchas。下一步 **Wave DT2.6**(@frontend 审稿页+裁决+验收 gate`pnpm gen:api`)。
- [2026-06-18] @orchestrator**Wave B 完成**T2.2✅C4 扩稳定)。审稿子图落地:`build_review_graph`(START→continuity 并行审→collect→END可扩四审) + `collect_reviews``chapter_reviews` 留痕 + `normalize_review`(SSE 加 `section`/`conflict`)M1 `build_write_graph` 不动。划清边界:本任务到 collect+归一缝为止,`interrupt`/accept 事务接线交 T2.4(对齐 R3accept 从领域表重读、checkpoint 仅控制流。全仓门禁绿ruff/format 干净、mypy **80 文件**、pytest **103 passed**。memory 登记 C4 扩 + 3 gotchasreducer/add_node 重载/失败隔离两层)。下一步 **Wave CT2.4+T2.5**(单 @backend agent 顺序做:验收事务+冲突 gate / review API+历史,避免 apps/api 路由+OpenAPI 写冲突)。
- [2026-06-18] @orchestrator**Wave A 完成**T2.1✅ C6 稳定 + T2.3✅)。两个 fresh agent 并行(@llm packages/agents+llm_gateway ‖ @backend core/domain目录不相交无冲突。**补上 M1 遗留网关缺口**`Gateway.run()` 经 instructor 接通 `output_schema→LlmResponse.parsed`(改 C1见 contracts 变更日志。T2.3 写侧三 repo章节 accepted 晋升/digest append/审稿留痕+裁决)只 flush 不 commit、交 T2.4 事务。全仓 compose 门禁绿ruff 干净、format 干净、mypy **77 文件**、pytest **89 passed**。memory 已登记 C6+C1 变更+2 decisions+3 gotchas。下一步 **Wave BT2.2**(@llm 并行审图+collect 留痕+review SSE依赖 C6+C4)。
- [2026-06-18] @orchestrator**进入 M2**:归档 Phase 1(M1) 至已归档Phase 2 七任务拉入台账。计划核对两处偏差并据实修正:(1) **T2.3「Repository 逻辑」落 `packages/core/ww_core/domain/`@backend owned而非 `packages/db`**——DB 全 MVP 表 + 唯一约束 `(project_id,chapter_no,version)` 已在 T0.2(@db) 一次建齐、M2 无新建表迁移,故 T2.3 由 @backend 承接 Repository 逻辑;(2) **网关结构化输出缺口**`Gateway.run()` 当前不消费 `output_schema`/不填 `LlmResponse.parsed`instructor 未接线),续审依赖此,归入 T2.1(@llm)。启动 **Wave AT2.1(@llm·packages/agents+llm_gateway) ‖ T2.3(@backend·core/domain)**(不同目录,无写冲突)。
- [2026-06-18] @orchestrator**🎉 M1 完成**Wave ET1.9 E2E✅。真实 DB + mock 网关 E2E 走通 立项→写章 SSE→自动保存→DB 真源断言projects/chapters/usage_ledger。**E2E 暴露并修复一个生产 bug**draft SSE 端点未提交注入 ledger 的请求 session`SqlAlchemyLedgerSink` 按设计只 flush、不 commit——写库事务归编排层导致真实写章的 `usage_ledger` 行被回滚丢失违背「成本账本从第一天」。修复draft 端点流耗尽后 `await session.commit()`E2E 改用请求 session 做 ledger、去掉手动 commit 以回归校验该提交。最终全门禁绿ruff / mypy 68 / pytest **57** / alembic 无漂移;前端 gen:api/lint/tsc/vitest 24/build 绿。
- [2026-06-18] @orchestrator**Wave D 完成**T1.5+T1.6+T1.8✅,单前端 agent`pnpm gen:api` 重生成客户端含全 M1 端点;路由 `/`(作品库)、`/projects/new`(5 步向导)、`/projects/[id]/write`(工作台 SSE 打字机+停+自动保存)、`/settings/providers`(脱敏+测试连接+能力徽标)。前端门禁全绿gen:api/lint/tsc/**test 24**/build。M1 占位(无 API 支撑、未造假端点):单章导航、本章助手/注入透明面板(M2)、向导主角/世界观字段折叠进 premise、档位路由只读。下一步 Wave ET1.9 E2E(@qa, mock 网关)。
- [2026-06-18] @orchestrator**Wave C 完成**T1.4✅ 立项+写章 API**C3 稳定**M1 端点全落)。记忆→网关→编排器串成 HTTP5 端点入 OpenAPI写章 SSE(token/done/error) + 幂等自动保存lifespan 幂等 seed stub user修 owner_id FK 缺口)。网关从凭据构建、测试经 dependency_overrides 注 mock。全仓 compose 绿ruff、mypy **68 文件**、pytest **56 passed**。后端/编排全部完成。下一步 Wave D单个前端 agent 做 T1.5+T1.6+T1.8(同一 Next 应用合并做,先 `pnpm gen:api`),避免 apps/web 写冲突。
- [2026-06-18] @orchestrator**Wave B 完成**T1.3✅ 编排器/C4稳定 + T1.7✅ 凭据/C3部分。两个 fresh agent 并行(各 ~9098k tokens比 fork 省)。全仓 compose 门禁绿ruff、mypy **61 文件**、pytest **48 passed**。修了跨包测试碰撞apps/api `fakes.py``fakes_providers.py`root mypy 排除 `conftest.py` 解决多 rootless conftest 同名)。⚠️ **Wave C 前置**DB 无 stub user而 projects/usage_ledger/provider_credentials.owner_id 均 FK→users.idT1.4 须先幂等 seed stub user(`uuid(int=1)`)。下一步 Wave CT1.4(@backend 立项+写章 SSE+自动保存,依赖 C4)。
- [2026-06-18] @orchestrator**Wave A 完成**T1.1✅ + T1.2✅,契约 C1/C5 稳定)。全仓 compose 门禁绿ruff 干净、mypy 45 文件、pytest **27 passed**9 基线 +10 网关 +8 记忆。T1.1 网关由 orchestrator 内联实现(原 fork 因 stream idle timeout 早夭、零产出T1.2 记忆由 fork 完成。下一步 Wave BT1.3(@llm 写章节点+SSE依赖 C1+C5) + T1.7(@backend 凭据,依赖 C1)。
- [2026-06-18] @orchestrator**进入 M1**:把 Phase 1 九任务拉入台账并归档 Phase 0新增 workspace 成员 `packages/llm_gateway`(ww-llm-gateway) + `packages/core`(ww-core),装 openai/instructor/langgraph/langgraph-checkpoint-postgres/cryptography/tenacity`pyproject.toml` members+mypy_path 已更,`uv sync` 通过,基线门禁全绿(ruff/mypy 27 文件/pytest 9 passed)。记录 decision`assemble` 返回中性文本以解耦 T1.1‖T1.2。启动 Wave AT1.1 @llm + T1.2 @backend)。
- [2026-06-18] @devops/@db/@backend/@frontend**Phase 0 全部完成**monorepo(uv workspace + pnpm)、16 MVP 表迁移(无漂移)、FastAPI(structlog+request_id+错误信封+/jobs/:id)、Next.js(纸感 token + OpenAPI→TS gen:api)、CI。门禁全绿API 实跑 200。下一步 M1/T1.1(网关接口)。
- [2026-06-18] @docs — DEV_PLAN 与规格对齐修订T0.3 加可观测性底座(structlog+request_id)、T1.1 加 `usage_ledger` 记账(从第一天)、T0.2/T2.3 统一建表口径(全 MVP 表一次建齐, T2.3 仅 Repository)、T4.2 把文风漂移并入第四审、新增 `PUT .../draft` 自动保存端点并回写 ARCH §7.2 + contracts C3。
- [2026-06-17] @docs — 四份规格 + CLAUDE.md + 协同系统PROGRESS/memory就绪可进 Phase 0 / T0.1。