Skip to content

PR jail: a nudge to clear your open PRs - #514

Merged
jarstelfox merged 22 commits into
masterfrom
pr-jail
Oct 10, 2026
Merged

jarstelfox merged 22 commits into
masterfrom
pr-jail

Conversation

@jarstelfox

@jarstelfox jarstelfox commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

🤖

Some people have far more open PRs than they can move, and the old ones rot. PR jail is a push to clear them. When you have more than 7 open PRs of your own, or one open past 14 days, a modal lists them with the ready-to-merge ones first. It comes back only when things get worse, at most every 4 hours.

Changes

  • The modal: your PRs grouped like My work (Ready to merge, Your move, Waiting on others), with a "6 to go" countdown that ticks down as you merge or close. It closes by itself once you're under the limits.
  • Getting out without fixing anything: hold "Hold to get back to work" for 2 seconds, by mouse, finger, Enter or Space. A click or Esc does nothing, on purpose.
  • Settings: Automatic, Manual (only the header lock) or Off, the two limits, and whether drafts count. Bots and deploy-held PRs never count.

Stacked on the Projects pull; retarget to master once that merges.

Review

Seven rounds of blind review, each fixed before the next; the last two found nothing serious. Fixes along the way: Esc can't reach Settings behind it, screen readers and voice control get out with a single click, the 4-hour wait holds after you get under the limits, and the jail never pops up over another dialog or in the middle of a drag.

QA

  • In the dummy board's Settings, press "Preview PR jail".
  • Click "Hold to get back to work" once and see it say "Hold it down".
  • Hold it for 2 seconds and see the lock open and the modal close.
  • Set PR jail to Manual, reload, and see only the header lock.

jarstelfox and others added 22 commits October 9, 2026 18:12
A playful nudge to close out PRs: when your own open PRs pass a limit
(more than 7 open, or any open longer than 14 days; drafts, bots and
deploy-held PRs don't count), a jail cell drops over the board and
lists them. Dragging the key into the padlock lets you out.

It shows again only when things get worse: at least 4 hours after it
last showed, with more open PRs or another one past the age line. A
refresh never brings it back, and open tabs stay in sync. A lock badge
beside the bell shows while you're over a limit and reopens the list.
Settings hold both limits, whether drafts count, and a preview button
(or #jail=1 in the URL).

The art follows the light and dark themes; the robot stands behind
the door with his tally wall beside him; on a phone the list comes
first and the key is one drag straight down into the lock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The open jail showed a copy of your PRs from the moment it dropped, so
a merge or a new PR arriving over the socket never reached it: it
stayed on "8 open PRs" after a ninth came in. The cell now reads the
live list; merging under the limits says "You're under the limits now.
Use the key to walk out." Leaving saves what you last saw, so PRs
opened while it was up don't drop it again right away.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The jail listed your PRs as one flat, oldest-first list, so the ones you
could merge in seconds sat between ones waiting on someone else. Now it
splits them the way My work does (same rowWord): Ready to merge on top,
then Your move, then Waiting on others, each oldest first. Each row
shows the age, the move, a CI mark, and who it waits on.

The why line counts against the groups ("Merge your 3 ready ones and
close 10 more"), never counts a parked PR as ready, and doesn't promise
"you're out" while an old PR would still hold you. The preview now
shows your own PRs as jail counts them. CiGlyph comes out of CiStatus
so the board and the jail draw the same CI mark.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
People complained about the jail. The full-screen animated cell with
the key and the lock was a lot to sit through, and some people don't
want the feature at all.

Now it's a modal with a small sad robot behind bars, drawn as a few
lines in the board's own color tokens so it matches the UI and themes
with dark mode, above the same grouped list. It still has no close
button: you drag the card onto a trash can at the bottom of the screen
(on a phone that's a swipe down), and a keyboard or screen reader
presses the trash. A new PR jail setting turns it off, badge and all;
it defaults to on. The cell, key, lock and inmate art and their CSS go
away.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Some people want the header lock without the pop-up: they'd rather
check their PRs when they choose to. The single on/off switch couldn't
say that, since Off hid the lock too.

Now the PR jail setting has three choices: Automatic pops it up when
you're over the limits, Manual only shows the lock to open when you
like, and Off hides both. Anyone who already picked Off keeps it.

The trash can at the bottom becomes a snooze clock labeled "Snooze".
Dragging your PR list into a trash can read like throwing the PRs
away; snooze is what it really does, since jail comes back when things
get worse. The hint under the list now says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dragging the card onto a clock was the only way past the jail without
fixing anything, and it didn't work the same on a phone or a keyboard.
The point is a little friction, not a puzzle.

1) Snooze is now a hold: press and hold the row at the bottom for 2
   seconds, with a pointer, a finger, Enter or Space. A small line-drawn
   padlock shows it: the key in the keyhole wiggles while it waits,
   turns a quarter turn as you hold while a ring around it fills, and
   the shackle pops open at the end. Letting go early springs it back.
   A tap, a click or Esc does nothing.
2) The jail lets you go by itself once you're under the limits: it
   says "You're out. Nice work." and closes after a couple of seconds.
3) A countdown to freedom: "6 to go" next to the title and on the
   header badge, enough PRs to get under the count limit plus every one
   past the age limit, ticking down live as you merge or close.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The jail's list was tight: 13px rows two pixels apart, the move and the
detail run together with dots, and the snooze lock just closed the card
when you finished holding it.

1) Finishing the hold opens the lock: the shackle lifts out of the
   body and swings over its right leg to the other side, and the ring
   and the key turn green, before the jail closes.
2) Focus starts on "Hold to snooze", so holding Enter or Space works
   the moment it opens.
3) More room: a wider card with more padding, rows split by hairlines
   with real space between, 14px titles, ages in days, and the next
   step as a small pill instead of a dot-separated word. Each group
   says what to do with it ("Each of these is waiting on you").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Hold to snooze" was our word, not the user's, and the jail had grown
its own styles (uppercase eyebrows, hint lines, a subtext under the
button) when the board already has a header system people know.

1) The button says what happens: "Hold to get back to work", full
   width with the lock at its side. A quick click says "Hold it down",
   so the gesture teaches itself; the subtext is gone (Settings
   already says when it comes back). Done, it reads "Unlocked".
2) Groups use the board's GroupHeader (title, a short note, the count
   on the right), pinned to the top of the list as you scroll.
3) Size: 40rem on a desktop so titles fit one line, at most 80% of
   the screen tall; a sheet up from the bottom on a phone, with the
   button at thumb height. The header and the button stay put and
   only the list scrolls.
4) "Copy a nudge" on Waiting on others copies a Slack-ready list of
   those PRs, their links, and who each one waits on.
5) A PR that merges or closes while the jail is up slides out of the
   list as the countdown ticks, instead of vanishing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A review of the jail found:

1) Esc while previewing from Settings closed Settings behind the jail,
   and once you left the jail the page couldn't scroll until a reload.
   The jail now stops Esc before anything behind it sees it, and the
   preview closes Settings first.
2) The 2-second hold was the only way out, which shuts out screen
   readers, voice control and switch access: they send a single click.
   A click with no pointer or key behind it now lets them out.
3) Getting under the limits never cleared the last showing, so going
   over again later could stay silent. Being free now forgets it.
4) "Preview PR jail" worked once per page load; it's an event now.
5) Focus returns to where it was when the jail closes, and stays in
   the dialog while it says "You're out".
6) A PR that stopped counting (the rule switched, or it went draft)
   slid out as if merged; only a real close does now. Closing records
   the latest case, not the one from when the hold started.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1) Firefox clicks a button on Space's keyup, so a quick Space tap
   produced a click with no pointer behind it, which the jail treats
   as assistive tech's lone click and lets you out. Key releases now
   cancel their default, and a click right after one doesn't count.
2) When the "who am I" lookup failed at load, the board started with
   no user, read that as "under the limits", and wiped the last
   showing in every tab, so the jail popped right back up. Jail now
   waits until it knows who you are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two visible Pulldasher windows both checked on the same data push, a
moment apart, and each read its own copy of the last showing before
the other window's storage event arrived, so jail could open in both.
The check now reads the stored record fresh before deciding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1) Getting under the limits deleted the last showing, so someone at
   the limit got jailed on every new PR: no record meant no 4-hour
   wait. Now it zeroes what was counted but keeps when it showed, so
   going over again is still a fresh offense and still waits out the
   4 hours, as Settings promises.
2) The board's /, j, k and c keys still ran while the jail (or
   Settings) was open, moving focus behind the scrim. They stand down
   while a modal dialog is open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1) The automatic check could open the jail on top of Settings (say,
   right after switching PR jail to Automatic), or mid-drag on the
   Roadmap, where it swallowed the Esc that cancels the drag, so a
   move you meant to cancel got saved. It now waits while another
   modal is open or a pointer is held, and tries again on the next
   update.
2) The CI mark in jail rows is aria-hidden, so screen readers heard
   nothing about a failing build. Rows now say "CI failing" or "CI
   running" to them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The "pointer held" flag that keeps the jail from popping up mid-drag
could stick on after a right-click (the context menu swallows the
pointerup), delaying the popup, and a native drag cleared it through
pointercancel. It now counts only the main button, clears on the
context menu and on leaving the window, and stays set through a
native drag until it ends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The last change stopped pointercancel from clearing the press, to keep
a native drag counted, but a touch that turns into a scroll also ends
with pointercancel and no pointerup, so on a phone the flag stuck on
after any scroll. A native drag is now tracked on its own, and
pointercancel clears the press again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dragend goes to the dragged node, and moving a Roadmap plan to another
lane takes that node off the page first, so dragend never reached the
document and the "drag under way" flag stayed on: the jail never
popped up again until the window lost focus. A drop, or any new
press, now ends it too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jarstelfox
jarstelfox marked this pull request as ready for review October 10, 2026 02:47
Base automatically changed from projectdasher to master October 10, 2026 02:47
@jarstelfox
jarstelfox merged commit 005fe40 into master Oct 10, 2026
1 check passed
@jarstelfox
jarstelfox deleted the pr-jail branch October 10, 2026 02:56
@jarstelfox jarstelfox added the P-review-flow [PD] How Pulldasher steers PRs: who reviews what, self-review, and nudges like PR jail label Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P-review-flow [PD] How Pulldasher steers PRs: who reviews what, self-review, and nudges like PR jail

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant