All jobs

Explain the Architecture of an Elixir Codebase

Yes. An agent reads an Elixir codebase and returns architecture.md with the request path, schemas, Oban jobs and a diagram, citing files.

Run this on RushIn a Project that has your repository.

What the agent does

The agent starts at the endpoint and the router, which is where an Elixir web app actually forks. In a Phoenix app shaped like hexpm/hexpm, mix.exs sets app :hexpm, elixir ~> 1.20 and phoenix ~> 1.6, with ecto_sql, ecto and oban ~> 2.23. HexpmWeb.Endpoint uses Phoenix.Endpoint, plugs HexpmWeb.Plugs.Forwarded, stores the session in a cookie named _hexpm_key, and mounts a LiveView socket at /live. HexpmWeb.Router then splits pipelines: browser, api, upload, scim, varsel, readme and admin. The browser pipeline includes HexpmWeb.Plugs.Attack, a content-security-policy plug, login and default_repository. The api pipeline accepts json, elixir and erlang. The document names those pipelines before it names a feature.

The request it traces is a package page, because that is the registry's main read. The browser scope maps get /packages/:name to HexpmWeb.PackageController.show. That action calls Releases.all(package) and then Release.latest_version with only_stable and unstable_fallback, and renders the readme for that release. The schema behind it is Hexpm.Repository.Package in lib/hexpm/repository/package.ex: schema packages, a name field, belongs_to repository, has_many releases, package_owners, downloads and workload_identities, and an embed meta. build/3 casts the name, requires at least 2 bytes, matches \A[a-z][a-z0-9_]*\z, and rejects a list of reserved names. The API scope under /api has its own PackageController.show. The document follows the HTML path and points at the API route as the same schema behind a different pipeline.

Background work is Oban, and the worker worth citing is specific. Hexpm.Repository.RegistryWorker uses Oban.Worker with queue :registry and max_attempts 5. Its moduledoc describes four job types, package, package_delete, repository and full, and says a full build takes a :registry advisory lock while other builds take it shared and then lock :registry_object. config/test.exs sets Oban to testing: :manual and queues: false, and points Hexpm.RepoBase at database hexpm_test on localhost with the SQL sandbox. config/config.exs names the store buckets the app writes: repo_bucket, docs_bucket, logs_bucket and the rest, each a Hexpm.Store.Local tuple in development. The document lists RegistryWorker and the buckets, and it does not describe a queue the config does not declare.

The file it writes is architecture.md. It does not open a pull request and it does not run mix ecto.reset. If Postgres is not there to boot the endpoint, the document says the app was not started and still cites the router, the controller and the schema, which can be read without the database. The Mermaid diagram is Endpoint to the browser pipeline to PackageController.show to Package and Release, with a side edge from a publish into RegistryWorker on the registry queue.

Start it with one API call

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

{
  "agent": "codex",
  "input": "Read this Elixir repository and write architecture.md. Cover the main components and what each owns, the path of one typical request from the endpoint to the database, the data model, background jobs, and a Mermaid diagram. Cite a file path for every claim. In a tree shaped like hexpm/hexpm, start at lib/hexpm_web/endpoint.ex and lib/hexpm_web/router.ex, trace GET /packages/:name through HexpmWeb.PackageController.show to Hexpm.Repository.Package, and describe Oban from Hexpm.Repository.RegistryWorker and config/test.exs. Do not change code. If you cannot boot the app, say so and write from the source.",
  "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 architecture.md on the session's artifacts. Each artifact has a name, a mime type and a url that downloads the file with no key until url_expires_at, about an hour. A later GET of the session mints a new url. With the key, GET /o/{org}/sessions/{id}/artifacts/architecture.md returns the same file. The webhook body is a poor copy of it: result is included only up to 16 KiB.

The document's request section is the package page: Endpoint, the browser pipeline, PackageController.show, Releases.all, Release.latest_version, and the packages schema. The jobs section is RegistryWorker on queue :registry, including the four job types and the advisory lock the moduledoc describes. The diagram uses those module names. There is no commit on the repository.

A reviewer opens package.ex and checks the name regex and the reserved-name exclusion against the document, then opens registry_worker.ex and checks that the queue is :registry. A paragraph that describes a GenServer the tree does not contain is a follow-up, sent with POST /o/{org}/sessions/{id}/messages once the turn has finished. While the turn is still running that call is 409 TURN_ACTIVE.

Run it on every new teammate

When someone joins the project, your server sends this POST to https://api.prix.dev/o/{org}/sessions with the repository in resources. One session writes one architecture.md for the tree as it is that day. Use an Idempotency-Key of the repository plus the date so a double submit does not start two writers. The GitHub App has to cover the repository.

The key's webhook posts run.completed with session_url. Pull architecture.md from artifacts and hand the teammate that file. Creates past max_concurrent, 4 by default, return 429, so onboarding several people across several repositories should be a queue of these requests, not a burst.

The use case this job follows, with its automation and trigger: Produce a report or file, no repo.

Why run it on Rush?

hex.pm's router has a browser pipeline, an API pipeline, an upload pipeline and a SCIM pipeline, and the package page is a different controller from the registry rebuild. Holding that in your head while you write an onboarding doc is the work. The agent reads those files in a sandbox and cites them. You are not asked to boot Postgres locally to get the map.

The proof is the file plus the transcript of which modules were opened. A teammate can challenge a sentence by opening the path. The same request can run for the registry and for another Elixir service at the same time, each session returning its own artifact, and a follow-up wakes the parked sandbox without a second clone.

Frequently asked questions

Does it run the ExUnit suite?

No. The prompt asks for a document, not a green suite. mix test in this project creates and loads a database named hexpm_test. The agent may run it if you add that to the prompt. The document itself is written from endpoint.ex, router.ex, package_controller.ex and package.ex.

Will RegistryWorker be described as a cron?

It is an Oban worker on queue :registry with max_attempts 5. The test config turns queues off and sets testing to manual, which the document should mention so a reader does not go looking for a running queue in the test environment. The four job types come from the worker's moduledoc, not from a guess.

HTML and API both show a package. Which one is the traced request?

The HTML route, GET /packages/:name in the browser scope, because PackageController.show is where the release and the readme are chosen. The /api scope's PackageController is named as the same schema behind the api pipeline. Ask in a follow-up if you want the publish path through the upload pipeline traced the same way.

Can the document include the store buckets?

Yes. config/config.exs sets repo_bucket, docs_bucket, logs_bucket, audit_bucket and the other buckets to Hexpm.Store.Local tuples. Those are part of what the app owns, and the document cites that file. It does not invent a cloud bucket name the config does not contain.

How do I correct a bad citation?

POST /o/{org}/sessions/{id}/messages with the path that is wrong. That wakes the parked sandbox and returns 202 with status running. Send it only after the first turn leaves running, or the answer is 409 TURN_ACTIVE. The next artifact is the revised architecture.md.