向导阶段(project 未建)一键推演结构化书级蓝图预填立项向导。 - 新 SPEC project_plan_spec(analyst 档,纯预览 reads/writes=())+ schema ProjectPlanResult(书名候选 + 时空背景/叙事结构/故事核心/结局设计/基调, 全字段默认值守解析韧性)+ 注册 SCHEMA_CATALOG;计数三处 21→22 + regen golden。 - 端点 POST /skills/project-plan/generate(不带 project 前缀,绕开 toolbox 404): 请求体序列化向导草稿为 project_context,复用 build_brief_context + run_generator; 种子门控(缺 genre/logline→422);请求 schema 加 max_length 上界。 - run_generator/_build_request 的 project_id 放宽 uuid.UUID|None(向导无 project)。 - 前端 wizard.ts 加 mapPlanResultToWizardForm(错配字段折进 premise 不静默丢)+ applyPlanPatch(仅回填空字段、保护已编辑)+ useProjectPlan hook + PlanAssistant。
118 KiB
PROGRESS — 多 Agent 协同任务台账
多 agent 共享的唯一协同入口。开工前读这里 +
memory/;认领任务、尊重依赖、完成即更新。 完整任务定义见DEV_PLAN.md;本台账只展开当前阶段,进入新阶段时再把该阶段任务拉进来。 协同规则见CLAUDE.md→「多 Agent 协同」。
状态图例:⬜ 待办 · 🔵 进行中(注明 @skill + 日期) · ✅ 完成 · ⛔ 阻塞(注明等什么)
当前阶段:QA-CR · 全项目 Code Review 整改批
背景:[2026-06-26] 对全仓做了一次七维度 Code Review(后端 Python 规范 / LangGraph 最佳实践 / 后端 FastAPI 架构 / 前端编程规范 / 前端架构 / 应用安全 / 依赖时效),6 个专科 reviewer 并行 + 依赖自查。绿门禁下仍揪出 2 CRITICAL + 13 HIGH + 一批 MEDIUM/LOW——再次证伪「测试过=没问题」。架构本身成熟、不变量纪律强(provider 中立 / HITL accept 单写 / checkpoint 仅控制流 / SecretStr 全覆盖);确认无虞:SSRF(
base_url仅来自硬编码_PROVIDER_BASE_URLS,无用户 URL 入网)/ SQL 注入(全 ORM 参数化)/ XSS(无dangerouslySetInnerHTML/eval)/ 错误信封不泄栈密钥 / Kimi 用 RFC 8628 device flow 无 CSRF 面。 整改 DoD:CRITICAL + HIGH 全部 ✅ 且各自补回归测试;MEDIUM 择批清理;门禁全绿(后端 ruff/format/mypy/pytest + alembic 无漂移;前端 lint/tsc/vitest/build)。守 §Definition of Done:每项 TDD 先红后绿、完成即小步 commit。 落地顺序:① 本周 CR-C1/C2 + 两资源泄漏(H1/H2)+ Fernet key(H8);② 合并前 计费两项(H3)+ request_id(H4)+ max_length(H9)+ 前端三 HIGH(H10/H11/H12);③ MEDIUM/LOW 技术债批。 依赖纪律:CR-C1(升 Next)须pnpm install重锁 +pnpm build验证、升级后轮换全部应用密钥(与 CR-H8 Fernet key 联动)。CR-H4/H9 改 schema → 若动 OpenAPI 形参须pnpm gen:api+memory/contracts.md记一笔。无 DB 迁移预期。
| 任务 | 状态 | 负责 | 依赖 | 备注 |
|---|---|---|---|---|
| CR-C1 🔴 升级 Next.js 修 RCE(CVE-2025-66478)+ React 补丁 + 轮换密钥 | ⬜ | @frontend | — | apps/web/package.json next 15.1.3→15.1.9(或 15.5.7/16.x),react/react-dom 19.0.0→补丁版(上游 CVE-2025-55182);App Router + RSC 应用正受影响。pnpm install 重锁 + pnpm build 验;升级后轮换全部应用密钥(联动 CR-H8)。Next15 LTS 2026-10-21 EOL,规划 16.x 迁移 |
CR-C2 🔴 多章链设 recursion_limit |
⬜ | @backend | — | services/chain_runner.py:210 默认 25 supersteps、每章 4 节点→超 ~6 章即 GraphRecursionError 整 job 失败,「批量产一卷(K章)」在目标规模不可用。config 加 recursion_limit=(last-start+1)*4+10;补超默认上限的 mock-gateway 回归测试 |
| CR-H1 🟠 Kimi OAuth 轮询不占 DB 会话 | ⬜ | @backend | — | services/job_runner.py:75+routers/kimi_oauth.py:85 轮询全程(最坏 >200s)占连接池连接、饿死其他请求;轮询循环无需 DB,仅最终 upsert_oauth_credential 开短会话 |
CR-H2 🟠 修 httpx.AsyncClient 泄漏 |
⬜ | @backend | — | routers/kimi_oauth.py:73 Depends(_default_http_client) 非 generator 依赖、永不 aclose();改 async def _http_client(): async with httpx.AsyncClient(...) as http: yield http |
| CR-H3 🟠 Anthropic 结构化输出记真实 usage | ⬜ | @llm | — | adapters/anthropic.py:161 硬编码 usage=0→usage_ledger 全记 0 成本、腐蚀计费(违 ARCH §4.8);用 create_with_completion 取原始响应 usage |
CR-H4 🟠 request_id 贯通网关日志 |
⬜ | @llm | — | gateway.py:183 所有 llm_call/llm_provider_failed 无 request_id;LlmRequest 加 request_id 字段并从 API 层透传(违 ARCH §9.3 端到端追踪不变量) |
CR-H5 🟠 thinking 字段:实现或删除 |
⬜ | @llm | — | types.py:41 声明但所有 adapter 忽略,thinking=True 静默无效、无报错;按 YAGNI 删除或实现转发 + 测试 |
| CR-H6 🟠 流式路径加 per-provider 重试 | ⬜ | @llm | — | gateway.py:268 流式仅 1 次尝试,首 token 前一次瞬时 429 烧光 fallback 链(与非流式 _complete_with_retry 不对称);用 _retrying() 包裹首 token 前尝试或显式文档化 |
CR-H7 🟠 TOOLBOX 注册表不可变 |
⬜ | @backend | — | packages/skills/ww_skills/toolbox_registry.py:70 裸 dict 可变;仿同库 SPECS 用 Final[Mapping]=MappingProxyType(...)(违不可变不变量) |
CR-H8 🟠 .env.example 移除可用 Fernet key |
⬜ | @devops | — | 已确认提交真实可用 key(注释「可直接用于本地」),换非功能占位符 + 突出轮换提示;联动 CR-C1 轮换 |
CR-H9 🟠 API 文本输入加 max_length |
⬜ | @backend | — | schemas/{providers,generation,projects}.py api_key/brief/final_text/segment 仅 min_length=1(DoS/成本失控);加上限(api_key≤512、brief≤1e4、final_text≤2e5)+ ASGI 请求体大小限 |
CR-H10 🟠 前端 errorCode 去重 |
⬜ | @frontend | — | lib/style/{useRefine,useStyleLearn}.ts 各自重复定义,统一 import 自 lib/generation/cards.ts:132(DRY 漂移隐患) |
| CR-H11 🟠 Drawer 关闭还原焦点 | ⬜ | @frontend | — | components/Drawer.tsx:41 关闭后焦点掉到 body(违 WCAG 2.4.3);传 triggerRef、关闭时 .focus() |
| CR-H12 🟠 RefineView 取消在途 refine | ⬜ | @frontend | — | components/style/RefineView.tsx:33 无 AbortController,段切换时旧响应可覆盖新响应;useRefine 暴露 abort 在 effect cleanup 调用,去 blanket exhaustive-deps disable |
| CR-M1 🟡 后端架构整改批 | ⬜ | @backend | — | outline.py:162 volume 下推 DB 过滤;generation.py:326/toolbox.py:431 N+1 INSERT→bulk_create;jobs.py:28 裸 ORM→repo;provider_deps.py:91 去私有 _client(加 probe_connection());列表端点加分页。⚠️assemble.py:155 8 串行查询:AsyncSession 不支持同一 session 并发,gather 须每查询独立 session,不可照搬 |
| CR-M2 🟡 网关/adapters 整改批 | ⬜ | @llm | — | gateway.py:90 is_open() 副作用违 CQS;pricing.py 未知 model 静默记 0 → 加 warning;adapter str(exc) 入异常消息可能带 vendor 响应体→只留类名+status |
| CR-M3 🟡 LangGraph 链健壮性 | ⬜ | @llm | — | chain_runner.py:124 accept commit 后 run_overdue_scan 非幂等且失败无法 resume→部分进度空洞(幂等化或纳入事务);chain_runner.py:159 改用公开 get_state().next 替私有 __interrupt__;chain/nodes.py:213 链内 4 审串行→并行/复用 review 子图 |
| CR-M4 🟡 前端 key/a11y/cleanup 批 | ⬜ | @frontend | — | 可编辑列表去 index-key(CharacterGenerator.tsx:135/GeneratorRunner.tsx:178/ForeshadowCard.tsx:68);SSE KNOWN_EVENTS 补 stop(核对 memory/contracts.md);ARIA 补全(AppShell nav label / NavDrawer aria-controls / ForeshadowCard <dl> 结构);ProjectWizard 步骤焦点;ReviewReport.tsx:301 setTimeout 卸载清理 |
| CR-M5 🟡 前端 TS 边界类型收紧 | ⬜ | @frontend | — | lib/api/server.ts:34 parseJsonBody 加最小结构校验;useAccept.ts:60 ApiErrorEnvelope 从生成 schema 派生;applyFix.ts hasApplicableFix 改类型谓词去 as string |
| CR-L1 🟢 LOW 清理批 | ⬜ | @backend·@llm·@frontend | — | chain.py:256 静默回退加 warning;SSE 端点补 OpenAPI text/event-stream 声明;冗余 as/.valueOf() cast 清理;测试脚本 print→logging |
| CR-D1 🟡 抬高后端依赖下界(可选升级评估) | ⬜ | @devops | — | pyproject.toml 下界过旧(langgraph>=0.2.40/anthropic>=0.34),抬到接近 lockfile 实锁版本保可复现;后端实锁版本均当前。可选评估 vitest 3.x / tailwind 4.x |
维度小结:后端 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。
已封板:T6 · 创作工具箱(通用生成器框架)✅
背景:对标竞品「创作工具箱」——把每个「XX 生成器」实现为声明式 skill(
AgentSpec的设计本意),用一条通用执行路径驱动。用户已定:① 走通用 skill 框架(非逐个硬编码)② 封面/图像本期跳过 ③ 文本生成器全做(上架已有 3 + 新建 8)。完整设计见~/.claude/plans/creation-toolbox-generators.md。 P1 目标(DoD):GeneratorTool描述符 +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.py 加 Idea/IdeaListResult;specs.py 加 brainstorm_spec(light, reads=[projects], writes=[]);generation_node.py 加 build_brief_context + 通用 run_generator(据 spec.output_schema 校验 parsed,不绑定具体类型,任一声明式生成器共用);两包 ruff/format/mypy 干净、新增 13 测 + 全包 252 passed 无回归。@backend T6.2 可起:从 ww_agents 取 brainstorm_spec/IdeaListResult、从 ww_core.orchestrator 取 run_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 ledger;ingest 复用 continuity 409 + partition_writes 白名单。未知 key 404 / 无 provider 503 |
| T6.4 E2E(toolbox 全路径) | ✅ | @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/build);E2E mock 网关零 token 全路径走通。实景 browse 复验(工具箱卡片栅格→脑洞预览→词条入库)待做。 后续可选 P5(封面图像轨道 / 自定义 skill 运行期 schema / 收敛已有 3 竖井)。
已封板:Prompt 管理重构(方案A)+ 全量 prompt 重写 ✅
背景:把 21 个内置 agent 的
system_prompt散文从specs.pyPython 常量外置为.md文件,并统一内置/用户 skill 的只读解析入口。设计真源docs/design/prompt-management.md;契约memory/contracts.mdC6-ext;决策/坑见memory/{decisions,gotchas}.md(2026-06-24)。多 agent 工作流交付:TDD + 并行开发 + 交叉验证评审。
| 任务 | 状态 | 负责 | 备注 |
|---|---|---|---|
方案A 步骤1–3:spec_model/prompt_loader/prompts/*.md×21/schema_catalog/SPECS/REVIEW_RESERVED_NAMES |
✅ | @llm | 金标准 sha256 取运行时值;SPECS[name] is *_spec 同一实例;三集合 name 恒等 |
方案A 步骤4–5:SpecResolver(内置纯内存零 DB)+ SkillRegistry 入库守卫前移 + toolbox_registry 桥接 SPECS |
✅ | @backend | 守卫锚 REVIEW_RESERVED_NAMES ∪ set(SPECS);删 12 生成器 *_spec 直接 import |
打包/CI:.gitattributes eol=lf + wheel artifacts 带 prompts/*.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 订阅 plan(device-flow OAuth)。已知情接受 ToS/封号风险——研究确认:用订阅 plan 调用需伪造官方客户端
User-Agent+X-Msh-*头,Kimi ToS 视为违规、可能封停会员(见变更日志研究结论)。用户明确选择此路径(非合规的 API Key 路径)。与既有 API-key провайдерkimi分离,新增独立 providerkimi-code以便切换。 集成契约(研究确认,实现时对照github.com/picassio/pi-kimi-coder校验):
- device flow:
POST https://auth.kimi.com/api/oauth/device_authorization(client_id17e5f671-d194-4dfb-9706-5516cb48c098,envKIMI_CLIENT_ID可覆盖,scopekimi-code)→ 返回 user_code/verification_uri/device_code/interval;轮询POST https://auth.kimi.com/api/oauth/token(grant device_code,处理 authorization_pending/slow_down)。refresh:同 token 端点 grant refresh_token。- 推理:base
https://api.kimi.com/coding/v1(OpenAI 兼容),modelkimi-for-coding,Authorization: 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。- token:access ~15min / refresh ~30d → 建网关时按需刷新(临近过期刷新并持久化)。存储:
provider_credentials加auth_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;迁移 1f011c42bd4d;alembic check 无漂移。⚠️ K1.3 @backend 须把 StoredCredential.api_key_enc 改 bytes|None(见下方请求 + memory) |
| K1.2 Kimi coding 适配器(伪造头 + OAuth bearer) | ✅ | @llm | — | C1扩 | 完成:adapters/kimi_code.py(KimiCodeAdapter 子类化 OpenAICompatAdapter + 伪造头 + 稳定 device_id);build_adapter 加 kimi-code 分支;UA 验证为 KimiCLI/1.5(pi-kimi-coder 仅设 UA,X-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_enc,K1.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 → 建网关时构 KimiCodeAdapter(coding base + 伪造 UA/X-Msh-* 头 + bearer)→ token 临近过期建网关时自动刷新并回写。后端门禁绿(ruff/format 干净 / mypy 154 / alembic 无漂移 / pytest 434);前端门禁绿(gen:api/lint/tsc/vitest 155/build);E2E(tests/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/单测仅验逻辑、不联网。
状态:M1–M5 全部完成(含 M5 三项收尾余项已清理)
当前无活跃阶段。 Phase 0–5(M1–M5)已全部交付,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.tomldeps 后已uv sync重建 ww-skills);Anthropic/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 韧性(C1✅扩;Anthropic/Gemini 适配器 + 回退链 + CircuitBreaker + tenacity 退避 + 能力协商/降级 served_by.degraded,无 OpenAPI 形变)@llm · T5.5 Skill 运行时 + 规则(C8 + C3✅扩;SkillRegistry.load 越权声明拒绝 + 表权限沙箱 filter_reads/partition_writes + POST /rules)@backend · T5.2 生成/入库 API(C3✅扩;world/characters generate 预览 + POST characters 入库双 gate:continuity 预检 409 + partition_writes 白名单 + schema→JSONB 形变 + GET rules/skills;build_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 / build);E2E 真 DB + mock 多 provider 零 token 走通。M5 完成 → M1–M5 全部交付。 三非阻塞余项(①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.5✅;JobRepo/SqlJobRepo + run_job 独立 session + lifespan zombie reaper)@backend · T4.3 API style + refine(C3✅扩;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 / build);E2E 真 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 + foreshadow(C3✅扩;GET .../foreshadow?status= 看板 + POST .../outline upsert outline 表含窗口)@backend · T3.6 伏笔看板 + 大纲编辑器 + 节奏报告(四泳道 + beats+窗口徽标 + 审稿页节拍图▁▃▅)@frontend · T3.7 M3 E2E(伏笔埋设→进展→验收后扫描 OVERDUE + 大纲含窗口 + 三审 SSE,strict-xfail 钉住并发记账 bug)@qa · T3.8 [bugfix] 并行审记账并发安全(SqlAlchemyLedgerSink.record 改 add-only 去 await flush,解 AsyncSession 并发 flush 冲突,xfail 转 XPASS 后解钉)@llm。
出口达成:后端门禁绿(ruff / mypy 111 / pytest 228 passed(0 xfailed/0 failed)/ alembic 无漂移,foreshadow 表已 T0.2 建齐无新建表);前端门禁绿(gen:api / lint / tsc / vitest 69 / build);E2E 真 DB + mock 网关零 token 走通,DB 真源逐项断言。T3.7 暴露并发记账 bug → T3.8 修复 → 解钉 xfail。
Phase 2 · 一致性 + 验收 (M2) — ✅ 全部完成(2026-06-18)
T2.1 续审 AgentSpec+结构化输出契约+网关 instructor 接线(C6✅稳定,改 C1:run() 填 parsed)@llm · T2.2 LangGraph 并行审+collect 留痕+review SSE(C4✅扩)@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 / build);E2E 写→审→裁决→验收→摘要入库闭环、DB 真源逐项断言。设计决策 R1–R6 全兑现(见 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+SSE(C4✅稳定)@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 / build);E2E 闭环走通。 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-06] @backend/@llm/@frontend — ✅ 灵感⑤ AI 立项方案生成+预填(develop 直提)。向导阶段(project 未建)一键推演结构化书级蓝图预填立项向导。新 SPEC
project_plan_spec(tier="analyst"不写 model,reads=()/writes=()纯预览,prompts/project-plan.md)+ schemaProjectPlanResult(书名候选 list + 时空背景/叙事结构/故事核心/结局设计/基调,全字段默认值守解析韧性)+ 注册SCHEMA_CATALOG["project-plan"];计数三处 21→22(specs.pyassert /test_prompt_loader.pylen /schema_catalog.pydocstring)+ regenprompt_hashes.json(仅加一条)。新端点POST /skills/project-plan/generate(不带 project 前缀绕开 toolbox 404)←ProjectPlanGenerateRequest(全字段max_lengthCR-H9,brief用str|None令 codegen 可选)→ProjectPlanView;种子门控缺 genre/logline→422,无凭据→503。复用build_brief_context+run_generator(run_generator/_build_request的project_id放宽uuid.UUID|None——向导无 project,ledger.project_id 本 nullable);新缝get_project_plan_gateway(analyst)。零迁移。前端wizard.ts加mapPlanResultToWizardForm(书名/结构/基调→对应字段;时空背景/结局设计→折进 premise 不静默丢;结局取向/视角预设枚举不臆造)+applyPlanPatch(仅回填空字段、保护已编辑)+canGeneratePlan/toPlanSeedRequest+useProjectPlanhook(renderHook 测试)+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/LOW:C1 Next.js 15.1.3 RCE(CVE-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 未取消。确认无虞:SSRF(base_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 修复 + 合并 develop(merge
513bf71)。对标星月「一键多章」+ 差异化「每章过四审、遇冲突才停人」。设计契约docs/design/chain-workflow.md(commit5ee9799)。多 agent 逐学科建造(契约先行、目录单写者):C1 @llm(7f3eaab) LangGraph cyclic 链图orchestrator/chain/{state,nodes,graph}.py(build_chain_graph:write→review→decide→accept 循环 + interrupt-on-conflict + resume;删死代码build_write_graph,write_node本体留用;7 单测 mock 网关+fake session+MemorySaver)·C2 @backend(29349dc) 服务/3 端点/schema/checkpointer 接线(见下条)·C3 @db(548b7ab) langgraph 检查点 4 表迁移d3e4f5a6b7c8(autocommit_block避开CREATE INDEX CONCURRENTLY与 alembic 事务死锁;env.pyinclude_object豁免这 4 表防漂移误报)·C4 @qa(061792d) E2Etests/test_chain_workflow_e2e.py真 pg + mock 网关零 token(无冲突两章全自动 + 冲突→interrupt→awaiting→resume→accept)。3 路对抗交叉评审(python/fastapi/不变量)在绿门禁下仍揪出 1 CRITICAL + 7 HIGH——证伪"测试过=没问题":CRITICAL=链把绑请求 session 的 gateway 传进 BackgroundTask,后台跑时 session 已关→write/review 的usage_ledger.record()写进死 session 静默丢失(链计费全丢,违 #1;E2E 清了 ledger 却没断言其存在故漏掉)。修复(d1ea83b):网关改chain_gateway_builder按节点 session 重建(仿digest_gateway_builder/style.py);日志脱敏(_classify_job_error+exc_type,去str(exc),§5);resume 原子 claimJobRepo.claim_awaiting_to_running(防并发双跑同 thread_id,非 awaiting→409)+ 所有权校验(JobView.project_id,跨项目→404);ChainResumeAccepted(去 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。剩余下一步(未做):① 前端链 UI(pnpm 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.py(POST .../chains/{key}/run→202ChainRunAccepted;POST .../chains/runs/{job_id}/resume→202;GET /jobs/{id}复用)。校验:count 1..50→422、未知 chain_key→404、项目不存在→404、resume job 不存在→404、resume 非 awaiting→409 新码CONFLICT、无凭据→503。② schemaschemas/chain.py(ChainRunRequest/ChainRunAccepted/ChainResumeRequest,ConflictDecision复用)。③ 服务services/chain_runner.py(run_chain_job仿run_job壳自建独立 session 驱动链图:set_running→ainvoke→据__interrupt__置awaiting_input或done/failed;build_accept_op在 apps/api 装配验收事务闭包注入图节点,守 #3/#4;token 不入 result/日志)+services/chain_deps.py(get_checkpointer_factory:运行时AsyncPostgresSaver上下文 / 测试 MemorySaver)。④ 零迁移(§7):复用jobs,新增status="awaiting_input"+JobRepo.set_awaiting,awaiting 章经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.py12 用例(mock 网关 + MemorySaver + fake session/accept_op,无 DB/无网络/无真 LLM):run→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。唯一新增 DDL(langgraph 检查点表)= 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.5:ww_agents+7 输出 schema + 7 spec(book-title/blurb/name/golden-finger/glossary/opening/fine-outline,只声明 tier #2)+build_outline_chapter_context(with_outline_chapter 策略)。@frontend T6.6:gen:api纳入 3 端点;app/projects/[id]/toolbox/page.tsx(RSC) +components/toolbox/{ToolboxPage,ToolCard,GeneratorRunner}+lib/toolbox/*(声明驱动纯函数,按input_fields渲染表单、按output_kind渲染预览、可入库者复用ConflictAdjudication走 409→ack)+ LeftNav「工具箱」+ ⌘Knav-toolbox/action-gen-*;legacy 3 跳现页不回归。@qa T6.4:tests/test_t6_toolbox_e2e.py5 用例真 pg + mock 网关零 token,未发现端点 bug。P2 收尾:限流→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)/#9(system_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}/injection←InjectionOverrideRequest{pinned,excluded,recent_n(1..20→422)}→InjectionResponse(新增回显pinned/excluded,selected[].reasons可含新值author_pin);select_relevant_entities加pinned/excludedfrozenset 入参(pin 强制纳入加 author_pin / excluded 强制剔除且优先于 pin);assemble加override关键字参(recent_n 覆盖回看章数);GET injection + PUT + draft 流式端点同读同一覆盖(看到的=写章用的)。持久化:新表chapter_injection(迁移ad2c4c663daf,唯一(project_id,chapter_no);复用 outline 行污染 beats 已否决)+ 新domain/injection_repo.py(InjectionOverride/EntityRef/SqlInjectionOverrideRepo,upsert 只 flush 端点 commit)。前端(@frontend):gen:api纳入 PUT + 新 schema;lib/workbench/injection.tsoverride 纯函数(currentOverride/withPinToggled/withExcluded/withRestored/withRecentN/isPinned,钳 1..20);useInjection加saving态 +togglePin/exclude/restore/setRecentN(PUT 后以服务端确定结果为准、写失败可读文案不改本地态);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.ts(GLOBAL_NAV_ITEMS/projectNavItems/isNavItemActive+ActiveNav类型,6 vitest),桌面静态侧栏与移动抽屉共用避免漂移;新增通用Drawer(遮罩点击/Esc 关闭/打开聚焦面板,复用CommandPalettea11y 模式,lg:hidden)+NavDrawer(汉堡aria-label=打开导航+ 左抽屉)+NavItems;LeftNav改hidden lg:block,AppShell顶栏加汉堡。M2 工具条不溢出 + 移动可达:Workbench工具条改flex-wrap(390px 不再横切「尚未保存」);ChapterList/ChapterAssistant抽出ChapterListContent/AssistantContent,Workbench经左/右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}.tsx。UX 计划余项:B0 可控版(PUT override) + F1 控件 + R1/R2/R3 审稿人体学 + Tier4。 -
[2026-06-20] UX计划 F3+F4 — ✅ 流式进度感 + 友好错误文案(纯前端)。F4:新
apps/web/lib/errors/messages.ts(friendlyError(code,fallback)→中文文案 + 可选「去设置提供商」动作;覆盖后端ErrorCode+ 前端NETWORK/STREAM_FAILED;未知码回退原 message;+4 vitest);写作页Workbench与审稿页ReviewReport的错误块改用之,不再直接暴露 raw error code。F3:Workbench工具条字数计数器流式时变「生成中… 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}/injection→InjectionResponse{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读 hook;ChapterAssistant改 client 组件列出选中实体 + 入选理由徽标(本章点名/主角常驻/近章出现/伏笔窗口)+ 空/载/错三态,「四审」段改指向审稿页;Workbench传projectId/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+ schemaDraftView;lib/api/types.ts加DraftView别名。新增两个 RSC 读 helper(仿fetchForeshadow/fetchProject服务端读、无 CORS):fetchOutline(projectId)→OutlineChapterView[](200 解包 chapters,任何错误/空降级为[]不阻塞进页),fetchDraft(projectId,chapterNo)→DraftView|null(复用getJsonOrNull,404→null 当空编辑器,不抛)。大纲页(outline/page.tsx) 进页fetchOutline作initialChapters种入OutlineEditor(useOutline已据非空初值置ready)→ 重访显已生成大纲;生成流照常覆盖所显章节。写作工作台(write/page.tsx+Workbench) 进页fetchDraft拿content作编辑器初值(useState(initialText))→ 重访重载已写正文;404/新章 →""空编辑器;SSE 流式写 + AbortController + PUT 自动保存全不动(流起始空、仅 streaming/done/aborted 变化才覆盖,初值不反扑活跃流);导出WORKBENCH_CHAPTER_NO(原M1_CHAPTER_NO)供页面拉对应章草稿。新增lib/api/server.test.ts(5 vitest,mock 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→ 200DraftView{project_id,chapter_no,volume,status,version,content,length}(比 PUT 的DraftResponse多content——读侧需正文重建编辑器);无草稿行/正文空白 → 404NOT_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 passed(442→+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→ 200OutlineResponse{chapters:[OutlineChapterView{no,volume,beats:list[str],foreshadow_windows}]}(与 POST 同形,按 chapter_no 升序);项目存在无大纲 → 200 空列表(非 404);项目不存在 → 404NOT_FOUND。复用 C5 读侧:扩OutlineRepo(domain) +SqlOutlineRepo(assemble 读侧) 加list_for_project(仿 Character/WorldEntityRepo,order_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 fake(test_memory/test_projects)满足扩展后的 protocol。全仓门禁绿:ruff/format 干净、mypy 154 Success、alembic 无漂移、pytest 442 passed(439→+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-coder(UA-only)把头集裁成仅 UA,是分歧/错误参考导致的误修——真源改为ooojustin/opencode-kimi(src/headers.ts+src/constants.ts,1: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-Name(hostname ASCII 化)+X-Msh-Device-Model(kimi_device_model():macOS=macOS {mac_ver} {machine})+X-Msh-Os-Version(platform.version())+X-Msh-Device-Id(稳定 32 位无连字符uuid4().hex:envKIMI_DEVICE_ID优先→否则持久化~/.kimi/device_id)。恢复kimi_device_id()/kimi_device_model()助手 + 重加 imports(os/uuid/socket/platform/pathlib)+__init__重导出。文件:packages/llm_gateway/ww_llm_gateway/adapters/kimi_code.py+__init__.py+ 两测(断全 7 头键 + 固定字面值 + device-id 32 位小写 hex 稳定 + host 派生值非空 ASCII,env 注入保 CI 确定)。更 contracts C1扩(7 头 + opencode 真源)+ gotcha(pi-kimi-coder 分歧→回退)。门禁绿:ruff/format 干净、mypy 干净(27 文件)、pytest 60 passed(packages/llm_gateway)。无 OpenAPI 形变。 -
[2026-06-19] @backend — K1.3 修正:device authorization 重新带
scope=kimi-code(实测 401 后修)。K1.5 联网实测登录拿到真 JWT 但调api.kimi.com/coding/v1回401 Invalid Authentication——根因 token 缺 coding entitlement(省略了 scope)。start_device_authorization请求体加scope=kimi-code(={"client_id":<id>,"scope":"kimi-code"},模块常量KIMI_CODE_SCOPE);scope 只放 device-auth,token 交换/刷新不带。文件:apps/api/ww_api/services/kimi_oauth.py+ 单测test_kimi_oauth_service.py(test_start_device_authorization_parses_response_and_sends_scope断data["scope"]=="kimi-code")。修正 C3扩 contract + decision「省略 scope」表述 + 加 gotcha。无 OpenAPI 形变,前端无需 re-gen。门禁绿:ruff/format 干净、mypy 干净、pytest 101 passed(apps/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、access
15m/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 providerkimi分离可切换。唯一未尽:对真 auth.kimi.com/api.kimi.com 的真账号联网冒烟(含封号风险,用户自担)——代码/E2E 仅验逻辑零联网。 -
[2026-06-19] @qa — K1.5 ✅ K1 E2E(Kimi Code OAuth device-flow 全 mock → 真 pg)。新增
tests/test_k1_kimi_oauth_e2e.py(4 用例,零联网,真 pg):①POST .../oauth/start→202{job_id,user_code,verification_uri,interval},fake httpx 跑 device-auth + token(pending×2→成功) 全程;后台run_job轮询跑在真 e2e_sm session(overrideget_session_factory→e2e_sm + monkeypatch 模块级kimi_oauth._default_http_client→同一 scripted fake +kimi_oauth.asyncio.sleep→no-op;端点 device-auth 走_default_http_clientdep 同样指 fake)→GET /jobs/{id}done,result{connected:true,provider:"kimi-code"};DB 真源:provider_credentials行auth_type="oauth"/oauth_enc非空/api_key_encnull,密文不含明文 token + 解密回环 access/refresh;GET .../oauth/statusconnected 无 token。② 存 oauth +tier_routingwriter→kimi-code:kimi-for-coding→build_gateway_for_tier→KimiCodeAdapter,其_client带 coding basehttps://api.kimi.com/coding/v1+ UAKimiCLI/1.5+ 全 X-Msh-* +api_key(=bearer)=存量 access token。③ 临近过期 oauth 包 →_build_provider_adapter触发刷新(fakeproject_deps.kimi_refresh+ 字符串 target monkeypatchproject_deps.httpx.AsyncClient)→ 适配器用新 token +oauth_enc(DB 真源)更新为新包。④POST .../oauth/disconnect→凭据行清除(DB 真源无 oauth)。token 全程负向断言:不进 job 结果/状态响应/start 响应/密文明文。全仓门禁绿:ruff/format 干净、mypy 154 Success、alembic 无漂移、pytest 434 passed(430→+4)。memory 记 1 gotcha。K1(Kimi 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/StatusResponse),lib/api/types.ts加 3 别名。纯逻辑(node-env vitest):lib/settings/kimiOauth.ts(connectPhase状态机 idle/awaiting/connected/error +toDeviceDisplay/authOpenUrl/toConnectionStatus/jobConnected/formatExpiresAt,16 测)+lib/settings/providers.ts扩(KNOWN_PROVIDERS加kimi-code(auth:oauth, model:kimi-for-coding) +API_KEY_PROVIDERS/TIERS/defaultModelFor+ 路由草稿纯函数toRoutingDrafts/applyProviderChange/draftsToRoutingInput,9 测)。组件:useKimiOauthhook(复用useJobPoll:connect=POST start→展示 user_code+window.open授权页+轮询 job→done 拉 status;disconnect=POST→复位)+KimiCodeOauth.tsx(连接区,user_code 用<output select-all tabIndex=0>可读可选可聚焦 + motion-safe)。ProvidersSettings.tsx改:档位路由从只读→可编辑(per-tier select provider + model input + 保存 PUT),API-key 凭据行只列API_KEY_PROVIDERS(OAuth 提供商有独立连接区,无 key 输入),挂入KimiCodeOauth。server.ts加fetchKimiOauthStatus,page.tsxPromise.all拉 providers+oauth 状态传kimiOauthprop(进页即显连接态)。job 结果无 token,只读 connected。前端门禁全绿:gen:api / lint / typecheck / vitest 155 passed(130→+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.py(start_device_authorization/poll_token/refresh,注入AsyncHttpClientProtocol 零联网;TokenSet+encrypt_oauth_bundle/decrypt_oauth_bundle复用 Fernet;needs_refresh300s 缓冲;client_id envKIMI_CLIENT_ID可覆盖、device authorization 省略 scope)+routers/kimi_oauth.py(POST .../oauth/start→202{job_id,user_code,verification_uri,...}+ BackgroundTaskrun_job后台循环轮询→成功存加密 oauth_enc+job done(结果只{connected,provider});POST .../oauth/disconnect→{disconnected};GET .../oauth/status→{connected,expires_at}无 token)+schemas/kimi_oauth.py(3 schema)+ 注册 main.py。services/credentials.py:StoredCredential加auth_type/oauth_enc、api_key_enc→bytes|None(K1.1 的 2 处 mypy red 消除),SqlCredentialStore读新列 +upsert_oauth_credential/delete_credential,upsert_credential显式置 api_key 态。services/project_deps.py:_build_provider_adapter对kimi-code/auth_type=oauth走_resolve_kimi_code_token(解密→临近过期则经 httpx 刷新+持久化→access token 喂build_adapter("kimi-code",…));provider_deps.py_PROVIDER_BASE_URLS加kimi-code。token 全程不进 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 passed(400→+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.py:KimiCodeAdapter子类化OpenAICompatAdapter(coding 端点 OpenAI 兼容,复用 complete/stream/结构化/瞬时错误包装/capabilities),provider 固定kimi-code(与 API-keykimi分离);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():envKIMI_DEVICE_ID优先,否则确定性uuid5缺省(绝不每次随机,稳定且来源可测/可配)。modelkimi-for-coding不硬编码(经.complete(req, model)传入,路由关注点)。factory.build_adapter加provider=="kimi-code"分支;包__init__导出全部符号。契约校正(已对照github.com/picassio/pi-kimi-coderextensions/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 passed(47→+11)。@backend 行动(K1.3):_build_provider_adapter对 providerkimi-code调build_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.pyProviderCredential:① 加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_enc改nullable=True(Mapped[bytes|None],OAuth-only 行无 api_key、既有 api_key 行保值);UniqueConstraint(owner_id,project_id,provider)不变。首个新迁移(M1–M5 全零建表)migrations/versions/1f011c42bd4d_provider_credentials_oauth_columns.py(down_revision=220ca2e3d53f):up=add_column auth_type/oauth_enc + alter api_key_enc→nullable,down 逆向;autogenerate 仅这 3 op 无 noise,手修模板重复 import + 改本仓 ruff 样式(见 gotcha)。upgrade head已应用、alembic check无漂移。门禁:ruff/format 干净、pytest 400 passed、alembic 无漂移;mypy 余 2 处arg-type错(均在 @backendapps/api/ww_api/services/credentials.py,因 api_key_enc 改 nullable 打穿,K1.3 吸收,见下方 @backend 请求)。memory 记 C2 扩 + 2 gotcha。 -
[请求 → @backend,K1.3]:K1.1 把
provider_credentials.api_key_enc改 nullable(bytes|None),打穿到你拥有的apps/api/ww_api/services/credentials.pymypy 报 2 处arg-type(StoredCredential.api_key_enc: bytes↳ 现bytes|None,dataclass line 28 + store line 75/97)。@db 不越权改 apps/api。K1.3 接 OAuth store 时把StoredCredential.api_key_enc改bytes | 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 — 🎉 M1–M5 全部交付 + M5 余项收尾完成。五个里程碑(Phase 0–5)全部 ✅;M5 三项非阻塞余项 + 本次台账归档共四项 follow-up 已清:#1 Codex 读端点(
GET /projects/:id/characters+GET .../world_entities,@backend)+ 前端接线(CodexPage 拉全量真源,去「会话内回显」局限,@frontend);#2build_adapterprovider→适配器工厂 + anthropic mypy 修复(@llm),build_gateway_for_tier按 provider 选适配器启用 Anthropic/Gemini 真实回退(@backend);#3packages/skills纳入 uv workspace + skill impl(registry/permissions)从ww_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/characters(CharacterListResponse{characters?})+GET .../world_entities(WorldEntityListResponse{world_entities?})+lib/api/types加 2 别名。lib/api/server加fetchCharacters/fetchWorldEntities(200 空列表非 404,仿fetchForeshadow);codex route(Server Component)Promise.all拉 项目+人物+世界观全量 → 传CodexPage初始数据。CodexPage人物 tab 渲染跨会话持久化真源(刷新不再空),本会话新入库卡经纯函数mergeCharacterCards(按 name 去重、持久化优先、不重复)合并补显(generate→ingest 后仍即时见新行);世界观 tab 渲染入库真源(本期无世界观入库端点,故只真源 + 生成器预览,无 session 合并);时间线维持 P2 占位。纯逻辑lib/generation/cards.{mergeCharacterCards,mergeWorldEntities}+ 5 node-env 单测。前端门禁全绿:gen:api/lint/tsc/vitest 130(125→+5)/build。Codex「会话内回显」局限已去除(解 gotcha + PROGRESS 余项①)。memory 把 Codex 缺口 gotcha 标 RESOLVED。 -
[2026-06-19] @backend — M5 follow-up R1 + R3 ✅(三 fix,与并行 @llm
llm_gateway改动 disjoint)。R1-Codex 读端点(解余项①):加GET /projects/:id/characters(CharacterListResponse)+GET /projects/:id/world_entities(WorldEntityListResponse),复用 C5 读侧SqlCharacterRepo/SqlWorldEntityRepo(经get_memory_repos,不动 assemble)+ 反向 JSONB 解包({"items":[...]}→list/{"text":...}→str/{"rules":[...]}→list),register main;C3 扩稳定。R3-skill 迁包(解余项③):skill_registry.py+skill_permissions.py从ww_core.domain迁入packages/skills/ww_skills/(ww_skills/__init__改直接导出,删门面);importer(generation.py/project_deps.py/test_generation.py)改from ww_skills import …;skill 单测移packages/skills/tests/(13 测);删 ww_core.domain 两模块+init 导出;packages/skills/pyproject.tomldeps 校准(去ww-core、补ww-llm-gateway+sqlalchemy),uv sync重建。R1#2-build_adapter 接线(解余项②的 apps 侧;@llm 的build_adapter工厂 + @devops 的 anthropic/google-genai SDK 均已落地,import 实解非 transient):build_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/OpenAICompatAdapterimport。门禁绿(隔离MYPY_CACHE_DIR=.mypy_cache_r1backend已清理):ruff/format 净、mypy 101 文件 0 error、pytestpackages/core packages/skills apps/api246 passed(226→+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_entities,CodexPage 初始列表拉全量去掉「会话内」局限(解 gotcha Codex 缺口)。@devops 行动:复核根uv.lock(@backend 改了packages/skills/pyproject.tomldeps,已uv sync重建 ww-skills)。M5 三非阻塞余项①②③ 至此全部清除。 -
[2026-06-19] @llm — R2 follow-up #2 ✅ 真多 provider 适配器选择(C1 扩 follow-up #2 稳定;接 @devops 已加
anthropic+google-genaiSDK 之后)。① 修真 SDK 装上后的 mypy 报错:instructor.from_anthropic(self._client)重载只收 SDK 具体AsyncAnthropic|...、AnthropicClientProtocol 不匹配 → adapter 内cast("AsyncAnthropic", self._client)(TYPE_CHECKINGimport,零运行时硬依赖)选中 AsyncInstructor 重载。gemini 走response_schema非 instructor,无该类错。② 新增 provider→适配器工厂factory.build_adapter(provider, *, api_key, base_url=None) -> ProviderAdapter(包__init__导出):anthropic→AnthropicAdapter、{gemini,google}→GeminiAdapter、其余→OpenAICompatAdapter(provider, AsyncOpenAI(...));从 api_key 构真实客户端(factory 处cast跨 Protocol read-only-attr 约束,adapter 仍声明 Protocol 形参、测试替身缝完好)。新增tests/test_build_adapter_factory.py6 测(按 provider 名断分派,不联网)。门禁绿(隔离 cache):ruff/format 净、mypy 24 源文件 0 错、pytest 47 passed(41→+6);全仓mypy packages apps144 文件 Success(anthropic.py 报错确认消除、gemini 无同类错)。无 OpenAPI 形变(served_by 不出 API),前端无需 re-gen。@backend 可在build_gateway_for_tier用build_adapter替换「一律 OpenAICompatAdapter」启用 anthropic/gemini 真实回退。 记 1 gotcha(Protocol vs 真 SDK cast 边界)。 -
[2026-06-19] @orchestrator — 🎉 M5 完成 + 独立复核 ✅(Wave C:T5.3+T5.6 ✅ + Wave D:T5.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 passed。M5(生成+多provider+扩展)出口 DoD 全达成:worldbuilder/character-gen 生成→预览→入库(continuity 409 gate + partition_writes 白名单 + schema→JSONB 形变);网关多 provider 回退/熔断/能力降级(真 Gateway 回退链,E2E 验主失败→fallback 服务 + 记账记实际 provider);Skill registry + 表权限沙箱 + 规则页/技能库/命令面板(⌘K)。M1–M5 全部交付。 非阻塞余项:① 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 D:T5.7✅ M5 E2E + 切 provider(真 pg + mock 多 provider,零 token;无契约变更)。
tests/test_m5_e2e.py3 用例:① 群像生成→入库闭环(mock 网关按req.output_schema路由 CharacterGenResult/WorldGenResult/ContinuityReview):POST /world/generate预览 +POST /characters/generate预览 3 卡 →POST /characters入库双 gate——precheck 有冲突且未acknowledge_conflicts→ 409 CONFLICT_UNRESOLVED+details.conflicts(并断言此刻 characters 表无行,守不变量 #3)→ 带acknowledge_conflicts=true重发 201;DB 真源断言 characters 行真落 pg + schema→JSONB 形变(traits/speech_tics→{"items":[...]}、arc→{"text":...}、tags/relations 直落 list),rejected_tables空(partition_writes 合法路径),4 条 ledger。② 切 provider 回退:HTTP 角色生成跑在真Gateway(非 stub)deepseek(每次complete抛TransientProviderError耗尽重试)→openai 回退链上,端点仍 200;served_by不出 API,故经 DB 真源usage_ledger断言实际服务方 = openai(fallback)≠deepseek(primary)(ARCH §4.5 记账记实际服务方)。③ 能力降级:structured_output=False唯一 provider 直测Gateway.run→served_by.degraded=True(§4.4)。坑:生成网关是请求 scope 依赖(get_worldbuilder_gateway/get_character_gen_gateway/get_precheck_gateway),直接app.dependency_overrides注假网关即可,无需 monkeypatchbuild_gateway_for_tier(与 M4 学文风后台自建网关不同)。全仓门禁绿:ruff/format 净、mypy 142 文件、alembic 无漂移、pytest 391 passed(388→+3)。未发现 REAL bug。M5 出口 DoD 全达成 → orchestrator 可封 M5。 -
[2026-06-19] @frontend — M5 Wave C:T5.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.6)components/generation/CharacterGenerator:一句话 brief + 数量(1–12) + 定位 →POST /characters/generate预览卡 →CharacterCardItem(勾选入库 + 就地编辑名/弧光,默认全选)→POST /characters入库;409 CONFLICT_UNRESOLVED 裁决流:useCharacterGen捕 409 →extractIngestConflicts收窄details.conflicts(复用 ReviewConflict 形) →ConflictAdjudication面板展示 continuity 冲突 → 作者「已知悉强制入库」= 带acknowledge_conflicts=true重发 / 「取消改卡」。② 世界观设计器WorldGenerator:POST /world/generate预览 type/name/rules(本期无入库端点,仅预览参考)。③ 设定库 Codex(UX §6.5)codex/CodexPage+app/projects/[id]/codex:人物/世界观/时间线三 tab(时间线 P2 占位);?gen=character|world命令面板跳转直开对应 tab。T5.6:④ 规则页rules/RulesPage+app/.../rules:四级规则列表(groupByLevel) + 新增(useRules乐观追加+回滚,仿 useForeshadow)。⑤ 技能库skills/SkillsPage(Server Component 纯读)+app/.../skills:GET /skills按 scope 分组只读注册表(name/tier/reads/writes)。⑥ 命令面板 ⌘Kcommand/{CommandPalette,CommandPaletteMount}+lib/command/palette:⌘K/Ctrl+K 开关、模糊过滤(filterCommands)、上下循环高亮(moveHighlight)、Esc/Enter,a11y(role=dialog/listbox/option + 自动聚焦 + prefers-reduced-motion);挂 RootLayout 对全局生效,读 pathname 注入项目上下文。⑦ LeftNavActiveNav加 codex/rules/skills(替换原 disabled 设定库占位)。纯逻辑全单测(node-env):lib/{generation/cards,rules/rules,skills/skills,command/palette}.test。前端门禁全绿:gen:api/lint/tsc/vitest 125(96→+29:cards 12 + rules 5 + skills 3 + palette 9)/build(codex/rules/skills 路由齐)。memory 记 2 gotcha + 1 gap(Codex 读端点缺口)。M5 前端交付完成 → 下一步 Wave D:T5.7(@qa) M5 E2E + 切 provider。 -
[2026-06-19] @orchestrator — M5 Wave B 收口 ✅(T5.2,C3 扩稳定)。5 端点入 OpenAPI:world/characters generate 预览 + characters 入库(双 gate:continuity 预检 409 + partition_writes 白名单 + schema→DB 形变)+ GET rules/skills;
build_gateway_for_tier接线回退链(OpenAI 兼容齐,Anthropic/Gemini 真实切换余量 deferred 给 T5.7 + @devops SDK)。全仓门禁绿:ruff/format 干净、mypy 142 文件、alembic 无漂移、pytest 388 passed(371→+17)。下一步 Wave C:T5.3+T5.6(@frontend 单 agent 顺序做)——先pnpm gen:api,做 角色生成器 + 世界观设计器 + 设定库 Codex + 规则页 + 技能库 + 命令面板(⌘K),入库流处理 409 裁决重发。 -
[2026-06-19] @backend — M5 Wave B:T5.2✅ 生成/入库 API(契约 C3 扩稳定;消费 Wave A 的 C6扩/C8/C1扩,与已合并 Wave A 无写冲突)。
routers/generation.py(+skills_router,已注册 main)落 5 端点:①POST /world/generate(worldbuilder writer 网关run_worldbuilder→ 预览世界观,不入库,末尾 commit 落 ledger);②POST /characters/generate(character-gen writer 网关,注入已有角色防雷同 → 预览角色卡);③POST /characters(入库 双 gate:precheck_generated_cardscontinuity 预检 analyst 网关——有冲突且未acknowledge_conflicts→ 409 CONFLICT_UNRESOLVED+冲突详情,作者裁决后放行;partition_writes(character_gen_spec,...)白名单过滤越权写表;过 gate 写characters行,schema list/str → DB JSONB dict 形变);④GET /rules(规则列表,复用 C5 读侧);⑤GET /skills(技能库,经 registry)。新写侧 repoww_core.domain.{character_repo(traits/speech_tics→{"items"}/arc→{"text"}),world_entity_repo(rules→{"rules"})}(只 flush,端点 commit)。T5.4 follow-up 接线完成:build_gateway_for_tier据 DBtier_routing.primary+fallback预备多OpenAICompatAdapter+ 注入chain_resolver=chain_from_routing(...)启用回退链;无路由行退回resolve_route(单 provider,M1 兼容),无可用凭据→503。仅 OpenAI 兼容 provider(deepseek/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 passed(371→+17:13 生成/入库端点 + 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 C:T5.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 /rules(C8 + C3扩)。全仓门禁绿:ruff/format 干净、mypy 135 文件、alembic 无漂移(M5 复用 T0.2 已建的 world_entities/characters/rules/skills 表,无建表迁移)、pytest 371 passed(296→+75)。Wave B 衔接待办(T5.2 @backend 须处理):① 角色 schematraits/speech_tics(list)/arc(str) ↔ DB JSONB dict 形变,入库须转换;② 入库 gate 调precheck_generated_cards(continuity 冲突拦截) +partition_writes(越权写丢弃审计);③ 补GET /rules+GET /skills供 T5.6 前端;④ 接线build_gateway_for_tier→chain_from_routing启用回退链(T5.7 切 provider 依赖)。@devops 待办:加anthropic/google-genaiSDK 依赖(适配器懒 import,单测不需);评估把packages/skills纳入 uv workspace(现 impl 落 ww_core.domain + ww_skills façade)。下一步 Wave B:T5.2(@backend 生成/入库 API)。 -
[2026-06-19] @llm — M5 Wave A:T5.4✅ 网关多 provider 韧性(契约 C1 扩稳定,仅扩
packages/llm_gateway/,与并行 T5.1 @llm 无文件冲突)。① 新适配器adapters/anthropic.py(AnthropicAdapter:原生结构化经 instructor.from_anthropic 懒构建、cache_control缓存断点、thinking 能力)+adapters/gemini.py(GeminiAdapter:response_mime_type=json+response_schema结构化、thinking)——均经注入的客户端 Protocol,不硬 import anthropic/google-genai SDK,单测零联网零依赖。② 回退链 + 重试 + 熔断gateway.py:Gateway加chain_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.py:TransientProviderError(三适配器按异常类名+status_code 包装)+网关视AppError(RATE_LIMITED)可重试。⑤ routing.py:resolve_chain/chain_from_routing(据 DB tier_routing 去重保序)/ChainResolver别名导出。⑥ServedBy加degraded(向后兼容,默认 False);pyproject.toml加tenacity>=8.2。23 新测(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/apibuild_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 A:T5.5✅ Skill 运行时 + 规则(契约 C8 + C3 扩稳定;与并行 T5.1/T5.4 @llm 无目录/写冲突,隔离
MYPY_CACHE_DIR=.mypy_cache_t55)。① Skill registry loader(packages/core/ww_core/domain/skill_registry.py):SkillRecord(frozen,skills 行声明快照) +SkillRepoProtocol +SqlSkillRepo(读skills表,裸 tier 非法→VALIDATION) +SkillRegistry.load(repo)(async,每条跑validate_declaration,越权声明→AppError VALIDATION 加载中断;frozendict[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)。守不变量#3(allowed 仍过验收 gate,不开写后门)。③POST /projects/:id/rules(routers/rules.py,已注册 main):RuleCreateRequest{level:Literal[global/genre/style/project],content(min1)}→201RuleView{level,content},非法 level/空 content→FastAPI 422;写侧domain/rule_repo.py(RuleWriteRepo/SqlRuleWriteRepo/RuleWriteView,只 flush,端点 commit);喂 assemble 四级merge_rules。④ 注入缝get_rule_write_repo/get_skill_registry(project_deps)。门禁绿(限本任务范围):ruff/format 净、MYPY_CACHE_DIR=.mypy_cache_t55 mypy packages/skills packages/core apps/api0 error/94 文件、pytestpackages/skills packages/core apps/api226 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.1✅(C6 扩稳定,与并行 T5.4 @llm/T5.5 @backend 无目录/写冲突,隔离 MYPY_CACHE_DIR)。worldbuilder + character-gen 落地:① schema(
packages/agents/ww_agents/schemas.py)WorldEntityCard{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/charactersDB 列供 T5.2 ingest 直映。② spec(specs.py)worldbuilder_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_gen(build_character_gen_context把已有+已生成卡序列化成name(role):traits简表注入,空时占位不崩,独立生成、网关失败上抛、parsed 违约 ValueError,只读不写库)。④ 入库前 continuity 校验缝(ARCH §6.5)precheck_generated_cards(spec=continuity_spec,*,cards,world_context,characters_context,...)->list[Conflict]——编排器追加的检查、非 character-gen 直接互调(守 §5.4/不变量#1),T5.2 入库端点调它做 gate。门禁绿(限本任务文件):ruff/format 净、mypy 本任务 7 文件 0 error(packages/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 gate;analyst/writer 网关复用 build_gateway_for_tier。下一步 Wave B:T5.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 四并行分支+SSEstyle+chapter_reviews.style) + 回炉同步 diff(不写库守不变量#3)。Phase 4 完成;M1–M4 全部交付。下一阶段 M5(生成+多 provider+Skill) 见 DEV_PLAN,进入时归档 M3/M4 并拉入新表。 -
[2026-06-19] @qa — 🎉 M4 完成(Wave D:T4.5✅ M4 E2E)。
tests/test_m4_e2e.py真 pg + 多档位 mock 网关(零 token)真跑通过 3 用例:① 学文风闭环:POST /style→202{job_id}→BackgroundTaskrun_job自建独立 session 跑run_style_extraction(analyst 假适配器产 StyleFingerprintResult)→SqlStyleFingerprintWriteRepo.append真落 pg→GET /jobs/{id}status=done(result.version/dims_count)→GET /style最新指纹→mode="update"学一次 version+1;DB 真源style_fingerprint2 行(version 1/2,dimensions/evidence)+jobs2 行 done。② 写章第四审:学文风后 assemble stable_core 含指纹→POST .../reviewSSE 四审齐(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 无真凭据,须 monkeypatchstyle.build_gateway_for_tier→真 Gateway 包假适配器(ledger 绑入参 session);写侧 repo +run_job默认SqlJobRepo保持真→指纹/job 真落 pg;overrideget_session_factory→e2e_sm(同测试 engine/loop)。最终全收口门禁绿:ruff/format 干净、mypy 115 文件、pytest 296 passed(293→+3)、alembic 无漂移(M4 无建表迁移)。M4 出口 DoD 全达成 → Phase 4 可归档。 -
[2026-06-19] @frontend — M4 Wave C:T4.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.ts加StyleEvent/StyleDriftReport/reduceReviewcase "style"(替换式仿 pace)/ReviewStreamState.style/seed;history-style 收窄normalizeStyleDrift落lib/style/style.ts;StylePanel(◔ 整体相似度% + 漂移段一键回炉)接进 ReviewReport(seed 扩四态)。④ 回炉RefineView+useRefine(POST /refine→新旧 diff→采纳:把 refined 替换 finalText 中原段,经既有 draft 路径合入,不另写库守不变量#3;503 优雅提示)。LeftNav 开「文风」入口(ActiveNav加 "style")。前端门禁全绿:gen:api/lint/tsc/vitest 96(+27:job 12 + style 10 + style-sse 5)/build(含/projects/[id]/style路由)。memory 记 1 gotcha。下一步 Wave D:T4.5(@qa) M4 E2E。 -
[2026-06-19] @orchestrator — M4 Wave B 完成 ✅(T4.3,C3 扩稳定)。style/refine 三端点入 OpenAPI:
POST /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 C:T4.4(@frontend)——先pnpm gen:api纳入 style/refine/GET-style + jobs 类型,再做文风页(上传/指纹/证据) +lib/jobs/useJobPoll+ 审稿页第四审 StylePanel + 回炉 diff。 -
[2026-06-19] @backend — M4 Wave B:T4.3✅ API style + refine(契约 C3 扩稳定)。三端点入 OpenAPI(独立
routers/style.py,仿 outline.py,已注册):①POST /projects/:id/style→ 202{job_id}(学文风走 jobs,M4-c):job_repo.create("style_learn")+commit →background_tasks.add_task(run_job, session_factory, job.id, work);work在run_job自建独立 session 上自造 analyst 网关+写侧 repo →run_style_extraction→ 拆dimensions_json/evidence_json→append(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=None→resp.text;不写库守不变量#3;末尾 commit 让 usage_ledger 落库)。③ 顺带补GET /projects/:id/style→ 最新指纹{dimensions,evidence,version}(UX §6.9;ARCH §7.2 原缺读端点——决策见 decisions,待 @docs 回写 ARCH §7.2/PRODUCT_SPEC §6);不动 C5 读侧SqlStyleRepo(assemble 行为不变)。新建写侧domain/style_repo.py(StyleFingerprintWriteRepo/Sql*,append只 flush +latest含证据/版本);project_deps加get_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 C:T4.4(@frontend)。 -
[2026-06-19] @orchestrator — M4 Wave A 收口 ✅(T4.2 + T4.1 全绿)。全仓门禁收口:ruff/format 干净、mypy 111 文件、alembic 无漂移(M4 无建表迁移)、pytest 280 passed(M3 基线 228 → +52:T4.2 37 + T4.1 15)。契约稳定:C6扩/C4扩(StyleFingerprintResult/StyleDriftReview/四审齐/SSE style 事件)、C3.5(JobRepo/run_job)。下一步 Wave B:T4.3(@backend)——单 @backend agent 顺序做 style/refine 两端点:新建
StyleFingerprintWriteRepo+routers/style.py(POST /style202 调job_repo.create+run_job(work=run_style_extraction→StyleFingerprintWriteRepo.append);POST /refine同步refiner_specwriter 网关返 {original,refined}),C3 扩;评估顺带GET /projects/:id/style。 -
[2026-06-19] @backend — M4 Wave A:T4.1✅ jobs 长任务基建(契约 C3.5 稳定,不碰 style 业务,与并行 T4.2 @llm 无目录/写冲突)。
packages/core/ww_core/domain/job_repo.py:JobRepoProtocol +SqlJobRepo(create/set_running/set_progress 夹取/complete/fail/get/reap_zombies) + frozenJobView——状态写只 flush(提交归run_job/端点),唯reap_zombies启动期独立调用故自 commit。apps/api/ww_api/services/job_runner.py:通用run_job(session_factory, job_id, work)自建独立 session(仿run_overdue_scan)→set_running→work→complete/异常→新 session fail,异常吞不冒泡;最小JobLifecycleRepoProtocol + 可注入repo_factory缝。get_job_repo加进project_deps;main.pylifespan 在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/core130 passed /apps/api50 passed。memory 登记 C3.5。T4.3 行动:POST /style调job_repo.create+background_tasks.add_task(run_job, session_factory, job.id, work=…)。 -
[2026-06-19] @llm — M4 Wave A 半程:T4.2✅(C6 扩 + 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→recordstyle=列;sse 加EVENT_STYLE/style_event+_section_result_eventsSTYLE 分支(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 B:T4.3(@backend style/refine 端点) 可起,调本任务run_style_extraction/refiner_spec。 -
[2026-06-19] @orchestrator — 进入 M4(文风):归档心智上 M3,Phase 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 A:T4.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 E:T3.7✅ E2E 交付 + 暴露并发 bug。
tests/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失败隔离静默吞成incomplete→foreshadow/pace 静默丢失(SSE 无事件、chapter_reviews列空)。M2 单审未触发。基线 222 passed + 1 xfailed。开 T3.8(@llm) 修复 → 修后 @qa 解钉 xfail → 才算 M3 达成。 -
[2026-06-18] @orchestrator — M3 Wave D 完成(T3.6✅)。前端三块落地:伏笔四泳道看板(
/foreshadow,OVERDUE 琥珀 + 登记/转移乐观更新)、大纲编辑器(/outline,逐章 beats + 伏笔窗口徽标 + 接近回收提示)、审稿页扩消费foreshadow/paceSSE(伏笔建议区 + 节奏节拍图 ▁▃▅,三审齐显,文风第四审留 M4)。pnpm gen:api纳入 M3 端点(看板/登记/转移/大纲),松散 JSONB 字段安全收窄不手写。前端门禁绿:gen:api/lint/tsc/vitest 69(+24)/build。memory +1 decision +2 gotchas。下一步 Wave E:T3.7 M3 E2E(@qa 真 DB + mock 网关零 token)。 -
[2026-06-18] @orchestrator — M3 Wave C 完成(T3.5✅,C3 扩稳定)。
GET .../foreshadow?status=看板(续 foreshadow.router,四泳道)+POST .../outline(独立 outline.py:run_outlineanalyst 网关 → 逐章 upsertoutline表含伏笔窗口 → 端点末尾 commit)。outline 写侧 repo 加Write前缀避撞 C5 读侧。全仓门禁绿:mypy 102 文件、pytest 220 passed(205→+15)。memory 登记 C3 扩 + 1 decision + 1 gotcha。下一步 Wave D:T3.6(@frontend 伏笔看板 + 大纲编辑器 + 节奏节拍图 + 审稿页消费 foreshadow/pace SSE,先pnpm gen:api)。 -
[2026-06-18] @orchestrator — M3 Wave B 完成(T3.2✅)。验收后到期扫描挂 BackgroundTask(
run_overdue_scan自建独立 session 置 OVERDUE,接 §5.5TODO(M3))+ 伏笔登记/状态端点(POST/PATCH .../foreshadow,重复 code/非法转移→VALIDATION422,未动 shared 错误码)。全仓门禁绿:mypy 95 文件、pytest 205 passed(196→+9)。memory 登记 C3 扩 + 1 decision + 2 gotchas。下一步 Wave C:T3.5(@backendGET .../foreshadow?status=看板续接 foreshadow.router +POST .../outline独立 outline.py 调 run_outline)。 -
[2026-06-18] @orchestrator — M3 Wave B 半程(T3.3✅,C4/C6 扩稳定)。foreshadow-analyst + pace-checker 并入
build_review_graph(REVIEW_SPECS三审齐,文风第四审留 M4);collect 一次 record 分列落conflicts/foreshadow_sug(扁平+kind 标记)/pace(整 dict);normalize_review加foreshadow/paceSSE 事件(向后兼容)。全仓门禁绿: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.4:outliner spec +OutlineResultschema(含foreshadow_windows)+run_outline节点(只读不写库,C6 扩稳定)。全仓门禁绿:ruff/format 干净、mypy 90 文件、pytest 169 passed(114→+37+18)。memory 登记 C6 扩 + 2 decisions + 2 gotchas。下一步 Wave B:T3.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+状态机」据实记 @backend(落core/ww_core/domain/,同 T2.3 先例);T3.3 复用 M2build_review_graph的review_specs扩展点加 foreshadow/pace 两审(文风第四审留 M4)。启动 Wave A:T3.1(@backend·core/domain) ‖ T3.4(@llm·packages/agents+orchestrator)(不同目录,无写冲突)。 -
[2026-06-18] @orchestrator — 🎉 M2 完成(Wave E:T2.7✅)。
tests/test_m2_e2e.py真实 pg + 多档位 mock 网关(零 token)真跑通过 2 用例:主用例串 立项→写章 SSE→自动保存→审稿 SSE(section/conflict)→GET 历史→残缺裁决触发 409CONFLICT_UNRESOLVED+missing_indices(gate 事务前拦截未写库)→全量裁决+终稿验收(200, accepted v2)→DB 真源逐项断言:chapters draft v1 留存 + accepted v2(content==final_text)、chapter_digests.facts追溯终稿标记(证 #4 digest 从终稿非草稿)、chapter_reviews.decisions写回、usage_ledger三档位(writer/analyst/light)各落一条且事务已 commit;补充用例验证零冲突直通。无新 bug(M1 曾暴露的 ledger 提交 bug 在 M2 三档位无复发——review 流末 + accept 事务末均 commit)。最终全收口门禁绿:ruff/format 干净、mypy 90 文件、pytest 114 passed、alembic 无漂移(M2 全程零建表迁移)。M2 出口 DoD 全达成。下一阶段 M3(伏笔+节奏)。 -
[2026-06-18] @orchestrator — Wave D 完成(T2.6✅)。审稿报告页落地:
app/projects/[id]/review(RSC 取历史)+components/review/*(报告卡/就地标注/AcceptPanel)+lib/review/*(SSE reducer/裁决完整性/请求体组装,纯逻辑单测)。pnpm gen:api纳入 review/accept/reviews 三端点类型(不手写);SSE 沿用useDraftStream的 fetch+ReadableStream 范式;五类冲突就地朱砂锚点(R6 段级降级)+裁决(采纳/忽略/手改)+未决禁验收 gate+409 missing_indices 高亮+「本次将更新」清单。前端门禁绿:gen:api/lint/tsc/vitest 45(+21)/build。memory +1 decision +2 gotchas。下一步 Wave E:T2.7 M2 E2E(@qa 真实 DB + mock 网关零 token)。 -
[2026-06-18] @orchestrator — Wave C 完成(T2.4✅ + T2.5✅,C3 扩稳定,单 @backend agent 顺序做)。三端点入 OpenAPI:
POST .../review(SSE section/conflict/done) +GET .../reviews(新→旧) +POST .../accept。验收:冲突 gate(裁决conflict_index须覆盖 review.conflicts 全下标,缺判→409CONFLICT_UNRESOLVED+missing_indices)→ 终稿 digest 提炼在事务外(R2,light 档)→ 单原子事务 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 D:T2.6(@frontend 审稿页+裁决+验收 gate,先pnpm gen:api)。 -
[2026-06-18] @orchestrator — Wave B 完成(T2.2✅,C4 扩稳定)。审稿子图落地:
build_review_graph(START→continuity 并行审→collect→END,可扩四审) +collect_reviews落chapter_reviews留痕 +normalize_review(SSE 加section/conflict);M1build_write_graph不动。划清边界:本任务到 collect+归一缝为止,interrupt/accept 事务接线交 T2.4(对齐 R3:accept 从领域表重读、checkpoint 仅控制流)。全仓门禁绿:ruff/format 干净、mypy 80 文件、pytest 103 passed。memory 登记 C4 扩 + 3 gotchas(reducer/add_node 重载/失败隔离两层)。下一步 Wave C:T2.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 B:T2.2(@llm 并行审图+collect 留痕+review SSE,依赖 C6+C4)。 -
[2026-06-18] @orchestrator — 进入 M2:归档 Phase 1(M1) 至已归档;Phase 2 七任务拉入台账。计划核对两处偏差并据实修正:(1) T2.3「Repository 逻辑」落
packages/core/ww_core/domain/(@backend owned)而非packages/db——DB 全 MVP 表 + 唯一约束(project_id,chapter_no,version)已在 T0.2(@db) 一次建齐、M2 无新建表迁移,故 T2.3 由 @backend 承接 Repository 逻辑;(2) 网关结构化输出缺口:Gateway.run()当前不消费output_schema/不填LlmResponse.parsed(instructor 未接线),续审依赖此,归入 T2.1(@llm)。启动 Wave A:T2.1(@llm·packages/agents+llm_gateway) ‖ T2.3(@backend·core/domain)(不同目录,无写冲突)。 -
[2026-06-18] @orchestrator — 🎉 M1 完成(Wave E:T1.9 E2E✅)。真实 DB + mock 网关 E2E 走通 立项→写章 SSE→自动保存→DB 真源断言(projects/chapters/usage_ledger)。E2E 暴露并修复一个生产 bug:draft SSE 端点未提交注入 ledger 的请求 session(
SqlAlchemyLedgerSink按设计只 flush、不 commit——写库事务归编排层),导致真实写章的usage_ledger行被回滚丢失(违背「成本账本从第一天」)。修复:draft 端点流耗尽后await session.commit();E2E 改用请求 session 做 ledger、去掉手动 commit 以回归校验该提交。最终全门禁绿:ruff / mypy 68 / pytest 57 / alembic 无漂移;前端 gen:api/lint/tsc/vitest 24/build 绿。 -
[2026-06-18] @orchestrator — Wave D 完成(T1.5+T1.6+T1.8✅,单前端 agent)。
pnpm gen:api重生成客户端含全 M1 端点;路由/(作品库)、/projects/new(5 步向导)、/projects/[id]/write(工作台 SSE 打字机+停+自动保存)、/settings/providers(脱敏+测试连接+能力徽标)。前端门禁全绿:gen:api/lint/tsc/test 24/build。M1 占位(无 API 支撑、未造假端点):单章导航、本章助手/注入透明面板(M2)、向导主角/世界观字段折叠进 premise、档位路由只读。下一步 Wave E:T1.9 E2E(@qa, mock 网关)。 -
[2026-06-18] @orchestrator — Wave C 完成(T1.4✅ 立项+写章 API,C3 稳定:M1 端点全落)。记忆→网关→编排器串成 HTTP:5 端点入 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 并行(各 ~90–98k tokens,比 fork 省)。全仓 compose 门禁绿:ruff、mypy 61 文件、pytest 48 passed。修了跨包测试碰撞(apps/api
fakes.py→fakes_providers.py;root mypy 排除conftest.py解决多 rootless conftest 同名)。⚠️ Wave C 前置:DB 无 stub user,而 projects/usage_ledger/provider_credentials.owner_id 均 FK→users.id;T1.4 须先幂等 seed stub user(uuid(int=1))。下一步 Wave C:T1.4(@backend 立项+写章 SSE+自动保存,依赖 C4)。 -
[2026-06-18] @orchestrator — Wave A 完成(T1.1✅ + T1.2✅,契约 C1/C5 稳定)。全仓 compose 门禁绿:ruff 干净、mypy 45 文件、pytest 27 passed(9 基线 +10 网关 +8 记忆)。T1.1 网关由 orchestrator 内联实现(原 fork 因 stream idle timeout 早夭、零产出);T1.2 记忆由 fork 完成。下一步 Wave B:T1.3(@llm 写章节点+SSE,依赖 C1+C5) + T1.7(@backend 凭据,依赖 C1)。
-
[2026-06-18] @orchestrator — 进入 M1:把 Phase 1 九任务拉入台账并归档 Phase 0;新增 workspace 成员
packages/llm_gateway(ww-llm-gateway) +packages/core(ww-core),装 openai/instructor/langgraph/langgraph-checkpoint-postgres/cryptography/tenacity,根pyproject.tomlmembers+mypy_path 已更,uv sync通过,基线门禁全绿(ruff/mypy 27 文件/pytest 9 passed)。记录 decision:assemble返回中性文本以解耦 T1.1‖T1.2。启动 Wave A(T1.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/pytest(56 passed)。 -
[2026-06-19] @backend — bugfix 空写章 prompt:
assemble(C5)从不含项目 premise/logline/theme/title 且无写章指令 → 全新项目(仅 premise)产空stable_core+volatile,写章触发 LLM400 message must not be empty。修复:MemoryRepos加第 8 repoproject:ProjectSpecRepo(SqlProjectSpecRepo按 project_id 读projects);assemble把「作品蓝本」放入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 回退「跳转」),ConflictCard加snippetprop 渲染朱砂引用块。R2:冲突按 type 分组 + 严重度排序(设定违例>能力不符>时间线倒错>地理矛盾>性格漂移,未知殿后)+ 组计数徽标 + 「跳到下一条未裁决」(按显示顺序环回)+ 主次裁决按钮(采纳改法=朱砂主、忽略/手改=次级)——新纯函数lib/review/grouping.ts(groupConflicts/displayOrder/nextUnresolvedInOrder,分组只改显示顺序、每条携原始 index,守 conflict_index 覆盖 range 不变量),ReviewReport改分组渲染。TDD:snippet 8 测 + grouping 10 测。前端门禁绿:lint/tsc/vitest 201(+18)/build。分支feat/ux-r1-r2-review-ergonomics。下一步(按 plan):R3 验收前清单 → Tier4。 -
[2026-06-20] @frontend — UX R3 完成(验收前清单 HITL gate,UX §7.4,纯前端无后端改,续
feat/ux-r1-r2-review-ergonomics)。新纯函数lib/review/accept-preview.ts(buildAcceptPreview:据现有 client state 列「本次验收将更新」——晋升版次 + 提炼章节摘要 + 写回裁决(有冲突时) + 验收后伏笔到期扫描(可能置 OVERDUE) + 伏笔建议待登记提醒(有建议时))。只列后端 accept 事务确实做的事(核对projects.pyaccept 端点:promote+digest+decisions+overdue 扫描;不声称改人物 latest_state/自动落库伏笔建议);带「以上为预期,最终以验收回执为准」免责。AcceptPanel加foreshadowCountprop + 未阻断时渲染清单,ReviewReport传foreshadow.length。TDD:4 测。前端门禁绿:lint/tsc/vitest 205(+4)/build。下一步(按 plan):Tier4(T4-a 顶部 AI 工具条 / T4-b 本章指令框+风格预设)。 -
[2026-06-22] @backend — ✅ T6.2+T6.3 创作工具箱通用端点稳定(通用生成器框架后端落地,分支
feat/t6-creation-toolbox)。新ww_skills.TOOLBOX(11 条:legacy 3 + 新 8) +get_tool(toolbox_registry.py,descriptor 在代码无迁移)。3 新端点(routers/toolbox.py,已注册):GET /skills/toolbox(描述符列表,legacy 携legacy_route:codex?gen=world|character//outline)、POST .../skills/{tool_key}/generate(按spec.tier经新注入缝get_tier_gateway_builder建网关 →run_generator结构化预览,不写库仅落 ledger;未知/legacy→404、项目不存在→404、无凭据→503)、POST .../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_context(4 策略,缺章/大纲→空节拍不报错)。response/request schemaschemas/toolbox.py(concrete 子模型,非裸 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:api(T6 前端前置)。记 contracts C3 扩(T6.2/T6.3)。 -
[2026-06-20] @frontend — Tier4 完成(T4-a 全局 AI 工具条 + T4-b 本章指令直通生成,分支
feat/ux-tier4-ai-toolbar,未并 develop)。T4-a:新lib/nav/ai-tools.ts(aiToolItems) +components/AiToolbar.tsx服务端组件,AppShell 顶栏下仅项目页渲染(写本章/审稿/大纲/设定库/工具箱常驻一排,写本章=朱砂主动作),用--chromeCSS 变量统一 chrome 高度(项目页 7rem=header4+toolbar3,余 4rem),6 个固定高度页改用calc(100vh-var(--chrome,4rem))适配。T4-b(全链):后端assemble/_build_volatile加directive形参(「本章指令」段领衔 volatile,绝不入 stable_core,守缓存前缀不变量 #9),stream_draft加可选 bodyDraftStreamRequest{directive}透传、directive_len入 log 不记原文、不持久化无迁移,重生成 TS 客户端;前端新lib/workbench/directive.ts(STYLE_PRESETS + composeDirective 纯函数)、useDraftStream.start(p,no,directive?)非空时发 JSON body、Workbench 加可折叠「本章指令」textarea + 风格预设 chips。TDD:ai-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_count,chapters加updated_at迁移8c1d2e3f4a5b;SqlProjectRepo聚合项目自身、章节、审稿时间作为最近编辑,并按草稿是否晚于最近 accepted/review 统计待审稿章数。前端pnpm gen:api后项目库默认按最近编辑排序,新增“待审稿”筛选,作品卡显示最近编辑与待审稿徽标。契约记memory/contracts.mdC3 扩,UI 计划记docs/design/ui-improvement-plan.md0.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/横向溢出。