dev-manager-tauri/AGENTS.md
lanrtop d1b9b0564e
All checks were successful
Push & PR Check / check (push) Successful in 1m2s
Push & PR Check / check (pull_request) Successful in 59s
feat(onboard/parity): 客户端适配器注册表与三端结构化注入结果,onboard 模块投影无关适应度测试(P8b、A1a)
一键接入(P8)编排前置:Claude local 与 DSH 托管块的成败原来只写日志,inject_mcp
笼统回「已配置 Codex 与 Claude」,失败会被报成成功(R4)。

- 新增 src-tauri/src/onboard/:ClientId、ClientOutcome(converged/applied/refreshed/
  removed/manual_kept/other_project/not_installed/skipped/missing/unavailable/
  needs_human/failed)、ClientAdapter(detect/static_status/apply)与 registry();
  适应度测试 onboard_module_is_projection_free 机器校验本体不依赖投影层
- 三端适配器实现在 mcp_inject,注册表反向接入;注入经 registry() 逐端 apply,
  新增 inject_project_mcp_report,inject_project_mcp 签名与「Codex 失败即整体失败」
  语义不变
- sync_claude_local / ensure_dsh_patch 抽出依赖注入版,每条分支返回结构化结果,
  日志类别与文案不变;upsert_codex_mcp_config 返回 converged/applied/manual_kept
- verify_onboarding(MCP)附加 clients 只读三端状态,不计入 checks、不影响 pass;
  inject_mcp 回执逐端列出实际结果
- 行为变化(有意):Codex 手写同名 server 改记 manual_kept 不再阻断 Claude/DSH;
  WSL 项目 Claude local 记 skipped 不再起 CLI
- 新增 9 条测试(假 CLI 覆盖 Claude 全部分支、临时 DSH 目录四态);cargo test
  295 passed;契约同步 project-context.yaml,AGENTS.md 架构速查补 onboard/

Feature-Confirmed: true
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 08:25:04 +09:00

21 KiB
Raw Blame History

炼境 — AI Agent 上下文

本文件遵循 AGENTS.md 开放规范,供 Claude Code、Qwen Code、Cursor、Copilot 等 AI 工具读取。

项目定位

炼境是 agent 开发子项目的管家:agent(Claude、Codex、DeepSeek 等)在哪里反复摩擦,管家就把那项能力沉淀并结构化为跨 agent 可调用的通用能力,让 agent 拿到任务即能开工、能自验、能交付。 分工:agent 负责推理、编码、模型与子 Agent 调度;炼境负责项目身份、环境就绪、验证资源、任务上下文与证据采集;子项目保留业务规则、spec、测试、部署链路与生产凭证,离开炼境仍可独立开发。 成长方式是摩擦驱动闭环:摩擦信号(envoy 回传、复盘、人工解围、返工)→ 准入筛选 → 结构化为 MCP 工具 / 能力包 / 分发基线 → 在成熟子项目实测收益 → 保留、调整或撤销。准入与边界见下方「管家准入与退出」。 炼境本身亦被纳入其中,形成可自我进化的开发智能闭环。

技术栈

  • 前端:React 19 + TypeScript + TailwindCSS + React Query + Zustand + React Flow
  • 后端:Rust + Tauri v2 + SQLite(rusqlite + r2d2)
  • MCP Server:内嵌于 Tauri 进程(HTTP),供 Codex、Claude 等客户端 adapter 调用炼境数据
  • 包管理:pnpm(禁止 npm/yarn/npx/bun)

炼境特有开发约束

通用约束(pnpm / TS 规范 / 需求对齐协议)见下方 ONBOARDING_MANAGED 块——单一事实来源,勿在此复抄。

Rust 业务函数:禁止在函数内部调用 pool().get(),连接由调用方传入(依赖注入,便于 in-memory DB 测试)。Tauri command 层负责获取连接并调用(薄包装,无需测试)。

架构速查

src/lib/commands.ts              所有 Tauri command 的前端封装(唯一调用入口)
src-tauri/src/commands/          Rust 后端实现(每功能一个 .rs 文件)
src-tauri/src/db.rs              SQLite 建表 + migration 逻辑
src-tauri/src/credential_store.rs Windows 本机受保护凭证存储与旧值兼容迁移(SQLite 仅保存引用)
src-tauri/src/mcp_server.rs      MCP Server 路由层 + SSE 协议(agent 调用炼境的入口)
src-tauri/src/mcp_tools.rs       MCP 工具 schema + dispatch + 实现(工具清单以 tools_list_result 为准)
src-tauri/src/envoy.rs           使者回传本体(三端回传写入、处置回执、待处置列表;连接由调用方注入)
src-tauri/src/mcp_webhook.rs     Gitea webhook 处理(push/PR 事件写入飞轮)
src-tauri/src/mcp_inject.rs      接入注入与三端适配(canonical context、Codex 项目配置、Claude local 条目、DSH 托管块、%USERPROFILE%\.lian-jing\bin 稳定 helper 入口)
src-tauri/src/onboard/           一键接入本体(客户端适配器注册表与结构化结果;不依赖 Tauri、不直接取连接池,适应度测试机器校验)
src-tauri/resources/onboarding/  接入包分发模板(AGENTS.md/lefthook/git-workflow)
.blueprint/                      项目蓝图(manifest + 模块详情 + 任务卡)
docs/ai-context/                 AI 上下文文档(速查卡、契约映射)
docs/templates/                  炼境接入包模板草案(设计层)

关键约定

  1. 新增 Tauri command → 必须同步更新 src/lib/commands.ts,否则前端无法调用
  2. SQLite 新增表或字段 → 必须在 db.rs 的 migrate() 里补 migration 语句,否则旧版本升级后启动报错
  3. 修改接入包模板(resources/onboarding/)→ 检查 docs/templates/agents-meta-rules.md 是否需要同步

Agent 友好工程四支柱

修改代码前,确认这个项目满足四支柱:

可导航:凭文件名/目录名可在 30 秒内定位某功能的代码。通用能力有独立家,不寄生在业务模块下。

可推理:公共类型只在一处定义。改一个接口,类型检查能报出所有受影响处。

可验证:typecheck / lint / test 各有一条命令真能跑。关键路径有冒烟测试。

可记忆:规则按场景注入(不是一份巨型文档)。决策只写"为什么",代码自己回答"是什么"。


文档防腐元规则

做任何改动时,判断它属于哪类变更:

T1 外部契约变更(最高优先级)

其他代码、服务、或 agent 依赖的定义——Tauri command 接口、MCP 接口、数据库 schema、共享类型。 → 查 docs/ai-context/project-context.yaml 找到对应文档,检查并同步更新。

T2 架构边界变更

模块划分、目录结构、依赖方向、命令分组变化。 → 检查本文件架构速查和 docs/ai-context/project-brief.md 是否需要同步。

T3 工具链变更

引入或替换库、Tauri 版本升级、Rust 依赖变更。 → 更新本文件技术栈声明;更新 docs/ai-context/project-context.yaml。

T4 常驻上下文过期

本文件(AGENTS.md)或 docs/ai-context/project-brief.md 描述的现实已经改变。 → 立即更新。这两份文档常驻 agent 上下文,过期危害最大。

不触发检查

内部重构、性能优化、bug fix(外部行为不变)、测试文件、UI 样式调整。


文档防腐铁律

  • 文档只写稳定的:为什么、铁律、意图、架构决策。
  • 易变的(端口、表名、命令清单)交给工具自省,不写死进常驻文档。
  • 单一事实来源:两处说同一事时,删掉派生的那处。
  • 两份文档打架时,信代码,不信文档。

定期防腐自查

  • 技术栈声明还和 package.json / Cargo.toml 一致吗?
  • project-brief.md 最近 30 天有没有随架构改动更新?
  • src/lib/commands.ts 的封装覆盖了所有 src-tauri/src/commands/ 下的 command 吗?
  • 接入包模板(resources/onboarding/)和 docs/templates/ 内容一致吗?

项目蓝图

本项目使用 .blueprint/ 目录维护项目全景架构图,驱动需求讨论和任务管理。 本节适用于任何 AI 编程工具(Claude / Qwen / Cursor / Copilot 等)。

对话开始时必须执行

  1. 读取 .blueprint/manifest.yaml 了解项目全景和当前状态
  2. 读取 .blueprint/CONVENTIONS.md 了解完整工作流规则

需求讨论 → 蓝图同步规则

用户说的 AI 应做的
"我想加个 XX 功能" 确认需求后:manifest 新增模块(status: concept),创建 .blueprint/modules/<id>.md
"XX 功能需要 A、B、C" 在模块文件中拆分为任务卡
"这个方案确定了" 模块 status → planned,补充任务卡 files/acceptance
"开始做 XX" 模块 status → in_progress
没提蓝图但在讨论功能 主动提议更新蓝图

复杂度决策(讨论新功能 / 拆解需求时)

complexity 执行流程
S / M 直接拆任务卡,确保每张卡有 files + acceptance + complexity → 标记 📋
L(复杂系统设计) 先做架构设计(Claude 用 /architect 技能,其他工具按 CONVENTIONS「复杂功能分析流程」章节执行)输出设计文档,用户确认后拆成 S/M 任务卡

L 级任务禁止直接写代码,必须先经过 架构设计 → 任务拆解 流程。

任务执行两阶段提交

  • 开始写代码前:任务卡前缀改为 🔵,status → in_progress
  • 完成验收后:任务卡前缀改为 ✅,status → done,更新 manifest updated 日期

完整规则(迭代管理、阻塞处理、复盘笔记等)详见 .blueprint/CONVENTIONS.md。

⚠️ 本块由炼境版本化托管,升级时整块原位覆盖——项目定制请写到块外,块内手改必丢(2026-07-15 炼境自身实锤丢失 5 段定制后新增本警示)。

核心开发约束

包管理

  • pnpm 唯一:禁止 npm / yarn / npx / bun
  • lock 文件只有 pnpm-lock.yaml,不生成其他

代码规范

  • TypeScript 优先,避免 any
  • 函数/变量 camelCase;组件 PascalCase
  • 异步统一 async/await,不用裸 Promise 链
  • 错误处理明确 try/catch,不吞异常
  • 优先编辑现有文件,避免创建不必要的新文件
  • Playwright 版本固定:package.json 里的 playwright 锁死版本号,去掉 ^; 另建 test:install 脚本显式安装浏览器(playwright install --with-deps), 升级时有意识操作,避免 pnpm install 静默触发 ~200MB 的浏览器重下

需求对齐协议

开始写代码前,先判断改动类型:

Bug Fix(当前行为与预期的意外偏差) → 建任务卡,直接执行,无需等确认词。

Feature / 行为变更(新增能力或主动改变已有行为) → 必须先输出确认卡,等用户说「确认」再动手:

  • S 级(单文件、行为对外无变化,任务卡 complexity=S):输出三行轻量卡
    改哪:<文件或模块>
    改什么:<一句话>
    验收:<agent_verify 路径>
    
  • M / L 级:输出完整任务卡(含 files + acceptance + complexity),等确认

边界模糊时:保守判断,按 Feature 处理,走完整确认卡。

提交时:feat: 提交须在 commit message 末尾加 Feature-Confirmed: true trailer(lefthook commit-msg 强制检查)。这是确认卡已输出的机器层存证。

⚠️ Session 结束汇总补录 ≠ 确认卡替代——补录仅适用于漂移检测触发后用户主动选择补录的场景,不得作为「先做再补」的通道。

Git 工作流

见 docs/ai-context/git-workflow.md(分支策略 + Conventional Commits + Rules-Applied trailer + PR 规范)。 commit 必须符合 Conventional Commits(lefthook 强制),炼境据此采集飞轮数据。

炼境项目上下文与能力包

  • .lian-jing/context.json 是项目 project_id 的工具无关单一事实来源;不要从客户端项目 UI、用户级插件或全局配置推断项目身份。
  • .claude/liangjing.json 只是旧项目的 Claude 兼容投影。只发现它时,调用 inject_mcp(project_id) 迁移,而不是手工复制或猜测 ID。
  • .lian-jing/capability-packs.json 记录炼境托管基线的版本。verify_onboarding(project_id) 报告 legacy、version_mismatch 等状态时,按其 detail 中的升级提示处理。
  • apply_onboarding_pack(project_id) 只更新炼境明确托管的接入包文件;项目自己的业务规则、测试、部署声明和手工定义的同名 MCP server 仍归项目所有,不能被升级覆盖。
  • 遇到炼境分发的模板、约定或 MCP 工具的摩擦,或验证出跨项目可复用的实践时,调用 report_envoy_return 回传炼境(只追加信号,不必逐条征得用户同意;Claude 会话结束时也可跑 /envoy);何时回传、字段怎么填见 lian-jing skill「遇到摩擦时回传炼境」一节。

Node/pnpm 工具链

  • Node 精确版本以 .nvmrc 为事实源,pnpm 精确版本以 package.json#packageManager 为事实源;不要追随 IDE、Codex 或全局 PATH 的 bundled runtime。
  • Node+pnpm 项目由炼境分发最小 mise.toml,只启用上述标准声明,不重复保存版本;已有手写 mise.toml 永不覆盖。
  • 开始运行 pnpm 命令前调用 get_toolchain_status(project_id)。返回 ready_managed 时使用 mise exec -- pnpm ...;mismatch/conflict/unavailable 时先报告证据。
  • prepare_toolchain(project_id, confirmed=true) 会下载/安装项目声明版本,只有用户明确确认本次机器状态变更后才能调用;不得为消除告警而修改项目版本或 lockfile。

agent 按钮与验证路径

功能的本体是代码层的能力;UI 按钮是它给人的投影,agent 按钮是给 agent 的投影 (可发现 + 可调用 + 有边界的能力声明)。任何功能 = 一个本体 + 两个投影,同源同边界; 设计交付时先定本体后盖投影(原型探索不受此序约束,交付前本体归位)。开发任何功能时遵守:

  1. 边界单点实现:业务校验只写在能力本体层(API/command),UI 只呈现不复制逻辑—— 否则人与 agent 的验证路径会分裂。同源的直接推论:人的操作序列 agent 皆可复刻—— 人报障即复现路径(操作 + 状态),agent 重放至同一状态定位病灶。 三分定位启发式:本体重放正常 → 优先怀疑投影层(接线/渲染/状态同步)→ 再查环境差异 (安全上下文/网络/OS);重放失败先怀疑初始状态差异,而非否定问题存在

  2. 载体就近选择(本项目的 agent 按钮是什么,按项目类型对号入座):

    项目类型 agent 按钮载体
    Web 服务 HTTP API 本身(前端按钮与 curl 调同一 endpoint,天然双投影)
    CLI/脚本 命令与 npm scripts
    桌面应用 测试直接调用 command 函数
    UI 呈现层 Playwright 驱动真界面(最后手段,仅关键路径)
  3. 完成的定义:功能实现后,由 agent 沿投影路径真实走通一次(起服务 → 调接口 → 断言行为),再交人做 UI 终验——不许绕过功能手改产物冒充验证

  4. 侦察 → 驻军:agent 走通的关键路径,顺手固化为一条测试(桌面应用用 cargo test;Web 项目纯逻辑层用 vitest); 一次性验收不固化(少而稳 > 多而脆)

  5. acceptance 可执行化:/splitter 生成任务卡时,acceptance 字段必须是可执行验证路径, 格式:[载体] 调用/运行什么(参数) → 断言什么。

    • 正例:[Tauri command] apply_onboarding_pack(project_id) → written≥1,文件在磁盘存在
    • 正例:[HTTP API] POST /api/users → 201,body.id 非空
    • 反例:功能正常可用(模糊,agent 无法自验)

    分层原则:凡含 UI 操作路径的 acceptance,必须拆成两段:

    • agent_verify: — 机器可断言(HTTP 状态码、数据库记录、函数返回值);stop hook / CI 只验此段
    • human_verify: — 需人眼判断(视觉效果、拖拽手势、30 秒浏览器终验) 纯 API / 命令行任务可省略 human_verify:;UI 拖拽 / 动画 / 视觉类必须拆,否则 stop hook 无法收敛。 human_verify 的否决理由值得记录——它是把体感转译成可断言规则的原料。
  6. 自验报告纪律:交人终验前的反馈必须含「没验什么」一节(未覆盖的路径、依赖的 假设、不确定的地方);自修过程中改了断言/验收标准必须显式声明理由(改功能让测试过是 常规,改测试让功能过需报备);agent 自验对 acceptance,人终验对意图——acceptance 可能继承需求理解偏差,两把尺子不可合一

收束:本体先行,边界一次,操作同语——人指的问题 agent 走得到,人在意的点 agent 读得懂。 后半句分两个时间尺度:当下会话由同源路径即时对称(反馈天然绑定双方走过的路径); 跨会话靠否决理由落账(→ 复盘笔记)积累,人反复在意的维度逐步迁移进可断言规则—— 人裁决区是飞轮推进的前线,不是墙上的洞。

多 AI CLI 协作

本项目可由多个 AI CLI 协同。交接时把结果总结成 3 条传给下一个:

1. 已完成:<改了哪些文件 + 核心决策>
2. 待验证:<需要确认的地方>
3. 约束继承:<影响后续的关键限制>

炼境自身约定(块外区——托管块升级不会触碰本节)

⚠️ 教训(2026-07-15):本地定制严禁写进 MANAGED 块内——块会被版本升级原位覆盖。 本节内容曾因写在块内被 v1.6.0 升级抹掉,现恢复至块外。

炼境自身的分支策略

块内 git-workflow 是分发给子项目的通用策略;炼境自身按下表执行。

任务复杂度 分支策略
S(简单增删改) 直接 push master,不开分支
M(中等逻辑) 开 feat/<blueprint-module-id> 分支,完成后 PR → master
L(复杂系统) 开 feat/<blueprint-module-id> 分支,必须走 PR + CI 验证

分支命名:直接对应蓝图模块 ID,如 feat/manage-multi-view;同名旧分支已存在时加卡号后缀(如 feat/onboarding-pack-u1)。

为什么 M/L 要开分支:

  • PR body 是 agent 自验报告的归宿,飞轮从中采集结构化数据(PR 事件比 push 事件包含更多意图信息)
  • feat/* 分支触发 PR CI,是 agent 自验链条的最后一环(本地 typecheck → PR CI → 人终验)
  • 炼境推荐子项目走 PR 工作流,自身也应遵守同一套规范

分工原则

人定目标 → agent 执行 → agent 自验(走 agent 按钮)→ 人终验。 人只保留两件事:需求澄清(目标定义权) 和 目标验收(终验权)。 完整体系设计见 docs/ai-context/agent-button-system.md。

炼境设计红线与本机事实(2026-09-11 自 Claude 私有记忆回流,任何 agent 均须遵守)

  • 炼境 = 信号采集层,不是评判层:炼境只采集与呈现信号(git 提交自动标 🔵), 任务状态的语义评判归 agent(读过代码才能标 ✅/🔴),用户只做方向决策。 凡「让用户手动改任务状态」的功能需求一律拒绝或撤销(2026-06 用户立法)。
  • MCP URL 一律写 127.0.0.1,禁用 localhost:Windows 11 将 localhost 解析为 ::1(IPv6),炼境服务只绑 IPv4,用 localhost 必连接失败。
  • 未提交改动处置:动手提交前发现目标文件带有先前遗留的未提交改动 → 先确认归属 (完整功能则独立提交;废弃则丢弃),禁止字符串手术做选择性暂存; 验证命令独立成步执行,不与提交串进一条复合命令(管道会吃退出码)。
  • commit message 强制是双层的(炼境自身):本地 lefthook + CI pr-check.yml 校验步 (.gitea/scripts/check-commit-msg.mjs)。lefthook 在 agent 沙箱内可能静默失效,CI 才是兜底; 注意 master 直推场景 CI 是事后红灯(提交已落库,红灯提醒修复),仅 PR 流程构成事前拦截—— 这是与「S 级直推 master」约定的有意权衡,勿以「加分支保护禁直推」名义收紧。

管家准入与退出(2026-09-30 用户立法)

  • 准入:新能力须同时满足五条才沉淀进炼境——通用(多个子项目会遇到)、可结构化(能成为 schema / MCP 工具,agent 可查询可断言)、跨 agent(同一入口,不绑某家客户端)、与 agent 原生能力 互补(不与其调度、子 Agent、模型选择竞争)、消除重复(每个项目/会话都要重做的配置或摸索)。
  • 不做:不替 agent 思考或选模型;不替 agent 判定完成;不接管子项目自有事实;不让子项目依赖炼境在线。
  • 分发 vs 查询:需随分支走、离线必读、客户端启动即读的稳定基线才写进子项目(版本化能力包 + 托管块,先预览再单项目 apply);易变、跨项目、含敏感、可重建的内容一律走 MCP 按需查询。凭据值永不进项目 Git。 进入 agent 上下文仅限 project-dev-variables 的有界例外(非生产、低权限、可重置,经项目级认证单项读取); 能不经手就不经手——优先写入经 git check-ignore 确认被忽略的本地文件,由项目自有脚本消费。
  • 退出:实测无收益、被 agent 原生能力覆盖、或维护成本超过收益的能力要撤销,不因「已经做了」而保留。
  • 为什么:管家的价值是给 agent 减负,一旦越权或膨胀,就会变成新的摩擦来源;能力是否留下要看实测数据, 验证场优先用最成熟的子项目 enterprise-system。

炼境自己的 Agent 按钮清单

能力 调用方式 通过标准
TypeScript 类型检查 pnpm typecheck 无输出,exit 0
Rust 单元测试 cargo test(src-tauri/ 目录) 无 FAILED
MCP 工具调用 见 src-tauri/src/mcp_tools.rs 工具列表 返回 JSON,无 error 字段
蓝图状态读取 读 .blueprint/manifest.yaml 文件可解析,字段完整
蓝图状态更新 编辑 .blueprint/modules/<id>.md 文件写入成功,格式合法

自验失败降级约定

  • 失败 2 次内:自行修正,继续自验
  • 失败 3 次:停止执行,输出以下内容后等待人工介入:
    1. 失败原因(具体报错或不通过的断言)
    2. 已尝试的修正路径
    3. 需要人决策的具体问题