fix(physics67): prevent agent escape to repo root + gitignore defense
审计发现 (用户提问 "项目有些文件夹代码是智能体运行非法写入的请审计"):
03_analysis/hermitian_review_section.md — 写到 repo 根 (应在 workspace)
nh_qgt/cycle_1/00_plan/research_plan.md — 同上
nh_qgt/cycle_1/models/nrssh.py — 同上
physics67 跑了两次, 都从 workspace 边界逃逸到了 main 仓库根。
内容是真实物理研究 (NR-SSH / Hatano-Nelson / 非厄米 QGT) — 已外部备份后
本 commit 之前 `rm -rf 03_analysis/ nh_qgt/` 清除。
## 根因 1 — orchestrator.yml base_workspace fallback 没强制绝对路径
line 56 原文 (instruction-style):
"如果用户未给出, 使用当前项目下 `physics_runs/{安全化标题}`"
问题: relative path + cwd=repo_root → 直接落在 repo 主仓库。
实测: 模型连 `physics_runs/` 前缀都没用 (生成的 base_workspace =
"nh_qgt"), `cycle_1` 拼上去就是 `./nh_qgt/cycle_1`。
Fix: 明确要求"绝对路径以 / 开头"为铁律, 并指示当用户未给 base_workspace
时, 必须先调用 Bash 工具 `echo "$HOME/physics_runs/{title}"` 拿到绝对
路径再用。加 self-check 段: 调用任何 sub-agent 前自检 input.workspace
开头是否 `/`。
## 根因 2 — sub-agent 用 `cd {workspace} && python3 STAGE/x.py`
analyst.yml:39, simulator.yml:36 原文:
`cd {workspace} && python3 03_analysis/analyze_results.py`
`cd {workspace} && python3 02_sim/simulate_main.py`
问题: 当 {workspace} substitution 失败 (从 fromconfig 传过来的 input
没替换), `cd ` (空参) 在 macOS bash 里跑到 $HOME, 然后相对路径
`03_analysis/` 写到 $HOME 而不是 workspace。这次还更糟: 跑到了 cwd
= repo 根。
Fix: 全部改成绝对路径调用 `python3 {workspace}/STAGE/x.py`, 脚本内部
如需相对 IO 在第一行 `os.chdir("{workspace}")`。`writer.yml` 的
cd 仍保留 (LaTeX 编译需要 cwd), 但加 `test -d "{workspace}/04_paper"
|| exit 1` 守门。
## 防御 — .gitignore
即使未来 LLM 又生成 escape 路径, 这些 pattern 拦下 repo 根的:
/physics_runs/ # legitimate fallback
/cycle_[0-9]*/ # base_workspace/cycle_N rooted at /
/_gates/ # gate 输出
/0[0-9]_{plan,lit,sim,analysis,paper,review}/ # stage 子目录
实测确认 `git check-ignore` 命中。注意: pattern 必须独占行, 不能写
inline comment (`/foo/ # comment` 会把整串当成 pattern) — 之前犯过
这个错。
## 不在本 commit 范围
- agentexample/physics67/agents/{reviewer,idea-planner,artifact-gate}.yml 也用了
`{workspace}/` 路径但没 cd-relative 模式, 不需要改。
- {workspace} substitution 本身在 fromconfig 端的失败模式 (为什么有时候
没替换) — 是 lambdagent 侧的真实 bug, 单独跟踪。
- audit 报告里其它 finding 不在本 commit 范围。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>