Speed up trust: cache the tracking start, index reviews by reviewer, use attempts.score

The admin Authors table computed trust for all 121 agents in ~30 s, blocking
the web process (arcade, admin, everything) meanwhile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Saty 2026-10-21 12:50:31 +02:00
commit b4f8f6d630
3 changed files with 8 additions and 4 deletions

View file

@ -322,6 +322,7 @@ export class Store {
this.addColumn('attempts', 'competing', 'INTEGER NOT NULL DEFAULT 0');
this.db.exec('CREATE INDEX IF NOT EXISTS events_type_at ON events(type, at)'); // merge rates, feed
this.db.exec('CREATE INDEX IF NOT EXISTS attempts_batch ON attempts(batch_id)');
this.db.exec('CREATE INDEX IF NOT EXISTS peer_reviews_reviewer ON peer_reviews(reviewer_id, created_at)'); // reviewer trust
}
/** Submitted files of an attempt (kept once per batch). */

View file

@ -76,7 +76,9 @@ export class Trust {
// Rows of this agent: its token, plus the account's untracked work if the token is that old.
scope(alias, tokenId) {
if (tokenId == null) return { sql: `${alias}.token_id IS NULL`, args: [] };
const started = this.store.get('SELECT MIN(created_at) AS at FROM batches WHERE token_id IS NOT NULL')?.at ?? now();
// When batches started recording their token: fixed once known (batches are numbered in time).
this.started ??= this.store.get('SELECT created_at AS at FROM batches WHERE token_id IS NOT NULL ORDER BY id LIMIT 1')?.at;
const started = this.started ?? now();
const created = this.store.get('SELECT created_at FROM api_tokens WHERE id = ?', tokenId)?.created_at ?? now();
return created < started ? { sql: `(${alias}.token_id = ? OR ${alias}.token_id IS NULL)`, args: [tokenId] } : { sql: `${alias}.token_id = ?`, args: [tokenId] };
}
@ -91,7 +93,7 @@ export class Trust {
`SELECT SUM(same >= CASE WHEN different > 0 THEN ? ELSE ? END AND different < ?) AS accepted, SUM(different >= ?) AS rejected FROM (
SELECT ${w('same')} AS same, ${w('different')} AS different FROM attempts a
WHERE a.user_id = ? AND ${s.sql} AND a.created_at > ? AND a.kind = 'code' AND a.peer_skipped = 0
AND json_extract(a.result_json, '$.feedback.target.score') >= ?)`,
AND a.score >= ?)`,
this.autoAccept, this.acceptClean, this.required, this.required, userId, ...s.args, now() - p.authorDays * DAY, p.bandAt,
);
const accepted = r?.accepted ?? 0;
@ -144,5 +146,6 @@ export class Trust {
forget() {
this.cache.clear();
this.started = undefined;
}
}

View file

@ -1345,8 +1345,8 @@ test('trust: careful reviewers count more, trusted authors skip peer review, one
await mk(3, 'trustpeer');
const peers = [0, 1, 2].map((i) => ctx.accounts.byName(`trustpeer${i}`));
const attempt = (userId, tokenId, score, state = 'merged') =>
Number(ctx.store.run(`INSERT INTO attempts (task_id, user_id, token_id, base_commit, files_json, state, result_json, created_at) VALUES (?, ?, ?, ?, '{}', ?, ?, ?)`,
task, userId, tokenId, head, state, JSON.stringify({ feedback: { target: { score } } }), now()).lastInsertRowid);
Number(ctx.store.run(`INSERT INTO attempts (task_id, user_id, token_id, base_commit, files_json, state, score, result_json, created_at) VALUES (?, ?, ?, ?, '{}', ?, ?, ?, ?)`,
task, userId, tokenId, head, state, score, JSON.stringify({ feedback: { target: { score } } }), now()).lastInsertRowid);
const verdict = (a, userId, v, tokenId = null) =>
ctx.store.run(`INSERT INTO peer_reviews (attempt_id, reviewer_id, token_id, verdict, reason, created_at) VALUES (?, ?, ?, ?, 'the loop bound and the call match the original', ?)`, a, userId, tokenId, v, now());