Skip to content

R26 集成批 6:网页只读 MCP 清单 + 提醒观测面 + routes 术语收口 + 台账 R25/R26 + 版本号 0.2.0 - #30

Merged
mycyg merged 27 commits into
mainfrom
r26/integration-9
Sep 5, 2026
Merged

mycyg merged 27 commits into
mainfrom
r26/integration-9

Conversation

@mycyg

@mycyg mycyg commented Sep 5, 2026

Copy link
Copy Markdown
Owner

R26 集成批 6(本轮收尾):网页只读 MCP 清单与契约错误码(M8)+ 重复动作提醒观测面(B6 事件 + 持久化)+ routes 层术语收口与桌面端稳定错误码 + 审查台账 R25/R26 两节 + 桌面端版本号 0.2.0。

一、网页只读「MCP 服务器」清单 + 契约稳定错误码(r26/m8-web-mcp-readonly,6 commits)

  • 契约新增 mcpServerErrorCodeSchema(九条:连接监督的八条会话失败原因 + mcp_connect_failed 兜底);McpServerVM / McpServerConnectionVM / McpServerSummaryVM 各加可选 last_error_code;不加 DB 列(行上的 last_error 已是同一份信息),码由连接快照的原因枚举在治理服务里翻出;openapi 三处同步。
  • 设置页 VM 加 mcp_servers?(仅管理员,非管理员结构性缺席);packages/ui 在插件区之下渲染只读清单,四种状态各说各的,连不上那行按码出人话,空态一句加「添加、启停和移除在桌面客户端的设置里操作」。文案 19 条进词典。
  • 顺带修:openapi 的设置页响应 schema 是 additionalProperties: false 却没列 permission_policies / plugins——一份真实的管理员响应按那份文档是不合法的,现已补齐。
  • 「系统诊断」两张卡改为仅管理员渲染(整段不进 HTML),抬头写明「仅管理员」。
  • 五个服务模块 11 处「事项 / 工单」→「任务」(先搬词典再改词,棘轮 2808→2795 只减不加);顺带修建任务透明日志在标题缺席时渲出 undefined
  • README 新增「MCP 服务器」小节(像产品文档:是什么、在哪里接、名字为什么受限、信任级别怎么选、为什么不能直接填 npx、密钥怎么给)。

二、审查台账 R25 / R26 两节(31e3dc05)

reports/审查台账-2026-08-19.md 十九、二十:两轮全部施工线、PR 对应、拍板与事实、门禁状态、待办。

三、桌面端版本号 0.2.0(e8c0cb5c)

pnpm sync:desktop-version 0.2.0 五处单一事实源同步,pnpm audit:desktop-version 通过;cargo test 198 / fmt 绿。合并后用 workflow_dispatchdry_run=falsedraft=truetag_name=v0.2.0)出草稿 Release。

四、重复动作提醒的观测面(r26/b6-reminder-events 5 commits + r26/b6b-reminders-persist 4 commits)

  • 新事件 agent_run.reminded(只有事实:tier / repeats / shape / tool_id,没有句子),两套引擎同点同形状,第三档不重复发(已有 escalated);equivalence 用例逐字段 deepEqual。
  • web 实时页与回放页、桌面回放各渲染一行人话(「第一次提醒:Cuu 连续 3 步做了同一件事(重复的是「run command」),已让它换个做法再继续。」),工具名去下划线不裸露原名;八条完整句子中英词典。
  • 迁移 0075agent_runsreminders_json(可空、replay 安全);运行器把事件累加进记录(封顶 32),随既有三处 run 行写入落盘,六条读回路径自动带上;实时 VM 与回放 VM 透传;worker 重启后从持久化读回仍在。真 PG 门断言列存在(删列即红)。

五、routes 层术语收口 + 桌面端按稳定码出话(r26/f3-routes-copy-and-desktop-codes 5 commits + b05eb13

  • 路由层与指派服务 25 处「事项 / 工单 / 工作项」按词表收成「任务」,全部经 services/locales.ts 词典;权限类一律「你没有权限…」;网盘与会议路由的 404 标签同步。
  • 桌面 MCP 分区按九条 last_error_code 各出一句(含此前给不出的「握手超时」),快照码优先于行上码,无码回落通用句;管理员门换成 vm.mcp_servers !== undefined

expected 基线 diff 摘要

模型可见文本零变化(pnpm gen:expected 幂等,git status 为空)。

验证

  • pnpm -r typecheck 全 Done;十五个包与 scripts 全过;cargo fmt / test / clippy 三门绿;qa:plugin-smoke / qa:mcp-smoke 通过;九道 audit 通过(文案 locale 棘轮 2764、禁词 49)。
  • 迁移新增 0075(journal idx 75)。

🤖 Generated with Claude Code

mycyg and others added 27 commits September 6, 2026 02:29
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
McpServerVM / McpServerConnectionVM / McpServerSummaryVM 各加可选 last_error_code
(八条会话失败码 + mcp_connect_failed 兜底)。连接监督只在快照里回原因枚举,翻码固定
发生在治理服务的同一张表上,避免两份词表漂移,也避免反向 import 绕成循环。

表里没有存码的列,所以码只在本进程还记得那次失败时才有;重启后诊断文本仍在、码缺席,
界面回落到通用说法而不是编一个原因。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
契约新增 agent_run.reminded:payload 只带结构化事实(档位/连续重复步数/重复形态/工具名),
不带任何用户可见句子——文案交给两端按 locale 组装。第三档仍走 agent_run.escalated,两者互斥。
loop.ts 与 loop2/config-builder.ts 在提醒真正注入的同一时点各发一条,equivalence 的事件投影
补上 tier/repeats/shape/tool_ids 逐条比对。运行 VM(live/trace/replay)加 additive optional
的 reminders 数组,供时间线补出这一行。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
设置页 VM 加 mcp_servers(McpServerSummaryVM,结构性不含命令/参数/环境变量/密钥引用/
工作目录/诊断串),路由与插件清单同一道管理员门、取数失败降级为不渲这一区。

清单四种说法各说各的:已停用 / 已连接·N 个工具 / 已连接·它没有提供工具 / 连不上。
连不上那一行按稳定错误码出话,而不是把服务端的英文诊断渲上去;码拿不到就只说「连不上」。
添加、启停与移除的入口指向桌面客户端。

顺带补齐 OpenAPI 里设置页响应缺失的三段管理员字段(此前 additionalProperties:false 之下
permission_policies / plugins 结构性不合法)。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
并发处理能力、消息通道、数据存储、用哪个模型、密钥配没配——这几行是部署的运行事实,
普通成员既判断不了也调不动,看得见却点不动正是审查里反复出现的假入口。与成员、预算策略、
工作区审计三区同一道门:整段不进 HTML,而不是 hidden 掉。分区抬头随之改成「系统诊断(仅管理员)」。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
glossary §11 里同一个实体只有一个名字。会议/网盘草稿的两条 409、任务评论的 404 与 403、
风险摘要的停滞段与摘要句、无标题回落词、聊天里建任务的两条透明日志,全部搬进
services/locales.ts 并改说「任务」;ui-i18n 棘轮基线净减 13 条(work-item-comments.ts 整份清空)。

「及其余 N 项」在停滞段与临期段是同一句话,改成共用一条词典条目。建任务的透明日志此前会在
标题缺席时渲出 undefined,改成回落到刚提交的那个标题。

模型可见的 tool_result 文本(提示词那一侧仍说「工单」)未动——那要与 packages/agent 的
提示词和 golden 基线一起改,不在本工位范围。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
词典加八条完整句子(档位 × 重复形态 × 有没有工具名),中英各一套;工具 id 经
humanizeAgentToolId 去下划线并按语言加引号,界面上不再可能出现 run_command 这类原名。
实时页与回放页都把提醒行插在它所属那一步之后,对不上步骤的补在末尾(劝过就不许看不见),
脏数据由 readAgentRunReminderFacts 挡掉、整行不渲。事件标签表补 agent_run.reminded。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
是什么、在哪里接、名字为什么受限、信任级别怎么选、为什么不能直接填 npx、密钥怎么给、
它跑在哪。包结构里补上 packages/mcp-client 一行。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
spotlight/locales.ts 补八条完整句子(与 web 端同措辞),labels.ts 出同口径的组装函数;
回放视图把提醒行插在它所属那一步之后,对不上步骤的补在末尾,脏数据整行不渲。
桌面 per-run SSE 订阅登记 agent_run.reminded——EventSource 按事件名订阅,漏登记就被静默丢弃。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
agentRunLive / replayTrace 两个响应 schema 都是 additionalProperties:false——不同步就等于
把这一列声明成非法字段。事件本身不进 openapi:/api/push/stream/* 一律只声明 text/event-stream
字符串,从不逐类枚举事件形状。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
七个路由文件与指派/认领服务里 21 处用户可见的 HTTP 错误消息与提示还在说「事项」。
按 M8 的做法先把整句搬进 apps/api/src/services/locales.ts(中文 key 集 + 英文 satisfies),
调用点改读词典,再改词——就地改词会同时产生「基线条目已消失」与「新增违规」。

顺带统一两处不一致:权限类消息此前有带「你」和不带「你」两种写法,一律收成
「你没有权限……」;三处 404 共用的那句去掉尾巴上的英文「(Work item not found.)」,
中文消息里不再夹半句英文(词典的英文侧已经覆盖 en-US)。
「待审批的任务比这里显示的更多」原本是行内 zh/en 三目,搬进词典后仍按请求 locale 出话。

ui-i18n 棘轮基线只减:2795 → 2768(净减 27,零新增);禁词基线 49 条不变;
pnpm gen:expected 无 diff(模型可见文本零变化)。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
B6 已经让「先劝再断」的前两档发出 agent_run.reminded、两端时间线也会渲这一行,
但那条事件只活在 SSE 流里——运行记录不留、库里不落,回放页(读的是库)永远看不到。

迁移 0075 给 agent_runs 加一列可空 jsonb(null 与空数组同义,既有行不回填),
仓储的 insert/update 一并读写。提醒不落 agent_steps:它不是模型的一步,占了步号
会让「跑了几步」这个数字开始撒谎。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
M7 的 Note 记着一条给不出的话:握手超时时界面只能说「连不上 +(英文诊断)」,
因为契约里没有字段把 M3 早就算出来的码带出来。M8 把 last_error_code 加到了三个读形状上,
这里消费它:九条码各一句人话,与网页只读清单逐字同句(同一台服务器在两端只有一种说法)。

码到词典键的映射用 satisfies Record<McpServerErrorCode, ...> 全表覆盖——契约新增一条码时
这里编译不过,而不是悄悄落到兜底句上。连接快照上的码优先于行上的码(前者来自这个进程最近
一次握手);码缺席时(重启之后这个进程不记得那次失败)仍说通用的那一句,不编一个不知道的原因。
重连预算耗尽时两句都说:为什么失败 + 为什么不再自动重试,两件事的下一步动作不同。

管理员门从 M7 借来的 vm.plugins !== undefined 换成 vm.mcp_servers !== undefined
(M8 已给 settings VM 加了这个字段):一个只有插件管理权的身份不会再看到一个必然 403 的分区。
渲染与拉清单两处一起换。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
补上 B6 记下的最后一跳:运行器在事件出门处把提醒累进 AgentRunQueueRecord
(readAgentRunReminderFacts 解析、剥掉 run_id 等事件专属字段),持久化层把它
映到 agent_runs.reminders_json 再读回,replay.ts 的实时 VM 与回放 VM 各透传一行。

提醒不进 trace:它不是模型的一步,占了步号会让「跑了几步」撒谎——渲染层按 step_no
把它插在所属步骤之后。累加不额外发一次写,随这次运行既有的落盘路径进库;单 run
封顶 32 条(正常最多两条,上限只是防御)。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
grep「事项 / 工单」漏了 glossary §11 里同为退役别名的「工作项」。proposals 路由的两条
415 消息(在线预览 / 逐行比对都拿不到文本)用户看得见,同样搬进词典再改词。
英文侧此前不存在(这两条只有中文),按词典口径补上。

ui-i18n 棘轮基线 2768 → 2766,相对本工包开工点净减 29、零新增。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
列不在就等于「Cuu 被劝过几次」只活在 SSE 流里——回放页读的是库,永远看不到那一行。
一并钉住可空、无默认值:null 与空数组同义,既有行不用回填。
本机一次性 postgres:16 容器实跑通过;把列 drop 掉后这条断言按预期报错(非空跑)。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
写清三件容易被后人当成漏接线的取舍:为什么存 agent_runs 一列 jsonb 而不是新开表/塞 trace;
为什么累加不额外发一次写(run 行一次执行只写三次,中途崩掉的 run 会从头重跑,上一轮提醒
本就是过期数据);以及新引入的 persistence↔runner ESM 环为什么无 TDZ 风险。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@mycyg mycyg changed the title R26 集成批 6:网页只读 MCP 清单与契约错误码 + 台账 R25/R26 + 版本号 0.2.0 R26 集成批 6:网页只读 MCP 清单 + 提醒观测面 + routes 术语收口 + 台账 R25/R26 + 版本号 0.2.0 Sep 5, 2026
@mycyg
mycyg merged commit 674a52f into main Sep 5, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant