From 32e947b622812f4061b3c30abcc31faf5c152012 Mon Sep 17 00:00:00 2001 From: lanrtop Date: Sat, 3 Oct 2026 05:43:32 +0900 Subject: [PATCH] =?UTF-8?q?fix(onboarding/parity):=20lian-jing=20skill=20?= =?UTF-8?q?=E5=85=8D=E7=A1=AE=E8=AE=A4=E4=BE=8B=E5=A4=96=E8=A1=A5=E5=88=97?= =?UTF-8?q?=20register=5Fproject=5Fdev=5Fvariable=EF=BC=8C=E7=AC=AC=208=20?= =?UTF-8?q?=E6=9D=A1=E5=BC=80=E5=8F=91=E5=8F=98=E9=87=8F=E6=94=B9=E7=94=A8?= =?UTF-8?q?=E5=AF=B9=E5=BA=94=E7=99=BB=E8=AE=B0=E5=B7=A5=E5=85=B7=EF=BC=88?= =?UTF-8?q?P7=20=E5=AE=A1=E6=9F=A5=E4=BF=AE=E5=A4=8D=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 服务器说明 MCP_SERVER_INSTRUCTIONS 的免确认例外是泛称「不含秘密的开发需求元数据」, register_project_test_account 与 register_project_dev_variable 都属于;skill 新增的 通用边界括注只列了前者,开发变量登记会被误读为须用户确认的「其他写操作」。同源旧 问题:skill 第 8 条把「开发变量(沙箱 key 等)」也只指向 register_project_test_account。 - skill 例外括注同时列出两个登记工具 - 第 8 条拆分:测试账号用 register_project_test_account 登记名称、目标系统、非生产 环境与用途;开发变量用 register_project_dev_variable 登记名称与用途 - base-onboarding 1.8.0 尚未发布,不再升版本,仅更新 TEMPLATE_FINGERPRINTS 摘要 - server_instruction_universal_rules_are_in_skill 加断言:服务器说明含「开发需求元 数据」,skill 写操作确认规则所在行同时含该泛称与两个登记工具名 - 蓝图 P7 known_limits 把「措辞与服务器说明一致」精确为「两条规则核心句逐字一致」, 并记录本次例外与第 8 条的修正 测试:cargo test --locked 全量通过(lib 273 passed / 5 ignored,0 failed)。 Co-Authored-By: Claude Opus 5.5 --- .blueprint/modules/agent-client-parity.md | 2 +- .../.agents/skills/lian-jing/SKILL.md | 4 ++-- src-tauri/src/commands/onboarding.rs | 2 +- src-tauri/src/mcp_server.rs | 17 +++++++++++++++++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.blueprint/modules/agent-client-parity.md b/.blueprint/modules/agent-client-parity.md index d6aaf99..ef7c3a4 100644 --- a/.blueprint/modules/agent-client-parity.md +++ b/.blueprint/modules/agent-client-parity.md @@ -146,7 +146,7 @@ skill 只是五个接入面之一,兼容层覆盖全部五面。 ③ DSH(桌面版内置运行时 headless;--patch 叠加层停用用户已有的三个 MCP 条目、插入指向桩服务的 dsh-mcp-client 条目,用户 ~/.dsh 与 DSH_HOME 均未改):支持。实验组答出 LJ-P7-B0628021BF,思考过程原样复述了说明全文;对照组答 NONE;实验组输入 token 多 53(6487 对 6434)。DSH 在 initialize 前先发 server/discover,桩服务与炼境一样回 -32601,DSH 随即回退到 initialize → tools/list;其 mcp-client 配置有 maxInstructionBytes(默认 32768)。 探针脚本、桩服务与原始日志留在本机 %TEMP%\lj-p7-probe(未入库,P4 固化时可参考)。" - known_limits: "Claude 与 DSH 只验了无头模式,Claude 只用了 sonnet-4-6;Codex 未验 TUI 与桌面版(桌面版可能走 app-server 路径,结论可能不同),也未验 SSE 传输。探针用的是桩服务的中英混合短说明,未用炼境真实说明(中文 238 字、UTF-8 500 字节,远低于 DSH 默认上限 32768 字节)实测。Codex 后续版本若开始带入服务器说明,按「检测行为而非嗅探版本」重跑本探针(P4 固化后纳入矩阵),三端都支持时再迁移。现有服务器说明五条要点中,「先读状态」「canonical project_id」「开发变量先查后登记」在 skill 有对应条目;「其他写操作须用户明确确认」与「unavailable/unknown 不得当作成功」在 skill 与 AGENTS.md 中只有分场景表述(合并 PR、CI workflow、工具链安装;MCP 不可用时不伪造诊断),Codex 会话只能从这些条目与工具描述获知——是否补成通用条目留待下次改 skill 时一并处理(需升接入包版本),本卡不改。 - 已补齐(2026-10-03,分支 feat/agent-client-parity-p7-skill-rules):两条已作为通用边界写进 lian-jing skill 模板开头(双投影到 .agents 与 .claude),措辞与服务器说明一致;只读查询、登记开发需求元数据与回传炼境明确列为无需确认的例外,与服务器说明的「其他写操作」及 skill「回传不必逐条征得同意」相容。接入包 base-onboarding 1.7.0→1.8.0;mcp_server 新增 server_instruction_universal_rules_are_in_skill,服务器说明与 skill 任一侧缺这两条即失败。AGENTS.md 托管块未改,仍只有分场景表述;存量项目需重建安装炼境后重跑 apply_onboarding_pack 才拿到新 skill。" + 已补齐(2026-10-03,分支 feat/agent-client-parity-p7-skill-rules):两条已作为通用边界写进 lian-jing skill 模板开头(双投影到 .agents 与 .claude),两条规则的核心句与服务器说明逐字一致;只读查询、登记开发需求元数据与回传炼境明确列为无需确认的例外,与服务器说明的「其他写操作」及 skill「回传不必逐条征得同意」相容。服务器说明的例外是泛称「不含秘密的开发需求元数据」,skill 例外括注同时列出两个登记工具 register_project_test_account 与 register_project_dev_variable(审查修复:初版只列前者,会把开发变量登记误归入须确认的写操作);同批修正 skill 第 8 条——开发变量改用 register_project_dev_variable 登记名称与用途,测试账号仍用 register_project_test_account(初版两者都指向后者)。接入包 base-onboarding 1.7.0→1.8.0(修复在 1.8.0 发布前,未再升版本,只更新指纹);mcp_server 新增 server_instruction_universal_rules_are_in_skill,服务器说明与 skill 任一侧缺这两条即失败,skill 例外行缺任一登记工具也失败。AGENTS.md 托管块未改,仍只有分场景表述;存量项目需重建安装炼境后重跑 apply_onboarding_pack 才拿到新 skill。" ### 📋 P8 — 一键接入:创建/添加子项目即完成三端可用 - status: todo diff --git a/src-tauri/resources/onboarding/.agents/skills/lian-jing/SKILL.md b/src-tauri/resources/onboarding/.agents/skills/lian-jing/SKILL.md index 38d96f4..680931a 100644 --- a/src-tauri/resources/onboarding/.agents/skills/lian-jing/SKILL.md +++ b/src-tauri/resources/onboarding/.agents/skills/lian-jing/SKILL.md @@ -9,7 +9,7 @@ description: 读取炼境项目健康状态,并使用炼境 MCP 的项目管 如果当前客户端已发现 `lian-jing` MCP,所有调用都遵守两条通用边界(与炼境 MCP 服务器说明一致): -- 只读查询、登记不含秘密的开发需求元数据(`register_project_test_account`)与回传炼境(`report_envoy_return`)可直接调用;其他写操作仅在用户明确确认目标与影响后调用,下文安装工具链、合并 PR、生成 CI workflow 是它的具体场景。 +- 只读查询、登记不含秘密的开发需求元数据(`register_project_test_account`、`register_project_dev_variable`)与回传炼境(`report_envoy_return`)可直接调用;其他写操作仅在用户明确确认目标与影响后调用,下文安装工具链、合并 PR、生成 CI workflow 是它的具体场景。 - 状态 `unavailable` / `unknown` 不得当作成功:如实报告实际状态,不据此宣称完成。 具体用法: @@ -21,7 +21,7 @@ description: 读取炼境项目健康状态,并使用炼境 MCP 的项目管 5. 交付、Gitea、CI、蓝图等平台状态优先通过 MCP 查询,不凭静态文档猜测。 6. 合并 PR 前调用 `get_delivery_status(project_id)`,向用户展示 PR 编号、完整 head SHA、CI 与 review。只有当前用户明确确认该 PR 与 SHA 后,才调用 `merge_pull_request(project_id, pr_number, expected_head_sha, confirmed=true)`;合并后再次读取交付状态。不得自行推断确认。 7. 生成 CI workflow 时先调用 `plan_cicd_workflow(project_id, workflow_type)`,向用户展示目标文件、变更类型、`content_digest`、工具链来源与所需 secret 名称;只有用户明确确认这份摘要后,才以同一 digest 调用 `apply_cicd_workflow(..., confirmed=true)`。该流程只写项目 workflow,不配置 secret、不触发 CI 或部署;不得通过 MCP 传服务器地址、命令、路径或 secret 值,部署类配置先由用户在炼境 UI 保存。 -8. 需要测试账号或开发变量(登录自验、沙箱 key 等)时,先调用 `list_project_dev_variables` 查找:已配置则用 `read_project_test_account` / `read_project_dev_variable` 单项读取;没有则用 `register_project_test_account` 登记名称、目标系统、非生产环境与用途,并请用户在炼境项目 UI「开发变量」中填写。不得在对话中向用户索要明文密码,不得登记生产账号,不得把读到的值写入受 Git 跟踪的文件。读取因缺少项目认证被拒时,如实报告并改用项目原有配置方式,不得绕过认证。若 lian-jing 工具中根本没有 `list_project_dev_variables`,说明当前客户端连的是全局地址 `/mcp` 而非本项目地址,按下方 `configured` 一步处理。 +8. 需要测试账号或开发变量(登录自验、沙箱 key 等)时,先调用 `list_project_dev_variables` 查找:已配置则用 `read_project_test_account` / `read_project_dev_variable` 单项读取;没有则先登记需求——测试账号用 `register_project_test_account` 登记名称、目标系统、非生产环境与用途,开发变量用 `register_project_dev_variable` 登记名称与用途——再请用户在炼境项目 UI「开发变量」中填写。不得在对话中向用户索要明文密码,不得登记生产账号,不得把读到的值写入受 Git 跟踪的文件。读取因缺少项目认证被拒时,如实报告并改用项目原有配置方式,不得绕过认证。若 lian-jing 工具中根本没有 `list_project_dev_variables`,说明当前客户端连的是全局地址 `/mcp` 而非本项目地址,按下方 `configured` 一步处理。 9. 遇到体系级摩擦时,按下方「遇到摩擦时回传炼境」调用 `report_envoy_return`。 ## 遇到摩擦时回传炼境 diff --git a/src-tauri/src/commands/onboarding.rs b/src-tauri/src/commands/onboarding.rs index 0043ba2..462bca2 100644 --- a/src-tauri/src/commands/onboarding.rs +++ b/src-tauri/src/commands/onboarding.rs @@ -1948,7 +1948,7 @@ mod tests { ( "resources/onboarding/**", "1.8.0", - "68846285b70344cfdf6c364fba112c28cbaa042f64358a91b872a601336b27ff", + "fac04a0bd9f3a443349fdd50d6eef22147c56d0843e1769a60b9bbddc372d091", ), ( "AGENTS.md.tmpl#ONBOARDING_MANAGED", diff --git a/src-tauri/src/mcp_server.rs b/src-tauri/src/mcp_server.rs index 8e04ab6..cb62762 100644 --- a/src-tauri/src/mcp_server.rs +++ b/src-tauri/src/mcp_server.rs @@ -550,6 +550,23 @@ mod tests { ); assert!(skill.contains(phrase), "lian-jing skill 缺少「{phrase}」"); } + // 服务器说明的免确认例外是泛称「开发需求元数据」,两个登记工具都属于; + // skill 的例外括注须同时列出两者,否则开发变量登记会被误归入「其他写操作」。 + assert!(MCP_SERVER_INSTRUCTIONS.contains("开发需求元数据")); + let exception = skill + .lines() + .find(|line| line.contains("其他写操作仅在用户明确确认目标与影响后调用")) + .expect("lian-jing skill 缺少写操作确认规则"); + for term in [ + "开发需求元数据", + "register_project_test_account", + "register_project_dev_variable", + ] { + assert!( + exception.contains(term), + "lian-jing skill 免确认例外缺少「{term}」" + ); + } } #[tokio::test]