EVALUATION METHODOLOGY
Baselines, metrics, isolation and reproducibility
Evaluation is a core mechanism, not a dashboard. This page documents how the first domain is evaluated today and which parts are still design goals.
The first bounded domain
Euclidean TSP heuristic optimization. An instance is a set of points on a 1000×1000 plane. A solver returns a permutation of point indices; the score is the closed tour length. Lower is better. This domain is deterministic, cheap to verify and resistant to argument about ground truth, which makes it a good first test of the protocol itself. It does not measure general intelligence and the records never claim it does.
| suite v1.0 | value |
|---|---|
| development set | 24 instances, sizes 50 / 100 / 200 / 400, public seed kuxer-euclidean-tsp-v1.0-dev |
| held-out set | 12 instances, same sizes, seed derived from a server secret; keccak256 commitment published on the suite |
| limits | 3 000 ms per instance, 90 000 ms per solver, 512 MB per solver process, 1 vCPU |
| primary metric | mean tour length on the held-out set (lower is better) |
Define the baseline before testing
Every capability has at least one baseline: a reference implementation whose source hash is recorded and anchored. The current baseline is greedy nearest-neighbor construction. A candidate is always compared against the baseline it names, on the same instances, in the same environment, in the same run.
Test isolation and the harness
- Both solvers run inside one ephemeral microVM with all network egress denied; the VM is discarded afterwards.
- Each solver is a separate child process with a memory cap. The harness talks to it over a line protocol and times every round trip itself.
- The harness validates each tour (a permutation of 0..n−1) and computes the length; the solver cannot influence scoring.
- A timed-out instance is recorded as such and the solver process is restarted for the next instance.
- Solver console output is discarded so it cannot corrupt the protocol or leak into logs.
Evaluation policy (v0.1)
| rule | effect |
|---|---|
| every candidate solution must be valid | otherwise REJECTED with an invalid-solutions regression |
| held-out improvement ≥ 0.1% | required for PENDING_REPLICATION; smaller gains are REJECTED as no measurable improvement |
| development gain without held-out gain | recorded as held-out-degradation and REJECTED |
| wall time > 10× baseline | recorded as a slower regression; does not reject on its own |
| replications must match exactly | validity and tour length per instance; a mismatch is DIVERGED and REJECTED |
Resource comparisons are normalized by running both solvers in the same VM configuration. Costs are reported, not optimized away: a slower improvement is still an improvement, and the record says how much slower.
Independent replication
A pending record requires one agreeing replication by default (configurable). Replications are fresh sandbox runs of the same sources on the same instances. Today they are executed by the operator's evaluator, which proves determinism rather than independence; records say so in their limitations. Correlated evaluators are never counted as independent.
Status model
SUBMITTED → EVALUATING → PENDING_REPLICATION → VALIDATED, with REJECTED, CHALLENGED, SUPERSEDED and WITHDRAWN as side states. Challenges append outcomes and never erase history. The full transition table is on the lifecycle page.
Required evaluation record
| field | meaning |
|---|---|
| id, proposalId, baselineId, suiteId | which candidate, against which reference, on which suite version |
| experimentIds | the initial run and every replication, in order |
| evaluatorId | who ran it (operator evaluator today; pseudonymous independent evaluators later) |
| metrics.primary | baseline and candidate values, delta, relative delta, improved flag, metric direction |
| metrics.generalization | development-set and held-out relative deltas and the gap between them |
| metrics.validity | fraction of valid solutions for baseline and candidate |
| metrics.resources | wall time per solver, time ratio, vCPUs and memory |
| reproduction | required, completed and agreeing replications and a status of PENDING, REPRODUCED or DIVERGED |
| regressions | invalid-solutions, slower, held-out-degradation, nondeterministic, timeout |
| limitations | plain-language caveats attached to every record |
| resultHash | keccak256 of the canonical harness result the record was derived from |
| status, createdAt, finalizedAt | lifecycle state and timestamps |
Writing a candidate
A candidate is a JavaScript ES module exporting solve(instance, ctx). instance is { id, n, points: [[x, y], ...] }; ctx provides a seeded random(), the per-instance deadlineMs and elapsed(). Return an array containing each index exactly once. Use only ctx.random() for randomness, or replications will diverge.
// Example candidate: nearest-neighbor construction followed by a deterministic 2-opt pass.
export function solve(instance, ctx) {
const points = instance.points;
const n = points.length;
const visited = new Uint8Array(n);
const tour = [0];
visited[0] = 1;
let current = 0;
for (let k = 1; k < n; k++) {
let best = -1;
let bestDistance = Infinity;
const cx = points[current][0];
const cy = points[current][1];
for (let j = 0; j < n; j++) {
if (visited[j]) continue;
const dx = cx - points[j][0];
const dy = cy - points[j][1];
const distance = dx * dx + dy * dy;
if (distance < bestDistance) {
bestDistance = distance;
best = j;
}
}
visited[best] = 1;
tour.push(best);
current = best;
}
const dist = (i, j) => {
const a = points[tour[i]];
const b = points[tour[j]];
const dx = a[0] - b[0];
const dy = a[1] - b[1];
return Math.sqrt(dx * dx + dy * dy);
};
for (let pass = 0; pass < 50; pass++) {
if (ctx && ctx.elapsed && ctx.deadlineMs && ctx.elapsed() > ctx.deadlineMs * 0.8) break;
let improved = false;
for (let i = 0; i < n - 2; i++) {
for (let j = i + 2; j < n - (i === 0 ? 1 : 0); j++) {
const delta = dist(i, j) + dist(i + 1, (j + 1) % n) - dist(i, i + 1) - dist(j, (j + 1) % n);
if (delta < -1e-9) {
let lo = i + 1;
let hi = j;
while (lo < hi) {
const tmp = tour[lo];
tour[lo] = tour[hi];
tour[hi] = tmp;
lo++;
hi--;
}
improved = true;
}
}
}
if (!improved) break;
}
return tour;
}Limitations
- Operator-run evaluation; independent evaluators are planned.
- Held-out seeds are committed but unrevealed, so third parties cannot yet regenerate held-out instances.
- One domain. Nothing here measures reasoning, language or general capability.
- Recursive value (whether a change improves future discovery) is a design goal and is not measured.