All checks were successful
Push & PR Check / check (push) Successful in 1m57s
- api-keys:按现状改为 Credential Manager 存储(R2/R3/R6 已完成) - manifest:补 project-resource-broker 两条依赖边 - notes-archive:补 R1 复盘 - blueprint-governance:指向 handoff-pilot 待议证据包 - docs/tasks:handoff-pilot(含蓝图规则并入能力包目标)+ dev-variables 落地增量提案 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
6.8 KiB
Markdown
61 lines
6.8 KiB
Markdown
# 测试账户落地到被忽略文件(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 模块后编号接续 V11)
|
||
|
||
- **V12 落地本体**(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 属另一仓库 / 账户未填写 → 拒绝且文件字节不变;返回与错误序列化不含账号密码。`
|
||
- **V13 MCP 投影**(M)— files: `src-tauri/src/mcp_tools.rs`;depends: V12
|
||
- acceptance: `agent_verify: [cargo test] tools/list 含 materialize_project_test_account,schema 要求 project_id;跨项目参数被 scope 拒绝;无认证调用可写入但响应只含变量名;仍无任何批量导出或 get_secret 工具。`
|
||
- **V14 Enterprise worktree 试点**(M)— files: `.blueprint/modules/project-dev-variables.md`, `docs/ai-context/project-context.yaml`, `docs/ai-context/agent-button-system.md`;depends: V13
|
||
- 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)的处置。
|