Skipped functions are not regressions when their annotation is removed

Once a function's no-decompile claim is accepted (task state skipped), removing its old annotation or changing its code no longer counts as breaking a function that matched before. This lets a maintenance batch clean up an annotation that was stacked on the wrong definition.
This commit is contained in:
ragnarok-clanker 2026-10-28 16:33:19 +01:00
commit b68343dae1
2 changed files with 16 additions and 1 deletions

View file

@ -458,7 +458,8 @@ export class Verifier {
const results = new Map([...bestResults(check)].map(([id, b]) => [id, b.f]));
const compiledFiles = new Set(check.units.map((u) => u.file));
const out = [];
for (const row of this.store.all(`SELECT * FROM func_status WHERE status IN ('exact', 'match_unresolved') OR confirmed = 1`)) {
// An accepted "no decompile" claim retires the function: removing its old annotation is the fix.
for (const row of this.store.all(`SELECT * FROM func_status WHERE (status IN ('exact', 'match_unresolved') OR confirmed = 1) AND symbol_id NOT IN (SELECT symbol_id FROM tasks WHERE state = 'skipped')`)) {
if (!compiledFiles.has(row.file)) continue;
const now_ = results.get(row.symbol_id);
// Exact and match_unresolved are the same bytes: whether a referenced label resolves depends

View file

@ -221,6 +221,20 @@ test('regressions are detected against func_status', () => {
ctx.store.run(`DELETE FROM func_status`);
});
test('removing the annotation of a skipped function is not a regression', () => {
ctx.store.run(`INSERT INTO func_status (symbol_id, file, status, score, confirmed, commit_hash, updated_at) VALUES ('fn_00002', 'src/a.cpp', 'mismatch', 0.7, 1, 'x', 0)`);
const check = { annotationErrors: [], units: [{ file: 'src/a.cpp', compiled: true, lintErrors: [], functions: [{ id: 'fn_00002', status: STATUS.MISMATCH, score: 0.4 }], unannotated: [] }] };
const task = ctx.store.get(`SELECT id, state FROM tasks WHERE symbol_id = 'fn_00002'`);
try {
assert.deepEqual(ctx.verifier.regressions(check).map((r) => r.id), ['fn_00002'], 'a confirmed function moving away from the original is a regression');
ctx.store.run(`UPDATE tasks SET state = 'skipped' WHERE id = ?`, task.id);
assert.deepEqual(ctx.verifier.regressions(check), [], 'not once it is skipped as needing no decompilation');
} finally {
ctx.store.run(`UPDATE tasks SET state = ? WHERE id = ?`, task.state, task.id);
ctx.store.run(`DELETE FROM func_status`);
}
});
test('expired leases return to the pool', async () => {
const token = await activeUser('dave');
const c = (await leaseTask(token)).body;