Repository navigation
Features
A comprehensive list of what ACE actually does, grounded in the source. See Architecture for how these pieces fit together, and the User Manual for how to use each one from the UI.
oracle/CheckId.java is the single source of truth: every run must produce a record for every
applicable check id — a missing record is scored as FAIL, never silently dropped.
| Category | ids | weight each | What's checked |
|---|---|---|---|
| Structure | S1–S9 | 1 | task docs present, compose file present, ≥3 real Gradle services, real Gradle wrapper, parseable OpenAPI spec, React in package.json dependencies, DB migrations present |
| Planning | P1–P3 | 2 | definition sections present; subtasks carry id/goal/deps/criterion; no source written during phase 0/1 |
| Lint | M1–M4 | 1 | money never float/double (Java/Kotlin/SQL); BigDecimal imported where money is handled; no .equals() on money; point-in-time replay correctly subtracts sells |
| Build | B1–B3 | 3 | compiles in the pinned JDK container; >0 tests executed and passing (JUnit-XML verified, not just exit code); the agent's own suite fails on a seeded mutation |
| Runtime | C1, C2 | 3, 2 | ≥3 non-DB services report healthy; the declared readiness endpoint returns 200 |
| Functional | F1–F6 | 5,5,5,5,5,4 | buy/sell symmetry; point-in-time query; insufficient-balance → 422; illegal-transition → 409; exact decimal round-trip; responses conform to the OpenAPI contract |
| Bespoke | F7–F9 | 5 each | HALF_EVEN deposit rounding; exclusive asOf boundary with echo; Idempotency-Key repeat → same order, 200, no re-execution |
See the Check Registry for every id's own detailed mechanics, grounded in its
checker's own implementation. Total weight: 77. CheckStatus has five values: PASS, FAIL, NOT_ATTEMPTED (feature simply
absent — still a FAIL), SKIPPED (infra unavailable before the check ran), INFRA (infra failed
mid-check). SKIPPED/INFRA are excluded from the denominator but still block a full-score
headline — a run missing Docker never gets to claim a clean 100%, it gets a partial_* score instead.
tasks/ladder.json defines graduated rungs, each a strict subset of the full registry — e.g.
L1_migration_entity (denominator 11, no C1/C2 compose/runtime checks — though it still includes
B1/B2, which run inside Docker via Docker-outside-of-Docker), L3p_point_in_time
(plan-first variant, denominator 36), up to L7_full_platform (the full 77). A rung also fixes the
task prompt text and a default wall-clock budget — a per-job parameter, overridable from the New Job
form, not a cap baked into the rung. Choosing a rung there immediately shows its default budget and
check list (see User Manual: Jobs). See the Task Ladder for what
every rung actually asks the agent to build.
oracle/checks/BuildChecks.java never trusts the agent's own Gradle wrapper or exit code:
-
B1 — every discovered Gradle root is built with
gradle assembleinside a pinnedgradle:8.14-jdk21container image, via Docker-outside-of-Docker (see Architecture §6). -
B2 —
gradle test, verified by parsing the real JUnit XML output (executed > 0,failed == 0, no neutered/disabled test task) — a green exit code with zero tests executed is not evidence. -
B3 — a seeded mutation test: one of five syntactic mutations (
.subtract(→.add(, a dropped unary minus,-=→+=on a money line, etc.) is applied to the real arithmetic nearest aSELL/point-in-time-replay token, and the agent's own test suite must fail under it. If no such arithmetic exists to mutate, B3 isNOT_ATTEMPTED, notFAIL.
oracle/checks/ComposeChecks.java builds and runs the agent's own docker-compose.yml from a
source-only scratch copy (build artifacts stripped — a host-built jar can never legitimately ship
in an image built from source), with two anti-gaming guards checked before any build even starts:
Dockerfiles may not COPY/ADD a prebuilt artifact without --from=, and compose files may not use
absolute context/mount paths that would escape the source-only copy. C1 counts non-DB services
reporting healthy (≥3 required); C2 polls the declared readiness endpoint over real HTTP.
oracle/checks/BlackboxScenarios.java is, in its own words, "THE correctness score" — real HTTP
scenarios driven against the agent's live stack, each creating its own account (so pass^k across
scenarios is statistically meaningful) and reading time from the server's own response timestamp
(never the oracle's clock, so clock drift can't fail a correct implementation). F6 grades every
response observed by F1–F5/F7–F9 against both the frozen contract and the agent's own shipped OpenAPI
spec — it always runs last, specifically so it grades a complete set of exchanges.
Three legs, all present:
- Fixed-denominator scoring (above) — absence is failure, a crash can never raise a score.
-
A positive control (
ace-service/fixtures/positive/) — a real, substantive known-good solution that must score ≥95% on every required check, used to find the oracle's own bugs. -
Adversarial "cheat" fixtures (
ace-service/fixtures/adversarial/cheat{A-F}_*) — six fixtures, each named for the specific gaming pattern it exercises (comment-only changes, bugs hidden in the test package, renamed fields, a directory merely namedjava, stub implementations, a prebuilt jar substituted for source), each asserted to stay below 70% and/or trip the specific check it targets.
SelftestIT.java is the two-sided gate running both legs 2 and 3. There is no CI configured in this
repository, so this only runs when a developer runs the Docker-gated test suite locally.
The LLM Providers tab (LlmProvidersView, backed by agent/ProviderStore.java) is an
operator-editable list of OpenAI-wire-compatible providers — name, the stable provider/model routing
prefix, base URL, API key, and an optional default model. Seeded with five external rows (OpenAI,
OpenRouter, Anthropic, Gemini, Nebius); only Nebius ships a seeded default model
(zai-org/GLM-5.3-Flash). The local oMLX server isn't one of the seeded rows, but it's expected to be
registered as an ordinary one too, under the literal key omlx — the main model picker hardcodes that
key to resolve a bare, unprefixed model string as local. See Architecture §11 for the
routing rules and User Manual: Providers for the UI.
A one-click readiness check (service/Preflight.java, UI: PreflightView) that runs a real gradle test against the positive-control fixture in the agent's actual environment before any benchmark
run is trusted. It reports per-check badges (ok / degraded / fatal) and an overall
runnable/blocked verdict. A job's own --model (possibly provider-prefixed) is checked
against whichever provider it's prefixed with — the generic Preflight view (no model selected) showing
the local model-server check as "unavailable" on a remote-only deployment is expected and harmless; it
doesn't block a job targeting a configured external provider.
A separate LLM session, run every N turns within a task (default 10), that reads the task's goal,
budget, diff-so-far, and recent trajectory, and returns ON TRACK/OFF TRACK plus guidance injected
as the agent's next instruction when drifting. Consecutive off-track verdicts tighten the check-in
cadence automatically; near budget exhaustion the judge switches to a "triage mode" notice. Every
checkpoint is visible per-task in the UI's Judge tab. On by default. See Architecture §8.
A tool (record_lesson) the agent can call at any point to report a cross-cutting finding — a
host/toolchain quirk, a discovered constraint — that should reach every later task, not just ones
that happen to depend on the task that found it. Judge's own off-track recommendations and a
budget-rescue reconnect's reason are recorded through the same path. Size-capped with deterministic
dedup once the cap is crossed. On by default. See Architecture §9.
An opt-in second chance for a task whose session ended via budget exhaustion, a context-window
overflow, a task-wall timeout, or an unresolved status: one more dedicated session, on its own
separate budget, before that final state is accepted — a trimmed-history reconnect, not a cold restart
or a raw continuation. Configurable (own wall-clock/token budgets, how many recent turns survive the
trim) and scoped to the ref harness. See
Design Decisions for why it's built this
specific way, and User Manual: Jobs for the toggle.
Two live controls on a running job's Live tab:
- Intervene — inject a steering message directly into a task's next agent turn, at any time, regardless of that task's own Judge setting. Not persisted as state, but durably logged into the session transcript.
-
Pause after task — a graceful stop request that waits for the currently-running task to finish
before pausing, as opposed to the immediate
/pauseaction which can discard in-progress turns.
Four pluggable mechanisms (CompactionStrategies), configurable and reorderable per job — see
Architecture §4 for what each one does: tool_result_mask, error_line_extraction,
and tool_output_recall are on by default; structured_eviction is opt-in.
-
Task granularity (
fine/medium/coarse) controls how finely the orchestrated plan splits work into tasks for a given rung. -
Parallel planning lets independent tasks run as concurrent waves feeding into a shared
INTEGRATIONtask, with merge-conflict handling inRunBenchand a dedicated parallelization weight knob controlling how aggressively the planner parallelizes.
GroupsView pools comparable runs by (task, model, key_hash) — the "key" is a hash of the run's
configuration (see StatsService.KEY_FIELDS), not its mode, which is read off the group for display
only, not used to decide what pools together — and reports ranked groups (k ≥ 5
comparable valid runs) separately from indicative ones (k < 5, never ranked). Each group card shows
functional/composite/agent-result means with 90% confidence intervals, a per-task pass/fail chip
matrix, and the excluded-run breakdown (invalid / partial due to Docker-skip-or-infra).
Two distinct tools on one page (CompareView):
-
Statistical A/B comparison — pick two groups of run ids, a metric, and comparability flags
(allow partial runs, include invalid runs, compare two different models, allow budget mismatch),
and get
StatsService's verdict with a bootstrap confidence interval and permutation-test p-value. By default it refuses unless the two groups' budgets actually match numerically — the "censor both arms the same way" rule. -
Task matching —
runner/TaskMatcher.javais an LLM-based matcher that semantically aligns two independently-decomposed--plan-source=agentplans (same goal, different task ids/granularity) before any task-by-task comparison is possible at all.
A templated batch of jobs run k times per arm, with an automatic comparison verdict once every job
finishes (ExperimentsService, UI: ExperimentsView/ExperimentNewView/ExperimentDetailView).
Three templates:
-
harness_effect— one model across multiple harness arms (orchestrated / monolithic / monolithic+rules / parallel), same budgets. -
model_ab— two models, same harness and budgets. -
agent_ab— the reference agent vs. Pi, same model and budgets.
RunsView/RunDetailView browse already-produced results/<run-id>/ directories — either freshly
produced by a job, or imported via Rescan results/. A run detail page shows the checks table, plan
tasks, per-step scores, a speed-vs-context-size chart, a compaction-overhead-over-time chart, full
provenance (model, quantization, harness/oracle SHAs, measured context window), and an embedded file
browser over the run's own results directory, including a standalone File Viewer for any individual
file (Markdown rendered, JSON/JSONL pretty-printed) and a colorized unified-diff Diff View for any
task's before/after changes.
- Architecture — how all of the above is actually implemented
- Design Decisions — why several of these are shaped the way they are
- Task Ladder — every task rung in detail
- Check Registry — every oracle check in detail
- User Manual — screenshots of every feature above in the live UI