All checks were successful
Push & PR Check / check (push) Successful in 1m2s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6.8 KiB
6.8 KiB
测试账户落地到被忽略文件(project-dev-variables 增量)
status: frozen(2026-10-04 MVP 收口期冻结为扩展,见统筹文档 §3)| complexity: L(拆为 3 张 M 卡)| created: 2026-09-30 | blueprint: project-dev-variables(模块已在 master;对应卡 V14–V16 为 📋) ⚠️ 处置条款:本简报 done 后 24h 内删除;结论并入
project-dev-variables模块的决策与任务卡,不让简报成为第二事实来源。 类型:Feature。解冻后开工前需用户确认本设计(卡已在模块内立为 V14–V16)。
为什么(压缩背景 + 证据)
- 依据 AGENTS.md「管家准入与退出」:agent 自验缺测试账号是高频摩擦。
project-dev-variables已解决「人填一次、炼境保管、agent 发现」——登记register_project_test_account、存 Windows Credential Manager、经项目 bearer 认证由read_project_test_account单项取明文(有界例外:非生产、低权限、可重置)。 - 该模块自己留了口子:「不自动注入子进程环境、不写
.env;需要时另立任务」。本简报即那个任务。仍存在三处摩擦:- 项目脚本拿不到值:Enterprise 已有
apps/api/scripts/agent-auth.mjs(读AGENT_USERNAME/AGENT_PASSWORD或仓库根.env.agent)、Playwrightauth.setup.ts(E2E_USERNAME/E2E_PASSWORD)。agent 从 MCP 读到明文后,还得自己 export 或写文件才能喂给脚本——明文在会话里转一手。 - Enterprise 沉淀的原则(
docs/agent-dx-playbook.md坑 4):凭据不进 agent 上下文、读取下沉到脚本;全局deny Read(./.env.*)是刻意安全兜底。2026-09-30 实测炼境会话读.env.agent同样被拦。 - worktree 缺文件:被 Git 忽略的
.env.agent不随git worktree add出现,每个隔离工作区都要人工重建——与炼境推荐的隔离 worktree 试点直接冲突。
- 项目脚本拿不到值:Enterprise 已有
- 客户端兼容:
read_project_test_account依赖 bearer helper,目前只在 Codex 验证过;其他客户端(Claude、DeepSeek harness)未验证。落地动作不返回值,可不依赖取值认证,天然跨 agent。
方案选择
| 方案 | 收益 | 代价 / 风险 | 结论 |
|---|---|---|---|
| 维持现状:agent 读明文再自行 export / 写文件 | 零开发 | 明文进会话;每个 worktree 重复;非 Codex 客户端无取值路径 | 保留为已有路径,不作首选 |
| 项目脚本经 helper 直接向炼境取值 | 值不落盘、不进会话 | 需改项目脚本并依赖炼境 CLI 契约;子项目对炼境产生运行期依赖 | 暂缓:v1 实测不够再考虑 |
materialize_project_test_account:炼境把已登记账户写入调用方指定、经 git check-ignore 确认被忽略的本地文件,只返回写入的变量名 |
复用项目现有脚本;worktree 一键补齐;值不进会话;不需要取值认证 | 值落本地磁盘(同现状 .env.agent 威胁模型);与 dev-variables「避免留在 .env」的初衷有张力 |
选定(v1) |
张力的处理:落地文件是可再生、可撤销的派生物,事实源仍是炼境。撤销账户后再调用即清除对应变量行;文件永不入 Git。
能力本体(v1)
materialize_project_test_account(project_id, name, target_file, username_var, password_var, worktree_path?)
- 调用方给出目标文件与变量名:agent 读项目脚本即可得知,例如 Enterprise
.env.agent+AGENT_USERNAME/AGENT_PASSWORD。v1 不新增项目声明文件;若同一项目反复重复参数,再考虑在项目 Git 中声明。 - 边界在本体层校验,fail closed:
worktree_path缺省为注册路径;给出时须与注册仓库共享git rev-parse --git-common-dir,否则拒绝;target_file规范化后必须在工作区内;git check-ignore必须确认被忽略,否则拒绝(防止入 Git);- 账户须已由人填写且为非生产类型;未配置时返回
missing; - 只替换这两个变量行,保留文件其他内容;幂等;账户已撤销时删除这两行;
- 返回值、错误文本、日志均不含账号或密码。
- MCP 投影走 scoped 路由,属写工具。客户端审批策略(参见 V7 blocker)按正常审批处理,不标注为只读来绕过。人的投影:
ProjectDevVariablesPanel可选加「写入工作区」按钮,属于 human_verify 范围,非 v1 必需。
任务卡草案(合入 dev-variables 模块后编号接续 V13;V12/V13 已被 UI 终验反馈占用)
- V14 落地本体(M)— files:
src-tauri/src/commands/dev_variables.rs,src/lib/commands.ts;depends: project-dev-variables 合入 master- acceptance:
agent_verify: [cargo test] 临时 git 仓库 + 模拟受保护存储:目标被忽略 → 仅两变量行写入、其他行保留、二次调用字节不变;撤销后调用 → 两行被删;目标未被忽略 / 越出工作区 / worktree 属另一仓库 / 账户未填写 → 拒绝且文件字节不变;返回与错误序列化不含账号密码。
- acceptance:
- V15 MCP 投影(M)— files:
src-tauri/src/mcp_tools.rs;depends: V14- acceptance:
agent_verify: [cargo test] tools/list 含 materialize_project_test_account,schema 要求 project_id;跨项目参数被 scope 拒绝;无认证调用可写入但响应只含变量名;仍无任何批量导出或 get_secret 工具。
- acceptance:
- V16 Enterprise worktree 试点(M)— files:
.blueprint/modules/project-dev-variables.md,docs/ai-context/project-context.yaml,docs/ai-context/agent-button-system.md;depends: V15- acceptance:
agent_verify: [CLI] Enterprise 新建隔离 worktree(无 .env.agent)→ [MCP] materialize_project_test_account(enterprise, <账户名>, ".env.agent", "AGENT_USERNAME", "AGENT_PASSWORD", worktree) → [CLI] 起本地 API 后 pnpm --silent --filter @enterprise-system/api agent:token exit 0 且 stdout 非空;git status 显示 .env.agent 未被跟踪;会话记录不含账号值。 human_verify: 在炼境登记一次后,agent 在新 worktree 中无需向人索要账号。- 度量:人工传递账号次数(目标 0)、新 worktree 就绪到首次 agent:token 成功的耗时。未达收益按「管家退出」规则撤销。
- acceptance:
不做什么
- 不向 agent 返回值(取值仍只走已有的
read_project_test_account有界例外);不提供通用export_env/ 命令代理 / 代为登录。 - 不接管 staging / production;不写入被 Git 跟踪的文件;不改项目脚本或统一变量名。
- 不宣称增强同一 Windows 用户下的进程隔离。
未验证 / 依赖的假设
- Enterprise 本地 API 能在隔离 worktree 中启动,未核实(端口冲突、依赖安装、数据库可达)。
- 其他客户端调用 scoped 写工具的审批行为,未验证。
project-dev-variables合入 master 的时间取决于其 V7(真实客户端审批 blocker)的处置。