All jobs

Add Health Checks to an ASP.NET Core App from a Linear Issue

Yes. An agent picks up the Linear issue, adds liveness and readiness checks to your ASP.NET Core app, tests them and opens a pull request.

Run this on RushIn a Project that has your repository.

What the agent does

The agent clones the repository into its own cloud sandbox and first finds what the app already has, because a .NET solution built on Aspire usually maps health endpoints before anyone asks for them. In a solution like jasontaylordev/CleanArchitecture (SDK 10.0.402 in global.json, packages pinned in Directory.Packages.props), src/ServiceDefaults/Extensions.cs has AddDefaultHealthChecks, which registers one check named self tagged live, and MapDefaultEndpoints, which maps /health for every check and /alive for the live ones. Both are mapped only inside if (app.Environment.IsDevelopment()), under a comment pointing to the Aspire guidance on exposing them in other environments. So today the endpoints exist, under different paths, return plain text, and are absent in production.

Next it looks for the database check the issue's ready endpoint needs. src/Web/Web.csproj already references Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore (version 10.0.13 in Directory.Packages.props), but nothing in src/ calls AddDbContextCheck, so the package is there and no check uses it. src/Infrastructure/DependencyInjection.cs registers ApplicationDbContext against SQLite, PostgreSQL or SQL Server depending on template symbols, and the PostgreSQL and SQL Server branches also call Aspire's EnrichNpgsqlDbContext or EnrichSqlServerDbContext. The agent checks whether that enrichment already adds a check for the context before adding its own, so the ready endpoint does not report the database twice under two names.

Then it makes the change in the file that owns health checks rather than in Program.cs: in Extensions.cs it adds a ready-tagged AddDbContextCheck<ApplicationDbContext>() (or tags the existing one), maps /health/live to the live checks and /health/ready to the ready ones, and sets ResponseWriter on both HealthCheckOptions so the body is JSON with the overall status and each check's name, status and duration. Whether the endpoints leave the development-only block is a decision for the issue's author, so the agent keeps them where the issue says, and if the issue does not say, it leaves the block alone and asks on the pull request. src/Web/Program.cs already calls app.MapDefaultEndpoints(), so it needs no edit.

Last, it writes the tests where the solution's tests already run against a real app. tests/Application.FunctionalTests starts TestAppHost with DistributedApplicationTestingBuilder, waits for the database resource to be healthy and builds a WebApiFactory, a WebApplicationFactory<Program> that sets ConnectionStrings:CleanArchitectureDb. The agent adds tests that call /health/live and /health/ready through that factory and read the JSON, and one where the database is unreachable and ready reports Unhealthy while live stays Healthy. It runs dotnet test the way .github/workflows/build.yml does, after dotnet restore and dotnet build, and fixes what fails before it pushes.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "codex",
  "input": "A Linear issue labeled agent says: \"Add Health Checks to an ASP.NET Core App. Add /health/live and /health/ready endpoints with ASP.NET Core health checks, where ready checks the database, and return JSON with each check's status.\" Before changing anything, find where this solution already registers and maps health checks (AddHealthChecks, MapHealthChecks, any Aspire ServiceDefaults project) and whether the endpoints are limited to Development, and list it in the pull request. Extend that code rather than adding a second registration: live runs only the checks tagged live, ready runs a database check through the EF Core DbContext, and both write JSON with the overall status and each check's name, status and duration. Do not change which environments expose the endpoints unless the issue says so; ask in the pull request instead. Add tests in the existing functional or integration test project, including one where the database is unreachable, run dotnet restore, dotnet build and dotnet test until they pass, and open a pull request that links back to the issue.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
  1. 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.
  2. 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.
  3. 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 its own branch, linked to the Linear issue. In a solution shaped like CleanArchitecture, the diff is small: src/ServiceDefaults/Extensions.cs gains the database check and the two mapped paths with a JSON response writer, and a new test class sits in tests/Application.FunctionalTests. The description lists what was already there (/health, /alive, the self check, the unused EF Core health check package), what changed, and the open question about exposing the endpoints outside Development.

The pull request's own checks run the solution's workflow: .github/workflows/build.yml restores, builds in Release and runs dotnet test on every pull request to main. The session's transcript keeps every command the agent ran in its sandbox with its output, so a reviewer can read the failing test run that came before the fix, not only the passing one.

Before merging, a reviewer checks that the old /health and /alive paths still answer for anything that probes them (an Aspire dashboard, a container orchestrator's liveness probe) or that the pull request says they moved, that the ready check uses the same connection string the app does, and that the JSON body exposes no connection string or exception detail to whoever can reach the endpoint.

Run it on every Linear issue labelled agent

Add an automation in the console with a linear trigger on linear.issue.labeled for the label agent, and every issue labelled that way starts one run in the Project's repository with the issue as its context. Changes an app integration makes never fire the trigger, so an agent's own comment on the issue does not start another run.

To start runs from your own service instead, send one POST /o/{org}/sessions per issue with the repository in resources, and the issue's https://linear.app/<workspace>/issue/<ID> URL beside it to have Rush read the issue through your Linear connection. Give the API key a webhook URL and Rush posts run.completed or run.failed when each turn finishes.

The use case this job follows, with its automation and trigger: Turn a Linear label into a PR.

Why run it on Rush?

Health checks only prove anything when the app starts and the database is really there. A Rush sandbox has its own .NET SDK, restores the solution's packages and starts the Aspire test host and its database on its own disk, so the agent runs the same dotnet test the workflow runs, including the case where the database is down, without anyone's local SQL Server or Docker state being touched.

The label is the only step a person takes, and the result arrives with its evidence: the transcript holds each dotnet command with its output, the pull request carries the workflow's checks, and the description says what existed before. Several labelled issues across services can run at once, each in its own sandbox and on its own branch.

Frequently asked questions

My app uses Aspire ServiceDefaults. Will it add a second set of health checks?

No. The prompt has the agent find AddDefaultHealthChecks and MapDefaultEndpoints first and extend them, so there is still one place where checks are registered and mapped. The pull request lists what was there before it changed anything.

Will the endpoints be exposed in production?

Only if the issue says so. The Aspire template maps health endpoints in Development only, on purpose, and the agent keeps that unless told otherwise. When the issue does not say, it asks in the pull request, because exposing them is a security decision and not an implementation detail.

Which database does the ready check use?

The one your DbContext is configured with. AddDbContextCheck runs a connection test through the registered context, so it follows whatever provider and connection string the app uses, whether SQLite, PostgreSQL or SQL Server.

How is the JSON response shaped?

The agent sets a ResponseWriter on HealthCheckOptions that writes the overall status and, for each check, its name, status and duration. If your team already has a format, such as one an orchestrator or a dashboard reads, name it in the issue and the agent writes that shape instead.