Two-Process Architecture
Relevant source files
The following files were used as context for generating this wiki page:
The AI Code Reviewer system utilizes a two-process architecture designed to decouple fast-response HTTP requirements from high-latency background tasks. This structure ensures that the system remains responsive to GitHub webhooks while performing intensive operations such as Large Language Model (LLM) calls and codebase indexing.
The architecture consists of a web server (apps/web) and a background worker (apps/worker), both of which share a single PostgreSQL database. This separation allows the web server to acknowledge GitHub events within the required time window (typically < 5 seconds) by offloading the actual processing—which can take 10–30 seconds—to the background worker.
Sources: README.md:144-160, CLAUDE.md:21-36
Core Components
The system is split into two distinct execution environments that communicate through a job queue managed within the shared database.
| Component | Responsibility | Technology Stack |
|---|---|---|
| Web Server | UI rendering, Auth, Webhook intake, API routes. | Next.js, Node.js |
| Worker | Background job execution, LLM calls, RAG indexing. | Plain Node.js |
| Database | Shared state, Persistence, Job queue (pg-boss). | PostgreSQL (with pgvector) |
Sources: README.md:144-156, README.md:162-167
apps/web (Next.js Server)
The web process serves as the entry point for users and external services. It handles HTTP requests, serves the dashboard UI, manages GitHub OAuth flows, and receives incoming webhooks from GitHub. Its primary role in the "Two-Process" flow is to verify webhook signatures, store the raw event data, and enqueue a background job. It does not perform heavy business logic inline.
Sources: README.md:148-151, apps/web/package.json:20-37
apps/worker (Node.js Process)
The worker process runs continuously in the background. It polls the pgboss queue for new tasks, such as webhook.process or review.pr. It performs the "heavy lifting," including cloning/indexing repositories via Tree-sitter AST parsing, calling LLM APIs (OpenAI/Anthropic), and posting results back to GitHub.
Sources: README.md:152-154, packages/ingestion/src/index-repository.ts:31-35, packages/review/src/orchestrator.ts:33-40
Data Flow and Job Queue
The system uses pg-boss for job orchestration. This allows the system to maintain a single database dependency while achieving transactional job enqueuing.
The following diagram illustrates the flow from an external GitHub event through both processes:
The diagram shows how apps/web receives events and uses the DB-backed queue to trigger apps/worker for high-latency tasks.
Sources: README.md:162-172, README.md:18-45
Job Lifecycle
- Ingestion: When a webhook hits
/api/webhooks/github, the web server verifies the signature and creates aWebhookDeliveryrecord. It then enqueuesJobNames.webhook.process. - Routing: The worker picks up the delivery and routes it based on event type (e.g.,
pull_request). For PRs, it creates anAiReviewrecord inPENDINGstate and enqueuesJobNames.ReviewPr. - Execution: The worker picks up the
review.prjob, fetches PR files, calls the LLM for each file, aggregates the review, and posts it to GitHub.
Sources: packages/ingestion/src/process-webhook.ts:30-65, packages/review/src/orchestrator.ts:40-75
Database Schema for Orchestration
The shared database contains specific models to track progress and ensure idempotency across the two processes.
- WebhookDelivery: Stores the raw payload and
processedAttimestamp to prevent duplicate processing of GitHub re-deliveries. - AiReview: Tracks the status of a specific review (
PENDING,RUNNING,COMPLETED,FAILED). - Job Queue (pg-boss): Native PostgreSQL tables that store job payloads and schedules.
Sources: README.md:195-207, packages/ingestion/src/process-webhook.ts:133-155
Architectural Decisions
| Decision | Rationale |
|---|---|
| Manual DI | container.ts wires Prisma and GitHub clients explicitly for end-to-end type safety without magic. |
| One Database | Using Postgres for app data, the queue (pg-boss), and vectors (pgvector) simplifies operations. |
| Comment Mode | The architecture is designed for advisory reviews that never block merges. |
| Separation of Concerns | Route handlers in web never contain business logic; services in packages/ are process-agnostic. |
Sources: README.md:174-185, README.md:295-310
Implementation of Background Handlers
The background worker utilizes specialized handlers for different stages of the review and RAG lifecycle.
Codebase Indexing (Layer 1)
When a repository is enabled, the worker triggers handleIndexRepository. This fetches the file tree and chunks code files using Tree-sitter before generating embeddings.
// Example from packages/ingestion/src/index-repository.ts
export function createIndexRepositoryHandler(deps: IndexRepositoryDeps) {
return async function handleIndexRepository(job: { data: IndexRepositoryPayload }): Promise<void> {
// ... repository discovery logic ...
await prisma.repository.update({
where: { id: repo.id },
data: { ingestionState: 'CHUNKING' },
});
// Batch processing of files for indexing
};
}
Sources: packages/ingestion/src/index-repository.ts:42-75
Review Orchestration
The handleReviewPr function manages the state transition of a review and coordinates between the GitHub API and LLM clients.
Sequence diagram of the background worker executing a review job.
Sources: packages/review/src/orchestrator.ts:40-100, packages/review/src/orchestrator.ts:205-235
Conclusion
The two-process architecture is the foundation of the AI Code Reviewer's reliability and scalability. By separating the synchronous web response from the asynchronous AI review and indexing pipeline, the system maintains high availability while handling the variable and often significant latencies associated with LLM and GitHub API integrations.
Sources: README.md:144-156, CLAUDE.md:231-238