What the agent does
The agent begins with the test setup as it is. In a Rails app like lobsters/lobsters it reads .ruby-version (Ruby 4.0.0), the Gemfile (an unpinned rails, sqlite3 for every environment, solid_queue and solid_cache, and in the test group rspec-rails, factory_bot_rails, database_cleaner, capybara, simplecov with require: false, standard, brakeman, vcr and webmock), .rspec (--require spec_helper) and spec/rails_helper.rb, which requires SimpleCov, calls SimpleCov.start "rails", loads spec/support/**/*.rb, and in before(:suite) creates a System user and a category1 category with the tags placeholder, tag1 and tag2 that every spec can rely on. config/database.yml.sample defines primary, cache, queue and rack_attack SQLite databases per environment, and .github/workflows/check.yml shows the exact test sequence CI uses: copy .github/workflows/check/* into config/, copy the database sample into place, ./bin/rails db:schema:load db:migrate, then bundle exec rspec, with libvips installed first.
It runs that same sequence in the sandbox so coverage/ is written (the directory is gitignored), then reads coverage/.last_run.json and the per-file table in coverage/index.html to rank app/controllers/. It also compares the controller list against spec/requests/ and spec/controllers/ directly: stories, comments, home, settings, login, signup, messages, tags and the mod/ controllers have request specs, while hats_controller.rb (index, doff, doff_by_user, edit, update_in_place, update_by_recreating), invitations_controller.rb (build, index, confirm_email, create, create_by_request, send_for_request, delete_request), filters_controller.rb, suggestions_controller.rb, categories_controller.rb and avatars_controller.rb have none, even though some of them have a feature spec under spec/features/ that drives the browser instead of the request layer.
For each chosen controller the agent writes one file in spec/requests/, in the style of spec/requests/tags_spec.rb: describe "...", type: :request, let(:user) { create(:user, :admin) }, sign_in user from AuthenticationHelper::RequestHelper (which posts to /login), then plain get and post calls against the real paths from config/routes.rb (/invitations/request, /invitations/confirm/:code, /filters, /categories/new, /hats/:id/edit) with expectations on the redirect, the flash and the rows written. Factories already exist for hat, invitation, tag, story, comment and user with traits such as :banned and :noinvite, so the specs create data through them rather than through fixtures. Where a controller branches on @user.can_invite? or require_logged_in_moderator, the spec covers both the allowed and the refused path, because that is where the untested code is.
It re-runs bundle exec rspec, then bundle exec standardrb on the new files since CI's lint job runs it, and records the coverage of each controller before and after from SimpleCov's output. Production code under app/ is left unchanged; the README says testing is deliberately lighter for moderator features, so the pull request description says which controllers it chose and which it left alone and why.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Set up the test database the way .github/workflows/check.yml does and run the suite with SimpleCov. From the coverage report and the spec directory, find the controllers with the lowest coverage, and write request specs for their actions in spec/requests using the existing factories, the sign_in helper and the real routes. Cover the refused paths as well as the happy ones. Run bundle exec rspec and standardrb, and open a pull request with the coverage before and after for each controller. Do not change production code.",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
]
}- 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
What comes back is a pull request on a new branch that adds request specs under spec/requests/, for example invitations_spec.rb, hats_spec.rb, filters_spec.rb, suggestions_spec.rb and categories_spec.rb, each using create(:user, ...), sign_in and the routes as written in config/routes.rb. No file under app/, config/ or db/ changes, and the Gemfile is untouched because SimpleCov and FactoryBot were already there.
The description holds a small table of the controllers it covered with their SimpleCov line coverage before and after, the bundle exec rspec summary line, and the standardrb result. The trajectory keeps the full output of the schema load, the first coverage run and the final run, so a reviewer can check that the new specs ran against the same database setup CI uses.
Before merging, a reviewer checks that the specs assert on behaviour (a redirect to /settings with a flash when a user cannot invite, an InvitationRequest marked verified after /invitations/confirm/:code) rather than on template text, that nothing relies on ordering between specs given DatabaseCleaner runs with the transaction strategy, and that moderator paths use a user with the right flags rather than stubbing require_logged_in_moderator.
Run it on every Monday morning
Create an automation in the Project with this prompt and a schedule trigger (cron 0 7 * * 1 in your timezone). Each week the run re-measures coverage and takes the next lowest controllers, so the suite grows a few request specs at a time and each pull request stays small enough to read before standup.
Give the API key a webhook URL so run.completed arrives with the session_url; a handler on your side can post the pull request link to the channel where tests are reviewed. A run whose new specs do not pass ends without a pull request and says why in its result.
The use case this job follows, with its automation and trigger: Write the missing tests.
Why run it on Rush?
A Rails suite with four SQLite databases, a credentials workaround and a libvips dependency takes real setup before the first spec runs. On Rush the agent does that setup in a sandbox from the CI workflow itself, keeps the schema load and the SimpleCov output in the record, and nothing is installed on a laptop or left behind in a shared test database.
Coverage work is repetitive and easy to put off, and it is exactly the kind of job that runs well in parallel: one sandbox per application, each returning a pull request whose description already carries the before and after numbers. The reviewer reads specs, not setup logs.
Frequently asked questions
Request specs or controller specs?
Request specs, because that is what the repository writes for new coverage (spec/requests/ has over twenty files, spec/controllers/ six older ones) and because they exercise routing, before_actions and the session the way a browser does. The agent follows the existing style in tags_spec.rb and stories_spec.rb.
Does it need MySQL or Postgres?
No. This application runs its tests on SQLite as config/database.yml.sample describes, with separate files for the primary, cache, queue and rack_attack databases. The agent copies the sample into place exactly as the CI workflow does.
Will it add gems?
Not for this job. SimpleCov, RSpec, FactoryBot and DatabaseCleaner are already in the Gemfile's test group. If a repository lacked SimpleCov the agent would add it to the test group and note the change, but here the Gemfile and lockfile stay as they are.
What about the feature specs that already cover hats and filters?
They stay. A Capybara feature spec drives the page; a request spec checks the controller's branches, redirects and database effects directly and runs faster. The pull request description says which controllers already had feature coverage so a reviewer can judge the overlap.
Does it run brakeman and database_consistency too?
It runs standardrb because the new files must pass the lint job. Brakeman and database_consistency check app/ and the schema, which this job does not change, so the agent leaves them to CI and says so.