@@ -223,3 +223,98 @@ echo "Current: $CURRENT Next: $NEXT"
223223```
224224
225225See ` .claude/skills/release/SKILL.md ` for the full release workflow.
226+
227+ ---
228+
229+ ## GPG Pitfalls
230+
231+ ### Pitfall: GPG signing is human-only
232+
233+ ** What happens:** Agent attempts to commit with a GPG signature but fails because
234+ the agent has no TTY available for pinentry. The commit may appear to succeed due
235+ to cached passphrase in gpg-agent, but cannot be reliably automated.
236+
237+ ** Why:** The working pattern is: agent stages changes and provides the exact
238+ ` git commit ` command; the human runs it. An agent-invoked commit CAN succeed if
239+ the gpg-agent passphrase cache is warm from a recent human commit, but must never
240+ be relied on.
241+
242+ ** Fix:** Agent-staged changes should be followed by human verification:
243+ ``` bash
244+ # Agent staging commands:
245+ git add < files>
246+ # Then provide exact command for human to run:
247+ git commit -m " chore: update"
248+ ```
249+
250+ ---
251+
252+ ## Pre-commit Pitfalls
253+
254+ ### Pitfall: Pre-commit hook re-staging
255+
256+ ** What happens:** When a commit fails on trailing-whitespace or end-of-file fixers,
257+ the hook has already fixed the files in the working tree -- the staged copy is
258+ the stale, unfixed version. Retrying with ` --no-verify ` commits that stale
259+ content and skips every other hook.
260+
261+ ** Why:** Pre-commit hooks modify the working tree with automatic fixes before
262+ rejection. Files that had such fixes applied must be re-staged with ` git add `
263+ rather than bypassing validation.
264+
265+ ** Fix:** After auto-fix failures, use:
266+ ``` bash
267+ # Re-stage affected files and retry without --no-verify
268+ git add < affected files>
269+ git commit -m " your message here"
270+ ```
271+
272+ ---
273+
274+ ## PR Pitfalls
275+
276+ ### Pitfall: Closed vs merged PRs
277+
278+ ** What happens:** A human says "PR merged" but it was only closed, not merged.
279+ The agent proceeds to delete the branch or close the issue prematurely.
280+ The agent does not verify PR state.
281+
282+ ** Why:** GitHub distinguishes between MERGED and CLOSED state. When a PR is
283+ closed without merging (e.g., via a "wip" or cancel workflow), it still appears
284+ as if it was merged to a human who didn't check the actual Git state.
285+
286+ ** Fix:** Always check the PR state before deleting branches or closing issues:
287+ ``` bash
288+ gh pr view < N> --json state # Should show MERGED, not CLOSED
289+ ```
290+
291+ If a branch was deleted prematurely:
292+ ``` bash
293+ git log --all --oneline | grep " <commit subject>" # find the orphaned SHA
294+ git branch < branch-name> < sha> # recreate the branch
295+ git push origin < branch-name> # restore it on the fork
296+ gh pr reopen < N> --repo xencon/aixcl # reopen the PR
297+ ```
298+
299+ ---
300+
301+ ### Pitfall: Force-push race on open PRs
302+
303+ ** What happens:** After force-pushing a PR branch, GitHub may merge the pre-push
304+ commit instead of the latest commit if confirmation isn't obtained.
305+
306+ ** Why:** Force-pushes change the branch history. If a human merges before checking
307+ the current HEAD OID in the PR against the local repository to confirm they match,
308+ the pre-push commit gets merged instead of the intended changes.
309+
310+ ** Fix:** After force-pushing, verify consistency:
311+ ``` bash
312+ # Confirm your local commit matches PR HEAD
313+ LOCAL_HEAD=$( git rev-parse HEAD)
314+ PR_HEAD=$( gh pr view < N> --json headRefOid --jq ' .headRefOid' )
315+ if [ " $LOCAL_HEAD " = " $PR_HEAD " ]; then
316+ echo " Local and PR HEAD match - safe to merge"
317+ else
318+ echo " Mismatch! Local:$LOCAL_HEAD PR:$PR_HEAD "
319+ fi
320+ ```
0 commit comments