diff --git a/skills/prm/prm.md b/skills/prm/prm.md index 1201dc1..7bcf9e0 100644 --- a/skills/prm/prm.md +++ b/skills/prm/prm.md @@ -37,6 +37,17 @@ checkout required. Detect which you are in: - **Remote (mobile/codex)** — no multi-repo checkout. Resolve the PR from the argument or by listing candidates (below), and **skip the local-only cleanup** with a one-line note. Never `cd` into a repo that isn't there. +- **Proxied web session (Claude Code on the web)** — remote as above, **plus it + cannot delete remote branches at all**: the egress proxy refuses ref deletions. + Probe once, before the close-out, and remember the answer for the whole run: + + ```bash + curl -sf "$HTTPS_PROXY/__agentproxy/status" >/dev/null && echo "ref deletes blocked" + ``` + + An answer means every `git push origin --delete` in this run will fail. Branch + cleanup is then **out of scope for the run**: don't attempt it, and don't + mention it — see step 5. ## The routine @@ -119,14 +130,19 @@ step 6. Order is forced by the tooling, so do not reorder: registered in `active.md` — which is exactly why step 3 comes first. 5. **Branches** — delete the remote `feature/` per proven-merged repo, plus any local branch left in the canonical checkout. Never delete a branch whose - merge you did not prove in sub-step 1. + merge you did not prove in sub-step 1. **Where the environment cannot delete + remote refs** (proxied web session, above), this sub-step does not exist: + attempt nothing, and report nothing about it. `/repo_cleanup` finds those + branches on origin by itself, so silence here loses nothing. 6. **Report the ledger** — PRs merged, issue closed, record path, `active.md` - released, worktree removed, branches deleted, and anything skipped. + released, worktree removed, branches deleted, and anything skipped. Branches + are simply absent from the ledger where sub-step 5 did not apply. -**Remote (mobile/codex):** sub-steps 1, 2 and 5 run over `gh`/`git ls-remote` as +**Remote (mobile/codex):** sub-steps 1 and 2 run over `gh`/`git ls-remote` as usual. Mind (3) works if PyAutoMind is checked out; otherwise say the record is pending. The worktree (4) is local-only — name it as outstanding rather than -implying it ran. +implying it ran. Branches (5) delete normally from mobile and Codex; a proxied +web session drops the sub-step silently. ### 6. The only guards that stop you diff --git a/skills/prm/reference.md b/skills/prm/reference.md index 3a3e54d..bb1c279 100644 --- a/skills/prm/reference.md +++ b/skills/prm/reference.md @@ -189,7 +189,41 @@ directory listing is the only way to find it. ### 5. Branches -Local branches go with the worktree; the remote ones do not: +Local branches go with the worktree; the remote ones do not. **First establish +whether this environment may delete remote refs at all** — one probe, once per +run, before any repo: + +```bash +curl -sf "$HTTPS_PROXY/__agentproxy/status" >/dev/null && echo "ref deletes blocked" +``` + +An answer means a proxied web session (Claude Code on the web). There, a ref +deletion dies on the `git-receive-pack` POST: + +``` +error: RPC failed; HTTP 403 curl 22 The requested URL returned error: 403 +send-pack: unexpected disconnect while reading sideband packet +``` + +That 403 is generated in front of GitHub — the ref advertisement to the same host +seconds earlier returns 200 with an `X-Github-Request-Id`, the 403 carries none — +so credentials, `gh` scopes and branch protection are **not** the cause, and no +retry, repo, or token changes it. The GitHub MCP surface has no delete verb +either (`create_branch` exists; nothing deletes a ref). So in that environment +**this whole sub-step is out of scope**: run no delete, and write no line about +branches in the ledger — not "deferred", not "blocked", not "see /repo_cleanup". +The step is structurally impossible there and would say the same thing on every +close-out, so it is noise, not a finding. + +Nothing is lost by the silence: `/repo_cleanup` Bucket B enumerates origin +branches directly (`gh api repos///branches`), so it rediscovers +these on the next local sweep without being told. Repo-side, "Automatically +delete head branches" (Settings → General → Pull Requests) removes the need for +the sub-step altogether. + +Report a blocked delete only if the user **asks** where a branch went. + +Otherwise — local CLI, mobile, Codex — delete as usual: ```bash git -C push origin --delete feature/ @@ -198,11 +232,16 @@ git -C fetch --prune ``` Only branches proven merged in step 1. `git ls-remote --heads origin feature/` -is the ground truth that the delete landed. +is the ground truth that the delete landed. If a delete 403s where you expected it +to work, treat it as the proxied case from that point on: **stop after the first +refusal** and drop the sub-step — do not repeat the push per repo, and do not +narrate the failure. ### 6. The ledger Report, per line: PR(s) merged (URL + `MERGED`), issue closed (number + state), record path under `complete///`, `active.md` claim released, worktree removed, branches deleted, and **anything skipped** with the reason. A close-out -that quietly skipped a step reads exactly like one that finished. +that quietly skipped a step reads exactly like one that finished — with one +deliberate exception: a sub-step the environment makes impossible (step 5 behind +the proxy) is omitted outright rather than reported as skipped.