From ed6e590cdef5b85e3683f9fe146f77db7dfba387 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 28 May 2026 08:06:45 +0100 Subject: [PATCH] =?UTF-8?q?retro:=202026-05-28=20memory=20updates=20?= =?UTF-8?q?=E2=80=94=20verify-ticket-issues-still-exist-on-main?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One learning surfaced from PR #29 (ENG-30) round-1 review feedback. Acceptance criteria moot before drafting; humans push small fixes direct-to-main between ticket creation and agent pickup. - learnings/2026-05-28-verify-ticket-issues-still-exist-on-main.md (new) - MEMORY.md (+1 index line) Memory-only; no code paths touched. --- .claude/memory/MEMORY.md | 1 + ...erify-ticket-issues-still-exist-on-main.md | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 .claude/memory/learnings/2026-05-28-verify-ticket-issues-still-exist-on-main.md diff --git a/.claude/memory/MEMORY.md b/.claude/memory/MEMORY.md index 139a498..1fcb6ba 100644 --- a/.claude/memory/MEMORY.md +++ b/.claude/memory/MEMORY.md @@ -17,6 +17,7 @@ Keep this file under 200 lines — anything longer is content bloat, not memory. - [learnings/sentry-dedupe-must-check-closed-tickets](learnings/2026-05-27-sentry-dedupe-must-check-closed-tickets.md) — step-2 Sentry dedupe must match closed tickets too, not just open — canary errors (no Sentry write tools / ENG-21) get re-filed forever otherwise (APP-1 → ENG-17 closed → ENG-29 dup) - [learnings/fetch-before-merge-on-long-lived-branch](learnings/2026-05-27-fetch-before-merge-on-long-lived-branch.md) — On long-lived branches, run `git fetch origin ` before `git merge origin/`; local origin ref goes stale during review-feedback rounds (PR #12 round 3 escalation) - [learnings/git-checkout-theirs-replaces-whole-file](learnings/2026-05-27-git-checkout-theirs-replaces-whole-file.md) — `git checkout --theirs ` during a merge replaces the WHOLE file, silently reverting unrelated edits earlier on the branch; verify with `git diff origin/` afterwards (PR #29 round 1) +- [learnings/verify-ticket-issues-still-exist-on-main](learnings/2026-05-28-verify-ticket-issues-still-exist-on-main.md) — Re-read the ticket's target file in current `origin/` before drafting; humans push small fixes direct-to-main between ticket creation and agent pickup (PR #29 ENG-30 round 1) ## 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-28-verify-ticket-issues-still-exist-on-main.md b/.claude/memory/learnings/2026-05-28-verify-ticket-issues-still-exist-on-main.md new file mode 100644 index 0000000..66ae4cd --- /dev/null +++ b/.claude/memory/learnings/2026-05-28-verify-ticket-issues-still-exist-on-main.md @@ -0,0 +1,63 @@ +# Re-read the ticket's target file in current `origin/` before drafting fixes + +For docs/copy tickets — and any ticket where the acceptance criteria are +described by line/snippet against a specific file — the criteria can be +moot by the time the agent starts drafting. Humans push small fixes +direct-to-main (no PR, no ticket reference) constantly, especially on +README and other docs. The window between ticket creation and agent +pickup is wide enough for entire sections to be rewritten. + +Mitigation: after `git checkout -b`, before writing any code, run + +```sh +git fetch origin +git log origin/ --since= -- +``` + +and re-read each target file at `origin/:`. If the file has +been touched since the ticket was filed, manually re-validate each +acceptance criterion against current content. Drop any criterion whose +fix is already in main; narrow the PR scope before pushing. + +## Anchor — PR #29 / ENG-30 (2026-05-27) + +Timeline: + +- `15:20:26Z` PR #28 (human) merged — README install section rewritten. +- `15:22:26Z` reviewer agent files ENG-30 with **4** acceptance criteria + based on the just-merged PR #28 state. +- **`15:23:01Z` human pushes `a028eb3` directly to `main`** (no PR, + no ticket reference) — rewrites the install section AGAIN, addressing + 3 of ENG-30's 4 criteria. +- `15:23:20Z` manager agent opens PR #29, forked off `a028eb3` (so the + fetch was current), but drafted all 4 fixes from the ticket without + re-reading the file in current main. +- Round 1: reviewer flags 3 of 4 fixes as already-applied. Agent merges + main, drops 3 fixes, narrows to 1 line, ships. Cost: one extra review + round, one extra build/lint pass, one stale draft on the wire. + +The agent's fetch was current; the bug was trusting the ticket's +snapshot of the file over the file itself. Re-reading the file at +`origin/main:README.md` before drafting would have caught all 3 +already-fixed criteria in seconds. + +## Distinct from existing learnings + +- `check-open-pr-before-ticket-pickup` / `recheck-open-prs-at-pr-open` — + agent-vs-agent races at ticket-pickup and PR-open time. Direct-to-main + commits don't show up in `list_pull_requests` so the PR-grep + mitigation doesn't catch them. +- `fetch-before-merge-on-long-lived-branch` — staleness at merge time, + on a long-lived branch. This is staleness at draft time, on a fresh + branch. +- The shape is: "reviewer-filed ticket snapshots a file; humans rewrite + the file in the gap; agent drafts against the snapshot." + +## Doesn't apply when + +- The ticket's acceptance criteria don't reference specific file + content (feature tickets, infra tickets). +- The branch was opened within seconds of the ticket (no realistic + window for a direct-to-main commit). +- The reviewer agent's filing timestamp matches the ticket's described + base SHA — implies the reviewer read against current main.