dev-manager-tauri/docs/tasks/2026-09-30-dev-variables-materialize.md
lanrtop 663a723b3b
All checks were successful
Push & PR Check / check (push) Successful in 1m5s
Push & PR Check / check (pull_request) Successful in 1m9s
feat(dev-variables): 修改时显式查看原值,并提示 agent 先查炼境测试账户
- V12:新增人用 Tauri command reveal_project_dev_variable(不进 MCP),
  点「修改」预填原账号与密码,密码默认遮罩可切换显示
- V13:lian-jing skill 新增第 8 步——需要测试账号先 list/read,
  没有则登记并请用户在 UI 填写;禁止对话索要明文;base-onboarding 升至 1.5.0
- 契约同步 project-context.yaml;materialize 提案顺延为 V14–V16

Feature-Confirmed: true
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 14:22:54 +09:00

61 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 测试账户落地到被忽略文件(project-dev-variables 增量)
> status: todo | complexity: L(拆为 3 张 M 卡)| created: 2026-09-30 | blueprint: project-dev-variables(该模块尚在 `feat/project-dev-variables` 分支,V7 blocked,未合入 master)
> ⚠️ 处置条款:本简报 done 后 24h 内删除;结论并入 `project-dev-variables` 模块的决策与任务卡,不让简报成为第二事实来源。
> 类型:Feature。开工前需用户确认本设计;且须等 `project-dev-variables` 合入 master 后在其模块内立卡。
## 为什么(压缩背景 + 证据)
- 依据 AGENTS.md「管家准入与退出」:agent 自验缺测试账号是高频摩擦。`project-dev-variables` 已解决「人填一次、炼境保管、agent 发现」——登记 `register_project_test_account`、存 Windows Credential Manager、经项目 bearer 认证由 `read_project_test_account` 单项取明文(有界例外:非生产、低权限、可重置)。
- 该模块自己留了口子:「不自动注入子进程环境、不写 `.env`;需要时另立任务」。本简报即那个任务。仍存在三处摩擦:
1. **项目脚本拿不到值**:Enterprise 已有 `apps/api/scripts/agent-auth.mjs`(读 `AGENT_USERNAME/AGENT_PASSWORD` 或仓库根 `.env.agent`)、Playwright `auth.setup.ts`(`E2E_USERNAME/E2E_PASSWORD`)。agent 从 MCP 读到明文后,还得自己 export 或写文件才能喂给脚本——明文在会话里转一手。
2. **Enterprise 沉淀的原则**(`docs/agent-dx-playbook.md` 坑 4):凭据不进 agent 上下文、读取下沉到脚本;全局 `deny Read(./.env.*)` 是刻意安全兜底。2026-09-30 实测炼境会话读 `.env.agent` 同样被拦。
3. **worktree 缺文件**:被 Git 忽略的 `.env.agent` 不随 `git worktree add` 出现,每个隔离工作区都要人工重建——与炼境推荐的隔离 worktree 试点直接冲突。
- 客户端兼容:`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 属另一仓库 / 账户未填写 → 拒绝且文件字节不变;返回与错误序列化不含账号密码。`
- **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 工具。`
- **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 成功的耗时。未达收益按「管家退出」规则撤销。
## 不做什么
- 不向 agent 返回值(取值仍只走已有的 `read_project_test_account` 有界例外);不提供通用 `export_env` / 命令代理 / 代为登录。
- 不接管 staging / production;不写入被 Git 跟踪的文件;不改项目脚本或统一变量名。
- 不宣称增强同一 Windows 用户下的进程隔离。
## 未验证 / 依赖的假设
- Enterprise 本地 API 能在隔离 worktree 中启动,未核实(端口冲突、依赖安装、数据库可达)。
- 其他客户端调用 scoped 写工具的审批行为,未验证。
- `project-dev-variables` 合入 master 的时间取决于其 V7(真实客户端审批 blocker)的处置。