maint: integrate reviewed contribution #3791

This commit is contained in:
haelyra committed 2026-10-29 11:34:19 -07:00
commit 60053622fe
3 files changed
+141 -10

No files matched your search

+15 -10
View File
@@ -8,6 +8,8 @@
*/
const DONE_STATUSES = new Set(['done', 'closed', 'resolved', 'merged', 'cancelled']);
// Only explicitly admitted work may be newly claimed.
const CLAIMABLE_STATUSES = new Set(['open', 'ready']);
const PRIORITY_RANK = { critical: 0, high: 1, urgent: 1, medium: 2, normal: 2, low: 3 };
// Kanban lanes the board renders, and the canonical status each maps to on a move.
@@ -21,11 +23,7 @@ const VALID_LANES = new Set(Object.keys(LANE_TO_STATUS));
const VALID_ASSIGNEE_KINDS = new Set(['agent', 'human']);
function isOpenStatus(status) {
return !DONE_STATUSES.has(
String(status || '')
.trim()
.toLowerCase()
);
return CLAIMABLE_STATUSES.has(String(status || '').trim().toLowerCase());
}
function priorityRank(priority) {
@@ -44,8 +42,9 @@ function selectClaimTarget(store, { id } = {}) {
}
return item;
}
const { items } = store.listWorkItems({ limit: 100 });
return items.filter(item => !item.owner && isOpenStatus(item.status)).sort((a, b) => priorityRank(a.priority) - priorityRank(b.priority))[0] || null;
// The native SQL query filters all eligible items before choosing the
// highest-priority claim; a newer 100-item slice can hide older READY work.
return store.getNextClaimableWorkItem();
}
/**
@@ -65,13 +64,19 @@ function claimWorkItem(store, { id, owner, assigneeKind, sessionId, status } = {
if (!target) {
return { claimed: false, reason: 'no-unassigned-open-items' };
}
if (!isOpenStatus(target.status)) {
throw new Error(`Work item ${target.id} is already done; cannot claim.`);
}
if (target.owner) {
if (target.owner !== owner) {
throw new Error(`Work item ${target.id} is already owned by ${target.owner}; cannot claim.`);
}
// Repeating an active claim by the same owner is idempotent.
if (['running', 'claimed', 'in-progress'].includes(String(target.status).trim().toLowerCase())) {
return { claimed: true, item: target };
}
}
if (!isOpenStatus(target.status)) {
throw new Error(`Work item ${target.id} is not READY; cannot claim.`);
}
if (target.owner) {
return { claimed: true, item: target };
}
const metadata = { ...(target.metadata || {}) };
+22
View File
@@ -482,6 +482,22 @@ function createQueryApi(db, { prepareRead = sql => db.prepare(sql) } = {}) {
FROM work_items
ORDER BY updated_at DESC, id DESC
`);
// Read the entire native READY set in SQL instead of truncating to the
// 100 most recently updated items before checking their eligibility.
const nextClaimableWorkItemStatement = prepareRead(`
SELECT *
FROM work_items
WHERE (owner IS NULL OR owner = '')
AND LOWER(TRIM(COALESCE(status, ''))) IN ('open', 'ready')
ORDER BY CASE LOWER(COALESCE(priority, ''))
WHEN 'critical' THEN 0
WHEN 'high' THEN 1
WHEN 'urgent' THEN 1
WHEN 'low' THEN 3
ELSE 2
END ASC, updated_at DESC, id DESC
LIMIT 1
`);
const getWorkItemStatement = prepareRead(`
SELECT *
FROM work_items
@@ -760,6 +776,11 @@ function createQueryApi(db, { prepareRead = sql => db.prepare(sql) } = {}) {
};
}
function getNextClaimableWorkItem() {
const row = nextClaimableWorkItemStatement.get();
return row ? mapWorkItemRow(row) : null;
}
function getStatus(options = {}) {
const activeLimit = normalizeLimit(options.activeLimit, 5);
const recentSkillRunLimit = normalizeLimit(options.recentSkillRunLimit, 20);
@@ -870,6 +891,7 @@ function createQueryApi(db, { prepareRead = sql => db.prepare(sql) } = {}) {
},
listRecentSessions,
listWorkItems,
getNextClaimableWorkItem,
upsertInstallState(installState) {
const normalized = normalizeInstallStateInput(installState);
assertValidEntity('installState', normalized);