This is the reviewer path for DevHire Cloud's flagship code-assessment workflow. It proves a production-shaped, Java-first LeetCode experience without moving trust to the browser: candidates run visible cases, final submissions execute visible and hidden cases server-side, employers review evidence, and admins monitor runner health.
| Area | Contract |
|---|---|
| Candidate submission | class CandidateSolution { String solve(String input) { ... } } |
| Java source rules | No package, no public class CandidateSolution, no JUnit or @Test requirement |
| Active challenge | Cloud Architecture Challenge, internal slug java-cloud-architecture |
| Test fixtures | Versioned visible/hidden cases with stdin, expected_output, weight, time limit, and memory limit |
| Output comparison | Runner normalizes line endings, trims trailing whitespace per line, then trims final output |
| Final score | 75% weighted runtime cases plus 25% static quality/security rubric |
| Trust boundary | application-service owns assignment, hidden cases, score, submission history, audit, and review; assessment-runner-service only executes code |
| Claim | Evidence |
|---|---|
| Candidate workflow is product-grade | /candidate/assessments includes challenge queue, problem statement, examples, visible cases, Monaco Java editor with textarea fallback, custom input, run output, rubric, risk signals, and history |
| Hidden fixtures do not leak | Candidate APIs and UI expose visible runs only; final submission hides hidden stdin, expected output, hidden stdout/stderr, and hidden compile output |
| Employer review is evidence-based | Employer dossier shows submitted code, score, verdict, risk flags, visible aggregate, hidden aggregate, time/memory, sanitized output, and attempt timeline |
| Admin/Ops can operate it | /admin surfaces accepted/wrong/compile/timeout/policy/unavailable rates, queue depth, fail-closed state, sandbox failures, risk backlog, and challenge authoring |
| Production fails closed | Production compose/Kubernetes use DEVHIRE_RUNNER_MODE=judge0 and require JUDGE0_BASE_URL; local deterministic mode is preview-only |
| Scoring stays server-owned | Browser requests cannot set score, hidden pass counts, runner verdict, code hash, or review decision |
| Audit trail is reviewable | Attempts store code hash, runner version, rubric version, risk flags, integrity risk, similarity score, run id, and employer decision |
- Sign in as
candidate@devhire.localand open/candidate/assessments. - Select
Cloud Architecture Challenge. - Review the statement, examples, visible cases, time/memory limits, and
CandidateSolution.java. - Run visible tests or custom stdin and inspect verdict, stdout, stderr, compile output, time, and memory.
- Submit and confirm the locked state, score, rubric, attempt metadata, and hidden redaction message.
- Sign in as
employer@devhire.local, open/employer, assign or open a code assessment, and inspect the review dossier. - Record
PASS,HOLD, orREJECT; the raw server score remains immutable. - Sign in as
admin@devhire.localand inspect assessment health, runner status, challenge authoring, and publish validation.
| Role | Endpoint | Behavior |
|---|---|---|
| Candidate | GET /api/candidate/code-assessments |
Lists own assignments with redacted code preview metadata |
| Candidate | GET /api/candidate/code-assessments/{id} |
Reads own assignment detail |
| Candidate | POST /api/candidate/code-assessments/{id}/run and /runs |
Runs visible cases only |
| Candidate | POST /api/candidate/code-assessments/{id}/submit and /submissions |
Executes final server-side grading and locks the assignment |
| Candidate | GET /api/candidate/code-assessments/{id}/submissions |
Lists own attempts with hidden evidence redacted |
| Employer | POST /api/employer/applications/{applicationId}/code-assessments |
Assigns the active Java challenge to an owned open application; duplicate assignment returns the existing row |
| Employer | GET /api/employer/code-assessments/{id} |
Reads employer-owned dossier detail |
| Employer | GET /api/employer/code-assessments/{id}/submissions |
Reads attempts with hidden aggregate metadata |
| Employer | PATCH /api/employer/code-assessments/{id}/review |
Records pass, hold, or reject without changing raw score |
| Admin | GET /api/admin/code-assessments/summary |
Reads grading rates, queue depth, risk backlog, and runner health |
| Admin | GET/POST/PATCH /api/admin/code-challenges |
Lists, drafts, versions, validates, publishes, or deactivates challenges |
| Internal | POST /internal/assessment-runs |
Executes Judge0-compatible runs behind the internal token boundary |
| Internal | GET /internal/assessment-runs/health |
Reports runner mode, Judge0 configuration, fail-closed reason, queue depth, and version |
| Verdict | Trusted final score? | Evidence persisted? | Candidate visibility |
|---|---|---|---|
ACCEPTED |
Yes | Yes | Visible aggregate and final score |
WRONG_ANSWER |
Yes, partial runtime score | Yes | Visible aggregate and final score |
RUNTIME_ERROR |
Yes, partial runtime score | Yes | Sanitized visible evidence |
TIME_LIMIT_EXCEEDED |
Yes, partial runtime score | Yes | Sanitized visible evidence |
COMPILE_ERROR |
No trusted final score | Yes | Compile output for visible run/final message |
POLICY_BLOCKED |
No trusted final score | Yes | Policy-blocked message |
RUNNER_UNAVAILABLE |
No trusted final score | Yes | Runner unavailable/fail-closed message |
The static rubric rewards readable Java structure, parsing robustness, simplicity, and security cleanliness. It flags starter-code-only submissions, hardcoded secrets, unsafe process/file/network boundaries, low-signal code, and non-executable signal stuffing. AI feedback is advisory only and never overrides runner verdict, risk flags, score, or employer decision.
| Signal | Purpose |
|---|---|
devhire_code_assessments{status} |
Assignment lifecycle by status, including ASSIGNED, IN_PROGRESS, SUBMITTED, REVIEWED, and EXPIRED |
devhire_code_submissions{language,status} |
Submission volume by grading status |
devhire_code_grading_requests_total{language,status} |
Server-side grading request outcome |
devhire_code_grading_latency_seconds |
Application grading latency histogram |
devhire_code_grading_score |
Average runtime-plus-static rubric score |
devhire_code_review_risk_flags{type} |
Static risk backlog |
devhire_code_review_decisions_total{decision,status} |
Employer review decisions |
devhire_code_runner_client_failures_total{language} |
Application-service runner client failures |
devhire_assessment_runner_requests_total{language,status,verdict} |
Runner request count by terminal verdict |
devhire_assessment_runner_latency_seconds |
Runner execution latency histogram |
devhire_assessment_runner_queue_depth |
In-process runner queue depth |
devhire_assessment_runner_sandbox_failures_total{reason} |
Policy and unavailable sandbox failures |
devhire_assessment_runner_fail_closed |
Fail-closed state gauge |
devhire_assessment_runner_judge0_configured |
Judge0 configuration gauge |
Focused backend:
mvn -pl common-lib,application-service,assessment-runner-service -am "-Dtest=CodeAssessmentServiceTest,CodeAssessmentControllerTest,CodeAssessmentGraderTest,AssessmentRunnerServiceTest" "-Dsurefire.failIfNoSpecifiedTests=false" testFrontend:
cd frontend
npm run typecheck
npm run e2e:code-assessment
npm run e2e:preview
npm run e2e:preview:mobileRuntime after Docker is up:
.\scripts\code-assessment-smoke.ps1 -GatewayUrl http://localhost:8080
.\scripts\runtime-observability-smoke.ps1 -GatewayUrl http://localhost:8080If Docker Desktop or another local stack already owns common ports, use the high-port parity path:
$env:GATEWAY_HOST_PORT="18080"
$env:FRONTEND_HOST_PORT="13001"
docker compose up -d --build
.\scripts\code-assessment-smoke.ps1 -GatewayUrl http://localhost:18080
.\scripts\runtime-observability-smoke.ps1 -GatewayUrl http://localhost:18080
.\scripts\reset-demo-data.ps1Live Judge0, when a runner is configured:
$env:RUN_JUDGE0_SMOKE = "1"
.\scripts\judge0-smoke.ps1 -RunnerUrl http://localhost:8089Before promoting a release that changes assessment behavior, run:
npm run typecheck
npm run e2e:preview
npm run e2e:preview:mobile
mvn -T1 test
.\scripts\api-compatibility.ps1 -ManifestOnly
docker compose config --quiet
kubectl kustomize deploy/k8sFor production-like compose, verify that config fails without JUDGE0_BASE_URL and passes when it is supplied. That is the intentional fail-closed guard.