Rescue paused E2B sandboxes before the 30-day cliff

Every morning at 8am, Geni finds paused E2B sandboxes nearing the 30-day deletion cliff, posts a Slack digest, and opens a Linear ticket for each urgent owner.

Agentic Task
E2BSlack BotLinearEngineeringOperationsDaily DigestsNotifications & AlertsResearch & Monitoring
PromptCreate

Every morning at 8am, scan my paused E2B sandboxes and rescue the ones about to be auto-deleted. E2B keeps paused sandboxes for up to 30 days and then permanently destroys them, which silently kills snapshotted state from long-running experiments, RL training runs, and in-progress agent sessions. I want to know about it before that happens.

Trigger: cron, daily at 8am in my local timezone.

What the agent should do each run:

1. Use the E2B List Sandboxes operation, filtered to the paused state, to pull every paused sandbox on the team. Paginate through all pages.

2. For each paused sandbox, call E2B Get Sandbox Lifecycle Events to find the most recent paused event. Use that timestamp as the pause time and compute days_remaining = 30 minus days since the pause.

3. Group results by owner (read the owner from the sandbox metadata, falling back to an Unassigned bucket if none is set) and by template ID. Flag anything with seven days or fewer remaining as urgent.

4. Post one tidy digest to a Slack channel I choose, using the Slack Bot Send a Message operation. The digest should list each at-risk sandbox with its sandbox ID, template, owner, age (days since pause), and days remaining. Sort urgent items first, then group the rest by owner. Keep it to a single message with Slack markdown formatting.

5. For every urgent sandbox (seven days or fewer remaining), open a Linear ticket using the Linear Create Issue operation in a Linear team I pick. Assign the ticket to the matching Linear user for that owner (match by email or by a configured owner-to-Linear-user map). The ticket title should be along the lines of "Decide on paused E2B sandbox <sandboxID>". The description should ask the owner to either resume the sandbox to extend it or kill it to release the snapshot, and should include the sandbox ID, template, days remaining, pause timestamp, and a link to the Slack digest message that was just posted.

6. Dedupe: before creating any Linear ticket, use Linear Search Issues to look for an existing open issue whose title or description references the same sandbox ID. If one already exists, skip creating a new ticket. Still mention that sandbox in the Slack digest (with a note that an open ticket already exists) so it does not disappear from view.

7. If there are zero paused sandboxes at risk, still post a short Slack message confirming the sweep ran and found nothing to rescue, so I know the workflow is alive.

Output: one Slack digest per run, plus a deduped backlog of Linear decision tickets, so no paused work ever silently expires without the owner explicitly choosing to resume it or kill it.

Additional information

What does this prompt do?
  • Checks your paused E2B sandboxes every morning and works out how many days each one has left before E2B permanently deletes it.
  • Groups the at-risk sandboxes by owner and template, then posts one tidy Slack digest to a channel you choose with IDs, ages, and days remaining.
  • For anything with seven days or fewer to live, opens a Linear ticket assigned to the owner asking them to either resume the sandbox or kill it on purpose.
  • Skips sandboxes that already have an open Linear ticket from a prior run so the same owner is never pinged twice for the same thing.
What do I need to use this?
  • An E2B team account with a team API key so Geni can list your sandboxes and read their lifecycle history.
  • A Slack workspace and the channel name where the daily digest should land.
  • A Linear workspace and the team where rescue tickets should be created, plus a way to map sandbox owner names to Linear users.
How can I customize it?
  • Change the run time. 8am local is the default, but you can pick any cron schedule that suits your team.
  • Tune the urgency threshold. Seven days is the default trip wire for opening a Linear ticket, but you can move it up or down.
  • Swap the destination Slack channel, the Linear team, and how owners are matched to Linear assignees (sandbox metadata field, email, or a fixed lookup).

Frequently asked questions

Why does this only look at paused sandboxes?
Paused sandboxes are the ones that silently disappear. E2B keeps them for up to 30 days and then permanently deletes the snapshot. Running sandboxes have their own time-to-live and idle-killer workflows, so this one only watches the paused pile.
Will it open a new Linear ticket every single morning?
No. Before opening a ticket, Geni searches your Linear workspace for an existing open ticket that references the same sandbox ID. If one is already open, the sandbox is mentioned in the Slack digest but no new ticket is created.
What counts as urgent?
Anything with seven days or fewer remaining before the 30-day deletion cliff. You can change that threshold when you set the workflow up.
Can I send the digest to more than one Slack channel?
Yes. By default it posts to one channel, but you can ask Geni to fan it out to multiple channels or to send a private DM to each affected owner instead.
What happens if a sandbox has no clear owner in its metadata?
It still shows up in the Slack digest under an Unassigned section so nothing slips through. Tickets are only opened for sandboxes where the owner can be matched to a Linear user.

Stop losing long-running E2B work to the 30-day timer.

Connect E2B, Slack, and Linear once, and Geni handles the morning rescue sweep for you.