Found by CodeRabbit on PR #936 (the develop -> main promotion PR), unrelated to that PR's own diff — flagging pre-existing skill content from #923.
The gap
drive-pr's and merge-and-release's post-merge branch cleanup (mirrored across .agents/skills/, .claude-plugin/fleet-skills/skills/, and .github/skills/ for both skills, six files total) does:
git ls-remote --heads origin <branch> to read the remote tip, then separately
git push origin --delete <branch>
git branch -D <exact-branch> locally, unconditionally.
None of these three steps is atomic with the read that justified it. A push to the branch between step 1's read and step 2's delete is not caught: git push --delete removes the ref regardless of what it currently points to. git branch -D has no expected-OID form either.
Ask
CodeRabbit's suggested shape: an expected-OID compare-and-delete for the local ref (git update-ref -d <ref> <old-oid> instead of branch -D), and an explicit remote lease (git push --force-with-lease=<ref>:<headRefOid> origin --delete <branch>) instead of the read-then-delete pair. That needs a matching narrow exception carved into git-commit-conventions' blanket "never force push" rule (a delete lease is not a history-rewriting force push, but the rule as worded doesn't distinguish today).
Apply to all six mirrored files if adopted, per skill-lifecycle's source-versus-generated split (source lives under .agents/skills/, the other two are generated copies via scripts/build_dist.py).
Found by CodeRabbit on PR #936 (the develop -> main promotion PR), unrelated to that PR's own diff — flagging pre-existing skill content from #923.
The gap
drive-pr's andmerge-and-release's post-merge branch cleanup (mirrored across.agents/skills/,.claude-plugin/fleet-skills/skills/, and.github/skills/for both skills, six files total) does:git ls-remote --heads origin <branch>to read the remote tip, then separatelygit push origin --delete <branch>git branch -D <exact-branch>locally, unconditionally.None of these three steps is atomic with the read that justified it. A push to the branch between step 1's read and step 2's delete is not caught:
git push --deleteremoves the ref regardless of what it currently points to.git branch -Dhas no expected-OID form either.Ask
CodeRabbit's suggested shape: an expected-OID compare-and-delete for the local ref (
git update-ref -d <ref> <old-oid>instead ofbranch -D), and an explicit remote lease (git push --force-with-lease=<ref>:<headRefOid> origin --delete <branch>) instead of the read-then-delete pair. That needs a matching narrow exception carved intogit-commit-conventions' blanket "never force push" rule (a delete lease is not a history-rewriting force push, but the rule as worded doesn't distinguish today).Apply to all six mirrored files if adopted, per
skill-lifecycle's source-versus-generated split (source lives under.agents/skills/, the other two are generated copies viascripts/build_dist.py).