fix: clarify code queue activity counts

This commit is contained in:
UniDesk Code Queue
2026-05-22 23:42:39 +00:00
committed by Codex
parent f3b5b449a2
commit 031c3fda39
6 changed files with 305 additions and 6 deletions
@@ -16,6 +16,10 @@ function asArray(value: unknown): unknown[] {
return value as unknown[];
}
function manyIds(prefix: string, count: number): string[] {
return Array.from({ length: count }, (_, index) => `${prefix}-${String(index + 1).padStart(2, "0")}`);
}
function fixtureResponse(): JsonRecord {
return {
ok: true,
@@ -76,6 +80,66 @@ function fixtureResponse(): JsonRecord {
};
}
function splitBrainLiveResponse(): JsonRecord {
const liveTaskIds = manyIds("task-running", 8);
return {
ok: true,
status: 200,
body: {
ok: true,
queue: {
total: 8,
queueCount: 2,
activeQueueIds: [],
activeTaskIds: [],
queuedTaskIds: [],
counts: { running: 8 },
unreadTerminal: 0,
executionDiagnostics: {
state: "split-brain",
splitBrain: true,
splitBrainLive: true,
effectiveLiveness: "live",
recommendedAction: "continue-supervision",
databaseActiveTaskCount: 8,
databaseActiveTaskIds: liveTaskIds,
schedulerActiveRunSlotCount: 0,
schedulerActiveTaskIds: [],
activeHeartbeatCount: 8,
activeHeartbeatTaskIds: liveTaskIds,
heartbeatFreshTaskIds: liveTaskIds,
heartbeatExpiredTaskIds: [],
heartbeatMissingTaskIds: [],
staleRecoveryCandidateTaskIds: [],
heartbeatRiskTaskIds: [],
},
},
queues: [
{
id: "alpha",
name: "Alpha",
total: 4,
counts: { running: 4 },
unreadTerminal: 0,
activeTaskId: null,
runnableTaskId: null,
updatedAt: "2026-05-20T00:00:00.000Z",
},
{
id: "beta",
name: "Beta",
total: 4,
counts: { running: 4 },
unreadTerminal: 0,
activeTaskId: null,
runnableTaskId: null,
updatedAt: "2026-05-20T00:01:00.000Z",
},
],
},
};
}
function assertQueuesShape(label: string, result: unknown, expectedView: string): void {
const data = asRecord(result);
const queues = asRecord(data.queues);
@@ -100,15 +164,51 @@ function assertQueuesShape(label: string, result: unknown, expectedView: string)
assertCondition(liveness.schedulerActiveRunSlotCount === 0, `${label} liveness summary should keep master active slot zero visible`, liveness);
assertCondition(asArray(liveness.heartbeatFreshTaskIds).length === 1, `${label} liveness summary should include bounded fresh heartbeat task ids`, liveness);
assertCondition(String(liveness.interpretation ?? "").includes("heartbeat is fresh"), `${label} liveness interpretation should explain slot-zero split-brain`, liveness);
const activity = asRecord(queues.activity);
assertCondition(activity.effectiveActiveTaskCount === 1, `${label} activity should foreground effective active task count`, activity);
assertCondition(activity.databaseRunningTaskCount === 1, `${label} activity should distinguish database running tasks`, activity);
assertCondition(activity.heartbeatFreshActiveTaskCount === 1, `${label} activity should distinguish heartbeat-fresh active runners`, activity);
assertCondition(activity.schedulerLocalActiveQueueCount === 1, `${label} activity should distinguish scheduler-local active queues`, activity);
assertCondition(activity.activeQueueIdsScope === "scheduler-local-active-run-slots", `${label} activity should label activeQueueIds scope`, activity);
assertCondition(Array.isArray(queues.activeTaskIds), `${label} activeTaskIds should be present`, queues);
assertCondition(Array.isArray(queues.queuedTaskIds), `${label} queuedTaskIds should be present`, queues);
}
function assertSplitBrainLiveActivity(label: string, result: unknown): void {
const queues = asRecord(asRecord(result).queues);
const totals = asRecord(queues.totals);
assertCondition(totals.activeQueueCount === 0, `${label} scheduler-local active queue count should be zero`, totals);
assertCondition(totals.schedulerLocalActiveQueueCount === 0, `${label} should preserve zero scheduler-local active queues`, totals);
assertCondition(totals.runnableQueueCount === 0, `${label} runnable queue count should be zero`, totals);
assertCondition(totals.databaseRunningTaskCount === 8, `${label} should foreground DB running task count`, totals);
assertCondition(totals.databaseActiveTaskCount === 8, `${label} should foreground DB active task count`, totals);
assertCondition(totals.heartbeatFreshActiveTaskCount === 8, `${label} should foreground heartbeat-effective active runners`, totals);
assertCondition(totals.effectiveActiveTaskCount === 8, `${label} should foreground effective active task count`, totals);
assertCondition(asArray(queues.activeQueueIds).length === 0, `${label} activeQueueIds should remain the scheduler-local list`, queues);
assertCondition(queues.activeQueueIdsScope === "scheduler-local-active-run-slots", `${label} activeQueueIds should be scoped`, queues);
assertCondition(String(queues.activeQueueIdsNote ?? "").includes("scheduler-local only"), `${label} activeQueueIds note should explain local-only semantics`, queues);
const activity = asRecord(queues.activity);
assertCondition(activity.effectiveActiveTaskCount === 8, `${label} activity should expose effective active count`, activity);
assertCondition(activity.effectiveActiveSource === "heartbeat-fresh", `${label} activity should choose heartbeat-fresh source`, activity);
assertCondition(activity.databaseRunningTaskCount === 8, `${label} activity should expose DB running count`, activity);
assertCondition(activity.heartbeatFreshActiveTaskCount === 8, `${label} activity should expose heartbeat-effective active count`, activity);
assertCondition(activity.schedulerLocalActiveQueueCount === 0, `${label} activity should expose scheduler-local queue count`, activity);
assertCondition(activity.schedulerLocalActiveRunSlotCount === 0, `${label} activity should expose scheduler-local slot count`, activity);
assertCondition(activity.runnableQueueCount === 0, `${label} activity should expose runnable queue count`, activity);
assertCondition(activity.splitBrainLive === true, `${label} activity should preserve split-brain live`, activity);
assertCondition(String(activity.activeQueueIdsNote ?? "").includes("zero local queue ids does not mean zero active runners"), `${label} activity note should prevent zero-active misread`, activity);
assertCondition(String(activity.interpretation ?? "").includes("continue supervision"), `${label} activity interpretation should keep supervision action`, activity);
}
export function runCodeQueueQueuesShapeContract(): JsonRecord {
const fetcher = (path: string): JsonRecord => {
assertCondition(path === "/api/microservices/code-queue/proxy/api/queues", "codex queues should use stable proxy path", { path });
return fixtureResponse();
};
const splitBrainFetcher = (path: string): JsonRecord => {
assertCondition(path === "/api/microservices/code-queue/proxy/api/queues", "codex queues should use stable proxy path", { path });
return splitBrainLiveResponse();
};
const summary = codexQueuesQueryForTest([], fetcher);
assertQueuesShape("summary", summary, "summary");
@@ -140,6 +240,11 @@ export function runCodeQueueQueuesShapeContract(): JsonRecord {
assertCondition(offsetFullQueues.hasPrevious === true, "offset full should expose previous page", offsetFullQueues);
assertCondition(asRecord(asArray(offsetFullQueues.items)[0]).id === "gamma", "offset full should return second page rows", offsetFullQueues);
const splitSummary = codexQueuesQueryForTest([], splitBrainFetcher);
assertSplitBrainLiveActivity("split-brain summary", splitSummary);
const splitFull = codexQueuesQueryForTest(["--full"], splitBrainFetcher);
assertSplitBrainLiveActivity("split-brain full", splitFull);
return {
ok: true,
checks: [
@@ -150,6 +255,7 @@ export function runCodeQueueQueuesShapeContract(): JsonRecord {
"deprecated full array omitted from default output",
"full explicit limit remains bounded and paged",
"offset pagination",
"split-brain live activity counts distinguish scheduler-local queues, DB running tasks, and heartbeat-fresh runners",
],
};
}