From 9a681ef1be82f04ee2ec6707817351700c320400 Mon Sep 17 00:00:00 2001 From: Self-Managing Codebase Manager <7004983+WillTaylor22@users.noreply.github.com> Date: Tue, 26 May 2026 10:11:40 +0000 Subject: [PATCH] memory: recheck open PRs at PR-open time, not just session start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Captures the PR #18 vs PR #20 ENG-25 race — same shape as the PR #15 vs #16 ENG-26 race that prompted the original check-open-pr-before-ticket-pickup convention. Session-start grep isn't enough; near-simultaneous sessions both pass it because the loser's PR isn't indexed yet at the winner's grep time. Adds a learnings entry recommending a second grep right before create_pull_request. --- .claude/memory/MEMORY.md | 1 + .../memory/learnings/2026-05-26-recheck-open-prs-at-pr-open.md | 1 + 2 files changed, 2 insertions(+) create mode 100644 .claude/memory/learnings/2026-05-26-recheck-open-prs-at-pr-open.md diff --git a/.claude/memory/MEMORY.md b/.claude/memory/MEMORY.md index 9f678d0..f776d9f 100644 --- a/.claude/memory/MEMORY.md +++ b/.claude/memory/MEMORY.md @@ -8,6 +8,7 @@ Keep this file under 200 lines — anything longer is content bloat, not memory. - [learnings/vercel-blocks-unknown-author-email](learnings/2026-05-26-vercel-blocks-unknown-author-email.md) — Vercel preview deploys block when commit author email has no GitHub account; use the noreply alias - [learnings/sandbox-cant-clone-private-repo](learnings/2026-05-26-sandbox-cant-clone-private-repo.md) — Don't `git clone` from sandbox bash; the `github_repository` resource is auth'd, raw `git clone` is not - [learnings/github-mcp-strips-html-comments](learnings/2026-05-26-github-mcp-strips-html-comments.md) — `update_pull_request` silently strips `` from PR bodies; session-id marker can't be set by agent (ENG-25) +- [learnings/recheck-open-prs-at-pr-open](learnings/2026-05-26-recheck-open-prs-at-pr-open.md) — session-start grep is insufficient; re-grep `list_pull_requests` right before `create_pull_request` to catch parallel-session races (PR #18 vs #20 ENG-25) ## Decisions - [decisions/mcp-for-small-writes-checkout-for-big](decisions/2026-05-26-mcp-for-small-writes-checkout-for-big.md) — Single-file writes go through GitHub MCP; multi-file or test-needing changes use the mounted checkout + `git push` diff --git a/.claude/memory/learnings/2026-05-26-recheck-open-prs-at-pr-open.md b/.claude/memory/learnings/2026-05-26-recheck-open-prs-at-pr-open.md new file mode 100644 index 0000000..12b25bb --- /dev/null +++ b/.claude/memory/learnings/2026-05-26-recheck-open-prs-at-pr-open.md @@ -0,0 +1 @@ +The `check-open-pr-before-ticket-pickup` convention (one `list_pull_requests` + grep before `git checkout -b`) is **not sufficient** when two sessions wake up for the same ticket within the same wall-clock minute. Today PR #18 (10:04:47Z, `sesn_01EhZHPuoB16G5mANW6B6b7U`) and PR #20 (10:07:21Z, `sesn_012j21sUvdmnhx3baX6ivYLW`) both shipped ENG-25 with ~2.5 min between PR-open events. The second session's session-start grep ran before #18 was indexed/visible, so the check passed and the dup got opened anyway — same root cause as the PR #15 vs #16 ENG-26 race that prompted the original convention. Mitigation: **re-grep `list_pull_requests` immediately before calling `create_pull_request`**, not just at session start. If a dup appeared mid-session, the later session aborts with a "closing as race-loser, see PR #X" Linear comment and stops, even if local code is already written. The cost is one extra MCP call per ticket pickup; the upside is preventing another ENG-27-style cleanup ticket every time two sessions race. Upstream fix (only spawn one session per ticket) belongs in the orchestration layer, not this codebase.