‧
7 min read
PA: a persistent agent for developer workflow automation
Filipe Silva
‧ 7 min read
Share this article
Think of all the stuff you have to do every morning before you even start coding. You need to get caught up from the day before, look over your tickets, figure out which one to work on, clone the right repo, check out a branch, get up to speed on the relevant area of the code, then maybe you can start rolling.
What is a persistent agent?
Most agents are one-shot: you give them a task, they do it, and everything they learned disappears with the session. A persistent agent maintains continuity: it saves its tasks and memory to disk, so it can pick up an unfinished job, wait for your feedback, and resume without you having to re-explain anything.
Persistent Agent, or pa for short, is our lightweight memory and task system for handling chores and getting to the fun stuff faster. pa is inspired by the Night Shift Agentic Workflow and note-taking systems like Obsidian.
pa frees up about 15% of my time each day
All those startup and admin tasks typically eat up between 10% and 20% of a developer’s time. Strangely, these gains get better the less normal your circumstances are: when you’re very busy, under the weather, or stressed, having pa consistently follow the start of day script and propose the next priority helps a lot.
These gains may sound modest compared to the hype surrounding agents. But they are real, low effort, and easy to verify. All you need to do is keep a terminal open on your machine.
A typical day with pa
I use pa as a background partner that I pair with and delegate work to. Each morning when I sit down to work, I run sod (start of day) to pair on my start-of-day routine. It:
- pulls updates from Slack, Linear, and GitHub since the last
sod - saves a daily note with a summary since the last one
- updates the state of tracked tasks
- sends my start-of-day message to my team’s Slack standup channel
Then I pick what I’m going to work on myself, and what I want to assign to pa to work on autonomously in the background. Saying work switches pa to the work loop. It will work over its own tasks in auto permissions, cloning repositories as needed into its own workspace, creating plans and PRs, blocking tasks when it needs input from me, waiting for CI and feedback on existing PRs, and logging everything on the task files.
At around lunch time I take a break from the work I’m doing and check up on pa’s progress by saying pair to enter pairing mode. In pairing mode it will ask questions about ongoing tasks, get approval for plans, or let me know that a PR is ready for review. When I’m done pairing, I tell it to work again.
Sometimes during the day I remember something I want pa to take a look at. I run pa todo look at issue XYZ to add it to the current todos, to be picked up on the next work loop. If I want to add to the backlog for later, I use pa backlog instead. I have Claude’s remote control turned on, so I can check on progress on my phone.
How to pick tasks to delegate
There are two broad categories of tasks that are good to delegate to pa: trivial tasks and boring tasks. In both cases, the task’s output should be easy to verify.
There’s no shortage of trivial tasks in any real work context. These tasks don’t require a lot of attention, are usually disruptive (even if they’re not urgent), and can usually be done quickly. With pa, you can just say please add XYZ to your todo, then start a work loop. You don’t have to switch branches, trace code, make tests, make a PR, link it to the issue, etc. You can just check in later and see a PR ready to review.
Boring tasks are usually dominated by downtime. They are tasks where you need to start processes that take a long time to finish, or monitor events over time, or make small changes to a bunch of different files and tests. These tasks need a medium amount of attention in bursts, and make it hard to switch context in the downtime.
Boring and trivial tasks aren’t the only tasks you can delegate, but they’re the ones that ask the least of your attention, and your attention is the limited resource. More open-ended tasks often end up requiring a lot of direction and verification, which can drastically reduce the value of delegation.
How you get started with pa
You’ll need to have Claude Code installed. Then fork our Persistent Agent repo, likely into a private repository. Now it’s your own thing to use and change, for personal use, work use, or both.
Then:
- clone your fork locally
cdinto it- run
bin/installto add thepacommands globally. - call
pa setup <your name>for initial setup
The default Metabase setup uses GitHub/Slack/Linear/Notion/Figma as external tools, but setup will ask you which you want to use and update itself.
How pa works
pa is mostly a file structure, a few markdown files on how to use it, and a claude wrapper script:
persistent-agent
├── .claude
│ └── settings.json // default plugins and permissions
├── bin
│ ├── pa // start pa or call other commands
│ ├── pa-backlog // add new task to backlog
│ ├── pa-install // installs commands globally
│ ├── pa-save // commit tasks and daily notes
│ ├── pa-tasks // show all tasks
│ ├── pa-today // show daily note
│ └── pa-todo // add new task to todo
├── daily-notes // saved as YYYY-MM-DD.md
├── memory
│ ├── archive
│ ├── feedback // saved during interactions
│ ├── skills // referenced in .claude/skills/*
│ │ ├── memory.md // how to use memory
│ │ ├── modes.md // modes of operation
│ │ ├── self-modification.md // how to change pa
│ │ ├── setup.md // initial setup checklist
│ │ ├── start-of-day.md // start of day routine
│ │ ├── tasks.md // how to use tasks
│ │ ├── update.md // how to update pa
│ │ └── work.md // how to work
│ ├── user.md // who the user is
│ └── workspace.md // tools and repositories
├── tasks // .md with yml metadata
│ ├── archive
│ ├── backlog // known, but not todo
│ ├── blocked // blocked on user
│ ├── in-progress // being worked on
│ ├── todo // ready to work on
│ └── waiting // waiting for someone else
├── workspace // where repos are cloned
├── CHANGELOG.md // used during update
├── CLAUDE.md
└── README.md
You can and should modify pa to work however suits you. The core idea is to give an agent a persistent place of its own, to work with you, in the way you like working.
Your routine
pa has become a part of my day, and I hope it can support you with your own routine tasks. If you fork the Persistent Agent repo and set up your own pa, I’d love to hear how you customized it.
More from Metabase Engineering
You might also enjoy
All posts
May 12, 2026 in Engineering
Improving the performance of the popular Clojure development tool clojure-lsp
Have you found clojure-lsp struggling with your large codebase? We did, so we made some improvements to our favorite development tool to cut startup time in half and memory allocation by two thirds.
Sashko Yakushev
‧
13 min read