## [ERR-20260519-003] git_branch_vv_prefix_trap

**Logged**: 2026-05-19T07:30:00Z
**Priority**: high
**Status**: resolved
**Area**: infra

### Summary

`git branch -vv` 输出对**被别的 worktree 检出**的分支，第一列前缀是 `+` 而不是常见的 ` ` 或 `*`。任何 `awk '{print $1}'` 风格的解析都会把 `+` 当成分支名取出来，留下"幽灵分支"。本仓库 `scripts/dev/sweep-stale-branches.sh` 因此误识别一条幽灵 `+` 进入待删清单，触发 `git branch -D +` 失败但意图错乱。

### Error

```
$ bash scripts/dev/sweep-stale-branches.sh
=== gone branches（远端已删，本地可清）===
  feature/approval-form-followup-batch1  (last: 2026-05-03)
  +  (last: ?)                            # ← 幽灵：本该是同一条分支，被 + 前缀骗成第二条

$ git branch -vv | grep gone
+ feature/approval-form-followup-batch1  9a3802eb (/path/to/approval-form-polish) [origin/feature/approval-form-followup-batch1: gone] ...
#                                                ↑ 被 worktree 检出的标记
```

awk `$1` 在 `+ feature/foo ...` 行取到 `+`，sed `s/^\*//` 只去 `*` 不去 `+`，于是 `+` 当成分支名进了删除清单。

### Context

- 执行场景：多 worktree 仓库（agent-pool 池 + 命名 worktree）跑 `sweep-stale-branches.sh`
- 触发条件：远端被 auto-delete-on-merge 删的 PR 分支恰好被某个 worktree 当前检出（`: gone]` + `+` 前缀同时出现）
- git 文档里 `+` 前缀语义：see `git branch --help` § "the worktree info"

### Suggested Fix

**根因层**：不要用 `git branch -vv | awk` 解析 porcelain 输出。`git branch -vv` 是 porcelain（面向人类）格式，前缀字符集随版本/状态扩展（` ` / `*` / `+` / `-`...），任何位置解析都脆。

**替代方案**：用 `git for-each-ref` 拿明确字段：

```bash
git for-each-ref --format='%(refname:short) %(upstream:track)' refs/heads/ \
  | awk '/\[gone\]/ {print $1}'
```

`%(refname:short)` 直接输出 `feature/foo`，`%(upstream:track)` 在远端被删时输出字面 `[gone]`。完全跳过前缀解析。

### Metadata

- Reproducible: yes（多 worktree + gone 分支的标准重现）
- Related Files:
  - scripts/dev/sweep-stale-branches.sh（本次修复点）
  - scripts/dev/lib/agent-pool-lib.sh（复用 ap_ref_absorbed 守门）
- See Also: 同 PR 修复的另外两个 sweep bug — park 分支命名空间未加白名单 + 删 gone 分支前缺 absorbed 守门（force-push / 远端误删丢工作）

### Generalization

**git porcelain（branch -vv / status / log）输出别用 awk 列号解析**——格式按"对人友好"演化，列位置和前缀字符随时可能扩。
脚本里要拿结构化字段，统一用 `git for-each-ref --format=...` / `git status --porcelain=v2` / `git log --pretty=format:...`，这些是 plumbing 输出，字段位置稳定有契约。

---
