What the agent does
The agent reads the issue first. The resources list names the repository and the Linear issue URL, which Rush places in the prompt through your Linear connection, so the description, the comments and the acceptance criteria are in front of the agent before it opens a file.
In a Flask application like flaskbb/flaskbb, pyproject.toml requires Python 3.12 or newer and pins Flask 3.1, Flask-SQLAlchemy 3.1, SQLAlchemy 2.1, Flask-Login, Flask-WTF, Flask-Allows2 for permissions and celery 5.6, with uv.lock as the lockfile and make test defined as uv run pytest. The forum blueprint is flaskbb/forum/views.py: MethodView classes such as ViewForum, ViewTopic, NewTopic, EditTopic, NewPost, EditPost, MarkRead, LockTopic, HideTopic and MarkdownPreview, registered in flaskbb_load_blueprints with register_view on routes like /forum/<int:forum_id> and /topic/<int:topic_id>/edit. The user blueprint in flaskbb/user/views.py has UserSettings, ChangePassword, ChangeEmail, ChangeAvatar, ChangeUserDetails and UserLookup, with the logic in flaskbb/user/services/update.py, validators.py and factories.py.
A ticket names a behaviour, and the agent traces it to the view, the form in forms.py, the model in models.py and the permission check, then changes the owner of that behaviour rather than adding a parallel path. A change to how a profile field validates goes into flaskbb/user/services/validators.py; a change to who may lock a topic goes into the permission the LockTopic view asks for.
Tests live under tests/unit/forum and tests/unit/user, in files like test_topic_moderation.py, test_mark_read.py, test_update_details_handler.py and test_lookup_view.py, and share fixtures that tests/conftest.py imports from tests/fixtures/. tests/fixtures/app.py builds the app from TestingConfig, whose database is sqlite:// in memory and whose Celery runs tasks eagerly, and an autouse fixture clears the cache and the permission state between tests. The agent writes its test in that style, runs uv sync --group dev and uv run pytest, as .github/workflows/tests.yml does through tox on Python 3.12 to 3.15, then ruff on the files it changed, and opens the pull request.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "codex",
"input": "Implement the Linear issue given as a resource in this Flask codebase. Read the issue and its comments first. Make the change in the forum or user blueprint the issue concerns, including its form, model, service or permission check, and keep the diff small. Add pytest tests under tests/unit using the fixtures in tests/fixtures. Run `uv sync --group dev`, then `uv run pytest` and `uv run ruff check` on the files you touched, and fix what fails. Open a pull request whose description links the issue, explains the change and quotes the test result. Do not merge.",
"resources": [
{
"url": "https://github.com/your-org/your-app"
},
{
"url": "https://linear.app/your-org/issue/ENG-42"
}
]
}- Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
- Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
- Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.
What comes back
A pull request on its own branch comes back. Its description links the issue, names the view and service the change touched, and quotes the pytest summary. The diff holds the change, its test and nothing else from the ticket's neighbourhood.
The pull request URL is on the session, in GET /o/{org}/sessions/{id} and in the run.completed webhook, and your handler comments it on the Linear issue. The transcript keeps the uv sync, the test run and every file the agent read, so a reviewer sees that a permission change was checked against tests/unit/forum/test_topic_page_permissions.py and not only described.
Before merging, a reviewer checks the acceptance criteria against the diff, confirms the new test fails on the old code, and reads any change to a permission with the plugin system in mind, since flaskbb_load_blueprints is a pluggy hook and plugins register views the same way.
Run it on every Linear issue labeled agent
Create an automation with a linear trigger on linear.issue.labeled, the label in config.labels and the team keys in config.teams. Each labeled issue starts one run with the issue as its context and this prompt. Changes made by an app integration never fire, so a label added by a bot starts nothing.
Pair it with a linear.issue.state_changed trigger whose config.states maps a review state to plan: that run changes no code and posts a plan as a comment on the issue through the runner's Linear connection. Move the issue on, and the state mapped to exec starts the run that opens the pull request.
The use case this job follows, with its automation and trigger: Turn a Linear label into a PR.
Why run it on Rush?
FlaskBB's suite runs on an in-memory SQLite database and eager Celery, so it is fast, but the project's tooling is uv, tox, ruff and basedpyright, and a ticket is not worth setting all of that up on a laptop. On Rush the sandbox installs from uv.lock, runs the suite and is discarded, and the output stays with the run.
Each ticket gets its own sandbox, so three small tickets about the user settings page run at once without sharing a checkout. The pull request quotes the test run, and the transcript shows which views and services the agent read, which is what a reviewer needs to trust a change to a permission check.
Frequently asked questions
How does the run get the issue?
From a resources entry with the Linear issue URL, read through your Linear connection and put into the prompt before the run starts. Connect Linear once with POST /me/connections and the app type, then name the issue URL on each run.
Does the agent comment on the issue?
No. A Linear sign-in cannot yet be named in a run's connections, so the sandbox has no Linear tools. The pull request URL comes back on the session and in the webhook, and your handler posts it.
Does it need PostgreSQL or Redis?
Not for the tests. TestingConfig uses sqlite:// and runs Celery tasks in process. The postgres extra in pyproject.toml is for deployments.
Will it touch the plugins?
Only if the ticket is about one. flaskbb-plugin-conversations and flaskbb-plugin-portal are dependencies, and the test app blocks every plugin not listed in tested_plugins, so a core change is tested without them.