v0.3.1 首个增量:工作区发布与清理安全¶
历史增量说明。 本文记录 v0.3.1 开发阶段的发布安全增量,不代表当前 v0.5.0 状态。当前 finish、锁、TaskSpec/EvidencePack 与发布边界见架构说明和v0.5.0 发布说明。
状态:独立候选补丁,不代表整个 v0.3.1 已发布。
基线:main / e8cc48ec7c98a5567f06466d8f12f3283c645452。
修复的问题¶
旧 pushed: true 只表示曾经推送,不能证明当前 HEAD 已发布。
此前执行「提交 A → 推送 A → 提交 B → cleanup」可能移除 B 的
worktree、本地分支和工作区记录,而远端只有 A。
恢复远端分支时,旧实现也可能删除含有未发布提交的遗留本地分支。
新的行为¶
- 默认 cleanup 遇到 dirty worktree 仍拒绝;有 base 之外的提交时,必须 从配置对应的远端获取该 feature branch 的新鲜发布证据。
- 当前本地 HEAD 必须等于远端 tip,或是远端 tip 的祖先。
- 远端缺失、网络/认证失败、远端回退/分叉或 origin 被改到其他仓库时, 默认保留工作区,不把旧 remote-tracking ref 或 pushed 标记当作授权。
- 已实际推送但本地状态未及时保存的工作,可以通过远端证据正常清理。
- 未修改的初始工作区不需要远端连接即可清理。
- 使用唯一临时 ref 获取证据,不覆盖共享 FETCH_HEAD 或 remote-tracking refs。
- 删除前核对项目 allowlist、实际 Git 仓库、工作分支及工作区状态。
- 本地分支采用携带 expected old SHA 的 compare-and-delete;如分支在检查后 前移,拒绝删除新 tip,并保留工作区记录供人工恢复。
- checkout-branch / checkout-mr 的遗留分支只有在其 tip 已被远端包含时才能替换; 恢复使用已检查的远端 SHA,而不是稍后可能变动的 tracking ref。
使用与兼容性¶
命令和现有 workspace JSON schema 不变;本补丁不引入新状态字段,也不要求迁移。
pushed 继续保留其历史含义,但不再决定 cleanup 能否删除工作。
gitlab-agent cleanup <workspace-id>
已存在提交的工作区,在默认清理时现在可能需要网络。 如果 feature branch 在 MR 合入后已删除,本补丁仍保守拒绝,而不猜测 squash/rebase 后的等价内容是否已发布。核对远端、保存需要的本地工作后再处理。
cleanup --force 仍是用户明确丢弃 dirty / 未发布工作的操作,不是建议的错误恢复方式。
它不绕过仓库身份、分支身份和项目 allowlist 检查。
验证¶
新增 tests/test_workspace_publication.py,使用真实临时本地 Git 仓库,
不连接业务 GitLab、不调用模型、不使用真实凭证。运行:
uv run python -m unittest discover -s tests -p test_workspace_publication.py -v
uv run python -m unittest discover -s tests -v
覆盖二次提交未推送、绕过控制器的直接 Git commit、远端删除/离线/回退、 origin 改写、远端后续提交、推送成功但 metadata 未保存、旧状态兼容、dirty、 显式 force、branch/repository identity mismatch、验证期间修改,以及删除瞬间的 分支前移。现有 CI 会继续执行完整测试及 Ubuntu/macOS/Windows 矩阵。
明确边界与后续顺序¶
这是数据保全补丁,不是 workspace locking、原子事务或完整 crash recovery。 若 worktree 已移除而最后的 compare-and-delete 失败,新的分支 tip 和工作区 metadata 会保留,但需要显式恢复 worktree。远端在验证之后仍可能被他人删除或改写。 可信开发机仍应避免多个 mutating writer 操作同一工作区。
后续按独立、可审阅的增量推进:
- 提交历史与候选内容的 secret coverage、窄化 placeholder 例外、MCP/CLI 日志脱敏统一、CLI 子进程退出码。
- start/resume/checkout 的统一 handoff 与标准 finish 文档。
- workspace/cache locks、版本化状态与 operation journal。
- 持久化 TaskSpec、attempt records、EvidencePack 与只读推理端集成。
不在本补丁中加入新 backend、并行 agent、自动合并或隐藏模型 API。