# cy-r0x/judgeengine architecture

> Architecture diagram of the GitHub repository cy-r0x/judgeengine, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/cy-r0x/judgeengine
- Repository: https://github.com/cy-r0x/judgeengine

## Overview

1. **What this repository is**
   - This is a Go-based judge engine for `judgenot0`, not a user-facing app.
   - Its job is to receive code submissions, queue them, execute them inside `isolate`, compare output, and report verdicts back to the main system.

2. **Top-level process shape**
   - The binary appears to support multiple runtime modes through `cmd/`:
     - worker/runtime execution,
     - HTTP serving/health endpoints,
     - submission handling,
     - node registration,
     - routes and metrics.
   - That suggests one deployable engine with multiple operational entrypoints rather than separate services.

3. **Configuration boundary**
   - `config/` centralizes runtime configuration, likely from environment variables as described in the README.
   - Important settings are RabbitMQ connection details, queue name, worker count, HTTP port, engine secret key, and the server webhook endpoint.
   - This config layer is the main boundary between deployment/environment and the engine logic.

4. **Messaging and async job flow**
   - `queue/` is the RabbitMQ integration layer.
   - The engine consumes submission jobs asynchronously from a queue, which decouples the front-end/API server from execution latency.
   - `queue/connection.go`, `publisher.go`, `consumer.go`, and `amqp.go` indicate explicit broker connection management plus separate publish/consume paths.

5. **Scheduling and concurrency**
   - `scheduler/` likely coordinates workers and submission execution concurrency.
   - The README’s `WORKER_COUNT` maps directly to a parallel worker pool model, where each worker runs an isolated sandboxed job.
   - This is the engine’s main internal throughput control point.

6. **Execution pipeline**
   - `handlers/` contains the submission lifecycle logic:
     - parsing metadata,
     - compiling/running code,
     - comparing output,
     - producing verdicts.
   - The flow is likely: decode submission metadata → select language handler → compile if needed → run in `isolate` → compare output → assemble verdict.
   - `handlers/types.go`, `submission.go`, and `verdict.go` suggest this package owns the core domain objects used during evaluation.

7. **Language-specific execution adapters**
   - `languages/` contains the per-language execution definitions for C, C++, Python, and Node.js.
   - This package is the main polymorphic boundary in the engine: it abstracts compile/run commands, file naming, and runtime requirements per language.
   - C and C++ are compile-to-binary flows; Python and Node.js are interpreted flows.

8. **Sandboxing and host dependencies**
   - The architecture depends on Linux-only `isolate` for security and resource limits.
   - Actual execution is constrained by host-level capabilities: namespaces, cgroups, and installed compilers/runtimes (`gcc`, `g++`, `python3`, `node`/`nodejs`).
   - This means execution is intentionally split between Go orchestration and OS-level sandboxing.

9. **Verdict and comparison logic**
   - `handlers/compare.go` and `compare_float.go` indicate two output comparison modes:
     - strict comparison,
     - tolerant floating-point comparison.
   - `handlers/verdict.go` likely normalizes execution results into the engine’s verdict model before reporting upstream.
   - This is a key correctness boundary separate from raw process execution.

10. **Integration back to the main server**
   - The engine does not appear to own the full judging system; it reports results to an external server.
   - The README’s `SERVER_ENDPOINT` and `ENGINE_KEY` suggest authenticated webhook callbacks to a central API after each verdict.
   - So the data flow is: main server enqueues submission → engine consumes and judges → engine posts verdict back to main server.

11. **HTTP and observability**
   - `cmd/serve.go`, `cmd/routes.go`, and `cmd/prom.go` indicate lightweight HTTP endpoints for operational use.
   - These are likely for health checks, internal debugging, and Prometheus-style metrics rather than user traffic.
   - That makes HTTP a side channel for observability, while RabbitMQ is the primary work transport.

12. **Core domain models**
   - `structs/` contains the shared data contracts:
     - `submission`,
     - `verdict`,
     - `worker`.
   - These structs likely travel across the queue, scheduler, handlers, and webhook boundary, so they define the stable internal schema of the engine.

13. **Utility layer**
   - `utils/sendResponse.go` suggests a small support layer for HTTP responses or internal API responses.
   - This is peripheral compared to the queue/execution pipeline, but it helps indicate the repo also exposes some service endpoints, not just background workers.

14. **Architecture summary for a diagram**
   - The main diagram should show:
     - external API/server submitting jobs,
     - RabbitMQ as the async buffer,
     - Go engine workers/scheduler as consumers,
     - `languages` + `handlers` as execution/comparison logic,
     - `isolate` plus host compilers/runtimes as the execution substrate,
     - webhook callback back to the main server,
     - optional HTTP/metrics endpoints for operations.

Main entry points: [`handlers/handler.go`](https://github.com/cy-r0x/judgeengine/blob/main/handlers/handler.go) (Submission flow), [`scheduler/scheduler.go`](https://github.com/cy-r0x/judgeengine/blob/main/scheduler/scheduler.go) (Scheduler), [`config/config.go`](https://github.com/cy-r0x/judgeengine/blob/main/config/config.go) (Config), [`languages/c.go`](https://github.com/cy-r0x/judgeengine/blob/main/languages/c.go) (Languages)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_external["External systems"]
  node_main_server["Main server<br/>external API"]
  node_rabbitmq["RabbitMQ<br/>message broker"]
  node_isolate{{"isolate<br/>sandbox"}}
  node_toolchain["Host runtimes<br/>compilers/runtime"]
end

subgraph group_engine["Judge engine"]
  node_config["Config<br/>[config.go]"]
  node_queue_layer["Queue layer<br/>amqp adapter<br/>[amqp.go]"]
  node_scheduler["Scheduler<br/>worker pool<br/>[scheduler.go]"]
  node_submission_handlers["Submission flow<br/>judge pipeline<br/>[handler.go]"]
  node_meta_parse["Meta parse<br/>request parsing<br/>[parse_meta.go]"]
  node_compare["Compare<br/>output checker<br/>[compare.go]"]
  node_verdicts["Verdicts<br/>result model<br/>[verdict.go]"]
  node_languages["Languages<br/>runtime adapters<br/>[c.go]"]
  node_language_c["C / C++<br/>compiled adapters<br/>[cpp.go]"]
  node_language_py_node["Python / Node<br/>interpreted adapters<br/>[python.go]"]
  node_submission_model["Submission<br/>domain model<br/>[submission.go]"]
  node_verdict_model["Verdict model<br/>domain model<br/>[verdict.go]"]
  node_worker_model["Worker model<br/>domain model<br/>[worker.go]"]
end

subgraph group_ops["Ops entrypoints"]
  node_run_cmd["Run worker<br/>entrypoint<br/>[run.go]"]
  node_serve_cmd["HTTP serve<br/>entrypoint<br/>[serve.go]"]
  node_metrics_cmd["Metrics<br/>entrypoint<br/>[prom.go]"]
  node_routes_cmd["Routes<br/>entrypoint<br/>[routes.go]"]
  node_submit_cmd["Submit mode<br/>entrypoint<br/>[submit.go]"]
  node_register_cmd["Register node<br/>entrypoint<br/>[register_node.go]"]
end

node_main_server -->|"enqueue"| node_rabbitmq
node_rabbitmq -->|"consume/publish"| node_queue_layer
node_config -->|"broker settings"| node_queue_layer
node_config -->|"worker count"| node_scheduler
node_config -->|"engine settings"| node_submission_handlers
node_scheduler -->|"dispatch"| node_submission_handlers
node_submission_handlers -->|"parse"| node_meta_parse
node_meta_parse -->|"select adapter"| node_languages
node_languages -->|"compiled languages"| node_language_c
node_languages -->|"interpreted languages"| node_language_py_node
node_language_c -->|"compile"| node_toolchain
node_language_py_node -->|"execute"| node_toolchain
node_submission_handlers -->|"sandbox run"| node_isolate
node_submission_handlers -->|"check output"| node_compare
node_compare -->|"normalize"| node_verdicts
node_submission_handlers -->|"build verdict"| node_verdict_model
node_verdicts -->|"callback"| node_main_server
node_worker_model -->|"coordination"| node_scheduler
node_submission_model -->|"input schema"| node_submission_handlers
node_run_cmd -->|"start workers"| node_scheduler
node_serve_cmd -->|"wire routes"| node_routes_cmd
node_serve_cmd -->|"expose metrics"| node_metrics_cmd
node_register_cmd -->|"register node"| node_main_server
node_submit_cmd -->|"submit job"| node_queue_layer

click node_config "https://github.com/cy-r0x/judgeengine/blob/main/config/config.go"
click node_queue_layer "https://github.com/cy-r0x/judgeengine/blob/main/queue/amqp.go"
click node_scheduler "https://github.com/cy-r0x/judgeengine/blob/main/scheduler/scheduler.go"
click node_submission_handlers "https://github.com/cy-r0x/judgeengine/blob/main/handlers/handler.go"
click node_meta_parse "https://github.com/cy-r0x/judgeengine/blob/main/handlers/parse_meta.go"
click node_compare "https://github.com/cy-r0x/judgeengine/blob/main/handlers/compare.go"
click node_verdicts "https://github.com/cy-r0x/judgeengine/blob/main/handlers/verdict.go"
click node_languages "https://github.com/cy-r0x/judgeengine/blob/main/languages/c.go"
click node_language_c "https://github.com/cy-r0x/judgeengine/blob/main/languages/cpp.go"
click node_language_py_node "https://github.com/cy-r0x/judgeengine/blob/main/languages/python.go"
click node_submission_model "https://github.com/cy-r0x/judgeengine/blob/main/structs/submission.go"
click node_verdict_model "https://github.com/cy-r0x/judgeengine/blob/main/structs/verdict.go"
click node_worker_model "https://github.com/cy-r0x/judgeengine/blob/main/structs/worker.go"
click node_run_cmd "https://github.com/cy-r0x/judgeengine/blob/main/cmd/run.go"
click node_serve_cmd "https://github.com/cy-r0x/judgeengine/blob/main/cmd/serve.go"
click node_metrics_cmd "https://github.com/cy-r0x/judgeengine/blob/main/cmd/prom.go"
click node_routes_cmd "https://github.com/cy-r0x/judgeengine/blob/main/cmd/routes.go"
click node_submit_cmd "https://github.com/cy-r0x/judgeengine/blob/main/cmd/submit.go"
click node_register_cmd "https://github.com/cy-r0x/judgeengine/blob/main/cmd/register_node.go"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main_server,node_rabbitmq,node_isolate,node_toolchain toneBlue
class node_config,node_queue_layer,node_scheduler,node_submission_handlers,node_meta_parse,node_compare,node_verdicts,node_languages,node_language_c,node_language_py_node,node_submission_model,node_verdict_model,node_worker_model toneAmber
class node_run_cmd,node_serve_cmd,node_metrics_cmd,node_routes_cmd,node_submit_cmd,node_register_cmd toneMint
```

## Components

### External systems

Outside services and host-level dependencies the engine relies on.

- **Main server**: external API · Upstream system that enqueues submissions and receives verdict callbacks.
- **RabbitMQ**: message broker · Asynchronous queue that buffers submission jobs between server and workers.
- **isolate**: sandbox · Linux sandbox used to run submissions with resource limits and isolation.
- **Host runtimes**: compilers/runtime · Installed language toolchain used by language adapters to compile or execute code.

### Judge engine

Core packages inside this repository that move submissions through judging.

- [Config](https://github.com/cy-r0x/judgeengine/blob/main/config/config.go): runtime config · Centralized environment-driven settings for broker, workers, HTTP, and webhook access. · `config/config.go`
- [Queue layer](https://github.com/cy-r0x/judgeengine/blob/main/queue/amqp.go): amqp adapter · RabbitMQ connection, publishing, and consuming logic. · `queue/amqp.go`
- [Scheduler](https://github.com/cy-r0x/judgeengine/blob/main/scheduler/scheduler.go): worker pool · Coordinates worker concurrency and submission execution throughput. · `scheduler/scheduler.go`
- [Submission flow](https://github.com/cy-r0x/judgeengine/blob/main/handlers/handler.go): judge pipeline · Owns submission parsing, execution orchestration, and verdict assembly. · `handlers/handler.go`
- [Meta parse](https://github.com/cy-r0x/judgeengine/blob/main/handlers/parse_meta.go): request parsing · Extracts submission metadata and selects the execution path. · `handlers/parse_meta.go`
- [Compare](https://github.com/cy-r0x/judgeengine/blob/main/handlers/compare.go): output checker · Performs strict output comparison and floating-point tolerant comparison. · `handlers/compare.go`
- [Verdicts](https://github.com/cy-r0x/judgeengine/blob/main/handlers/verdict.go): result model · Normalizes execution outcomes into verdicts reported upstream. · `handlers/verdict.go`
- [Languages](https://github.com/cy-r0x/judgeengine/blob/main/languages/c.go): runtime adapters · Per-language compile and run definitions for supported submissions. · `languages/c.go`
- [C / C++](https://github.com/cy-r0x/judgeengine/blob/main/languages/cpp.go): compiled adapters · Adapters for compiled languages that build a binary before execution. · `languages/cpp.go`
- [Python / Node](https://github.com/cy-r0x/judgeengine/blob/main/languages/python.go): interpreted adapters · Adapters for interpreted runtimes executed directly by the sandbox. · `languages/python.go`
- [Submission](https://github.com/cy-r0x/judgeengine/blob/main/structs/submission.go): domain model · Shared submission data contract passed across queue, scheduler, and handlers. · `structs/submission.go`
- [Verdict model](https://github.com/cy-r0x/judgeengine/blob/main/structs/verdict.go): domain model · Shared verdict data contract used to report results back to the main server. · `structs/verdict.go`
- [Worker model](https://github.com/cy-r0x/judgeengine/blob/main/structs/worker.go): domain model · Worker state and identity used by the scheduler and runtime orchestration. · `structs/worker.go`

### Ops entrypoints

HTTP and process entrypoints used to run or observe the engine.

- [Run worker](https://github.com/cy-r0x/judgeengine/blob/main/cmd/run.go): entrypoint · Starts the worker/runtime execution mode. · `cmd/run.go`
- [HTTP serve](https://github.com/cy-r0x/judgeengine/blob/main/cmd/serve.go): entrypoint · Starts lightweight HTTP service endpoints for operations. · `cmd/serve.go`
- [Metrics](https://github.com/cy-r0x/judgeengine/blob/main/cmd/prom.go): entrypoint · Exposes Prometheus-style operational metrics. · `cmd/prom.go`
- [Routes](https://github.com/cy-r0x/judgeengine/blob/main/cmd/routes.go): entrypoint · Registers HTTP routes for health and support endpoints. · `cmd/routes.go`
- [Submit mode](https://github.com/cy-r0x/judgeengine/blob/main/cmd/submit.go): entrypoint · Handles submission-related process mode and wiring. · `cmd/submit.go`
- [Register node](https://github.com/cy-r0x/judgeengine/blob/main/cmd/register_node.go): entrypoint · Registers the engine node with the main system. · `cmd/register_node.go`

## Connections

- Main server → RabbitMQ: enqueue · The upstream system places submissions onto the broker.
- RabbitMQ → Queue layer: consume/publish · The engine connects to the broker through its AMQP layer.
- Config → Queue layer: broker settings · Queue connection and queue names are configured centrally.
- Config → Scheduler: worker count · Runtime concurrency is driven by environment configuration.
- Config → Submission flow: engine settings · Handler behavior depends on shared runtime settings and secrets.
- Scheduler → Submission flow: dispatch · The scheduler sends jobs into the judging pipeline.
- Submission flow → Meta parse: parse · Submission metadata is decoded before execution starts.
- Meta parse → Languages: select adapter · Parsed metadata determines which language adapter runs.
- Languages → C / C++: compiled languages · C and C++ use compile-then-run adapter logic.
- Languages → Python / Node: interpreted languages · Python and Node.js use direct execution adapter logic.
- C / C++ → Host runtimes: compile · Compiled language adapters depend on host compilers.
- Python / Node → Host runtimes: execute · Interpreted runtimes depend on installed host interpreters.
- Submission flow → isolate: sandbox run · Execution happens inside the isolate sandbox.
- Submission flow → Compare: check output · Produced output is compared against expected results.
- Compare → Verdicts: normalize · Comparison results are converted into verdict objects.
- Submission flow → Verdict model: build verdict · The pipeline assembles the final verdict contract.
- Verdicts → Main server: callback · Final verdicts are posted back to the main system.
- Worker model → Scheduler: coordination · Worker state is managed as part of scheduling.
- Submission → Submission flow: input schema · Submission records flow through the judging pipeline.
- Run worker → Scheduler: start workers · Worker entrypoint boots the scheduling and execution loop.
- HTTP serve → Routes: wire routes · HTTP service loads route definitions.
- HTTP serve → Metrics: expose metrics · Operational metrics are served alongside HTTP endpoints.
- Register node → Main server: register node · Node registration reaches the upstream system.
- Submit mode → Queue layer: submit job · Submission mode can publish work into the broker.
