From b4f8f6d6308ef5217637f34a24cde016b8b38afc Mon Sep 17 00:00:00 2001 From: Saty <5752427+SatyPardus@users.noreply.github.com> Date: Wed, 21 Oct 2026 12:50:31 +0200 Subject: [PATCH] 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 --- src/server/db.js | 1 + src/server/trust.js | 7 +++++-- test/server.test.js | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/server/db.js b/src/server/db.js index c7f7604..ef85349 100644 --- a/src/server/db.js +++ b/src/server/db.js @@ -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). */ diff --git a/src/server/trust.js b/src/server/trust.js index 9b0b6f9..a86f410 100644 --- a/src/server/trust.js +++ b/src/server/trust.js @@ -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; } } diff --git a/test/server.test.js b/test/server.test.js index 3fd419e..75ae04c 100644 --- a/test/server.test.js +++ b/test/server.test.js @@ -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());