Architecture
Three processes, one database, and a clear chain boundary.
ForkReason runs as three durable processes:
ProcessResponsibility
forkreason-webNext.js frontend. Renders the product surface.
forkreason-apiFastAPI. Validation, job creation, case and evidence reads, chain read endpoints.
forkreason-workerDurable analysis worker. Runs the forensic pipeline outside any request.
The job queue
Jobs live in PostgreSQL and are claimed with FOR UPDATE SKIP LOCKED. No Redis: the server already runs PostgreSQL, and one fewer broker is one fewer failure mode.
- A crashed worker's job is recovered when its lease expires, because the lease is deliberately preserved on the failure path.
- Repeating failures are stopped rather than retried forever.
- Resubmitting the same pinned pair does not duplicate work: the idempotency key is unique.
Data model
- RepositorySnapshot — an immutable pinned view at one commit.
- AnalysisJob — durable work with real stage states.
- Case — a pointer to the current revision number, never mutable verdict fields.
- CaseRevision — append-only, with a unique (case, revision) constraint.
- EvidenceItem, EvidenceRelation, AlternativeExplanation, Challenge, ChainTransaction.
The chain boundary
The database indexes and caches chain state. It is never allowed to become the authority over on-chain revision or verdict state.