Files
writer-work-flow/PROGRESS.md
Yaojia Wang f6e88d7438 test(qa): AI 对话(聊天记录)E2E + #1/#6 真源围栏守卫(AC-4)
计划 §6/§8。收口 AI-chat-history 功能(AC-1..AC-4 全交付)。

- tests/test_ai_chat_history_e2e.py:真 pg、零 LLM/无网关(纯 CRUD 侧记录),
  覆盖 §6 全 6 用例——缓冲多轮线程一批落库 + GET newest-first/meta 保真、
  作用域分区(本章 ∪ 项目级 NULL)、跨批分页 + kind 过滤、
  append 只写 ai_messages(其它业务表零变 + usage_ledger 恒 0)/GET 只读、
  404 + 五类 422 失败零落库、clarify-abandon(服务端无部分写路径)。
- tests/test_ai_messages_not_in_generation_path.py:AST 静态围栏——
  memory/orchestrator 两目录无一 import/引用 ai_messages,
  MemoryRepos 捆绑与 assemble 形参都不含它;植入违规自证探测器非空,能变红。
- memory/gotchas.md:登记 ai_messages 真源围栏(append-only 侧记录,
  绝不喂 assemble/prompt;接入生成链 = code-review BLOCKER)。

门禁全绿:ruff/format · mypy 238 · alembic 无漂移 · pytest 1002 passed(+10)。
2026-07-09 17:42:45 +02:00

154 KiB
Raw Blame History

PROGRESS — 多 Agent 协同任务台账

多 agent 共享的唯一协同入口。开工前读这里 + memory/;认领任务、尊重依赖、完成即更新。 完整任务定义见 DEV_PLAN.md;本台账只展开当前阶段,进入新阶段时再把该阶段任务拉进来。 协同规则见 CLAUDE.md →「多 Agent 协同」。

状态图例 待办 · 🔵 进行中(注明 @skill + 日期) · 完成 · 阻塞(注明等什么)


已交付AI 对话聊天记录持久化AC-1..AC-4 全绿)· develop 上新功能

背景[2026-07-09] 用户要求把作者↔AI 每轮往复refine/rewrite/clarify/continue/工具箱生成器)落库为聊天记录每章一个「AI 对话」抽屉展示。多 agent4 学科起草→4 视角交叉评审→合稿)产出实施计划 docs/design/ai-chat-history-plan.md决策全 Aclarify 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 2026-07-09 @db 计划 §2 canonical DDL迁移 ceabd3c2c00d(down=f6a7b8c9d0e1)C2 扩已「稳定」AC-2 可动工
AC-2 repo + append/list 端点 + schema + 契约 @backend 2026-07-09 @backend AC-1 c675a74SqlAiMessageRepo(批 append seq/thread_id + newest-first union/分页) + POST/GET /projects/{id}/ai-messages + schemasC3 扩已「稳定」→ AC-3 可动工(须 pnpm gen:api
AC-3 gen:api + AiConversationDrawer + useAiConversation + 接线 5 处交互 @frontend 2026-07-09 @frontend AC-2 dce882c/ddf7fa0/59f2f60/33a9b76gen:api + 纯视图模型 + hook + 抽屉 + 五类交互留痕clarify buffer-until-concludedvitest 706 passed / cov 95% / build OK
AC-4 E2E + #1/#6 围栏守卫 @qa 2026-07-09 @qa AC-3 计划 §6/§8tests/test_ai_chat_history_e2e.py6 用例,真 pg 零 LLM+ tests/test_ai_messages_not_in_generation_path.pyAST 围栏能变红pytest 1002 passed+10AI 对话聊天记录AC-1..AC-4 全交付

已完成阶段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 全覆盖);确认无虞SSRFbase_url 仅来自硬编码 _PROVIDER_BASE_URLS,无用户 URL 入网)/ SQL 注入(全 ORM 参数化)/ XSSdangerouslySetInnerHTML/eval/ 错误信封不泄栈密钥 / Kimi 用 RFC 8628 device flow 无 CSRF 面。 整改 DoDCRITICAL + HIGH 全部 且各自补回归测试MEDIUM 择批清理;门禁全绿(后端 ruff/format/mypy/pytest + alembic 无漂移;前端 lint/tsc/vitest/build守 §Definition of Done:每项 TDD 先红后绿、完成即小步 commit。 落地顺序:① 本周 CR-C1/C2 + 两资源泄漏H1/H2+ Fernet keyH8② 合并前 计费两项H3+ request_idH4+ max_lengthH9+ 前端三 HIGHH10/H11/H12③ MEDIUM/LOW 技术债批。 依赖纪律CR-C1升 Nextpnpm 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.20registry 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/criticallib/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 withaclose);两处测 override 跟随改,堵住 E2E 误触真网
CR-H3 🟠 Anthropic 结构化输出记真实 usage @llm cb8fddfcreate_with_completionraw.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.thinkingYAGNICapabilities.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。契约 C3gen:api 无漂移
CR-H10 🟠 前端 errorCode 去重 @frontend 5665cc9 lib/style/{useRefine,useStyleLearn} 统一 import 自 generation/cards
CR-H11 🟠 Drawer 关闭还原焦点 @frontend 6e2b478 行为本分支早已修;提取 lib/a11y/useRestoreFocus + renderHook 回归测试 + DRYDrawer/ContextDrawer 共用)
CR-H12 🟠 RefineView 取消在途 refine @frontend 5c02792 useRefine 暴露 abortsetState-free+ AbortController + aborted 守卫弃迟到响应RefineView cleanup 调用 + 真 deps
CR-M1 🟡 后端架构整改批 大部 @backend c596a8d outline volume 下推 DB WHEREProtocol/Sql/fake 加 keyword volumebf3dabe 角色/世界观入库 N+1→create_many(世界观 add_all角色一次 IN 查+一次 flush 保 upsert 幂等/批内去重;单条 create 薄封装);1392830 jobs 读端点裸 ORM→JobRepo0892ff6 projects/templates 列表加分页(ww_api.pagination limit∈[1,200]/offset≥0越界 422下推 LIMIT/OFFSETitem#4 provider_deps _client→已由 @llm 交付832ab7d OpenAICompatAdapter.probe_connection() 公开探测 + provider_deps 改调,删私有 _client 反手 + type:ignore/noqa:SLF001isinstance 收窄兜非 OpenAI 兼容)。item#6 assemble 并行→SKIP8 查询共享同一注入 AsyncSessiongather 会腐蚀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.8collect 仍一次落库;并发峰值测 + 五审落齐测)。item run_overdue_scan 幂等→SKIPscan_overdue 本已幂等(单条 UPDATE...RETURNING + status NOT IN [CLOSED,OVERDUE] + commit-only-if-changed原子无部分空洞且下一章扫描 current+1 自愈漏标;再动会触碰验收事务边界,单用户零收益
CR-M4 🟡 前端 key/a11y/cleanup 批 @frontend 47d5558 ARIANavDrawer aria-controls + Drawer id + ForeshadowCard 语义化 <dl>/<dt>/<dd>+ 125908e ReviewReport flashMark setTimeout 卸载清理ref 存句柄)。核实为无需改/已具备index-key三处均 replace-all/append-only 静态展示、无天然稳定 idindex 安全;卡名可编辑作 key 更糟)、stop(经查服务端 SSE 帧、是客户端 AbortController 动作加则处理不存在事件、AppShell nav label<nav aria-label> 已有、ProjectWizard 步骤焦点(stepHeadingRef+首帧守卫 useEffect 已实现)
CR-M5 🟡 前端 TS 边界类型收紧 @frontend d80d41a ApiErrorEnvelope 改由生成 schemacomponents.schemas.ErrorEnvelope)派生防漂移 + 9cf4915 hasApplicableFix 改对象参类型谓词、消除 applyConflictFix 两处 as string + 16f2eae parseJsonBody(结构校验 HEAD 已具备,补非对象/非 JSON 守卫分支测试)
CR-L1 🟢 LOW 清理批 @backend·@llm·@frontend @backend49e3cb6 SSE draft/rewrite/review 补 OpenAPI text/event-stream 声明(共享 _SSE_RESPONSEprint→logging 无需改owned 目录唯一 print(export_openapi.py CLI stdout前端 gen:api 管道消费,改则断管道)。@llmc9ffada 续写链前一章无已验收终稿发 chain_prior_accepted_missing warning。@frontend6414542 去冗余 as/.valueOf() caststream/sse.ts idx.valueOf、jobs/job.ts dict[error] as string;保留 load-bearing 的 CSS-var 键/变量键强转)
CR-D1 🟡 抬高后端依赖下界(可选升级评估) @devops 8 个 pyproject 后端运行时下界抬到 lockfile 主次版本(langgraph>=1.2/anthropic>=0.111/openai>=2.43/pydantic>=2.13/fastapi>=0.137/cryptography>=49 等,每条 ≤ 实锁);uv.lock 纯元数据刷新(仅 requires-dist specifier零 pinned 版本变动);uv lock --check 绿、pytest 971、ruff 干净。root dev 工具下界 + 前端 vitest/tailwind 升级评估未纳入(超范围)

[2026-07-08] CRITICAL + HIGH 全部 落地14 项 + 4 项低危收尾),多 agent 并行开发(@llm/@backend/@devops/@frontend 四簇串行整合,各 TDD 红→绿、逐项补回归测试)。门禁全绿:后端 ruff/format 干净 · mypy 229 · alembic 无漂移 · pytest 934;前端 lint/tsc 干净 · vitest 669 · build OK · coverage 95.41%14 项对抗式复核 0 problemskeptic 逐条实证 test 非 vacuous。落地含 3 处前提证伪C2 非实活崩溃/H4 sync-SSE 已由 contextvars 贯通/H11 行为本分支已修)。

[2026-07-08] MEDIUM/LOWCR-M1..M5 / L1 / D1亦全部清理 (四簇串行整合):明确取舍——高价值低风险项落地、风险>价值或前提已陈旧的子项有据 SKIP/NOOPassemble 并行 gather / breaker is_open CQS / overdue-scan 已幂等 / index-key 安全 / stop 非服务端帧 / 已具备的 nav-label、wizard 焦点)。门禁全绿:后端 mypy 232 · alembic 无漂移 · pytest 971;前端 vitest 681 · build · coverage 95.45%。附带修复:一 agent 误提交的非源文件(.coverage/AGENTS.md/example_skills)已撤销还原为未跟踪(1bda024)。

维度小结:后端 FastAPI 架构 0C/2H/7M·Python 规范 0C/4H/6M·LangGraph 1C/2H/5M·前端 React 0C/2H/9M·前端 TS 0C/1H/8L·安全 0C/2H/4M·依赖 1C。后端依赖全部当前大版本线前端唯一关键缺口=Next RCE。

[2026-07-08] CR-M1 + CR-L1 后端片 落地@backend6 提交 c596a8d/bf3dabe/1392830/0892ff6/49e3cb6各行为改动先写红测再实现。CR-M1 4/6 完成volume 下推 · N+1→create_many · jobs→JobRepo · 列表分页item#4_client)与 item#6assemble 并行SKIP理由见 CR-M1 行CR-L1 后端片完成SSE OpenAPIprint 属误报)。门禁全绿:后端 ruff/format 干净 · mypy 230 · pytest 960 passed(较基线 955 +5 新测volume 下推 1 + 分页 2 + 批量入库 2· 无模型改动故免 alembic。新增 5 测无回归,既有 upsert 幂等/冲突 gate + m5 真 pg E2E 全绿。

[请求 → @llm] CR-M1 item#4apps/api/ww_api/services/provider_deps.py:91 需去掉对 adapter 私有 _client 的探测(adapter._client.models.list()。owning 类 OpenAICompatAdapter/ProviderAdapterpackages/llm_gateway/ww_llm_gateway/adapters/)在 @llm 域——请在 adapter 上加一个公开 async probe_connection()(内部最小请求验 Keymodels.list()@backend 改调该公开方法即可删私有属性访问 + type: ignore/noqa: SLF001。行为保持不变。


进行中写作工作台重构writing-first· 分支 feat/writing-first-workspace

背景[2026-07-07] 用户对写作体验提 8 点反馈,产品主张升级为 writing-first 工作台——进来即写、所有工具/AI 动作从编辑器内按需调用并回填正文、元数据由内容渐进生成。多 agent 工作流扎根代码→Web+GitHub 调研→三方设计→四镜头对抗评审→定稿)产出 DEV_PLANscratchpad/writing-first-workspace-DEVPLAN.mdephemeral 未入库;灵感/取舍见 memory/selectable-write-prompts.md)。 已拍板决策:进来即写=延迟落库(首次击键才建占位项目 + 列表过滤空稿);可选提示词 MVP=纯前端 directive→volatile不改 DraftStreamRequest 契约、不动 write_craft.md 字节 → 金标准零回归);预设 MVP=先只上内置;续写=多候选卡点选插入。 纪律:全程 TDD 小步提交,回填全守 HITLAI 绝不 auto-replace点选/接受才落草稿);/refine/rewrite 只读不写库(不变量 #3门禁全绿:前端 vitest 678 / lint / tsc / build / coverage 95.36%;后端 ruff / mypy 229 / pytest 955(含 WFW-9 clarify E2E/ alembic 无漂移。WFW-0~9 全部交付WFW-5/6/7 多 agent 并行 → 3dd7d28WFW-8 整章重写跨栈 → 6ed9c89+542c2abWFW-9 三段全交付 M1 1652ad9+e30c933 / M2 4a09f27..8e29b33 / M3 ea9a9d9+a703a90,契约 C-Rewrite+C-Clarify 见 memory/contracts.md)。未 push、未开 PR(等用户示意)。

任务 状态 负责 依赖 反馈# 备注
WFW-0 进来即写(延迟落库) @frontend #5 8389572 /write(DraftComposer) + lib/start/useDeferredDraft(懒建占位项目+种首章草稿,双重幂等,空进空出不落库) + 落地页 CTA「直接开始写」主/「先立项」辅
WFW-1 润色 / 再沟通 @frontend #1#2 2f0b841 useRefine(同步/refine,版本栈,再沟通=上一版产出+新意见再回炉) + refineApply(接受回填按内容重锚,原文变则提示重选) + RefinePanel 内联卡 + Editor 上报选区
WFW-2 续写(多候选) @frontend WFW-0 #2 9195cf3 useContinue(continue 生成器 with_prior_chapter 读前文,多候选累加) + ContinuePanel 候选卡点选插入章末 + flush 后读最新草稿
WFW-3 内联工具箱 + 金手指露出 @frontend #4#8 04f4785 useToolboxTools(客户端拉描述符) + InlineToolbox(列非 legacy 生成器含金手指) + GeneratorRunneronInsertText(文本产物插入正文)
WFW-4 AI 写作三槽(文风/剧情/自定义) @frontend #3 44b0b8a directive.tsPLOT_PRESETS + composeDirective 合并;DirectivePanel 拆文风/剧情两组 chips + 自定义。纯前端零契约,write_craft.md 字节不变
WFW-5 内容感知书名 @frontend #6 3dd7d28 纯前端零后端 MVPbuildManuscriptExcerpt(首尾摘录+硬上界) + GeneratorRunner「用当前正文」按钮把摘录填 briefbook-title 据正文反推。后续更佳版:后端富化 book-title.md + with_manuscript 策略(未做)
WFW-6 侧栏 IA 收敛ContextDrawer @frontend #7 3dd7d28 加法式 ContextDrawer 右侧速查抽屉 + 底栏「速查」按钮;设定库/大纲完整只读速查,伏笔/规则/文风摘要+跳全宽页(后续可补真实数据)。CONTEXT_DRAWER_ENABLED 一键回滚、旧侧栏/全宽页路由全保留
WFW-7 首次 AI 写作前极轻 genre 采集 + 无大纲降级 @frontend WFW-0 3dd7d28 无题材首次写章前弹 GenrePicker(临时并入本次 directive 不落库) + chapters 空时「尚无大纲,将按设定自由生成」提示,杜绝无题材 slop
WFW-8 整章级「再沟通/重写」(对话式迭代) @backend·@llm·@frontend 新#1 6ed9c89(后端)+542c2ab(前端)。后端 SSE POST .../rewriterewrite.md 教条 + rewrite_node + RewriteStreamRequest,复用 assemble 记忆注入,只读不写库、工具非写节点、守 #3/#7/#9前端 useChapterRewrite(版本栈)+ChapterRewritePanel+底栏「整章重写」:给意见→流式重写整章→多轮迭代→接受某版才替换正文(HITL)。契约 C-Rewrite。用户反馈「整章不满意要跟 AI 交流」
WFW-9 M1 AI 反问澄清refine 侧路线A 两阶段) @backend·@llm·@frontend 新#2 1652ad9(后端)+e30c933(前端)。多agent并行(后端整片‖ChoiceChips)+主线集成。非流式预检 POST .../refine/clarifyClarifyDecision(结构化,analyst,只读,失败回退放行)+clarify_refine spec/教条(SPECS#24);既有 refine 未改。前端 useClarify+ChoiceChips+clarify.ts(foldClarifications/门控)+RefinePanel 门控接线:意见<10字或点「帮我理清方向」→AI反问选项→折答案进instruction→走既有refine。契约 C-Clarify。M1 refine 侧完成M2/M3 见下两行
WFW-9 M2 AI 反问澄清rewrite 侧,整章重写路径) @backend·@llm·@frontend 新#2 4a09f27+6fd6375(后端)+9b32743+4b1088a+8e29b33(前端),多 agent 串行整合。新非流式预检 POST .../rewrite/clarifyClarifyDecision(复用 M1 schema/run_clarify)+新 clarify_rewrite spec/教条(章级,SPECS 24→25,prompt_hashes +1)+RewriteClarifyRequest{feedback,prior_draft?}(仅取有界 3000 字摘录喂 analyst,不整章入 LLM);只读不写库、失败放行。前端 useRewriteClarify+toVM/PROCEED 提取入共享 clarify.ts(DRY)+ChapterRewritePanel 门控(镜像 RefinePanel):意见<10字或「帮我理清方向」→反问→折进 feedback→走既有 rewrite SSE。契约 C-Clarify 扩;gen:api 纳入新端点
WFW-9 M3 澄清 UX 打磨 + E2E @frontend·@qa ea9a9d9(a11y):refine/rewrite 两面板 AI 反问块加 role=status 向读屏动态播报(WCAG 4.1.3 Status Messages)。a703a90(E2E):tests/test_wfw9_clarify_e2e.py 7 用例真 pg+mock 网关零 token——refine/rewrite 含糊→反问 / 清晰→放行 / 失败开路(parsed=None→200 need_clarification=false,不 500) / 只读不写业务表但记 usage_ledger / 404。无产品 bug。深度视觉/交互 QA(真起前端浏览)为人工验收事项
WFW-9 M2 AI 反问澄清rewrite 侧路线A 两阶段) 后端 @llm·@backend WFW-8·WFW-9 M1 新#2 4a09f27(llm)+6fd6375(后端)。镜像 M1非流式预检 POST .../rewrite/clarifyRewriteClarifyRequest{feedback(必给),prior_draft(可选)}ClarifyDecision(复用同一 schema,analyst,只读,失败回退放行)+clarify_rewrite_spec/教条 clarify_rewrite.md(segment→整章,SPECS#25);既有 .../rewrite SSE 未改。端点只喂 prior_draft 开头 3000 字摘录(不整章入 LLM)、日志脱敏。契约 C-Clarify(扩)。门禁绿:后端 ruff/format·mypy229·pytest948·alembic 无漂移。前端仍欠 pnpm gen:api+M2 UI 接线(仿 RefinePanel 门控 ChapterRewritePanel) + M3 UX/E2E 待办
WFW-9 E2E两阶段 AI 反问澄清refine+rewrite @qa WFW-9 M1·M2 新#2 tests/test_wfw9_clarify_e2e.py 7 用例真 pg + mock 网关provider/adapter 层,同 M2/T6 范式)零 tokenrefine 含糊→反问1问 / refine 明确→放行、rewrite 含糊→反问 / rewrite 明确→放行、失败开放(网关产非 ClarifyDecision→仍200 need_clarification=false 不 500 且仍记账)、只读(seed chapter 字节一致+无 review/digest 行)但 usage_ledger 真落 analyst 一行、404 信封。响应绝不回灌原文摘录。无产品 bug。门禁绿:ruff/format·mypy 本文件净·pytest 955 passed

已封板T6 · 创作工具箱(通用生成器框架)

背景对标竞品「创作工具箱」——把每个「XX 生成器」实现为声明式 skillAgentSpec 的设计本意),用一条通用执行路径驱动。用户已定:① 走通用 skill 框架(非逐个硬编码)② 封面/图像本期跳过 ③ 文本生成器全做(上架已有 3 + 新建 8。完整设计见 ~/.claude/plans/creation-toolbox-generators.mdP1 目标DoDGeneratorTool 描述符 + TOOLBOX 注册表 + 通用 GET /skills/toolbox & POST /projects/{id}/skills/{tool_key}/generate 端点 + 1 个最简生成器(脑洞)端到端打通mock 网关 E2E 零 token。证实「加生成器 = 加一份声明」这条路。 执行波次A(@llm 脑洞 spec + IdeaListResult schema + brief_only context 策略 + 通用 run 路径) → B(@backend GeneratorTool/TOOLBOX 注册表 + 通用 toolbox/generate 端点 + response schema + 接线 build_gateway_for_tier) → C(@qa 脑洞 generate E2E真 DB + mock 网关,断言 unknown key 404 / 无 provider 503 / 仅记 ledger 不写业务表)。 契约纪律B 改 OpenAPI → memory/contracts.md 记 C 扩 + PROGRESS.md 记一笔(前端 P2 才 pnpm gen:api)。守不变量 #2只声明 tier/#3预览不写库预计无 DB 迁移descriptor 在代码、复用既有表)。

任务 状态 负责 依赖 契约 备注
T6.1 脑洞 spec + IdeaListResult schema + brief_only context + 通用 run 路径 @llm 新 schema/spec 完成:schemas.pyIdea/IdeaListResultspecs.pybrainstorm_spec(light, reads=[projects], writes=[])generation_node.pybuild_brief_context + 通用 run_generator(据 spec.output_schema 校验 parsed不绑定具体类型任一声明式生成器共用两包 ruff/format/mypy 干净、新增 13 测 + 全包 252 passed 无回归。@backend T6.2 可起:从 ww_agentsbrainstorm_spec/IdeaListResult、从 ww_core.orchestratorrun_generator/build_brief_context
T6.2 GeneratorTool 描述符 + TOOLBOX 注册表 @backend T6.1 C3扩稳定 packages/skills/ww_skills/toolbox.py(描述符类型,frozen) + toolbox_registry.py(TOOLBOX 11 条 + get_tool)。25+7 测
T6.3 通用端点 toolbox/generate(+ingest) @backend T6.2 C3扩稳定 routers/toolbox.py 3 端点 + schemas/toolbox.py + services/toolbox_context.py(纯 dispatch) + get_tier_gateway_builder 注入缝。generate 预览仅 commit ledgeringest 复用 continuity 409 + partition_writes 白名单。未知 key 404 / 无 provider 503
T6.4 E2Etoolbox 全路径) @qa T6.3 tests/test_t6_toolbox_e2e.py 5 用例真 pg + mock 网关零 token列表 11 key、brainstorm 预览仅 ledger 零业务写(#3)、glossary ingest 409→ack 放行真落 world_entities、unknown 404、无 provider 503、token 不泄漏。无端点 bug
T6.5 7 新生成器 spec+schema + with_outline_chapter @llm 新 schema/spec schemas.py +7 输出 schema、specs.py +7 spec(book-title/blurb/name/golden-finger/glossary/opening/fine-outline只声明 tier #2)、generation_node.py +build_outline_chapter_context。309 passed
T6.6 工具箱落地页 + 声明驱动 Runner @frontend T6.3 app/projects/[id]/toolbox/page.tsx(RSC) + components/toolbox/{ToolboxPage,ToolCard,GeneratorRunner} + lib/toolbox/*(纯函数) + LeftNav「工具箱」+ ⌘K nav-toolbox/action-gen-*。legacy 3 跳现页。vitest 155→279/build OK
P2 收尾(限流/noopener/Committable @backend+@frontend 限流→decisions.md 记延后(单用户原型)noopener 与 Committable 经查本分支早已修;provider_deps.py 残留 type:ignore 为 SDK 私有属性探活,load-bearing 保留

T6 出口DoD 达成:通用执行器驱动全部 8 个新生成器 + 工具箱落地页声明驱动后端门禁绿ruff/format/mypy 195/alembic 无漂移/pytest 583前端门禁绿gen:api/lint/tsc/vitest 279/buildE2E mock 网关零 token 全路径走通。实景 browse 复验(工具箱卡片栅格→脑洞预览→词条入库)待做。 后续可选 P5封面图像轨道 / 自定义 skill 运行期 schema / 收敛已有 3 竖井)。


已封板Prompt 管理重构方案A+ 全量 prompt 重写

背景:把 21 个内置 agent 的 system_prompt 散文从 specs.py Python 常量外置为 .md 文件,并统一内置/用户 skill 的只读解析入口。设计真源 docs/design/prompt-management.md;契约 memory/contracts.md C6-ext决策/坑见 memory/{decisions,gotchas}.md2026-06-24多 agent 工作流交付TDD + 并行开发 + 交叉验证评审。

任务 状态 负责 备注
方案A 步骤13spec_model/prompt_loader/prompts/*.md×21/schema_catalog/SPECS/REVIEW_RESERVED_NAMES @llm 金标准 sha256 取运行时值;SPECS[name] is *_spec 同一实例;三集合 name 恒等
方案A 步骤45SpecResolver(内置纯内存零 DB+ SkillRegistry 入库守卫前移 + toolbox_registry 桥接 SPECS @backend 守卫锚 REVIEW_RESERVED_NAMES set(SPECS);删 12 生成器 *_spec 直接 import
打包/CI.gitattributes eol=lf + wheel artifactsprompts/*.md + agents-wheel-smoke 冒烟;structlog 补声明 @devops 裸装 import ww_agents; assert SPECS 通过;.gitattributes 须完整嵌套路径
集成回归:#12 编排器无回归 + #15 apps/api import-smoke*_spec is SPECS[name]+ #16 CI 冒烟 @qa 内容无关,长青
全量重写 21 prompt 内容(任务对齐 + prompt 工程最佳实践schema 契约/不变量保持) @llm/@qa 激进重写;金标准 fixture 重生成;护栏全验(无占位/无 model 名/中文/≤1 尾 LF/四审只读)

出口DoD:后端门禁绿 ruff/format clean · mypy 209 · pytest 744 passed;缓存断点前块字节稳定(不变量 #9金标准守零 schema 变更、前端零影响(无 pnpm gen:api)。已合并 develop(外置 wave 4f561da、重写 wave eb356c4)。后续可选:编排器 + apps/api 3 路由切 SpecResolver 后删 *_spec 导出。


已封板K1 · Kimi Code OAuth订阅 plan 接入)

背景:用户要求接入 Kimi Code 订阅 plandevice-flow OAuth已知情接受 ToS/封号风险——研究确认:用订阅 plan 调用需伪造官方客户端 User-Agent + X-Msh-*Kimi ToS 视为违规、可能封停会员(见变更日志研究结论)。用户明确选择此路径(非合规的 API Key 路径)。与既有 API-key провайдер kimi 分离,新增独立 provider kimi-code 以便切换。 集成契约(研究确认,实现时对照 github.com/picassio/pi-kimi-coder 校验)

  • device flowPOST https://auth.kimi.com/api/oauth/device_authorizationclient_id 17e5f671-d194-4dfb-9706-5516cb48c098env KIMI_CLIENT_ID 可覆盖scope kimi-code)→ 返回 user_code/verification_uri/device_code/interval轮询 POST https://auth.kimi.com/api/oauth/tokengrant device_code处理 authorization_pending/slow_down。refresh同 token 端点 grant refresh_token。
  • 推理base https://api.kimi.com/coding/v1OpenAI 兼容model kimi-for-codingAuthorization: Bearer <access_token> + 必需伪造头User-Agent(如 KimiCLI/1.x) + X-Msh-Platform/X-Msh-Version/X-Msh-Device-Name/X-Msh-Device-Model/X-Msh-Os-Version/X-Msh-Device-Id(持久 UUID)。缺头→403。
  • tokenaccess ~15min / refresh ~30d → 建网关时按需刷新(临近过期刷新并持久化)。存储:provider_credentialsauth_type(api_key|oauth) + oauth_enc(Fernet 加密 JSON {access_token,refresh_token,expires_at})。 执行波次A(@db 加列+迁移 ‖ @llm Kimi coding 适配器) → B(@backend OAuth device 服务 + 端点 + store + _build_provider_adapter 接线) → C(@frontend 设置页连接/轮询/断开 + 路由档位) → D(@qa E2E device-flow mock + 头断言)。 测试纪律device flow 注入 fake httpx零联网适配器断言伪造头集token 刷新逻辑单测E2E mock auth+coding 两端点。
任务 状态 负责 依赖 契约 备注
K1.1 provider_credentials 加 auth_type + oauth_enc 列 @db C2扩 完成models 加 auth_type/oauth_enc + api_key_enc 改 nullable迁移 1f011c42bd4dalembic check 无漂移。⚠️ K1.3 @backend 须把 StoredCredential.api_key_encbytes|None(见下方请求 + memory
K1.2 Kimi coding 适配器(伪造头 + OAuth bearer @llm C1扩 完成:adapters/kimi_code.py(KimiCodeAdapter 子类化 OpenAICompatAdapter + 伪造头 + 稳定 device_id)build_adapterkimi-code 分支UA 验证为 KimiCLI/1.5pi-kimi-coder 仅设 UAX-Msh-* 为契约附带,见 C1扩 校正11 测全绿
K1.3 OAuth device 服务 + 端点 + store + 接线 @backend K1.1,K1.2 C3扩 完成:services/kimi_oauth.py(start/poll/refresh,注入 httpx Protocol)+3 端点(start 202→jobs 后台轮询/disconnect/status,复用 run_job)+StoredCredential 收口(api_key_enc→nullable+auth_type/oauth_encK1.1 的 2 mypy red 已消)+store upsert_oauth_credential/delete_credential+_build_provider_adapter OAuth 按需刷新(300s 缓冲)。token 不进 job 结果/日志/响应。全仓门禁绿(ruff/format/mypy 154/alembic 无漂移/pytest 430)。OpenAPI 加 3 端点→@frontend K1.4 须 pnpm gen:api
K1.4 设置页 Kimi Code 连接流 @frontend K1.3 完成:gen:api 纳入 3 OAuth 端点;KimiCodeOauth 连接区(显 user_code+开授权页+轮询 job→已连接/断开)+ 可编辑档位路由(含 kimi-code:kimi-for-coding);纯逻辑 lib/settings/{kimiOauth,providers} + 25 新 vitest前端门禁全绿gen:api/lint/typecheck/vitest 155/build。运行时验真 auth.kimi.com 留 K1.5
K1.5 K1 E2E @qa K1.4 tests/test_k1_kimi_oauth_e2e.py(4 用例,真 pg)device-flow(pending×2→成功)→加密 token 真落 pg(无明文+回环)→建网关断言 KimiCodeAdapter coding base+伪造头+bearer→refresh-on-build 更新存量 token(DB 真源)→disconnect 清除token 全程不进 job 结果/状态/start 响应。全仓门禁绿(ruff/format/mypy 154/alembic 无漂移/pytest 434)。K1 完成,可封板

K1 出口DoD 全部达成:作者在设置页用 Kimi Code OAuth 登录device flow显 user_code + 开授权页 + 轮询 job→ token Fernet 加密入库(oauth_enc,全程不进 job 结果/日志/响应)→ 把档位路由到 kimi-code:kimi-for-coding → 建网关时构 KimiCodeAdaptercoding base + 伪造 UA/X-Msh-* 头 + bearer→ token 临近过期建网关时自动刷新并回写。后端门禁绿ruff/format 干净 / mypy 154 / alembic 无漂移 / pytest 434前端门禁绿gen:api/lint/tsc/vitest 155/buildE2Etests/test_k1_kimi_oauth_e2e.py 4 用例device-flow mock 零联网走通DB 真源逐项断言(含 token 不泄漏 + refresh-on-build + disconnect 清除)。K1 完成。 ⚠️ 仍需用户用真账号对真 auth.kimi.com/api.kimi.com 做一次联网冒烟device-flow 需伪造官方客户端 UA → ToS 视为违规、可能封停会员用户已知情自担E2E/单测仅验逻辑、不联网。


状态M1M5 全部完成(含 M5 三项收尾余项已清理)

当前无活跃阶段。 Phase 05M1M5已全部交付M5 的三项非阻塞收尾余项①Codex 读端点、②Anthropic/Gemini 真实适配器选择、③packages/skills 纳入 workspace亦已清理。各阶段详情见下方「已归档阶段」+「变更日志」。 最终门禁(本次全绿):后端 ruff/format 干净、mypy 144 文件、alembic 无漂移、pytest 400 passed;前端 lint/typecheck 干净、vitest 130 passed、build OK。 下一步若继续DEV_PLAN §4 的 P2/后续(向量检索 / 真任务队列 / 全书一致性扫描 / 社区市场),进入时把对应任务拉入本表。 仍开放的非阻塞备注@devops 复核根 uv.lock@backend 改了 packages/skills/pyproject.toml deps 后已 uv sync 重建 ww-skillsAnthropic/Gemini 真实回退已接线(build_adapter 工厂 + 按 provider 选适配器)但尚未对真 SDK 联网验证(单测/E2E 用 OpenAI 兼容 mock


已归档阶段

Phase 5 · 生成 + 多 provider + 扩展 (M5) — 全部完成2026-06-19

T5.1 worldbuilder + character-gen 节点C6扩;群像防雷同注入已生成+已有 + 入库前 continuity 校验缝 precheck_generated_cards@llm · T5.4 网关多 provider 韧性C1Anthropic/Gemini 适配器 + 回退链 + CircuitBreaker + tenacity 退避 + 能力协商/降级 served_by.degraded,无 OpenAPI 形变)@llm · T5.5 Skill 运行时 + 规则C8 + C3扩;SkillRegistry.load 越权声明拒绝 + 表权限沙箱 filter_reads/partition_writes + POST /rules@backend · T5.2 生成/入库 APIC3world/characters generate 预览 + POST characters 入库双 gatecontinuity 预检 409 + partition_writes 白名单 + schema→JSONB 形变 + GET rules/skillsbuild_gateway_for_tier 接线 chain_from_routing 回退)@backend · T5.3+T5.6 角色生成器 + 世界观设计器 + 设定库 Codex + 规则页 + 技能库 + 命令面板⌘K@frontend · T5.7 M5 E2E + 切 provider真 Gateway deepseek 失败→openai 回退、DB ledger 记实际服务方、能力降级)@qa。 出口达成后端门禁绿ruff/format 干净 / mypy 142 / pytest 391 / alembic 无漂移,复用 T0.2 既有表零建表迁移前端门禁绿gen:api / lint / tsc / vitest 125 / buildE2E 真 DB + mock 多 provider 零 token 走通。M5 完成 → M1M5 全部交付。 三非阻塞余项①Codex 读端点、②Anthropic/Gemini 真实适配器选择、③packages/skills 纳入 workspace随后于同日全部清理见变更日志 follow-up #1#4

Phase 4 · 文风 (M4) — 全部完成2026-06-19

T4.2 style-auditor 双轨 + 第四审C6扩/C4扩;style_extract_spec(analyst,16 维指纹带证据,不进 review 图) + style_drift_spec(name="style",light,第四审并入 REVIEW_SPECS) + refiner_spec(writer 纯文本)REVIEW_SPECS 四审齐 + collect/SSE 加 style@llm · T4.1 jobs 长任务基建C3.5JobRepo/SqlJobRepo + run_job 独立 session + lifespan zombie reaper@backend · T4.3 API style + refineC3扩;POST /style 202+jobs BackgroundTask、GET /style 最新指纹、POST /refine 同步 diff 不写库)@backend · T4.4 文风页 + 漂移 + 回炉 + job 轮询(useJobPoll 状态机 + StyleUpload/FingerprintView + 审稿页第四审 StylePanel + RefineView diff 采纳合入)@frontend · T4.5 M4 E2E学文风→202 job→后台跑完→指纹真落 pg version+1 + 第四审 SSE/chapter_reviews.style 真填 + 回炉不写库)@qa。 出口达成后端门禁绿ruff/format 干净 / mypy 115 / pytest 296 / alembic 无漂移,全程零建表迁移,复用 T0.2 预留的 style_fingerprint/chapter_reviews.style/jobs前端门禁绿gen:api / lint / tsc / vitest 96 / buildE2E 真 DB + mock 网关零 token 走通 学文风→第四审打分→回炉DB 真源逐项断言。@docs 已把 GET /style 回写 ARCH §7.2/PRODUCT_SPEC §6。

Phase 3 · 伏笔 + 节奏 (M3) — 全部完成2026-06-18

T3.1 foreshadow Repository + 纯函数状态机OPEN/PARTIAL/CLOSED/OVERDUE 全转移 + 到期判据 + ForeshadowLedger* 写侧 repo@backend · T3.4 outliner Agent + 伏笔窗口C6扩;outliner_spec + OutlineResult(含 foreshadow_windows) + run_outline 只读节点)@llm · T3.3 foreshadow-analyst + pace-checker 节点C6扩/C4扩;并入 REVIEW_SPECS 三审齐 + collect 分列 + SSE foreshadow/pace 事件)@llm · T3.2 到期扫描 BackgroundTask + 登记/状态接口(验收后 run_overdue_scan 自建 session 置 OVERDUE + POST/PATCH .../foreshadow,重复/非法→VALIDATION 422@backend · T3.5 API outline + foreshadowC3扩;GET .../foreshadow?status= 看板 + POST .../outline upsert outline 表含窗口)@backend · T3.6 伏笔看板 + 大纲编辑器 + 节奏报告(四泳道 + beats+窗口徽标 + 审稿页节拍图▁▃▅)@frontend · T3.7 M3 E2E伏笔埋设→进展→验收后扫描 OVERDUE + 大纲含窗口 + 三审 SSEstrict-xfail 钉住并发记账 bug@qa · T3.8 [bugfix] 并行审记账并发安全(SqlAlchemyLedgerSink.record 改 add-only 去 await flush,解 AsyncSession 并发 flush 冲突xfail 转 XPASS 后解钉)@llm。 出口达成后端门禁绿ruff / mypy 111 / pytest 228 passed0 xfailed/0 failed/ alembic 无漂移,foreshadow 表已 T0.2 建齐无新建表前端门禁绿gen:api / lint / tsc / vitest 69 / buildE2E 真 DB + mock 网关零 token 走通DB 真源逐项断言。T3.7 暴露并发记账 bug → T3.8 修复 → 解钉 xfail。

Phase 2 · 一致性 + 验收 (M2) — 全部完成2026-06-18

T2.1 续审 AgentSpec+结构化输出契约+网关 instructor 接线C6稳定,改 C1run()parsed@llm · T2.2 LangGraph 并行审+collect 留痕+review SSEC4扩)@llm · T2.3 摘要/审稿留痕 Repository+章节 version@backend表已 T0.2 建)· T2.4 验收事务+冲突 gate单原子事务 + R2 事务外提炼 digest@backend · T2.5 review API+历史C3扩)@backend · T2.6 审稿报告页+冲突裁决+验收 gate @frontend · T2.7 M2 E2E真 DB+多档位 mock 网关零 token@qa。 出口达成后端门禁绿ruff / mypy 90 / pytest 114 / alembic 无漂移前端门禁绿gen:api / lint / tsc / vitest 45 / buildE2E 写→审→裁决→验收→摘要入库闭环、DB 真源逐项断言。设计决策 R1R6 全兑现(见 memory/decisions)。

Phase 1 · 写章闭环骨架 (M1) — 全部完成2026-06-18

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 占位:本章助手/注入透明面板、向导主角/世界观字段、档位路由可写。

Phase 0 · 基建与栈修订 — 全部完成2026-06-18

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


变更日志append-only最新在最上

格式:- [YYYY-MM-DD] @skill 完成/进展 Txx — 一句话结果 + 影响的契约/文件

  • [2026-07-09] @qa — AC-4 E2E + #1/#6 真源围栏守卫AI 对话聊天记录AC-1..AC-4 全交付(计划 §6/§8E2Etests/test_ai_chat_history_e2e.py,真 pg、零 LLM 无网关——纯 CRUD 侧记录,镜像 test_t6_toolbox_e2e.pye2e_sm 生命周期)覆盖 §6 全 6 用例:① 缓冲多轮线程一批落库作者含糊→AI 反问〔选项进 meta→作者答→AI 定稿,同 thread_id/seq 0..3)→ GET newest-firstseq/role/thread_id/meta{options,version_no,segment} 往复保真、全文 content 未截断);② 作用域分区(章级 项目级 chapter_no IS NULL——?chapter_no=N 两者都返回、缺省仅项目级、项目级现于任一章抽屉);③ 跨多批 newest-first + limit/offset 分页 + kind 过滤;④ append 只写 ai_messagesUsageLedger/Chapter/ChapterReview/WorldEntity/Job 逐表零变化、usage_ledger 恒 0 证无网关、GET 只读不建行;⑤ 未知项目 POST/GET 皆 404、非法 role/kind·空 messages·超上限 content/meta 五类 422 且失败零落库;⑥ clarify-abandon 代理(服务端无部分写路径,只持久化被显式 POST 的已定线程)。围栏tests/test_ai_messages_not_in_generation_path.pyAST 静态守卫,能变红memory/orchestrator 两目录 23 文件无一 import/引用 AiMessage*/ai_message_repoName/Attribute/Import 全扫)+ MemoryRepos 捆绑与 assemble 形参都不含它 + 植入违规自证探测器非空——把 ai_message repo 接进 assemble() 会直接失败(已用真 assemble.py 源注入验证变红)。守 #1/#6聊天记录是 append-only 旁路侧记录(同 usage_ledger 物种),绝不喂 prompt/记忆注入。门禁全绿ruff/format 干净 · mypy 238 文件 · alembic check 无漂移 · pytest 1002 passed992 基线 + 10E2E 6 + 围栏 4。gotcha 已登记ai_messages 真源围栏 = code-review BLOCKER。仅动 tests/ + memory/gotchas.md + PROGRESS.md未碰任何产品代码

  • [2026-07-09] @frontend — AC-3 gen:api + AI 对话 hook/抽屉 + 五类交互留痕(计划 §4dce882c/ddf7fa0/59f2f60/33a9b76)。gen:apidce882cPOST/GET /projects/{id}/ai-messages + AiMessage* 4 schema 入 schema.d.tsopenapi.json 为 gitignore 构建产物),lib/api/types.ts re-export 码生成名。核心ddf7fa0lib/workbench/aiConversation.ts 纯视图模型(kindLabel/kindBadgebubbleSidegroupByThread(created_at,seq) 组内+线程定序〔绝不单靠 created_at——同批共享 created_at 靠 repo 的 seq 消歧〕、partitionByScope〔本章 项目级〕、acceptActionForrewrite→替换整章 / continue·generator→插入正文 / refine→回填选段 / clarify→无+ 11 单测;lib/workbench/useAiConversation.ts Workbench 级单实例(懒加载去重 + mergeById 防并发覆盖 + 乐观插入/正位对账/失败回滚,fail-soft 绝不 throw 进生成/HITL〔守 #3 意图〕;silent 直投供无抽屉的工具箱页)+ 9 renderHook 测试;components/workbench/AiConversationDrawer.tsx 克隆 ContextDrawer 的 a11yrole=dialog/logaria-live additions、Esc、focus trap、还原焦点、prefers-reduced-motion本章对话 + 项目级生成两段气泡、clarify 只读选项芯片、ai 气泡挂 DRAFT-only 再接受。hook 返回产物59f2f60):四生成 hook 加返回值(RefineVersion|null/string|null/RewriteVersion|null/GeneratorArtifact|null,向后兼容,补成功用例断言)。五处接线33a9b76RefinePanel/ChapterRewritePanel 结束后 append [author(意见/答复), ai(产出)]clarify buffer-until-concluded——澄清 Q&A原含糊意见→AI 反问〔选项进 meta→作者答复缓冲随最终产出批一起落库同 thread_id纯放弃不记refine ai 行 meta 存 version_no+原选段每版重锚ContinuePanel ai-only续写无作者输入meta candidate_indexGeneratorRunner append [author(字段摘要,meta{tool_key,input_fields}), ai(渲染预览,meta{tool_key,output_kind})](空产物不记,lib/toolbox/aiSummary.ts 纯助手+5 单测InlineToolbox 挂本章号、ToolboxPage silent 项目级(chapter_no=null)Workbench 挂 hook 单实例 + 抽屉 + 底栏「AI 对话」入口(AI_CONVERSATION_ENABLED 灰度)+ 三个再接受回调(成功关抽屉+toast、refine 漂移不盲替换)。留痕永不改「是否/何时写正文」——正文仍只在验收事务落库(守 #3门禁全绿lint/typecheck 干净 · vitest 706 passed681 基线 + 25aiConversation 11 + useAiConversation 9 + aiSummary 5· test:coverage 通过(lib/** 95.44% ≥ 80新纯模块/hook 全测)· build OK。→ 剩 AC-4 @qa E2E计划 §6+ P4 #1/#6 围栏。

  • [2026-07-09] @backend — AC-2 repo + append/list 端点 + schema + 契约(计划 §3c675a74。repo packages/core/ww_core/domain/ai_message_repo.pyAiMessageRepo/SqlAiMessageRepo/AiMessageView/AiTurnRow,经 ww_core.domain 导出):append(一批多条 bubble → 批内 seq=enumerate 0 基位置、同 thread_id、meta 新 dict 不原地 mutate、add_all+一次 flush+refresh只 flush 不 commit) + list_for_chapter(created_at DESC, seq DESC newest-firstchapter_no 非 None → 本章 项目级 IS NULLNone → 仅项目级;可选 kindlimit/offset)。schemas apps/api/ww_api/schemas/ai_messages.py:批级 append 信封 AiMessageAppendRequest{thread_id,chapter_no(ge=1)|null,kind,tool_key,messages} + AiMessageInput{role,content(min1,max200_000),meta(序列化≤50_000)} + AiMessageView + AiMessageListResponse{messages}Literal 为 kind/role 枚举权威(边界 422。端点 apps/api/ww_api/routers/ai_messages.pyprefix /projectstag ai-messages,已注册 mainPOST /projects/{id}/ai-messages(201项目 404校验 422append 只 flush + 端点 commit()) + GET /projects/{id}/ai-messages?chapter_no=&kind=+PageDep(200newest-first只读)。这是显式记录写入——五个生成端点逐字节不变、只读(守 #3ai_messages 旁路侧记录,assemble()/agent 永不读(守 #1/#6。注入缝 get_ai_message_repoTDDrepo 真 pg 单测 9 passedseq 0..n-1 / 同 thread_id / created_at DESC,seq DESC / union 含 NULL / 分页 / flush-only 跨 session 不可见);端点集成 12 passedround-trip / 本章∪项目级 / kind 过滤 / 404×2 / 422×5非法 role/kind、空 messages、空 content、超上限 content、超上限 meta / commit 边界 / 响应 key 集合不泄漏)。门禁全绿ruff/format 干净 · mypy 238 文件 · alembic check 无漂移(本任务不加模型)· export_openapi 成功(新端点+4 schema 已入表面)· pytest 992 passed971 基线 + 21· 新模块 cov router 100%/schemas 100%/repo 97%(余 Protocol ... 桩),全局 89%。契约 C3 扩AC-2已登记「稳定」@frontend AC-3 须 cd apps/web && pnpm gen:api 后消费码生成名。

  • [2026-07-09] @db — AC-1 ai_messages 表 + 迁移(计划 §2 canonical DDLpackages/db/ww_db/models.pyAiMessage(UuidPk, CreatedAt, Base)(补 Uuid 导入):project_id(FK projects CASCADE, NOT NULL, indexed)/chapter_no(Integer nullable=项目级)/thread_id(Uuid NOT NULL)/seq(Integer NOT NULL, repo 批内 0 基定序)/kind(Text 无 CHECK)/tool_key(Text nullable)/role(Text + ck_ai_messages_role CHECK author|ai)/content(Text NOT NULL 全文)/meta(JSONB NOT NULL server_default '{}')/id+created_at(mixin)append-only 无 updated_at。复合索引 ix_ai_messages_project_chapter=(project_id,chapter_no,created_at DESC) 手写 sa.text DESC + FK 单列索引。迁移 ceabd3c2c00ddown=f6a7b8c9d0e1autogenerate 仅捕获 ai_messages 无杂散漂移DESC 表达式归一为 sa.text)。T0.2 MVP schema 后第一张新业务表——对话历史是 18 表都无的能力、正交于 review/job/手稿,属真新增(非重复建表);是旁路侧记录非手稿真源assemble()/agent 永不读(守 #1/#3/#6围栏留 AC-4/P4 收口)。门禁全绿ruff/format 干净 · mypy 233 文件 · alembic upgrade head + alembic check 无漂移 + downgrade→upgrade 往复干净 · pytest 971 passed(基线不变,无代码用新表)。契约 C2 扩AC-1已登记「稳定」 → AC-2 @backend 可动工。

  • [2026-07-08] @devops — QA-CR CR-D1 抬高后端依赖下界至 lockfile 主次版本(保可复现)。8 个 pyprojectapps/api + packages/{core,agents,config,db,llm_gateway,shared,skills})的后端运行时依赖下界从过旧值抬到实锁 MAJOR.MINORlanggraph>=1.2/langgraph-checkpoint-postgres>=3.1/openai>=2.43/anthropic>=0.111/google-genai>=2.9/instructor>=1.15/tenacity>=9.1/pydantic>=2.13/pydantic-settings>=2.14/structlog>=26.1/asyncpg>=0.31/alembic>=1.18/fastapi>=0.137/uvicorn>=0.49/cryptography>=49(每条 ≤ lockfile 实锁,同小版本线的 sqlalchemy/psycopg 留原样)。uv.lock 变动为纯元数据刷新——仅各 workspace 成员 [package.metadata].requires-dist 的 specifier 字符串随下界更新,零 pinned version= 变动、零 re-resolve、零第三方版本 bump。root dev 工具下界pytest/ruff/mypy/httpx+ 前端 vitest 3.x/tailwind 4.x 升级评估明确不纳入(非运行时可复现关键,超范围)。门禁uv lock --check 绿(元数据刷新后一致)· uv run ruff check . 干净 · pytest 971 passed(与基线一致,无回归)。无源码/测试改动。

  • [2026-07-08] @llm — QA-CR MEDIUM/LOW 网关+链整改批CR-M2/M3/L1@llm/M1.4TDD 逐项提交)完成 632451a9 pricing 未知 model 发 pricing_unknown_model warning成本仍 09439b97 三 adapter 瞬时错误消息经 provider_error_summary(exc) 只留类名+status不泄 vendor 响应体);832ab7d OpenAICompatAdapter.probe_connection() 公开探测 + provider_deps 弃私有 _client 反手CR-M1.4c9ffada 续写链前一章无已验收终稿发 chain_prior_accepted_missing warningCR-L1ec91c8f 链 runner 改用公开 graph.aget_state(config).interrupts 判暂停(弃私有 __interrupt__6a739ca review 节点五审 asyncio.gather 并行扇出(复用主图 add-only 记账并发范式 T3.8collect 一次落库)。SKIP 2CR-M2 is_open() CQS惰性半开转移是唯一转半开点、拆分漏发命令会致熔断永不复位风险>收益CR-M3 run_overdue_scan 幂等(scan_overdue 本已是原子 UPDATE...RETURNING+NOT IN[CLOSED,OVERDUE]+commit-only-if-changed且下一章 current+1 扫描自愈漏标,再动会触碰验收事务边界)。门禁全绿:后端 ruff/format 干净 · mypy 232 文件 · pytest 971 passed+11 新测pricing 2 / 错误脱敏 4 / probe 2 / 续写缺前文告警 2 / 并行审 1· 无 DDL/无迁移。守不变量 #1/#3/#4熔断/验收事务/add-only 记账 sink 未动)。

  • [2026-07-08] @llm/@backend/@devops/@frontend — QA-CR CRITICAL + HIGH 整改批全部落地14 项 + 4 低危收尾)。多 agent 工作流:先 14 个只读 agent 逐项扎根真实代码产精确修复+测试规格(纠出 3 处台账前提漂移),再按 owner 四簇串行整合入单工作树(避免并发写树 + repo 级 ruff format . 竞态),各 TDD 红→绿、逐项补回归测试、逐 fix 小步提交,末尾 14 个 skeptic 对抗式复核(实证每条 test 非 vacuous0 problem关键落地/纠偏C1 next 15.1.3→15.5.20+react 19.2.7pnpm audit 清、dependencyFloors.ts 下界守卫,CVE 号无法对真库核验+密钥轮换为用户运维事项C2 前提证伪langgraph 默认上限 10007 非 25无实活崩溃仍加显式顶层 recursion_limitH4 request_id 条件透传(否则覆盖 contextvars 反退化H2 修请求级 httpx 泄漏时揪出 E2E 会误触真网override 跟随修H9 全文本字段上限+2 MiB body 中间件 413 兜底(契约 C3gen:api 无漂移H8 .env.example 换不可用占位符(真 key 仍在 git 历史,曾用环境须轮换)。门禁全绿:后端 mypy 229/pytest 934/alembic 无漂移;前端 vitest 669/build/coverage 95.41%。契约 C1-扩LlmRequest.request_id+ C3H9 capsMEDIUM/LOW 择批后清理。 提交 cb8fddfdd6d2fc19 提交)。

  • [2026-07-08] @backend — QA-CR 后端整改 5 项TDD逐 fix 提交)CR-C2chain_runner.run_chain_jobgraph.ainvoke 传显式 top-level recursion_limit=count*NODES_PER_CHAPTER+HEADROOM(防御硬化,命名常量)。CR-H1Kimi OAuth 设备轮询移出 DB 会话——新增 _poll_for_token(纯 HTTP)/_make_persist_work/_run_kimi_oauth_poll,仅最终持久化经 run_job 开短会话(防连接池饥饿;删 _make_poll_work)。CR-H2:请求级 httpx 客户端改生成器依赖 _http_clientasync with ... yield,请求结束 aclose 修泄漏);_default_http_client 保留供后台裸调E2E + 端点测试 override 键跟随改 _http_clientCR-H7:冻结 TOOLBOX 为只读 MappingProxyType_TOOLBOX_BY_KEY 私有底 dict + Final[Mapping],仿 SPECSCR-H9:用户请求字符串字段补 max_lengthproviders/generation/projects/style/foreshadow/rules/templates命名常量无魔数样本列表长度+每条双上界)+ 新错误码 ErrorCode.PAYLOAD_TOO_LARGE(413) + 应用级 body_size_limit_middleware(2 MiB按 Content-Length 拦截自建 413 信封)main.py 注册。门禁全绿ruff/format 干净 · mypy 229 文件0 错)· pytest 928+23recursion_limit 1 / poll-no-session 1 / http-gen 1 / toolbox-readonly 1 / input-size 19[17 参数化 + samples 1 + body413 1])· 无 DDL/无迁移。记 contracts C3CR-H9新增 maxLength + PAYLOAD_TOO_LARGE)。→ @frontend 须 pnpm gen:api(请求字段现有 maxLength;本 cluster 未代跑)。守不变量 #3/#8/#9。

  • [2026-07-06] @backend/@llm/@frontend — 灵感⑦ 群像按定位配比·缩减版 + §0 归属纠偏develop 直提)。角色群像生成支持「按定位配比」下发。契约变更 CharacterGenerateRequestrole_mix:dict[str,int]|None——model_validator(mode="after") 定义与既有 count 的关系在场时校验非空、每项≥1、总和≤MAX_GENERATE_COUNT=12并把 count 归一为各值之和(构造期归一化,忽略客户端 count缺省退回单一 role+count§0 归属纠偏build_character_gen_context+run_character_genww_core/orchestrator/generation_node.py)确为 @llm 域——加末位默认 role_mix=None 关键字参,在场时注入「角色定位配比」块(保插入序、确定性、无时间戳,守 #6/#7 assemble 纯函数;覆盖单一 role 行);routers/generation.py 穿 role_mix=body.role_mixcharacter-gen.md 加「按配比严格分配 role、各定位之和=总数」纪律 → regen prompt_hashes.json(仅 character-gen 哈希变,不进 SPECS→不 bump 计数)。前端 cards.tssanitizeRoleMix(去空/去重/clamp≥1/按 12 截断)+roleMixTotal+buildCharacterGenerateRequest 第 4 参 roleMixuseCharacterGen CharacterGenInput.roleMix 穿参;新 RoleMixEditor.tsx + CharacterGenerator SegmentedControl 单一/配比双模。TDDschema 校验 7 例总和≤12/空 dict/非正值拒绝)+ context 注入 2 例 + run 穿参 1 例 + 前端 cards 构造/clamp 5 例 + hook renderHook 1 例。门禁全绿:后端 ruff/format 干净 · mypy 222 · pytest 858+11· 无迁移(未动模型,未跑 alembic前端 gen:api/lint/typecheck 干净 · vitest 543+6· coverage 95%cards.ts 100%)· build OK。记 contracts C3。守不变量 #2/#6/#7/#9。无 DB 迁移

  • [2026-07-06] @llm/@db/@backend/@frontend — 灵感③ 人物塑造 advisory 审develop 直提)。写→审链新增第五审「人物塑造」:advisory 单维——仅建议、不阻断验收(不进 conflicts、不碰 assert_conflicts_resolved不入 REVIEW_RESERVED_NAMESD2只做人物塑造、不做氛围氛围噪声大折进 style/pace新 SPEC characterization_spectier="analyst" 不写 modelreads=("characters",) 以人物卡 motive/appearance 为客观锚点,writes=() 只读,prompts/characterization.md 显式忽略文本长度与辞藻华丽度、引用逐字片段+置信度对抗 LLM-judge 冗长/辞藻偏见)+ schema CharacterizationReview{issues:[…character/aspect/where/quote/diagnosis/suggestion/confidence]}(全字段默认值守解析韧性)+ 注册 SCHEMA_CATALOG["characterization"]计数三处 22→23specs.py assert / test_prompt_loader.py len / schema_catalog.py docstring+ regen prompt_hashes.json(仅加一条,无其余漂移)。DB chapter_reviews 加 1 列 characterizationJSONB nullable,迁移 f6a7b8c9d0e1nullable 免 backfill契约变更 ReviewHistoryItem+ReviewViewcharacterization;接线链 graph.py REVIEW_SPECS 末位追加 + chain/nodes.py ReviewRecordRepo + collect.py {CHARACTERIZATION/extract_characterization/ReviewRecorder/collect_reviews} + review_repo.py {Protocol/SqlReviewRepo/_to_view} + sse.py {EVENT_CHARACTERIZATION/characterization_event/_section_result_events}normalize 按 sorted 键自动纳入,字典序排最前不打乱既有四审断言)。前端 lib/review/{sse.ts,history.ts,useReviewStream.ts} + 新 CharacterizationPanel.tsxadvisory 只展示、无裁决 UI、按置信度降序 + 低置信度折叠控注意力预算)+ ReviewReport.tsx 挂面板 + 双 seed。门禁全绿:后端 ruff/format 干净 · mypy 221 · pytest 848+核心 char 审 12 + agents spec 11 + api accept 2 等)· alembic 无漂移;前端 gen:api/lint/typecheck 干净 · vitest 536+10 含 test_characterization_does_not_block_accept 对应前端 reducer/normalize/parse· coverage 95% · build OK。记 contracts C3+C4。守不变量 #2/#3/#9。依赖 ⑧motive/appearance 已入 CharacterCard 契约,作客观锚点)。

  • [2026-07-06] @backend/@llm/@frontend — 灵感⑤ AI 立项方案生成+预填develop 直提)。向导阶段project 未建)一键推演结构化书级蓝图预填立项向导。新 SPEC project_plan_spectier="analyst" 不写 modelreads=()/writes=() 纯预览,prompts/project-plan.md+ schema ProjectPlanResult(书名候选 list + 时空背景/叙事结构/故事核心/结局设计/基调,全字段默认值守解析韧性+ 注册 SCHEMA_CATALOG["project-plan"]计数三处 21→22specs.py assert / test_prompt_loader.py len / schema_catalog.py docstring+ regen prompt_hashes.json(仅加一条)。新端点 POST /skills/project-plan/generate不带 project 前缀绕开 toolbox 404ProjectPlanGenerateRequest(全字段 max_length CR-H9briefstr|None 令 codegen 可选)→ ProjectPlanView种子门控缺 genre/logline→422无凭据→503。复用 build_brief_context+run_generatorrun_generator/_build_requestproject_id 放宽 uuid.UUID|None——向导无 projectledger.project_id 本 nullable新缝 get_project_plan_gatewayanalyst零迁移前端 wizard.tsmapPlanResultToWizardForm(书名/结构/基调→对应字段;时空背景/结局设计→折进 premise 不静默丢;结局取向/视角预设枚举不臆造)+ applyPlanPatch仅回填空字段、保护已编辑+ canGeneratePlan/toPlanSeedRequest + useProjectPlan hookrenderHook 测试)+ ProjectWizard.tsx 第 2 步 PlanAssistant(生成→预览→按字段回填)。门禁全绿:后端 ruff/format 干净 · mypy 218 · pytest 814+新端点 6 + agents spec 8 测)· alembic 无漂移(零 ORM 变更);前端 gen:api/lint/typecheck 干净 · vitest 526+28· coverage 95%wizard/generation 100%)· build OK。记 contracts C3 新端点。守不变量 #2/#3/#9。依赖 ④(已交付)。

  • [2026-06-26] @orchestrator — 全项目 Code Review七维度完成 → QA-CR 整改批立项。6 个专科 reviewer 并行(后端 FastAPI 架构 / Python 规范 / LangGraph 最佳实践 / 前端 React 架构 / 前端 TS 类型安全 / 应用安全)+ 依赖时效自查212 py + 168 tsx 全覆盖。绿门禁下仍揪出 2 CRITICAL + 13 HIGH + 一批 MEDIUM/LOWC1 Next.js 15.1.3 RCECVE-2025-66478「React2Shell」App Router+RSC 受影响,升 15.1.9/15.5.7/16.x + 轮换密钥);C2 多章链缺 recursion_limit(默认 25 supersteps、每章 4 节点→超 ~6 章即崩批量产卷不可用。HIGH 含 Kimi OAuth 占 DB 会话 / httpx 泄漏 / Anthropic 计费记 0 / request_id 未贯通 / .env.example 提交可用 Fernet key / 文本输入无 max_length / 前端 errorCode 重复 / Drawer 焦点 / RefineView 未取消。确认无虞SSRFbase_url 仅硬编码)/SQL 注入(全 ORM/XSS无 dangerouslySetInnerHTML/错误信封不泄密/Kimi device-flow 无 CSRF。已登记 QA-CR 任务表CR-C1/C2 + CR-H1..H12 + CR-M1..M5 + CR-L1 + CR-D1按 owner 分派 @frontend/@backend/@llm/@devops落地顺序见当前阶段 background。本批为评审立项,尚无代码改动。

  • [2026-06-23] @orchestrator — 🎉 多章工作流链Chain Workflow交付 + 多 agent 交叉评审 + CRITICAL 修复 + 合并 developmerge 513bf71。对标星月「一键多章」+ 差异化「每章过四审、遇冲突才停人」。设计契约 docs/design/chain-workflow.mdcommit 5ee9799)。多 agent 逐学科建造(契约先行、目录单写者):C1 @llm(7f3eaab) LangGraph cyclic 链图 orchestrator/chain/{state,nodes,graph}.pybuild_chain_graphwrite→review→decide→accept 循环 + interrupt-on-conflict + resume删死代码 build_write_graphwrite_node 本体留用7 单测 mock 网关+fake session+MemorySaver·C2 @backend(29349dc) 服务/3 端点/schema/checkpointer 接线(见下条)·C3 @db(548b7ab) langgraph 检查点 4 表迁移 d3e4f5a6b7c8autocommit_block 避开 CREATE INDEX CONCURRENTLY 与 alembic 事务死锁;env.py include_object 豁免这 4 表防漂移误报)·C4 @qa(061792d) E2E tests/test_chain_workflow_e2e.py 真 pg + mock 网关零 token无冲突两章全自动 + 冲突→interrupt→awaiting→resume→accept3 路对抗交叉评审python/fastapi/不变量)在绿门禁下仍揪出 1 CRITICAL + 7 HIGH——证伪"测试过=没问题"CRITICAL=链把绑请求 session 的 gateway 传进 BackgroundTask后台跑时 session 已关→write/review 的 usage_ledger.record() 写进死 session 静默丢失(链计费全丢,违 #1E2E 清了 ledger 却没断言其存在故漏掉)。修复(d1ea83b):网关改 chain_gateway_builder 按节点 session 重建(仿 digest_gateway_builder/style.py);日志脱敏(_classify_job_error+exc_type,去 str(exc)§5resume 原子 claim JobRepo.claim_awaiting_to_running(防并发双跑同 thread_id非 awaiting→409+ 所有权校验(JobView.project_id跨项目→404ChainResumeAccepted(去 start/count=0 哨兵);删死导入 extract_conflicts补回归断言(链 usage_ledger 必有行 + chapter_reviews 每章一行)。出口DoD:后端门禁绿 ruff/format 干净 · mypy 194 Success · alembic 无漂移(业务表零迁移,复用 jobs.status=awaiting_input + result.awaiting_chapter;唯一新 DDL=langgraph 检查点表)· pytest 608 passed+6 回归测)。首次真正启用 LangGraph checkpointer/interrupt。守不变量 #1/#3/#4/#5/#9。剩余下一步(未做):① 前端链 UIpnpm gen:api 纳入 run/resume + 发起页/进度轮询/awaiting 裁决续跑面板,复用 ConflictAdjudication);② §12 文档回写 ARCHITECTURE.md §5.2(补 cyclic 链图 + 更正现状:写章直连流式/单章 accept 为事务/链图首启 checkpointer③ 未 push 远端。可选:续写/扩写节点入链UGC 链市场需多租户deferred

  • [2026-06-23] @backend — Chain Workflow C2多章链 服务+端点+schema+checkpointer 接线,分支 feat/chain-workflow。承 C1(@llm)链图(build_chain_graph §3.3),落地服务/端点壳:① 3 端点routers/chain.pyPOST .../chains/{key}/run→202 ChainRunAcceptedPOST .../chains/runs/{job_id}/resume→202GET /jobs/{id} 复用。校验count 1..50→422、未知 chain_key→404、项目不存在→404、resume job 不存在→404、resume 非 awaiting→409 新码 CONFLICT、无凭据→503。② schemaschemas/chain.pyChainRunRequest/ChainRunAccepted/ChainResumeRequestConflictDecision 复用)。③ 服务services/chain_runner.pyrun_chain_job 仿 run_job 壳自建独立 session 驱动链图set_running→ainvoke→据 __interrupt__awaiting_inputdone/failedbuild_accept_op 在 apps/api 装配验收事务闭包注入图节点,守 #3/#4token 不入 result/日志)+ services/chain_deps.pyget_checkpointer_factory:运行时 AsyncPostgresSaver 上下文 / 测试 MemorySaver。④ 零迁移§7复用 jobs,新增 status="awaiting_input" + JobRepo.set_awaitingawaiting 章经 result.awaiting_chapter;新错误码 ErrorCode.CONFLICT(409)。⑤ 新网关缝project_deps.build_chain_gateway/get_chain_gateway(按请求 tier writer/analyst/light 分派——单档网关恒返该档会错路由 review/digest见 gotcha+ get_digest_gateway_builder单测apps/api/tests/test_chain.py 12 用例mock 网关 + MemorySaver + fake session/accept_op无 DB/无网络/无真 LLMrun→202、resume→202、未知 key 404、count 越界(>50/0) 422、resume 非 awaiting 409、项目/ job 不存在 404、run_chain_job 无冲突→done+written 满、冲突→awaiting→resume→done、错误脱敏、accept_op 冲突缺判→CONFLICT_UNRESOLVED。全仓门禁绿ruff/format 干净、mypy 193 Success、alembic 无漂移(无 ORM 变更、pytest 600 passed。守不变量 #1/#3/#4/#5/#9。记 contracts C-Chain 稳定 + 2 decision + 3 gotcha。唯一新增 DDLlanggraph 检查点表)= C3 迁移;前端链 UI = 契约稳定后 @frontend follow-up本期非目标

  • [2026-06-22] @orchestrator — 🎉 T6 创作工具箱(通用生成器框架)全工具箱交付 + 独立复核(分支 feat/t6-creation-toolbox。多 agent 并行波次Wave 0@llm T6.5 ‖ @backend 描述符类型 ‖ P2 收尾)→ Wave A@backend T6.2+T6.3 TOOLBOX+端点合龙,契约稳定点)→ Wave B@frontend T6.6 ‖ @qa T6.4)→ Wave C 收口,目录单写者零写冲突、契约先行、零返工。@llm T6.5ww_agents +7 输出 schema + 7 specbook-title/blurb/name/golden-finger/glossary/opening/fine-outline只声明 tier #2+ build_outline_chapter_contextwith_outline_chapter 策略)。@frontend T6.6gen:api 纳入 3 端点;app/projects/[id]/toolbox/page.tsx(RSC) + components/toolbox/{ToolboxPage,ToolCard,GeneratorRunner} + lib/toolbox/*(声明驱动纯函数,按 input_fields 渲染表单、按 output_kind 渲染预览、可入库者复用 ConflictAdjudication 走 409→ack+ LeftNav「工具箱」+ ⌘K nav-toolbox/action-gen-*legacy 3 跳现页不回归。@qa T6.4tests/test_t6_toolbox_e2e.py 5 用例真 pg + mock 网关零 token未发现端点 bugP2 收尾:限流→decisions.md 记延后单用户原型noopener/Committable 经查本分支早已修;provider_deps.py 残留 type:ignore 为 SDK 私有属性探活、load-bearing 保留。最终独立复跑全仓门禁绿:后端 ruff/format 干净、mypy 195 Success、alembic 无漂移descriptor 在代码、复用既有表零建表迁移、pytest 583 passed;前端 gen:api/lint/tsc/vitest 279/build OK。守不变量 #2只声明 tier/#3预览不写库、入库经验收 gate/#9system_prompt 进缓存前块)。"加生成器=加一份声明" 经实证8 个新生成器复用同一通用执行器 + 同一前端组件)。 实景 browse 复验(工具箱卡片栅格→脑洞预览→词条入库)待做。 后续可选 P5封面图像轨道 / 自定义 skill 运行期 schema / 收敛已有 3 竖井。

  • [2026-06-20] UX计划 B0(可控版)+F1(控件) — 本章注入透明 可控版(分支 feat/ux-b0-controllable-injection,提交 0d473e7 后端 + 6449c31 前端,未合 develop。在 B0 读端点之上加作者微调,守不变量 #6「确定性选择」的作者兜底。后端(@backend/@db)PUT /projects/{id}/chapters/{no}/injectionInjectionOverrideRequest{pinned,excluded,recent_n(1..20→422)}InjectionResponse(新增回显 pinned/excludedselected[].reasons 可含新值 author_pinselect_relevant_entitiespinned/excluded frozenset 入参pin 强制纳入加 author_pin / excluded 强制剔除且优先于 pinassembleoverride 关键字参recent_n 覆盖回看章数);GET injection + PUT + draft 流式端点同读同一覆盖(看到的=写章用的)。持久化:新表 chapter_injection(迁移 ad2c4c663daf,唯一 (project_id,chapter_no);复用 outline 行污染 beats 已否决)+ 新 domain/injection_repo.pyInjectionOverride/EntityRef/SqlInjectionOverrideRepoupsert 只 flush 端点 commit前端(@frontend)gen:api 纳入 PUT + 新 schemalib/workbench/injection.ts override 纯函数(currentOverride/withPinToggled/withExcluded/withRestored/withRecentN/isPinned,钳 1..20useInjectionsaving 态 + togglePin/exclude/restore/setRecentNPUT 后以服务端确定结果为准、写失败可读文案不改本地态);ChapterAssistant 每实体 📌置顶/✕排除 + 「近 N 章」步进器 + 「已排除」恢复区。全仓门禁绿:后端 ruff/format/mypy 163/alembic 无漂移/pytest 476;前端 lint/tsc/vitest 183/build。记 contracts C3 再扩。实景 browse 复验待做。 UX 计划余项R1/R2/R3 审稿人体学 + Tier4。

  • [2026-06-20] UX计划 M1+M2 — 移动端可用(纯前端,分支 feat/ux-m1-m2-mobile 提交 9b893a6。救活手机端390px写→审主路径。M1 导航响应式抽屉:抽出纯逻辑 lib/nav/items.tsGLOBAL_NAV_ITEMS/projectNavItems/isNavItemActive + ActiveNav 类型6 vitest桌面静态侧栏与移动抽屉共用避免漂移新增通用 Drawer(遮罩点击/Esc 关闭/打开聚焦面板,复用 CommandPalette a11y 模式,lg:hidden+ NavDrawer(汉堡 aria-label=打开导航 + 左抽屉)+ NavItemsLeftNavhidden lg:blockAppShell 顶栏加汉堡。M2 工具条不溢出 + 移动可达Workbench 工具条改 flex-wrap390px 不再横切「尚未保存」);ChapterList/ChapterAssistant 抽出 ChapterListContent/AssistantContentWorkbench 经左/右 Drawer<lg 触达目录/助手。实景 390px 复验browse:汉堡显示 + 静态导航 display:none、抽屉开合(聚焦 + Esc 关闭、工具条两行无横向溢出、助手抽屉真注入面板。前端门禁绿lint/typecheck 干净 · vitest 177(171→+6) · build OK。无后端/契约变更。文件:lib/nav/{items,items.test}.ts(新) · components/{Drawer,NavDrawer,NavItems}.tsx(新) · components/{AppShell,LeftNav}.tsx · components/workbench/{Workbench,ChapterList,ChapterAssistant}.tsxUX 计划余项B0 可控版(PUT override) + F1 控件 + R1/R2/R3 审稿人体学 + Tier4。

  • [2026-06-20] UX计划 F3+F4 — 流式进度感 + 友好错误文案(纯前端)。F4apps/web/lib/errors/messages.tsfriendlyError(code,fallback)→中文文案 + 可选「去设置提供商」动作;覆盖后端 ErrorCode + 前端 NETWORK/STREAM_FAILED;未知码回退原 message+4 vitest写作页 Workbench 与审稿页 ReviewReport 的错误块改用之,不再直接暴露 raw error code。F3Workbench 工具条字数计数器流式时变「生成中… N 字」+ 朱砂 motion-safe:animate-pulse(尊重 prefers-reduced-motion停后回「字数 N」text.length无后端改动。前端门禁绿lint/typecheck/vitest 171/build。文件lib/errors/{messages,messages.test}.ts · components/workbench/Workbench.tsx · components/review/ReviewReport.tsx。无契约变更。

  • [2026-06-20] UX计划 B0(读)+F1 — 本章注入透明(读端点 + 右栏真面板)。兑现差异化信任牌「看到的=写章用的」(不变量 #6把先前写作页右栏「M1 暂未接 / M2 开放」的过时假占位换成真数据。后端(@backend)GET /projects/{id}/chapters/{no}/injectionInjectionResponse{project_id,chapter_no,selected:[{kind,name,reasons[]}],recent_n},调既有 assemble() 回放确定性 SelectionTrace无 LLM、无 commit、无 DDL项目不存在→404无大纲→selected:[]。文件:schemas/injection.py(新) · routers/projects.py(+GET+2 import) · tests/test_injection.py(新,3 测)。前端(@frontend)gen:api 纳入端点;纯逻辑 lib/workbench/injection.ts(理由/类型→中文徽标 + 4 vitest) + useInjection 读 hookChapterAssistant 改 client 组件列出选中实体 + 入选理由徽标(本章点名/主角常驻/近章出现/伏笔窗口)+ 空/载/错三态,「四审」段改指向审稿页;WorkbenchprojectId/chapterNo全仓门禁绿:后端 ruff/format/mypy 159 Success/alembic 无漂移/pytest 454 passed;前端 lint/typecheck/vitest 167 passed/build。记 contracts C3扩。B0 余项可控版PUT override pin/排除/recent_n + selection 加参 + draft 同读 override + 持久化)+ F1 可控控件待后续。

  • [2026-06-20] @frontend — 接上两个新读端点:大纲页 / 写作工作台重访时回显已存内容pnpm gen:api 纳入 GET .../outline + GET .../chapters/{no}/draft + schema DraftViewlib/api/types.tsDraftView 别名。新增两个 RSC 读 helper仿 fetchForeshadow/fetchProject 服务端读、无 CORSfetchOutline(projectId)OutlineChapterView[]200 解包 chapters任何错误/空降级为 [] 不阻塞进页),fetchDraft(projectId,chapterNo)DraftView|null(复用 getJsonOrNull404→null 当空编辑器,不抛)。大纲页(outline/page.tsx) 进页 fetchOutlineinitialChapters 种入 OutlineEditoruseOutline 已据非空初值置 ready)→ 重访显已生成大纲;生成流照常覆盖所显章节。写作工作台(write/page.tsx + Workbench) 进页 fetchDraftcontent 作编辑器初值(useState(initialText))→ 重访重载已写正文404/新章 → "" 空编辑器;SSE 流式写 + AbortController + PUT 自动保存全不动(流起始空、仅 streaming/done/aborted 变化才覆盖,初值不反扑活跃流);导出 WORKBENCH_CHAPTER_NO(原 M1_CHAPTER_NO)供页面拉对应章草稿。新增 lib/api/server.test.ts(5 vitestmock fetch 验解包/降级/404→null)。前端门禁全绿gen:api / lint / typecheck / vitest 160(155→+5) / build。文件lib/api/{types,server,server.test}.ts · app/projects/[id]/{outline,write}/page.tsx · components/workbench/Workbench.tsx。消费 contracts C3扩@backend 两读端点)。

  • [2026-06-20] @backend — GET /projects/{id}/chapters/{no}/draft 草稿读端点(补缺口,镜像 GET /outline。写作工作台先前只有 POST .../draft(SSE 流写)+PUT .../draft(自动保存) 无读端点 → 重访工作台编辑器空白、看似「未保存」(其实 chapters 行在库)。补对称读侧:GET /projects/{id}/chapters/{no}/draft → 200 DraftView{project_id,chapter_no,volume,status,version,content,length}比 PUT 的 DraftResponsecontent——读侧需正文重建编辑器);无草稿行/正文空白 → 404 NOT_FOUND(工作台据此呈现空编辑器,仿其它缺资源端点)。直接复用既有 chapter_repo.get_draft(同续审 _resolve_review_draft 读缝,ChapterDraftView 已含全字段,无新 repo 方法/view只读不写库多版本固定返草稿版次(DRAFT_VERSION=1)。文件:schemas/projects.py(+DraftView) · routers/projects.py(+GET endpoint+import) · tests/test_projects.py(+2回灌正文 / 无草稿 404)。全仓门禁绿ruff/format 干净、mypy 154 Success、alembic 无漂移、pytest 444 passed442→+2。OpenAPI 新增 1 端点 → @frontend 须 cd apps/web && pnpm gen:api + 工作台初次加载拉已保存草稿回灌编辑器。记 contracts C3扩。

  • [2026-06-20] @backend — GET /projects/{id}/outline 大纲读端点(补缺口,仿 Codex 读端点)。大纲页先前只有 POST .../outline(生成+落库)无读端点 → 重访页面已落库大纲不回显、看似「未保存」。补对称读侧:GET /projects/{id}/outline → 200 OutlineResponse{chapters:[OutlineChapterView{no,volume,beats:list[str],foreshadow_windows}]}(与 POST 同形,按 chapter_no 升序);项目存在无大纲 → 200 空列表(非 404项目不存在 → 404 NOT_FOUND复用 C5 读侧:扩 OutlineRepo(domain) + SqlOutlineRepo(assemble 读侧) 加 list_for_project(仿 Character/WorldEntityRepoorder_by chapter_no既有 get 不动);新注入缝 get_outline_read_repo(仿 get_rules_read_repo)。beats DB JSONB {"beats":[...]} → 解包裸 list[str](同 POST。文件routers/outline.py(+GET) · services/project_deps.py(+dep) · domain/repositories.py(+protocol method) · memory/sql_repositories.py(+impl) · tests/{test_outline.py(+3),fakes_projects.py(+FakeOutlineReadRepo)} + 补 2 既有 outline faketest_memory/test_projects满足扩展后的 protocol。全仓门禁绿ruff/format 干净、mypy 154 Success、alembic 无漂移、pytest 442 passed439→+3。OpenAPI 新增 1 端点 → @frontend 须 cd apps/web && pnpm gen:api + 大纲页初次加载拉已持久化大纲。记 contracts C3扩。

  • [2026-06-19] @llm — K1.2 修头校正:恢复 opencode 规范的完整 7 头UA KimiCLI/1.37.0。先前误信 picassio/pi-kimi-coderUA-only把头集裁成仅 UA是分歧/错误参考导致的误修——真源改为 ooojustin/opencode-kimisrc/headers.ts+src/constants.ts1:1 镜像 kimi-cli v1.37.0,已重新拉取 master 核对)。kimi_code_headers() 现发 7 头:User-Agent=KimiCLI/1.37.0 + X-Msh-Platform=kimi_cli(字面常量)+ X-Msh-Version=1.37.0 + X-Msh-Device-Namehostname ASCII 化)+ X-Msh-Device-Modelkimi_device_model()macOS=macOS {mac_ver} {machine}+ X-Msh-Os-Versionplatform.version()+ X-Msh-Device-Id(稳定 32 位无连字符 uuid4().hexenv KIMI_DEVICE_ID 优先→否则持久化 ~/.kimi/device_id)。恢复 kimi_device_id()/kimi_device_model() 助手 + 重加 importsos/uuid/socket/platform/pathlib+ __init__ 重导出。文件:packages/llm_gateway/ww_llm_gateway/adapters/kimi_code.py + __init__.py + 两测(断全 7 头键 + 固定字面值 + device-id 32 位小写 hex 稳定 + host 派生值非空 ASCIIenv 注入保 CI 确定)。更 contracts C1扩7 头 + opencode 真源)+ gotchapi-kimi-coder 分歧→回退。门禁绿ruff/format 干净、mypy 干净27 文件、pytest 60 passedpackages/llm_gateway。无 OpenAPI 形变。

  • [2026-06-19] @backend — K1.3 修正device authorization 重新带 scope=kimi-code(实测 401 后修。K1.5 联网实测登录拿到真 JWT 但调 api.kimi.com/coding/v1401 Invalid Authentication——根因 token 缺 coding entitlement省略了 scopestart_device_authorization 请求体加 scope=kimi-code={"client_id":<id>,"scope":"kimi-code"},模块常量 KIMI_CODE_SCOPEscope 只放 device-authtoken 交换/刷新不带。文件:apps/api/ww_api/services/kimi_oauth.py + 单测 test_kimi_oauth_service.pytest_start_device_authorization_parses_response_and_sends_scopedata["scope"]=="kimi-code")。修正 C3扩 contract + decision「省略 scope」表述 + 加 gotcha。无 OpenAPI 形变,前端无需 re-gen。门禁绿ruff/format 干净、mypy 干净、pytest 101 passedapps/api

  • [2026-06-19] @orchestrator — 🎉 K1 完成 + 独立复核Kimi Code OAuth 订阅 plan 接入)。波次 A(K1.1 @db 加列+迁移 ‖ K1.2 @llm KimiCodeAdapter)→B(K1.3 @backend OAuth device 服务+端点+store+接线)→C(K1.4 @frontend 连接流+可编辑路由)→D(K1.5 @qa E2E) 全绿,契约先行、零返工、无新 bug。研究先行device flow at auth.kimi.com、client_id、伪造 UA/X-Msh-*、coding base、kimi-for-coding、access15m/refresh30d+ 对照 pi-kimi-coder/ooojustin/lemon07r 校验(省略 scope 匹配 kimi-cli v1.41.0+)。最终独立复跑确认:后端 ruff/format 干净、mypy 154 文件、alembic 无漂移(首个新迁移=provider_credentials 加 auth_type/oauth_enc)、pytest 434 passed;前端 vitest 155/build。能力闭环设置页 device-flow 登录→token Fernet 加密入库(oauth_enc,不泄漏)→路由 kimi-code:kimi-for-coding→网关构 KimiCodeAdapter(伪造头+bearer)→临过期自动刷新。封号风险用户已知情接受;与既有 API-key provider kimi 分离可切换。唯一未尽:对真 auth.kimi.com/api.kimi.com 的真账号联网冒烟(含封号风险,用户自担)——代码/E2E 仅验逻辑零联网。

  • [2026-06-19] @qa — K1.5 K1 E2EKimi Code OAuth device-flow 全 mock → 真 pg。新增 tests/test_k1_kimi_oauth_e2e.py4 用例,零联网,真 pgPOST .../oauth/start→202 {job_id,user_code,verification_uri,interval}fake httpx 跑 device-auth + token(pending×2→成功) 全程;后台 run_job 轮询跑在真 e2e_sm sessionoverride get_session_factory→e2e_sm + monkeypatch 模块级 kimi_oauth._default_http_client→同一 scripted fake + kimi_oauth.asyncio.sleep→no-op端点 device-auth 走 _default_http_client dep 同样指 fakeGET /jobs/{id} doneresult {connected:true,provider:"kimi-code"}DB 真源provider_credentialsauth_type="oauth"/oauth_enc 非空/api_key_enc null密文不含明文 token + 解密回环 access/refreshGET .../oauth/status connected 无 token。② 存 oauth + tier_routing writer→kimi-code:kimi-for-codingbuild_gateway_for_tierKimiCodeAdapter,其 _client 带 coding base https://api.kimi.com/coding/v1 + UA KimiCLI/1.5 + 全 X-Msh-* + api_key(=bearer)=存量 access token。③ 临近过期 oauth 包 → _build_provider_adapter 触发刷新fake project_deps.kimi_refresh + 字符串 target monkeypatch project_deps.httpx.AsyncClient)→ 适配器用新 token + oauth_enc(DB 真源)更新为新包。④ POST .../oauth/disconnect→凭据行清除DB 真源无 oauthtoken 全程负向断言:不进 job 结果/状态响应/start 响应/密文明文。全仓门禁绿ruff/format 干净、mypy 154 Success、alembic 无漂移、pytest 434 passed430→+4。memory 记 1 gotcha。K1Kimi Code OAuth 订阅 plan 接入)全 5 子任务 ,可封板。⚠️ 仍未对真 auth.kimi.com/api.kimi.com 联网验证(含封号风险,用户自担)。

  • [2026-06-19] @frontend — K1.4 设置页 Kimi Code OAuth 连接流 + 可编辑档位路由pnpm gen:api 纳入 K1.3 的 3 端点OAuthStart/Disconnect/StatusResponselib/api/types.ts 加 3 别名。纯逻辑node-env vitestlib/settings/kimiOauth.tsconnectPhase 状态机 idle/awaiting/connected/error + toDeviceDisplay/authOpenUrl/toConnectionStatus/jobConnected/formatExpiresAt16 测)+ lib/settings/providers.ts 扩(KNOWN_PROVIDERSkimi-code(auth:oauth, model:kimi-for-coding) + API_KEY_PROVIDERS/TIERS/defaultModelFor + 路由草稿纯函数 toRoutingDrafts/applyProviderChange/draftsToRoutingInput9 测)。组件:useKimiOauth hook复用 useJobPollconnect=POST start→展示 user_code+window.open 授权页+轮询 job→done 拉 statusdisconnect=POST→复位+ KimiCodeOauth.tsx连接区user_code 用 <output select-all tabIndex=0> 可读可选可聚焦 + motion-safeProvidersSettings.tsx 改:档位路由从只读→可编辑per-tier select provider + model input + 保存 PUTAPI-key 凭据行只列 API_KEY_PROVIDERSOAuth 提供商有独立连接区,无 key 输入),挂入 KimiCodeOauthserver.tsfetchKimiOauthStatuspage.tsx Promise.all 拉 providers+oauth 状态传 kimiOauth prop进页即显连接态job 结果无 token只读 connected。前端门禁全绿gen:api / lint / typecheck / vitest 155 passed130→+25/ build。memory 记 1 gotcha。⚠️ 运行时对真 auth.kimi.com 设备授权 + 真 api.kimi.com 调用验证留 K1.5/手动(含封号风险,用户自担)。

  • [2026-06-19] @backend — K1.3 Kimi Code OAuth device-flow 服务 + 端点 + store + 网关接线C3 扩稳定)。新增 apps/api/ww_api/services/kimi_oauth.pystart_device_authorization/poll_token/refresh,注入 AsyncHttpClient Protocol 零联网;TokenSet+encrypt_oauth_bundle/decrypt_oauth_bundle 复用 Fernetneeds_refresh 300s 缓冲client_id env KIMI_CLIENT_ID 可覆盖、device authorization 省略 scope+ routers/kimi_oauth.pyPOST .../oauth/start→202 {job_id,user_code,verification_uri,...}+ BackgroundTask run_job 后台循环轮询→成功存加密 oauth_enc+job done(结果只 {connected,provider})POST .../oauth/disconnect{disconnected}GET .../oauth/status{connected,expires_at} 无 token+ schemas/kimi_oauth.py3 schema+ 注册 main.py。services/credentials.pyStoredCredentialauth_type/oauth_encapi_key_encbytes|NoneK1.1 的 2 处 mypy red 消除SqlCredentialStore 读新列 + upsert_oauth_credential/delete_credentialupsert_credential 显式置 api_key 态。services/project_deps.py_build_provider_adapterkimi-code/auth_type=oauth_resolve_kimi_code_token(解密→临近过期则经 httpx 刷新+持久化→access token 喂 build_adapter("kimi-code",…)provider_deps.py _PROVIDER_BASE_URLSkimi-codetoken 全程不进 job 结果/日志/响应(仅 Fernet 密文存 oauth_enc。TDD 先红后绿:tests/test_kimi_oauth_service.py(11) + test_kimi_oauth_endpoints.py(5) + test_kimi_code_wiring.py(3)fake httpx 零联网)。全仓门禁绿ruff/format 干净、mypy 154 源文件 Success、alembic 无漂移、pytest 430 passed400→+30。OpenAPI 新增 3 端点 + 3 schema → @frontend K1.4 须 pnpm gen:api。memory 记 C3 扩K1.3+ 1 decision + 2 gotcha。⚠️ 真 auth.kimi.com/api.kimi.com 联网验证(含封号风险)留 K1.5,用户自担。

  • [2026-06-19] @llm — K1.2 Kimi Code 订阅 plan 适配器C1 扩稳定)packages/llm_gateway/ww_llm_gateway/adapters/kimi_code.pyKimiCodeAdapter 子类化 OpenAICompatAdaptercoding 端点 OpenAI 兼容,复用 complete/stream/结构化/瞬时错误包装/capabilitiesprovider 固定 kimi-code(与 API-key kimi 分离);build_kimi_code_client(access_token, base_url?)AsyncOpenAI(api_key=access_token, base_url="https://api.kimi.com/coding/v1", default_headers=kimi_code_headers())——access_token 当 bearer伪造头随客户端发。kimi_code_headers()User-Agent + 全 X-Msh-*(Platform/Version/Device-Name/Device-Model/Os-Version/Device-Id)。kimi_device_id()env KIMI_DEVICE_ID 优先,否则确定性 uuid5 缺省(绝不每次随机,稳定且来源可测/可配。model kimi-for-coding 不硬编码(经 .complete(req, model) 传入,路由关注点)。factory.build_adapterprovider=="kimi-code" 分支;包 __init__ 导出全部符号。契约校正(已对照 github.com/picassio/pi-kimi-coder extensions/index.ts:参考实现对 coding API User-Agent: "KimiCLI/1.5"(精确值,已采用)、设 X-Msh-* 头——与 PROGRESS 契约「缺 X-Msh→403」不符本实现以验证到的 UA 为准 + 附带 X-Msh-* 客户端标识头(真客户端会发、额外标识无害、最大化避免 403真 api.kimi.com 联网验证头集是否足够留 K1.3/K1.5(含封号风险,用户自担)。TDD 先红后绿;tests/test_kimi_code_adapter.py(8) + tests/test_kimi_code_factory.py(3),不联网(断 base_url + default_headers + 稳定 device_id + 工厂分派)。门禁绿(隔离 MYPY_CACHE_DIR=.mypy_cache_k12 已清理ruff/format 干净、mypy 27 源文件 Success、pytest 58 passed47→+11@backend 行动K1.3_build_provider_adapter 对 provider kimi-codebuild_adapter("kimi-code", api_key=<刷新后的 access_token>, base_url=…)token 刷新/获取归 K1.3。无 OpenAPI 形变,前端无需 re-gen。memory 记 C1 扩K1.2)契约 + 1 gotcha。

  • [2026-06-19] @db — K1.1 provider_credentials 加 OAuth 列C2 扩稳定)packages/db/ww_db/models.py ProviderCredential:① 加 auth_type: Mapped[str](Text, nullable=False, server_default="'api_key'",值 api_key|oauth);② 加 oauth_enc: Mapped[bytes|None](LargeBinary, nullable=True,持 Fernet 加密 JSON {access_token,refresh_token,expires_at});③ api_key_encnullable=True(Mapped[bytes|None]OAuth-only 行无 api_key、既有 api_key 行保值)UniqueConstraint(owner_id,project_id,provider) 不变。首个新迁移M1M5 全零建表)migrations/versions/1f011c42bd4d_provider_credentials_oauth_columns.pydown_revision=220ca2e3d53fup=add_column auth_type/oauth_enc + alter api_key_enc→nullabledown 逆向autogenerate 仅这 3 op 无 noise手修模板重复 import + 改本仓 ruff 样式(见 gotchaupgrade head 已应用、alembic check 无漂移。门禁ruff/format 干净、pytest 400 passed、alembic 无漂移;mypy 余 2 处 arg-type 错(均在 @backend apps/api/ww_api/services/credentials.py,因 api_key_enc 改 nullable 打穿K1.3 吸收,见下方 @backend 请求)。memory 记 C2 扩 + 2 gotcha。

  • [请求 → @backendK1.3]K1.1 把 provider_credentials.api_key_enc 改 nullablebytes|None),打穿到你拥有的 apps/api/ww_api/services/credentials.py mypy 报 2 处 arg-typeStoredCredential.api_key_enc: bytes ↳ 现 bytes|Nonedataclass line 28 + store line 75/97。@db 不越权改 apps/api。K1.3 接 OAuth store 时把 StoredCredential.api_key_encbytes | None(并加 auth_type/oauth_enc 字段 + OAuth 读写路径mypy 即全绿。oauth_enc 持 Fernet 加密 JSON {access_token,refresh_token,expires_at}key=settings.credential_enc_key,同 api_key_enc

  • [2026-06-19] @orchestrator — 🎉 M1M5 全部交付 + M5 余项收尾完成。五个里程碑Phase 05全部 M5 三项非阻塞余项 + 本次台账归档共四项 follow-up 已清:#1 Codex 读端点(GET /projects/:id/characters + GET .../world_entities@backend+ 前端接线CodexPage 拉全量真源,去「会话内回显」局限,@frontend#2 build_adapter provider→适配器工厂 + anthropic mypy 修复(@llmbuild_gateway_for_tier 按 provider 选适配器启用 Anthropic/Gemini 真实回退(@backend#3 packages/skills 纳入 uv workspace + skill implregistry/permissionsww_core.domain 迁入 ww_skills@backend@devops 加 SDK#4 本次把 M5/M4/M3 三段折叠进「已归档阶段」、顶部改短状态行(@orchestrator。最终门禁全绿后端 ruff/format 干净、mypy 144 文件、alembic 无漂移、pytest 400 passed;前端 lint/typecheck 干净、vitest 130 passed、build OK。台账已归档当前无活跃阶段。

  • [2026-06-19] @frontend — M5 follow-up #1 Codex 展示真源(解余项①)(消费 @backend C3 扩 Codex 读端点,无契约变更)。先 pnpm gen:api 纳入 GET /projects/:id/charactersCharacterListResponse{characters?}+ GET .../world_entitiesWorldEntityListResponse{world_entities?}+ lib/api/types 加 2 别名。lib/api/serverfetchCharacters/fetchWorldEntities200 空列表非 404仿 fetchForeshadowcodex routeServer ComponentPromise.all 拉 项目+人物+世界观全量 → 传 CodexPage 初始数据。CodexPage 人物 tab 渲染跨会话持久化真源(刷新不再空),本会话新入库卡经纯函数 mergeCharacterCards(按 name 去重、持久化优先、不重复合并补显generate→ingest 后仍即时见新行);世界观 tab 渲染入库真源(本期无世界观入库端点,故只真源 + 生成器预览,无 session 合并);时间线维持 P2 占位。纯逻辑 lib/generation/cards.{mergeCharacterCards,mergeWorldEntities} + 5 node-env 单测。前端门禁全绿gen:api/lint/tsc/vitest 130125→+5/build。Codex「会话内回显」局限已去除(解 gotcha + PROGRESS 余项①。memory 把 Codex 缺口 gotcha 标 RESOLVED。

  • [2026-06-19] @backend — M5 follow-up R1 + R3 (三 fix与并行 @llm llm_gateway 改动 disjointR1-Codex 读端点(解余项①):加 GET /projects/:id/charactersCharacterListResponse+ GET /projects/:id/world_entitiesWorldEntityListResponse),复用 C5 读侧 SqlCharacterRepo/SqlWorldEntityRepo(经 get_memory_repos,不动 assemble+ 反向 JSONB 解包({"items":[...]}→list/{"text":...}→str/{"rules":[...]}→listregister mainC3 扩稳定。R3-skill 迁包(解余项③):skill_registry.py+skill_permissions.pyww_core.domain 迁入 packages/skills/ww_skills/ww_skills/__init__ 改直接导出删门面importergeneration.py/project_deps.py/test_generation.py)改 from ww_skills import …skill 单测移 packages/skills/tests/13 测);删 ww_core.domain 两模块+init 导出;packages/skills/pyproject.toml deps 校准(去 ww-core、补 ww-llm-gateway+sqlalchemyuv sync 重建。R1#2-build_adapter 接线(解余项②的 apps 侧;@llm 的 build_adapter 工厂 + @devops 的 anthropic/google-genai SDK 均已落地import 实解非 transientbuild_gateway_for_tier_build_provider_adapter(原 _build_openai_compat_adapter)改调 ww_llm_gateway.build_adapter(provider, api_key=…, base_url=…)——Anthropic/Gemini 传 base_url=None 走原生适配器,去掉直接 AsyncOpenAI/OpenAICompatAdapter import。门禁绿隔离 MYPY_CACHE_DIR=.mypy_cache_r1backend 已清理ruff/format 净、mypy 101 文件 0 error、pytest packages/core packages/skills apps/api 246 passed226→+20+10 迁移 skill 测 +3 Codex 读端点测 + 其余)。两新端点入 OpenAPI验证 get 存在。memory 登记 C3 扩Codex 读端点)+ C8 实现位置更新 + build_adapter 接线 + 3 decisions。@frontend 行动cd apps/web && pnpm gen:api 纳入 GET characters/GET world_entitiesCodexPage 初始列表拉全量去掉「会话内」局限(解 gotcha Codex 缺口)。@devops 行动:复核根 uv.lock@backend 改了 packages/skills/pyproject.toml depsuv sync 重建 ww-skillsM5 三非阻塞余项①②③ 至此全部清除。

  • [2026-06-19] @llm — R2 follow-up #2 真多 provider 适配器选择C1 扩 follow-up #2 稳定;接 @devops 已加 anthropic+google-genai SDK 之后)。① 修真 SDK 装上后的 mypy 报错instructor.from_anthropic(self._client) 重载只收 SDK 具体 AsyncAnthropic|...AnthropicClient Protocol 不匹配 → adapter 内 cast("AsyncAnthropic", self._client)TYPE_CHECKING import零运行时硬依赖选中 AsyncInstructor 重载。gemini 走 response_schema 非 instructor该类错。② 新增 provider→适配器工厂 factory.build_adapter(provider, *, api_key, base_url=None) -> ProviderAdapter(包 __init__ 导出):anthropicAnthropicAdapter{gemini,google}GeminiAdapter、其余→OpenAICompatAdapter(provider, AsyncOpenAI(...));从 api_key 构真实客户端factory 处 cast 跨 Protocol read-only-attr 约束adapter 仍声明 Protocol 形参、测试替身缝完好)。新增 tests/test_build_adapter_factory.py 6 测(按 provider 名断分派,不联网)。门禁绿(隔离 cacheruff/format 净、mypy 24 源文件 0 错、pytest 47 passed41→+6全仓 mypy packages apps 144 文件 Successanthropic.py 报错确认消除、gemini 无同类错)。无 OpenAPI 形变served_by 不出 API前端无需 re-gen。@backend 可在 build_gateway_for_tierbuild_adapter 替换「一律 OpenAICompatAdapter」启用 anthropic/gemini 真实回退。 记 1 gotchaProtocol vs 真 SDK cast 边界)。

  • [2026-06-19] @orchestrator — 🎉 M5 完成 + 独立复核 Wave CT5.3+T5.6 + Wave DT5.7 )。波次 A(T5.1‖T5.4‖T5.5)→B(T5.2)→C(T5.3+T5.6)→D(T5.7) 全绿,契约先行、零返工、无新 bug。最终独立复跑确认后端 ruff/format 干净、mypy 142 文件alembic 无漂移M5 复用 T0.2 既有 world_entities/characters/rules/skills 表全程零建表迁移、pytest 391 passed;前端 tsc 干净、vitest 125 passedM5生成+多provider+扩展)出口 DoD 全达成worldbuilder/character-gen 生成→预览→入库continuity 409 gate + partition_writes 白名单 + schema→JSONB 形变);网关多 provider 回退/熔断/能力降级(真 Gateway 回退链E2E 验主失败→fallback 服务 + 记账记实际 providerSkill registry + 表权限沙箱 + 规则页/技能库/命令面板(⌘K)。M1M5 全部交付。 非阻塞余项:① Codex 读端点缺口(无 GET characters/world_entities现以生成+会话内回显管理);② Anthropic/Gemini 真实回退待 @devops 加 SDK + 按 provider 选适配器类E2E 用 OpenAI 兼容 mock 验证回退);③ packages/skills 纳入 uv workspace现 impl 落 ww_core.domain + façade。建议下一步清理 PROGRESS 把 M3/M4/M5 折叠归档,或处理上述余项。

  • [2026-06-19] @qa — M5 Wave DT5.7 M5 E2E + 切 provider(真 pg + mock 多 provider零 token无契约变更tests/test_m5_e2e.py 3 用例:① 群像生成→入库闭环mock 网关按 req.output_schema 路由 CharacterGenResult/WorldGenResult/ContinuityReviewPOST /world/generate 预览 + POST /characters/generate 预览 3 卡 → POST /characters 入库双 gate——precheck 有冲突且未 acknowledge_conflicts409 CONFLICT_UNRESOLVED+details.conflicts(并断言此刻 characters 表无行,守不变量 #3→ 带 acknowledge_conflicts=true 重发 201DB 真源断言 characters 行真落 pg + schema→JSONB 形变traits/speech_tics→{"items":[...]}、arc→{"text":...}、tags/relations 直落 listrejected_tablespartition_writes 合法路径4 条 ledger。② 切 provider 回退HTTP 角色生成跑在Gateway(非 stubdeepseek(每次 completeTransientProviderError 耗尽重试)→openai 回退链上,端点仍 200served_by 不出 API故经 DB 真源 usage_ledger 断言实际服务方 = openai(fallback)≠deepseek(primary)ARCH §4.5 记账记实际服务方)。③ 能力降级structured_output=False 唯一 provider 直测 Gateway.runserved_by.degraded=True§4.4)。坑:生成网关是请求 scope 依赖get_worldbuilder_gateway/get_character_gen_gateway/get_precheck_gateway),直接 app.dependency_overrides 注假网关即可,无需 monkeypatch build_gateway_for_tier(与 M4 学文风后台自建网关不同。全仓门禁绿ruff/format 净、mypy 142 文件alembic 无漂移、pytest 391 passed388→+3未发现 REAL bugM5 出口 DoD 全达成 → orchestrator 可封 M5。

  • [2026-06-19] @frontend — M5 Wave CT5.3+T5.6 生成 + 设定库 + 规则 + 技能 + 命令面板(消费 C3 扩 T5.2 + C8/T5.5,无契约变更)。先 pnpm gen:api 纳入 5 端点world/characters generate + characters ingest + GET rules + GET skills+ lib/api/types 加 12 别名。T5.3:① 角色生成器UX §6.6components/generation/CharacterGenerator:一句话 brief + 数量(112) + 定位 → POST /characters/generate 预览卡 → CharacterCardItem(勾选入库 + 就地编辑名/弧光,默认全选)→ POST /characters 入库;409 CONFLICT_UNRESOLVED 裁决流useCharacterGen 捕 409 → extractIngestConflicts 收窄 details.conflicts(复用 ReviewConflict 形) → ConflictAdjudication 面板展示 continuity 冲突 → 作者「已知悉强制入库」= 带 acknowledge_conflicts=true 重发 / 「取消改卡」。② 世界观设计器 WorldGeneratorPOST /world/generate 预览 type/name/rules本期无入库端点仅预览参考。③ 设定库 CodexUX §6.5codex/CodexPage + app/projects/[id]/codex:人物/世界观/时间线三 tab时间线 P2 占位);?gen=character|world 命令面板跳转直开对应 tab。T5.6:④ 规则页 rules/RulesPage + app/.../rules:四级规则列表(groupByLevel) + 新增(useRules 乐观追加+回滚,仿 useForeshadow)。⑤ 技能库 skills/SkillsPageServer Component 纯读)+ app/.../skillsGET /skills 按 scope 分组只读注册表(name/tier/reads/writes)。⑥ 命令面板 ⌘K command/{CommandPalette,CommandPaletteMount} + lib/command/palette⌘K/Ctrl+K 开关、模糊过滤(filterCommands)、上下循环高亮(moveHighlight)、Esc/Entera11y(role=dialog/listbox/option + 自动聚焦 + prefers-reduced-motion);挂 RootLayout 对全局生效,读 pathname 注入项目上下文。⑦ LeftNav ActiveNav 加 codex/rules/skills替换原 disabled 设定库占位。纯逻辑全单测node-envlib/{generation/cards,rules/rules,skills/skills,command/palette}.test。前端门禁全绿gen:api/lint/tsc/vitest 125(96→+29cards 12 + rules 5 + skills 3 + palette 9)/buildcodex/rules/skills 路由齐。memory 记 2 gotcha + 1 gapCodex 读端点缺口)。M5 前端交付完成 → 下一步 Wave DT5.7(@qa) M5 E2E + 切 provider

  • [2026-06-19] @orchestrator — M5 Wave B 收口 T5.2C3 扩稳定。5 端点入 OpenAPIworld/characters generate 预览 + characters 入库(双 gatecontinuity 预检 409 + partition_writes 白名单 + schema→DB 形变)+ GET rules/skillsbuild_gateway_for_tier 接线回退链OpenAI 兼容齐Anthropic/Gemini 真实切换余量 deferred 给 T5.7 + @devops SDK。全仓门禁绿ruff/format 干净、mypy 142 文件alembic 无漂移、pytest 388 passed371→+17。下一步 Wave CT5.3+T5.6(@frontend 单 agent 顺序做)——先 pnpm gen:api,做 角色生成器 + 世界观设计器 + 设定库 Codex + 规则页 + 技能库 + 命令面板⌘K入库流处理 409 裁决重发。

  • [2026-06-19] @backend — M5 Wave BT5.2 生成/入库 API(契约 C3 扩稳定;消费 Wave A 的 C6扩/C8/C1扩与已合并 Wave A 无写冲突)。routers/generation.py+ skills_router,已注册 main落 5 端点:① POST /world/generateworldbuilder writer 网关 run_worldbuilder预览世界观,不入库,末尾 commit 落 ledgerPOST /characters/generatecharacter-gen writer 网关,注入已有角色防雷同 → 预览角色卡);③ POST /characters(入库 双 gateprecheck_generated_cards continuity 预检 analyst 网关——有冲突且未 acknowledge_conflicts409 CONFLICT_UNRESOLVED+冲突详情,作者裁决后放行;partition_writes(character_gen_spec,...) 白名单过滤越权写表;过 gate 写 characters 行,schema list/str → DB JSONB dict 形变);④ GET /rules(规则列表,复用 C5 读侧);⑤ GET /skills(技能库,经 registry。新写侧 repo ww_core.domain.{character_repo(traits/speech_tics→{"items"}/arc→{"text"}),world_entity_repo(rules→{"rules"})}(只 flush端点 commitT5.4 follow-up 接线完成build_gateway_for_tier 据 DB tier_routing.primary+fallback 预备多 OpenAICompatAdapter + 注入 chain_resolver=chain_from_routing(...) 启用回退链;无路由行退回 resolve_route(单 providerM1 兼容无可用凭据→503。仅 OpenAI 兼容 providerdeepseek/kimi/qwen/glm/openai——Anthropic/Gemini 真实回退需 @devops 加 SDK + provider_deps 据 provider 选适配器类(余量 deferred 给 T5.7 切 provider。全仓门禁绿ruff/format 净、mypy 142 文件alembic 无漂移M5 复用 T0.2 既有表、pytest 388 passed371→+1713 生成/入库端点 + 4 网关回退接线 + 4 形变 helper。新端点入 OpenAPI验证 world/characters generate + POST characters + GET rules + GET skills 齐。memory 登记 C3扩稳定 + 2 decisions入库 gate / 形变)+ 2 gotchas。@frontend(T5.3/T5.6) 行动:先 cd apps/web && pnpm gen:api 纳入这 5 端点;入库流处理 409展示冲突→裁决勾选→带 acknowledge_conflicts 重发)。下一步 Wave CT5.3+T5.6(@frontend)(依赖 T5.2+T5.5,可起)。

  • [2026-06-19] @orchestrator — M5 Wave A 收口 T5.1 + T5.4 + T5.5 三 agent 并行disjoint 目录 + 隔离 mypy cache零写冲突零返工。worldbuilder/character-gen 双 spec + 节点 + 入库前 continuity 校验缝C6扩‖ 网关多 provider 韧性Anthropic/Gemini 适配器 + 回退链 + 熔断 + 能力降级C1扩无 OpenAPI 形变)‖ Skill registry + 表权限白名单filter_reads/partition_writes+ POST /rulesC8 + C3扩。全仓门禁绿ruff/format 干净、mypy 135 文件alembic 无漂移M5 复用 T0.2 已建的 world_entities/characters/rules/skills 表无建表迁移、pytest 371 passed296→+75Wave B 衔接待办T5.2 @backend 须处理):① 角色 schema traits/speech_tics(list)/arc(str) ↔ DB JSONB dict 形变,入库须转换;② 入库 gate 调 precheck_generated_cards(continuity 冲突拦截) + partition_writes(越权写丢弃审计);③ 补 GET /rules + GET /skills 供 T5.6 前端;④ 接线 build_gateway_for_tierchain_from_routing 启用回退链T5.7 切 provider 依赖)。@devops 待办:加 anthropic/google-genai SDK 依赖(适配器懒 import单测不需评估把 packages/skills 纳入 uv workspace现 impl 落 ww_core.domain + ww_skills façade。下一步 Wave BT5.2(@backend 生成/入库 API)

  • [2026-06-19] @llm — M5 Wave AT5.4 网关多 provider 韧性(契约 C1 扩稳定,仅扩 packages/llm_gateway/,与并行 T5.1 @llm 无文件冲突)。① 新适配器adapters/anthropic.py(AnthropicAdapter:原生结构化经 instructor.from_anthropic 懒构建、cache_control 缓存断点、thinking 能力)+adapters/gemini.py(GeminiAdapterresponse_mime_type=json+response_schema 结构化、thinking)——均经注入的客户端 Protocol不硬 import anthropic/google-genai SDK单测零联网零依赖。② 回退链 + 重试 + 熔断gateway.pyGatewaychain_resolver/max_retries/breaker(保留 resolver= M1 兼容→自动包成单元素链);沿链逐 provider→瞬时失败(tenacity 指数退避)重试 R 次→仍失败/熔断打开/无适配器→切下一个;首个成功者服务、非链首标 served_by.fell_back;链耗尽抛 LLM_UNAVAILABLE;记账记实际服务方(回退后不记主模型);流式仅首块前可切(产出后中途失败上抛不重连)。CircuitBreaker(threshold/reset_seconds/clock) 连续失败超阈值短时熔断、成功清零、冷却半开。③ 能力协商/降级:结构化请求按 capabilities().structured_output 重排链优先选支持者;链上无支持者→降级首个可用(适配器自走 instructor JSON 提示)标 served_by.degraded。④ 瞬时错误契约errors.pyTransientProviderError(三适配器按异常类名+status_code 包装)+网关视 AppError(RATE_LIMITED) 可重试。⑤ routing.pyresolve_chain/chain_from_routing(据 DB tier_routing 去重保序)/ChainResolver 别名导出。⑥ ServedBydegraded(向后兼容,默认 False)pyproject.tomltenacity>=8.223 新测(test_fallback_chain 10/test_capability_degradation 4/test_new_adapters 7/test_multi_provider_accounting 2),包内 41 passed全仓门禁绿ruff/format 净、mypy 135 文件、core+api 226 passed(无回归)。无 OpenAPI 形变(served_by 不出 API前端无需 re-gen)。memory 登记 C1 扩 + 2 gotcha。后续待办apps/api build_gateway_for_tier 接线回退链(预备多适配器+传 chain_resolver=chain_from_routing 包装)、@devops 加 anthropic/google-genai SDK 依赖供真实接线。下一步 Wave B(T5.2 @backend依赖 T5.1)。

  • [2026-06-19] @backend — M5 Wave AT5.5 Skill 运行时 + 规则(契约 C8 + C3 扩稳定;与并行 T5.1/T5.4 @llm 无目录/写冲突,隔离 MYPY_CACHE_DIR=.mypy_cache_t55)。① Skill registry loaderpackages/core/ww_core/domain/skill_registry.pySkillRecord(frozen,skills 行声明快照) + SkillRepo Protocol + SqlSkillRepo(读 skills 表,裸 tier 非法→VALIDATION + SkillRegistry.load(repo)async每条跑 validate_declaration越权声明→AppError VALIDATION 加载中断frozen dict[name,AgentSpec]+ get/names/list_scope。复用 §5.1 网关机制(不重实现网关),不变量#2 只带 tier。② 表权限沙箱skill_permissions.py,纯函数/不可变§5.6「声明式权限+apply 层白名单」非进程沙箱):KNOWN_TABLES(10 创作表白名单) + filter_reads(注入只喂声明 reads 表) + partition_writes(写库只应用声明 writes越权→rejected 供审计 log+丢弃) + validate_declaration(reads/writes 越界→VALIDATION)。守不变量#3allowed 仍过验收 gate不开写后门。③ POST /projects/:id/rulesrouters/rules.py,已注册 mainRuleCreateRequest{level:Literal[global/genre/style/project],content(min1)}201 RuleView{level,content},非法 level/空 content→FastAPI 422写侧 domain/rule_repo.py(RuleWriteRepo/SqlRuleWriteRepo/RuleWriteView,只 flush,端点 commit);喂 assemble 四级 merge_rules。④ 注入缝 get_rule_write_repo/get_skill_registryproject_deps。门禁绿限本任务范围ruff/format 净、MYPY_CACHE_DIR=.mypy_cache_t55 mypy packages/skills packages/core apps/api 0 error/94 文件、pytest packages/skills packages/core apps/api 226 passed+18 新测6 permissions + 4 registry + 2 rule_repo + 3 rules 端点 + 既有)。POST /rules 已入 OpenAPI验证实现位置决策registry/沙箱落 ww_core.domain§5.6 强制点在编排/写库层 + packages/skills 当前非 uv workspace member根 pyproject @devops 未接线);ww_skills 留再导出门面,待 @devops 纳入 workspace 可迁移(见 decisions/gotchas@frontend(T5.6) 行动:先 cd apps/web && pnpm gen:api 纳入 POST /rules(规则页);技能库经 get_skill_registry(若 T5.6 需 GET /skills 端点,请在此提请 @backend 补)。@llm/T5.2 行动:生成入库层用 partition_writes 守自定义 skill 产出白名单(仅声明 writes 表),仍过验收。

  • [2026-06-19] @llm — M5 Wave A 半程T5.1C6 扩稳定,与并行 T5.4 @llm/T5.5 @backend 无目录/写冲突,隔离 MYPY_CACHE_DIR。worldbuilder + character-gen 落地:① schemapackages/agents/ww_agents/schemas.pyWorldEntityCard{type,name,rules:list[str]}/WorldGenResult{entities} + CharacterRelation{name,kind,note?}/CharacterCard{name,role,traits,backstory,arc,speech_tics,tags,relations}/CharacterGenResult{cards}——字段对齐 world_entities/characters DB 列供 T5.2 ingest 直映。② specspecs.pyworldbuilder_spec(writer,reads=projects,writes=world_entities,硬规则显式 prompt)、character_gen_spec(writer,reads=world_entities+characters,writes=characters,system_prompt 注入「已生成卡+已有角色」差异化要求=M5-a 防雷同)。③ 生成节点(packages/core/ww_core/orchestrator/generation_node.py,模块内自有 GatewayRun Protocol不重复导出run_worldbuilder/run_character_genbuild_character_gen_context 把已有+已生成卡序列化成 name(role)traits 简表注入空时占位不崩独立生成、网关失败上抛、parsed 违约 ValueError只读不写库。④ 入库前 continuity 校验缝ARCH §6.5precheck_generated_cards(spec=continuity_spec,*,cards,world_context,characters_context,...)->list[Conflict]——编排器追加的检查、非 character-gen 直接互调(守 §5.4/不变量#1T5.2 入库端点调它做 gate。门禁绿限本任务文件ruff/format 净、mypy 本任务 7 文件 0 errorpackages/agents packages/core 余 3 error 全在并行 @backend T5.5 的 rule_repo/skill 测试、pytest 246 passed(+34 新测22 spec 契约 + 12 节点/防雷同/校验缝)。memory 登记 C6 扩稳定T5.2(@backend) 行动POST /world/generate→run_worldbuilder、/characters/generate→run_character_gen(批量循环把已产卡传 generated_so_far)、POST /characters 入库前调 precheck_generated_cards gateanalyst/writer 网关复用 build_gateway_for_tier。下一步 Wave BT5.2(依赖本任务,可起)。

  • [2026-06-19] @docs — spec 一致性回写:把 T4.3 顺带新增的 GET /projects/:id/style(最新指纹 {dimensions, evidence, version},无指纹 404补进 ARCHITECTURE.md §7.2 端点表(紧邻 POST /style 行)+ PRODUCT_SPEC.md §6 端点清单(紧邻 POST /style 行),消除 code↔spec 漂移。memory/decisions.md 该决策的「待回写规格」flag 至此已解决。仅改两份 spec未动代码/测试。

  • [2026-06-19] @orchestrator — M4 收官独立复核 。波次按计划走通 A(T4.2‖T4.1)→B(T4.3)→C(T4.4)→D(T4.5),每波契约先行 + 全仓门禁收口、零返工、无新 bug。最终独立复跑后端门禁确认绿ruff/format 干净、mypy 115 文件alembic 无漂移M4 全程零建表迁移,全靠 T0.2 预留的 style_fingerprint/chapter_reviews.style/jobs 列表、pytest 296 passed;前端 gen:api/lint/tsc/vitest 96/build 绿。M4文风出口 DoD 全达成:学文风(16 维指纹带证据,版本化,异步 jobs+zombie reaper) + 漂移打分作为第四审真持久化(review 四并行分支+SSE style+chapter_reviews.style) + 回炉同步 diff(不写库守不变量#3)。Phase 4 完成M1M4 全部交付。下一阶段 M5(生成+多 provider+Skill) 见 DEV_PLAN进入时归档 M3/M4 并拉入新表。

  • [2026-06-19] @qa — 🎉 M4 完成Wave DT4.5 M4 E2Etests/test_m4_e2e.py 真 pg + 多档位 mock 网关(零 token真跑通过 3 用例:① 学文风闭环POST /style202 {job_id}→BackgroundTask run_job 自建独立 session 跑 run_style_extraction(analyst 假适配器产 StyleFingerprintResult)→SqlStyleFingerprintWriteRepo.append 真落 pg→GET /jobs/{id} status=done(result.version/dims_count)→GET /style 最新指纹→mode="update" 学一次 version+1DB 真源 style_fingerprint 2 行(version 1/2,dimensions/evidence)+ jobs 2 行 done。② 写章第四审:学文风后 assemble stable_core 含指纹→POST .../review SSE 四审齐(continuity/foreshadow/pace/style)无 error + section{name:"style"} + style{score:72,segments:[{idx:2,score:40,label:"机翻腔"}]} 帧真发 + GET .../reviews 留痕 style(dict)DB 真源 chapter_reviews.style 列真填。③ 回炉POST .../refine→200 {original,refined},refined≠original(writer 据 output_schema is None 返改写串)+ 不写库(无 chapter/review 行,不变量#3)+ writer 记账落 usage_ledger。无新 bug。关键坑(记 memory/gotchas):学文风 BackgroundTask 在独立 session 上自造网关(build_gateway_for_tier 从凭据建真 OpenAI 适配器)→E2E 无真凭据,须 monkeypatch style.build_gateway_for_tier→真 Gateway 包假适配器(ledger 绑入参 session);写侧 repo + run_job 默认 SqlJobRepo 保持真→指纹/job 真落 pg;override get_session_factorye2e_sm(同测试 engine/loop)。最终全收口门禁绿ruff/format 干净、mypy 115 文件、pytest 296 passed(293→+3)、alembic 无漂移(M4 无建表迁移)。M4 出口 DoD 全达成 → Phase 4 可归档。

  • [2026-06-19] @frontend — M4 Wave CT4.4 文风页 + 漂移 + 回炉 + job 轮询(消费 C3 扩 + C4 扩,无契约变更)。先 pnpm gen:api 纳入 style/refine/GET-style + jobs 类型(lib/api/types 加 4 别名)。① job 轮询:新模式 lib/jobs/job.ts(纯状态机 narrowJob/reducePoll/isTerminal/styleLearnResult——GET /jobs/{id} 是松散 {[k]:unknown} 裸端点须安全收窄) + useJobPoll.ts(setTimeout 轮询done/failed 终态停,卸载清理)。② 文风页 app/projects/[id]/style/page.tsx(RSC 取 project + GET /style→404 容忍返 null) + components/style/StyleUpload(多段文本粘贴/选文件 file.text() 读成文本→空行切段→POST /style)、useStyleLearn(受理 202→useJobPoll→done 拉指纹)、FingerprintView(16 维行+可展开证据)。③ 审稿页第四审lib/review/sse.tsStyleEvent/StyleDriftReport/reduceReview case "style"(替换式仿 pace)/ReviewStreamState.style/seedhistory-style 收窄 normalizeStyleDriftlib/style/style.tsStylePanel(◔ 整体相似度% + 漂移段一键回炉)接进 ReviewReport(seed 扩四态)。④ 回炉 RefineView + useRefine(POST /refine→新旧 diff→采纳把 refined 替换 finalText 中原段,经既有 draft 路径合入,不另写库守不变量#3503 优雅提示)。LeftNav 开「文风」入口(ActiveNav 加 "style")。前端门禁全绿gen:api/lint/tsc/vitest 96(+27job 12 + style 10 + style-sse 5)/build(含 /projects/[id]/style 路由)。memory 记 1 gotcha。下一步 Wave DT4.5(@qa) M4 E2E

  • [2026-06-19] @orchestrator — M4 Wave B 完成 T4.3C3 扩稳定。style/refine 三端点入 OpenAPIPOST /style(202+jobs BackgroundTask 跑 run_style_extraction→StyleFingerprintWriteRepo.append)、GET /style(最新指纹含证据/版本)、POST /refine(writer 网关同步返 {original,refined} 不写库)。全仓门禁绿ruff/format 干净、mypy 115 文件alembic 无漂移、pytest 293 passed(+13)。GET /style 顺带补入(回写 ARCH §7.2/PRODUCT_SPEC §6 留 @docs。下一步 Wave CT4.4(@frontend)——先 pnpm gen:api 纳入 style/refine/GET-style + jobs 类型,再做文风页(上传/指纹/证据) + lib/jobs/useJobPoll + 审稿页第四审 StylePanel + 回炉 diff。

  • [2026-06-19] @backend — M4 Wave BT4.3 API style + refine(契约 C3 扩稳定)。三端点入 OpenAPI独立 routers/style.py,仿 outline.py已注册POST /projects/:id/style202 {job_id}(学文风走 jobsM4-cjob_repo.create("style_learn")+commit → background_tasks.add_task(run_job, session_factory, job.id, work)workrun_job 自建独立 session 上自造 analyst 网关+写侧 repo → run_style_extraction → 拆 dimensions_json/evidence_jsonappend(version+1) → {version,dims_count}jobs.result;无凭据 → dep 解析阶段 503(调度 job 前拦下,不凭空写注定失败的 job。② POST /projects/:id/chapters/:no/refine → 同步 200 {original,refined}writer 网关 run(refiner_spec)output_schema=Noneresp.text;不写库守不变量#3末尾 commit 让 usage_ledger 落库)。③ 顺带补 GET /projects/:id/style → 最新指纹 {dimensions,evidence,version}UX §6.9ARCH §7.2 原缺读端点——决策见 decisions待 @docs 回写 ARCH §7.2/PRODUCT_SPEC §6);不动 C5 读侧 SqlStyleRepoassemble 行为不变)。新建写侧 domain/style_repo.py(StyleFingerprintWriteRepo/Sql*append 只 flush + latest 含证据/版本)project_depsget_style_write_repo/get_style_extract_gateway(analyst)/get_refine_gateway(writer)。全仓门禁绿ruff/format 干净、mypy 115 文件alembic 无漂移(M4 无建表)、pytest 293 passed(280→+13)。memory 登记 C3 扩 + 2 decisions + 1 gotcha。@frontend 行动T4.4 前 cd apps/web && pnpm gen:api 纳入 style/refine/GET style + jobs 轮询类型。下一步 Wave CT4.4(@frontend)

  • [2026-06-19] @orchestrator — M4 Wave A 收口 T4.2 + T4.1 全绿。全仓门禁收口ruff/format 干净、mypy 111 文件alembic 无漂移M4 无建表迁移、pytest 280 passedM3 基线 228 → +52T4.2 37 + T4.1 15。契约稳定C6扩/C4扩StyleFingerprintResult/StyleDriftReview/四审齐/SSE style 事件、C3.5JobRepo/run_job。下一步 Wave BT4.3(@backend)——单 @backend agent 顺序做 style/refine 两端点:新建 StyleFingerprintWriteRepo + routers/style.py(POST /style 202 调 job_repo.create+run_job(work=run_style_extractionStyleFingerprintWriteRepo.append)POST /refine 同步 refiner_spec writer 网关返 {original,refined})C3 扩;评估顺带 GET /projects/:id/style

  • [2026-06-19] @backend — M4 Wave AT4.1 jobs 长任务基建(契约 C3.5 稳定,不碰 style 业务,与并行 T4.2 @llm 无目录/写冲突)。packages/core/ww_core/domain/job_repo.pyJobRepo Protocol + SqlJobRepo(create/set_running/set_progress 夹取/complete/fail/get/reap_zombies) + frozen JobView——状态写只 flush(提交归 run_job/端点),唯 reap_zombies 启动期独立调用故自 commitapps/api/ww_api/services/job_runner.py:通用 run_job(session_factory, job_id, work) 自建独立 session(仿 run_overdue_scan)→set_running→work→complete/异常→新 session fail异常吞不冒泡最小 JobLifecycleRepo Protocol + 可注入 repo_factory 缝。get_job_repo 加进 project_depsmain.py lifespan 在 seed_stub_user 后跑 reaper(M4-d幂等自 commit)。门禁绿(限本任务文件)ruff/format 干净、mypy 本任务文件 0 error(packages/core apps/api 余 7 error 全在 @llm 在做的 test_style_*)、pytest 15 新测(13 job_repo+2 job_runner)packages/core 130 passed / apps/api 50 passed。memory 登记 C3.5。T4.3 行动POST /stylejob_repo.create + background_tasks.add_task(run_job, session_factory, job.id, work=…)

  • [2026-06-19] @llm — M4 Wave A 半程T4.2C6 扩 + C4 扩稳定。style-auditor 双轨落地:①提取轨 style_extract_spec(analyst,独立生成仿 outliner,不进 review 图)+StyleFingerprintResult{dimensions:[StyleDimension{name,value,evidence}]}(16 维带证据)+orchestrator/style_extract_node.py(build_style_extract_request/run_style_extraction,模块内自有 GatewayRun Protocol,网关失败上抛/parsed 违约抛 ValueError,只读不写库);②漂移轨第四审 style_drift_spec(name="style",light,只读)+StyleDriftReview{score=100,segments:[StyleDriftSegment{idx,score,label?}]}(默认值即无指纹降级态)→REVIEW_SPECS 四审齐collect 加 STYLE/extract_style→record style=sse 加 EVENT_STYLE/style_event+_section_result_events STYLE 分支(style{score,segments},字典序 continuity<foreshadow<pace<style 天然纳入);③回炉 refiner_spec(writer,output_schema=None 纯文本,非持久)。门禁绿ruff/format 净、mypy 47 文件(隔离 cache 避与 @backend T4.1 竞争)、packages/agents+core pytest 197 passed(+37 新测:双轨 spec/schema 契约 + 四审图跑通 len(calls)==4 + collect 落 style 列 + SSE style 事件 + 无指纹降级落库)。memory 登记 C6扩/C4扩。T4.1(@backend) 已并行完成→ Wave BT4.3(@backend style/refine 端点) 可起,调本任务 run_style_extraction/refiner_spec

  • [2026-06-19] @orchestrator — 进入 M4文风:归档心智上 M3Phase 4 五任务拉入台账。探查确认免重复建表:style_fingerprint 表/chapter_reviews.style 列/jobs 表+GET /jobs/:id/读侧 SqlStyleRepo.latest 均已在前期建齐 → M4 无新建表迁移assemble 已把指纹纳入 stable_core → 第四审天然在 review_context 拿指纹对照、无需额外注入。已定决策style-auditor 双轨拆 style_extract_spec(analyst,独立生成,仿 outliner)+style_drift_spec(light,第四审并入 REVIEW_SPECS);学文风走 jobs+BackgroundTask(独立 session,仿 run_overdue_scan)+启动 zombie reaper回炉 refine 同步返回 {original,refined} 不写库(守不变量#3。启动 Wave AT4.2(@llm·agents+orchestrator) ‖ T4.1(@backend·jobs 基建)(不同目录,隔离 MYPY_CACHE_DIR

  • [2026-06-18] @orchestrator — 🎉 M3 完成T3.8 修复 + @qa 解钉 xfail。T3.8 把 SqlAlchemyLedgerSink.record 改 add-only去并行路径里唯一的 await flush(),靠端点/事务 commit 持久化),并发回归测试 RED 已验旧实现抛 Session is already flushing@qa 移除 T3.7 case3 strict-xfail、收紧为严格正向断言三审 section 齐 + foreshadow/pace 真发事件 + chapter_reviews.foreshadow_sug/pace 列真填 + beat_map 精确断言。最终全收口门禁绿ruff/format 干净、mypy 111 文件、pytest 228 passed(0 xfailed/0 failed)、alembic 无漂移;前端 lint/tsc/vitest 69 绿。M3 出口 DoD 全达成。 下一阶段 M4文风

  • [2026-06-18] @orchestrator — M3 Wave ET3.7 E2E 交付 + 暴露并发 bugtests/test_m3_e2e.py 真 pg 跑通:① 伏笔 埋设→进展→验收后 BackgroundTask 扫描置 OVERDUE→看板过滤(DB 真源)✓ ② 大纲 POST .../outline→outline 表行+窗口+幂等 upsert+记账✓。③ 三审 SSE 用例 strict-xfail 钉住真 bug:三审同 LangGraph superstep 并行 + 共用请求 session 的 SqlAlchemyLedgerSink.record(add+await flush)→AsyncSession 非并发安全→第二/三审 flush 撞「Session is already flushing」→被 run_review 失败隔离静默吞成 incompleteforeshadow/pace 静默丢失(SSE 无事件、chapter_reviews 列空)。M2 单审未触发。基线 222 passed + 1 xfailed。开 T3.8(@llm) 修复 → 修后 @qa 解钉 xfail → 才算 M3 达成。

  • [2026-06-18] @orchestrator — M3 Wave D 完成T3.6)。前端三块落地:伏笔四泳道看板(/foreshadowOVERDUE 琥珀 + 登记/转移乐观更新)、大纲编辑器(/outline,逐章 beats + 伏笔窗口徽标 + 接近回收提示)、审稿页扩消费 foreshadow/pace SSE伏笔建议区 + 节奏节拍图 ▁▃▅,三审齐显,文风第四审留 M4pnpm gen:api 纳入 M3 端点(看板/登记/转移/大纲),松散 JSONB 字段安全收窄不手写。前端门禁绿gen:api/lint/tsc/vitest 69(+24)/build。memory +1 decision +2 gotchas。下一步 Wave ET3.7 M3 E2E(@qa 真 DB + mock 网关零 token)。

  • [2026-06-18] @orchestrator — M3 Wave C 完成T3.5C3 扩稳定)。GET .../foreshadow?status= 看板(续 foreshadow.router四泳道+ POST .../outline(独立 outline.pyrun_outline analyst 网关 → 逐章 upsert outline 表含伏笔窗口 → 端点末尾 commit。outline 写侧 repo 加 Write 前缀避撞 C5 读侧。全仓门禁绿mypy 102 文件、pytest 220 passed(205→+15)。memory 登记 C3 扩 + 1 decision + 1 gotcha。下一步 Wave DT3.6(@frontend 伏笔看板 + 大纲编辑器 + 节奏节拍图 + 审稿页消费 foreshadow/pace SSEpnpm gen:api)。

  • [2026-06-18] @orchestrator — M3 Wave B 完成T3.2)。验收后到期扫描挂 BackgroundTaskrun_overdue_scan 自建独立 session 置 OVERDUE接 §5.5 TODO(M3)+ 伏笔登记/状态端点(POST/PATCH .../foreshadow,重复 code/非法转移→VALIDATION 422未动 shared 错误码。全仓门禁绿mypy 95 文件、pytest 205 passed(196→+9)。memory 登记 C3 扩 + 1 decision + 2 gotchas。下一步 Wave CT3.5(@backend GET .../foreshadow?status= 看板续接 foreshadow.router + POST .../outline 独立 outline.py 调 run_outline)。

  • [2026-06-18] @orchestrator — M3 Wave B 半程T3.3C4/C6 扩稳定。foreshadow-analyst + pace-checker 并入 build_review_graphREVIEW_SPECS 三审齐,文风第四审留 M4collect 一次 record 分列落 conflicts/foreshadow_sug(扁平+kind 标记)/pace(整 dict)normalize_reviewforeshadow/pace SSE 事件向后兼容。全仓门禁绿ruff/format 干净、mypy 91 文件、pytest 196 passed(169→+27)。memory 登记 C4/C6 扩 + 2 gotchas。Wave B 顺序执行T3.3 改完 orchestrator → 现启 T3.2(@backend apps/api),对最终 orchestrator 构建、无编译竞争。

  • [2026-06-18] @orchestrator — M3 Wave A 完成T3.1 + T3.4)。两 agent 并行(@backend core/domain ‖ @llm agents+orchestrator隔离 MYPY_CACHE_DIR 避缓存竞争。T3.1:伏笔纯函数状态机(OPEN/PARTIAL/CLOSED/OVERDUE 全转移+到期判据)+写侧账本 repo(ForeshadowLedger*,加 Ledger 前缀避撞 C5 读侧)。T3.4outliner spec + OutlineResult schema(含 foreshadow_windows)+run_outline 节点(只读不写库C6 扩稳定)。全仓门禁绿ruff/format 干净、mypy 90 文件、pytest 169 passed(114→+37+18)。memory 登记 C6 扩 + 2 decisions + 2 gotchas。下一步 Wave BT3.2(@backend 到期扫描+登记接口) ‖ T3.3(@llm foreshadow/pace 第三审并入 review_specs)

  • [2026-06-18] @orchestrator — 进入 M3:归档 Phase 2(M2) 至已归档Phase 3 七任务拉入台账。沿用 M2 节奏:契约先行 + 分目录并行 + 全仓门禁收口。核对:foreshadow 表已在 T0.2 建齐 → M3 无新建表迁移T3.1「Repository+状态机」据实记 @backendcore/ww_core/domain/,同 T2.3 先例T3.3 复用 M2 build_review_graphreview_specs 扩展点加 foreshadow/pace 两审(文风第四审留 M4。启动 Wave AT3.1(@backend·core/domain) ‖ T3.4(@llm·packages/agents+orchestrator)(不同目录,无写冲突)。

  • [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补充用例验证零冲突直通。无新 bugM1 曾暴露的 ledger 提交 bug 在 M2 三档位无复发——review 流末 + accept 事务末均 commit。最终全收口门禁绿ruff/format 干净、mypy 90 文件、pytest 114 passedalembic 无漂移M2 全程零建表迁移。M2 出口 DoD 全达成。下一阶段 M3伏笔+节奏)

  • [2026-06-18] @orchestrator — Wave D 完成T2.6)。审稿报告页落地:app/projects/[id]/reviewRSC 取历史)+ 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.5C3 扩稳定,单 @backend agent 顺序做)。三端点入 OpenAPIPOST .../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 审稿页+裁决+验收 gatepnpm gen:api)。

  • [2026-06-18] @orchestrator — Wave B 完成T2.2C4 扩稳定)。审稿子图落地:build_review_graph(START→continuity 并行审→collect→END可扩四审) + collect_reviewschapter_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.parsedinstructor 未接线),续审依赖此,归入 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_ledgerE2E 暴露并修复一个生产 bugdraft SSE 端点未提交注入 ledger 的请求 sessionSqlAlchemyLedgerSink 按设计只 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,单前端 agentpnpm 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 立项+写章 APIC3 稳定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.pyfakes_providers.pyroot 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 passed9 基线 +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/tenacitypyproject.toml members+mypy_path 已更,uv sync 通过,基线门禁全绿(ruff/mypy 27 文件/pytest 9 passed)。记录 decisionassemble 返回中性文本以解耦 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。

  • [2026-06-19] @llm — K1.2 修头Kimi Code 适配器 kimi_code_headers() 改为 {"User-Agent": "KimiCLI/1.5"},删全部 X-Msh-* 头 + kimi_device_id/KIMI_DEVICE_ID/确定性 device-id 机制K1.5 联网实测:有效 token 下 X-Msh-* 疑似触发 401 Invalid Authentication;对齐 pi-kimi-coder = UA-only。改 adapters/kimi_code.py + __init__ 导出 + 两测adapter 6 测/factory 3 测,断 default_headers 仅 UA、无 X-Msh-*)。更 contracts C1扩头集 UA-only+ gotcha。门禁绿ruff/format/mypy/pytest56 passed

  • [2026-06-19] @backend — bugfix 空写章 promptassembleC5从不含项目 premise/logline/theme/title 且无写章指令 → 全新项目(仅 premise产空 stable_core+volatile,写章触发 LLM 400 message must not be empty。修复:MemoryRepos 加第 8 repo project:ProjectSpecRepoSqlProjectSpecRepo 按 project_id 读 projectsassemble 把「作品蓝本」放入 stable_core 首段(书级 spec→缓存前缀守 #9+ volatile 始终含「请创作第 N 章的正文。」。改 domain/repositories.py(+ProjectSpecView/Repo) · memory/sql_repositories.py(+SqlProjectSpecRepo, sql_memory_repos 装配) · memory/assemble.py(_build_spec_section + 注入);测试 test_memory.py(+bare-project/chapter-directive 两测+fake) · test_projects.py/test_generation.py(补 project= fake)。无 DDL/迁移只读既有列。门禁全绿ruff/format/mypy(154 文件)/alembic check(无漂移)/pytest 438 passed。更 contracts C5 + gotcha。消费方注意手搓 MemoryRepos(...) 须补 project=

  • [2026-06-20] @frontend — UX R1+R2 完成审稿裁决人体学纯前端无后端改。R1冲突卡内联命中段预览——新纯函数 lib/review/snippet.ts(从 where「第 N 段」解析 1-based 段号 → 取终稿对应段截断预览,无段号/越界/空段→null 回退「跳转」),ConflictCardsnippet prop 渲染朱砂引用块。R2冲突按 type 分组 + 严重度排序(设定违例>能力不符>时间线倒错>地理矛盾>性格漂移,未知殿后)+ 组计数徽标 + 「跳到下一条未裁决」(按显示顺序环回)+ 主次裁决按钮(采纳改法=朱砂主、忽略/手改=次级)——新纯函数 lib/review/grouping.tsgroupConflicts/displayOrder/nextUnresolvedInOrder分组只改显示顺序、每条携原始 index守 conflict_index 覆盖 range 不变量ReviewReport 改分组渲染。TDDsnippet 8 测 + grouping 10 测。前端门禁绿lint/tsc/vitest 201(+18)/build。分支 feat/ux-r1-r2-review-ergonomics。下一步(按 planR3 验收前清单 → Tier4。

  • [2026-06-20] @frontend — UX R3 完成(验收前清单 HITL gateUX §7.4,纯前端无后端改,续 feat/ux-r1-r2-review-ergonomics)。新纯函数 lib/review/accept-preview.tsbuildAcceptPreview:据现有 client state 列「本次验收将更新」——晋升版次 + 提炼章节摘要 + 写回裁决(有冲突时) + 验收后伏笔到期扫描(可能置 OVERDUE) + 伏笔建议待登记提醒(有建议时))。只列后端 accept 事务确实做的事(核对 projects.py accept 端点promote+digest+decisions+overdue 扫描;声称改人物 latest_state/自动落库伏笔建议);带「以上为预期,最终以验收回执为准」免责。AcceptPanelforeshadowCount prop + 未阻断时渲染清单,ReviewReportforeshadow.length。TDD4 测。前端门禁绿lint/tsc/vitest 205(+4)/build。下一步按 planTier4T4-a 顶部 AI 工具条 / T4-b 本章指令框+风格预设)。

  • [2026-06-22] @backend — T6.2+T6.3 创作工具箱通用端点稳定(通用生成器框架后端落地,分支 feat/t6-creation-toolbox)。新 ww_skills.TOOLBOX(11 条legacy 3 + 新 8) + get_tooltoolbox_registry.pydescriptor 在代码无迁移。3 新端点(routers/toolbox.py,已注册):GET /skills/toolbox描述符列表legacy 携 legacy_routecodex?gen=world|character / /outline)、POST .../skills/{tool_key}/generate(按 spec.tier 经新注入缝 get_tier_gateway_builder 建网关 → run_generator 结构化预览,不写库仅落 ledger未知/legacy→404、项目不存在→404、无凭据→503POST .../skills/{tool_key}/ingest(仅 ingest!=None 工具world_entities 走 continuity 预检 409 gate(acknowledge_conflicts 放行) + partition_writes 白名单 + schema→JSONB 写库outline 细纲按 idx 拼 beats upsert不可入库→422。PURE context 派发 services/toolbox_context.build_toolbox_context4 策略,缺章/大纲→空节拍不报错。response/request schema schemas/toolbox.pyconcrete 子模型,非裸 dict。守不变量 #2/#3/#9。TDD注册表 7 + context 8 + 端点 11 = +26 测全仓门禁绿ruff/format 干净、mypy 183 Success(隔离 cache、alembic 无漂移无新迁移、pytest 578 passed。OpenAPI 新增 3 端点 → @frontend 须 cd apps/web && pnpm gen:apiT6 前端前置)。记 contracts C3 扩T6.2/T6.3)。

  • [2026-06-20] @frontend — Tier4 完成T4-a 全局 AI 工具条 + T4-b 本章指令直通生成,分支 feat/ux-tier4-ai-toolbar,未并 develop。T4-alib/nav/ai-tools.ts(aiToolItems) + components/AiToolbar.tsx 服务端组件AppShell 顶栏下仅项目页渲染(写本章/审稿/大纲/设定库/工具箱常驻一排,写本章=朱砂主动作),用 --chrome CSS 变量统一 chrome 高度(项目页 7rem=header4+toolbar3余 4rem6 个固定高度页改用 calc(100vh-var(--chrome,4rem)) 适配。T4-b全链后端 assemble/_build_volatiledirective 形参(「本章指令」段领衔 volatile绝不入 stable_core,守缓存前缀不变量 #9stream_draft 加可选 body DraftStreamRequest{directive} 透传、directive_len 入 log 不记原文、不持久化无迁移,重生成 TS 客户端;前端新 lib/workbench/directive.ts(STYLE_PRESETS + composeDirective 纯函数)、useDraftStream.start(p,no,directive?) 非空时发 JSON body、Workbench 加可折叠「本章指令」textarea + 风格预设 chips。TDDai-tools 4 测 + directive 4 测 + assemble directive 测 + draft 端点 directive/向后兼容 2 测。门禁全绿:后端 ruff/format/mypy(163 文件)/pytest 479 passed;前端 lint/tsc/vitest 213/build。契约记 contracts C3 扩T4-b

  • [2026-06-28] @backend/@frontend — UI Phase G 后端依赖补齐ProjectResponse 增加 updated_at / pending_review_countchaptersupdated_at 迁移 8c1d2e3f4a5bSqlProjectRepo 聚合项目自身、章节、审稿时间作为最近编辑,并按草稿是否晚于最近 accepted/review 统计待审稿章数。前端 pnpm gen:api 后项目库默认按最近编辑排序,新增“待审稿”筛选,作品卡显示最近编辑与待审稿徽标。契约记 memory/contracts.md C3 扩UI 计划记 docs/design/ui-improvement-plan.md 0.16。

  • [2026-06-29] @frontend/@qa — UI review follow-up 修复完成:补 lib/review/chapterNav.ts 使新增章导航测试可运行;ReviewSectionPanel 改为本地 open 状态,避免用户折叠后重渲染强制弹开;ReviewReport.hasReport 纳入 clean review新增 tests/test_project_metadata_e2e.py 用真实 DB 覆盖项目最近编辑/待审稿统计口径。验证:前端 lint/typecheck/vitest 490 passed/build后端 ruff/format/mypy、pytest 763 passed;浏览器抽样 review/settings 无 console error/横向溢出。

  • [2026-07-06] @frontend — 灵感⑥ 关系图谱(缩减版)+ D4 完成(纯前端,无后端契约/迁移/gen:api。新增 lib/characters/graphLayout.ts(纯逻辑:roleStyle role→分组配色关键词映射、buildGraphNodes/buildGraphEdges(kind→标签DEFAULT_RELATION_LABEL 命名常量)、countDanglingRelationslayoutGraph(@dagrejs/dagre 一次性确定性初始坐标、中心→左上、不可变)、buildRelationshipGraph 端到端)——仅用现有 CharacterCardView.relations={name,kind,note}:边按 name-join、kind 作中文标签、节点按 role 上色,无 closeness/阵营(数据不存在,不硬造);悬空边(引用未入库角色)跳过并计数。新增 components/characters/RelationshipGraph.tsx'use client'React Flow @xyflow/reactCodexPage 经 dynamic(ssr:false) 挂载于人物 tab显式容器高度 h-[28rem] + import '@xyflow/react/dist/style.css' + prefers-reduced-motion 关 fitView 动画 + 纸感 CSS 变量配色 + 悬空计数提示)。依赖:@xyflow/react@^12.11.2+@dagrejs/dagre@^3.0.0(见 contracts.md 2026-07-06。TDDgraphLayout +22 测role 映射/节点去空重名/kind 标签+默认/悬空跳过/自指跳过/无向去重/边 id 唯一/悬空计数/布局确定性+不可变/端到端);组件走人工/E2E。前端门禁全绿lint 干净 · typecheck 干净 · vitest 565 passed · coverage lib 95.4%graphLayout.ts 97.6% · build OKcodex 路由 7.58 kBReact Flow 懒加载独立 chunk。注pnpm build 门禁与运行中的 next dev(3001) 共享 .next → 触发 dev 服务临时 500stale chunk非代码缺陷、dev watcher 下次重编自愈,未重启服务。

  • [2026-07-08] @frontend — CR-M4/M5/L1 前端评审收尾MEDIUM/LOW 打磨,仅 apps/web无后端契约/gen:api。DONE①a11y——NavDrawer 汉堡按钮补 aria-controls(新增 Drawer 可选 id prop 指向面板,默认 nav-drawer)、ForeshadowCard<dl><div> 行改真 <dt>/<dd> 结构可视文案不变importance 用 sr-only 标签);②ReviewReport.flashMarksetTimeout 句柄入 ref + 卸载 useEffect 清理(防定时器泄漏,提 FLASH_DURATION_MS 常量);③useAccept 手写 ApiErrorEnvelope 改由生成 schema 派生 components["schemas"]["ErrorEnvelope"](端点专属 details 就地收窄,行为不变);④applyFix.hasApplicableFix 重写为对象入参类型谓词 patch is ApplicablePatch,消除 applyConflictFix 里两处 as string(含收窄单测);⑤server.parseJsonBody 已具边界校验,补两条守卫分支测试(非对象体/非 JSON 体);⑥去冗余 caststream/sse.ts idx.valueOf()idxjobs/job.ts dict["error"] as stringtypeof 守卫后 TS 自动收窄。SKIP/NOOP前提已过时/本就安全):ProjectWizard 换步聚焦标题已实现;AppShell/LeftNav 两处 <nav> 均已带 aria-labelKNOWN_EVENTSstop——stop 是客户端 abort 动作非服务端 SSE 帧(对照 contracts.md 草稿 token/done/error、续审 section/conflict/foreshadow/pace/style/characterization/done/error 均无 stop加入会为不存在的事件建处理CharacterGenerator/GeneratorRunner/ForeshadowCard.progress 的 index-key——三处均为整表替换/追加式/静态展示列表(无逐项重排或删除,CharacterCardItem/PreviewRow 为无内部状态受控组件,选择/编辑均按 index 且随新预览整体重置index 作 key 安全且无天然稳定 id加合成 UUID 需重做 index 选择/编辑态属过度改造。门禁全绿lint 干净 · typecheck 干净 · vitest 681 passed+3· coverage lib 95.45%exit 0· build OK