fix: clarify code queue liveness snapshots

This commit is contained in:
Codex
2026-05-23 12:36:20 +00:00
parent 15d074424c
commit 758377c551
4 changed files with 338 additions and 23 deletions
+218 -22
View File
@@ -300,6 +300,17 @@ interface CompactTaskMutationResponseOptions {
interface CompactSubmitQueueConfirmationOptions {
submittedTasks?: Record<string, unknown>[];
idPreviewLimit?: number;
submittedAt?: string | null;
}
type CodeQueueLivenessSnapshotRole = "submit-confirmation" | "supervisor-poll" | "queue-summary";
interface CompactCodeQueueActivityOptions {
schedulerLocalActiveQueueIds?: string[];
runnableQueueCount?: number | null;
snapshotRole?: CodeQueueLivenessSnapshotRole;
snapshotAt?: string | null;
submittedAt?: string | null;
}
interface CodexTasksOptions {
@@ -649,6 +660,26 @@ function asNumber(value: unknown, fallback = 0): number {
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
}
function timestampMs(value: unknown): number | null {
const text = asString(value);
if (text.length === 0) return null;
const parsed = Date.parse(text);
return Number.isFinite(parsed) ? parsed : null;
}
function maxIsoTimestamp(values: unknown[]): string | null {
let best: string | null = null;
let bestMs = -Infinity;
for (const value of values) {
const text = asString(value);
const parsed = timestampMs(text);
if (parsed === null || parsed < bestMs) continue;
best = text;
bestMs = parsed;
}
return best;
}
function finiteNumber(value: unknown): number | null {
return typeof value === "number" && Number.isFinite(value) ? value : null;
}
@@ -1696,16 +1727,101 @@ function activeHeartbeatCountFromDiagnostics(record: Record<string, unknown>, ac
return Number.isFinite(explicit) ? explicit : Math.max(activeHeartbeatTaskIds.count, heartbeatFreshTaskIds.count);
}
function compactRecoveryDecision(record: Record<string, unknown>, counts: {
heartbeatRiskTaskCount: number;
staleRecoveryCandidateTaskCount: number;
}, options: {
snapshotRole?: CodeQueueLivenessSnapshotRole;
snapshotAt?: string | null;
submittedAt?: string | null;
} = {}): Record<string, unknown> {
const confirmedIds = boundedUniqueStringList(record.staleRecoveryConfirmedTaskIds ?? record.confirmedStaleRecoveryCandidateTaskIds);
const repeatedPollConfirmed = asBoolean(record.repeatedPollConfirmed)
|| asBoolean(record.recoveryRepeatedPollConfirmed)
|| confirmedIds.count > 0;
const riskVisible = counts.heartbeatRiskTaskCount > 0 || counts.staleRecoveryCandidateTaskCount > 0;
const recoveryMutationAllowedByThisSnapshot = riskVisible && repeatedPollConfirmed;
const rePollBeforeRecovery = riskVisible && !repeatedPollConfirmed;
const snapshotRole = options.snapshotRole ?? "supervisor-poll";
const snapshotAt = options.snapshotAt ?? (asString(record.now) || null);
const submittedAt = options.submittedAt ?? null;
const lastObservedAgentEventAt = asString(record.lastObservedAgentEventAt) || null;
const lastSchedulerHeartbeatAt = asString(record.lastSchedulerHeartbeatAt) || null;
const lastObservedMs = timestampMs(lastObservedAgentEventAt);
const submittedMs = timestampMs(submittedAt);
const snapshotMs = timestampMs(snapshotAt);
const lastObservedAgentEventBeforeSubmit = lastObservedMs !== null && submittedMs !== null && lastObservedMs < submittedMs;
const lastObservedAgentEventBeforeSnapshot = lastObservedMs !== null && snapshotMs !== null && lastObservedMs < snapshotMs;
const hint = riskVisible
? recoveryMutationAllowedByThisSnapshot
? "run dry-run reconcile before recovery"
: "re-poll supervisor before recovery"
: null;
if (!riskVisible) {
return {
riskVisible: false,
disposition: "none",
hint: null,
rePollBeforeRecovery: false,
pollConfirmationRequired: false,
repeatedPollConfirmed,
recoveryMutationAllowedByThisSnapshot: false,
heartbeatRiskTaskCount: 0,
staleRecoveryCandidateTaskCount: 0,
snapshotRole,
boundedSnapshot: snapshotRole === "submit-confirmation",
};
}
return {
riskVisible,
disposition: !riskVisible
? "none"
: recoveryMutationAllowedByThisSnapshot
? "confirmed-stale-active-candidate"
: "transient-needs-repoll",
hint,
rePollBeforeRecovery,
pollConfirmationRequired: rePollBeforeRecovery,
repeatedPollConfirmed,
recoveryMutationAllowedByThisSnapshot,
staleActiveCandidateVisibility: counts.staleRecoveryCandidateTaskCount > 0 ? "visible-candidate-not-mutation-proof" : "none",
heartbeatRiskTaskCount: counts.heartbeatRiskTaskCount,
staleRecoveryCandidateTaskCount: counts.staleRecoveryCandidateTaskCount,
confirmedStaleRecoveryCandidateTaskIds: confirmedIds.items,
confirmedStaleRecoveryCandidateTaskCount: confirmedIds.count,
snapshotRole,
boundedSnapshot: snapshotRole === "submit-confirmation",
snapshotAt,
submittedAt,
lastObservedAgentEventAt,
lastSchedulerHeartbeatAt,
lastObservedAgentEventBeforeSubmit,
lastObservedAgentEventBeforeSnapshot,
nextPollCommand: rePollBeforeRecovery ? "bun scripts/cli.ts codex tasks --view supervisor --limit 20" : null,
dryRunReconcileCommand: recoveryMutationAllowedByThisSnapshot ? "bun scripts/cli.ts microservice proxy code-queue '/api/scheduler/reconcile?dryRun=1' --raw" : null,
mutationBoundary: "Never recover, restart, cancel, or interrupt from a single bounded liveness snapshot.",
};
}
function compactLivenessDecision(record: Record<string, unknown>, lists: {
activeHeartbeatTaskIds: { items: string[]; count: number; truncated: boolean; omitted: number };
heartbeatFreshTaskIds: { items: string[]; count: number; truncated: boolean; omitted: number };
heartbeatRiskTaskIds: { items: string[]; count: number };
databaseActiveTaskIds: { count: number };
}): Record<string, unknown> {
staleRecoveryCandidateTaskIds?: { count: number };
}, recoveryOptions: {
snapshotRole?: CodeQueueLivenessSnapshotRole;
snapshotAt?: string | null;
submittedAt?: string | null;
} = {}): Record<string, unknown> {
const splitBrainLive = splitBrainLiveFromDiagnostics(record);
const effectiveLiveness = effectiveLivenessFromDiagnostics(record);
const recommendedAction = recommendedActionFromDiagnostics(record);
const activeHeartbeatCount = activeHeartbeatCountFromDiagnostics(record, lists.activeHeartbeatTaskIds, lists.heartbeatFreshTaskIds);
const recovery = compactRecoveryDecision(record, {
heartbeatRiskTaskCount: lists.heartbeatRiskTaskIds.count,
staleRecoveryCandidateTaskCount: lists.staleRecoveryCandidateTaskIds?.count ?? stringList(record.staleRecoveryCandidateTaskIds).length,
}, recoveryOptions);
return {
effectiveLiveness,
recommendedAction,
@@ -1717,8 +1833,12 @@ function compactLivenessDecision(record: Record<string, unknown>, lists: {
databaseActiveTaskCount: asNumber(record.databaseActiveTaskCount, lists.databaseActiveTaskIds.count),
schedulerActiveRunSlotCount: record.schedulerActiveRunSlotCount ?? null,
heartbeatRiskTaskCount: lists.heartbeatRiskTaskIds.count,
staleRecoveryCandidateTaskCount: lists.staleRecoveryCandidateTaskIds?.count ?? stringList(record.staleRecoveryCandidateTaskIds).length,
recovery,
interpretation: splitBrainLive
? "scheduler heartbeat is fresh; treat active task count from heartbeat as live and continue supervision"
: recovery.rePollBeforeRecovery === true
? "heartbeat risk is visible in this bounded snapshot; re-poll supervisor before recovery"
: effectiveLiveness === "at-risk"
? "heartbeat risk is present; investigate heartbeat freshness before recovery"
: effectiveLiveness === "degraded"
@@ -1749,7 +1869,11 @@ function boundedInlineString(value: unknown, maxChars: number): { text: string |
};
}
function compactExecutionDiagnostics(value: unknown): Record<string, unknown> | null {
function compactExecutionDiagnostics(value: unknown, recoveryOptions: {
snapshotRole?: CodeQueueLivenessSnapshotRole;
snapshotAt?: string | null;
submittedAt?: string | null;
} = {}): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
const fullHeartbeatRiskTaskIds = Array.from(new Set([
@@ -1776,7 +1900,12 @@ function compactExecutionDiagnostics(value: unknown): Record<string, unknown> |
heartbeatFreshTaskIds,
heartbeatRiskTaskIds,
databaseActiveTaskIds,
});
staleRecoveryCandidateTaskIds,
}, recoveryOptions);
const recovery = asRecord(liveness.recovery) ?? compactRecoveryDecision(record, {
heartbeatRiskTaskCount: heartbeatRiskTaskIds.count,
staleRecoveryCandidateTaskCount: staleRecoveryCandidateTaskIds.count,
}, recoveryOptions);
const omittedCounts = {
databaseActiveTaskIds: databaseActiveTaskIds.omitted,
schedulerActiveTaskIds: schedulerActiveTaskIds.omitted,
@@ -1798,6 +1927,7 @@ function compactExecutionDiagnostics(value: unknown): Record<string, unknown> |
splitBrainLive: splitBrainLiveFromDiagnostics(record),
effectiveLiveness: liveness.effectiveLiveness,
recommendedAction: liveness.recommendedAction,
recovery,
liveness,
livenessSummary: livenessSummary.text,
livenessSummaryChars: livenessSummary.chars,
@@ -1832,8 +1962,12 @@ function compactExecutionDiagnostics(value: unknown): Record<string, unknown> |
};
}
function compactQueueExecutionDiagnostics(value: unknown): Record<string, unknown> | null {
const diagnostics = compactExecutionDiagnostics(value);
function compactQueueExecutionDiagnostics(value: unknown, recoveryOptions: {
snapshotRole?: CodeQueueLivenessSnapshotRole;
snapshotAt?: string | null;
submittedAt?: string | null;
} = {}): Record<string, unknown> | null {
const diagnostics = compactExecutionDiagnostics(value, recoveryOptions);
if (diagnostics === null) return null;
const listBudget = asRecord(diagnostics.listBudget) ?? {};
const omittedCounts = asRecord(listBudget.omittedCounts) ?? {};
@@ -1844,6 +1978,7 @@ function compactQueueExecutionDiagnostics(value: unknown): Record<string, unknow
splitBrainLive: diagnostics.splitBrainLive ?? null,
effectiveLiveness: diagnostics.effectiveLiveness ?? null,
recommendedAction: diagnostics.recommendedAction ?? null,
recovery: diagnostics.recovery ?? null,
liveness: diagnostics.liveness ?? null,
executionStateSource: diagnostics.executionStateSource ?? null,
controlPlane: diagnostics.controlPlane ?? null,
@@ -1883,7 +2018,7 @@ function stringListCount(value: unknown): number | null {
function compactCodeQueueActivity(
queue: Record<string, unknown>,
diagnostics: Record<string, unknown> | null,
options: { schedulerLocalActiveQueueIds?: string[]; runnableQueueCount?: number | null } = {},
options: CompactCodeQueueActivityOptions = {},
): Record<string, unknown> {
const rawDiagnostics = asRecord(queue.executionDiagnostics) ?? {};
const compactDiagnostics = diagnostics ?? {};
@@ -1938,6 +2073,17 @@ function compactCodeQueueActivity(
const recommendedAction = asString(rawDiagnostics.recommendedAction ?? compactDiagnostics.recommendedAction ?? rawLiveness.recommendedAction ?? compactLiveness.recommendedAction);
const splitBrain = asBoolean(rawDiagnostics.splitBrain) || asBoolean(compactDiagnostics.splitBrain) || executionState === "split-brain";
const splitBrainLive = splitBrainLiveFromDiagnostics(rawDiagnostics) || splitBrainLiveFromDiagnostics(compactDiagnostics);
const snapshotAt = options.snapshotAt ?? (asString(rawDiagnostics.now ?? compactDiagnostics.now) || null);
const recovery = compactRecoveryDecision({ ...compactDiagnostics, ...rawDiagnostics }, {
heartbeatRiskTaskCount,
staleRecoveryCandidateTaskCount,
}, {
snapshotRole: options.snapshotRole,
snapshotAt,
submittedAt: options.submittedAt ?? null,
});
const recoveryMutationAllowed = recovery.recoveryMutationAllowedByThisSnapshot === true;
const rePollBeforeRecovery = recovery.rePollBeforeRecovery === true;
const effectiveActiveSource = heartbeatFreshActiveTaskCount > 0 && heartbeatFreshActiveTaskCount >= databaseActiveTaskCount
? "heartbeat-fresh"
: databaseActiveTaskCount > 0
@@ -1948,8 +2094,13 @@ function compactCodeQueueActivity(
const activeQueueIdsNote = schedulerLocalActiveQueueIds.length === 0 && effectiveActiveTaskCount > 0
? "activeQueueIds are scheduler-local only; zero local queue ids does not mean zero active runners when database or heartbeat counts are nonzero."
: "activeQueueIds are scheduler-local active-run slots; use effectiveActiveTaskCount for commander concurrency decisions.";
const recommendedActionIntervenes = recommendedAction.length > 0 && recommendedAction !== "continue-supervision";
const interventionRequired = heartbeatRiskTaskCount > 0 || staleRecoveryCandidateTaskCount > 0 || recommendedActionIntervenes || (splitBrain && !splitBrainLive);
const recommendedActionIntervenes = recommendedAction.length > 0
&& !["none", "continue-supervision", "observe-degraded", "investigate-heartbeat-risk"].includes(recommendedAction);
const attentionRequired = heartbeatRiskTaskCount > 0
|| staleRecoveryCandidateTaskCount > 0
|| recommendedActionIntervenes
|| (splitBrain && !splitBrainLive);
const interventionRequired = recoveryMutationAllowed || recommendedActionIntervenes || ((splitBrain && !splitBrainLive) && !rePollBeforeRecovery);
const splitBrainDisposition = splitBrainLive
? "live-count-as-active"
: splitBrain
@@ -1962,15 +2113,35 @@ function compactCodeQueueActivity(
: "control-plane and execution-plane activity signals are not split-brain.";
const interventionReason = splitBrainLive
? "fresh heartbeat makes split-brain live; count these runners as active and continue supervision."
: heartbeatRiskTaskCount > 0
? "heartbeat risk is present; inspect before adding replacement work or recovering tasks."
: staleRecoveryCandidateTaskCount > 0
? "stale recovery candidates are present; follow the recovery runbook before changing concurrency."
: rePollBeforeRecovery
? "heartbeat risk is visible, but this snapshot is not repeated-poll confirmation; re-poll supervisor before recovery."
: recoveryMutationAllowed
? "repeated-poll confirmation is present; run dry-run reconcile before any recovery mutation."
: recommendedActionIntervenes
? `execution diagnostics recommend ${recommendedAction}; intervene before adding work.`
: splitBrain
? "split-brain is not proven live; inspect raw diagnostics before treating capacity as available."
: "no intervention signal in compact activity summary.";
const schedulerHeartbeatFreshness = {
source: "executionDiagnostics.schedulerHeartbeat",
heartbeatFreshActiveTaskCount,
activeHeartbeatTaskCount,
heartbeatRiskTaskCount,
staleRecoveryCandidateTaskCount,
lastSchedulerHeartbeatAt: recovery.lastSchedulerHeartbeatAt,
lastObservedAgentEventAt: recovery.lastObservedAgentEventAt,
};
const snapshotSemantics = {
role: recovery.snapshotRole,
boundedSnapshot: recovery.boundedSnapshot,
snapshotAt: recovery.snapshotAt,
submittedAt: recovery.submittedAt,
submitConfirmationIsImmediate: recovery.snapshotRole === "submit-confirmation",
databaseActiveField: "activity.databaseActiveTaskCount",
schedulerHeartbeatFreshnessField: "activity.schedulerHeartbeatFreshness",
queuedSubmittedStateField: "submitted.taskStates[]",
recoveryHint: recovery.hint,
};
const commanderConcurrency = {
activeRunnerCount: effectiveActiveTaskCount,
activeRunnerCountField: "activity.effectiveActiveTaskCount",
@@ -1978,8 +2149,11 @@ function compactCodeQueueActivity(
decisionRule: "subtract activeRunnerCount from the commander concurrency target; for a 15-runner policy, remaining slots = 15 - activeRunnerCount.",
splitBrainDisposition,
splitBrainReason,
attentionRequired,
interventionRequired,
interventionReason,
recoveryHint: recovery.hint,
recoveryDisposition: recovery.disposition,
};
return {
effectiveActiveTaskCount,
@@ -1990,6 +2164,9 @@ function compactCodeQueueActivity(
activeHeartbeatTaskCount,
heartbeatRiskTaskCount,
staleRecoveryCandidateTaskCount,
schedulerHeartbeatFreshness,
recovery,
snapshotSemantics,
schedulerLocalActiveQueueCount: schedulerLocalActiveQueueIds.length,
schedulerLocalActiveRunSlotCount,
runnableQueueCount,
@@ -2003,8 +2180,10 @@ function compactCodeQueueActivity(
activeQueueIdsNote,
interpretation: splitBrainLive
? "split-brain live: database-active tasks have fresh scheduler heartbeat; continue supervision."
: heartbeatRiskTaskCount > 0
? "heartbeat risk is present; investigate before retry or recovery."
: rePollBeforeRecovery
? "heartbeat risk is visible; re-poll supervisor before recovery."
: recoveryMutationAllowed
? "repeated poll confirms stale-active candidate; dry-run reconcile is the next recovery check."
: effectiveActiveTaskCount > 0
? "active work is present; compare database, heartbeat, and scheduler-local counts before changing concurrency."
: "no active work observed by database, heartbeat, or scheduler-local signals.",
@@ -2012,7 +2191,7 @@ function compactCodeQueueActivity(
}
function supervisorExecutionDiagnostics(value: unknown): Record<string, unknown> | null {
const diagnostics = compactExecutionDiagnostics(value);
const diagnostics = compactExecutionDiagnostics(value, { snapshotRole: "supervisor-poll" });
if (diagnostics === null) return null;
const liveness = asRecord(diagnostics.liveness) ?? {};
const listBudget = asRecord(diagnostics.listBudget) ?? {};
@@ -2020,6 +2199,7 @@ function supervisorExecutionDiagnostics(value: unknown): Record<string, unknown>
state: diagnostics.state ?? null,
effectiveLiveness: diagnostics.effectiveLiveness ?? null,
recommendedAction: diagnostics.recommendedAction ?? null,
recovery: diagnostics.recovery ?? null,
splitBrainLive: diagnostics.splitBrainLive ?? null,
activeHeartbeatCount: diagnostics.activeHeartbeatCount ?? null,
databaseActiveTaskCount: diagnostics.databaseActiveTaskCount ?? null,
@@ -3943,7 +4123,7 @@ function codexTasksCommanderResult(
const rawQueue = asRecord(taskPage.queue) ?? {};
const rawDiagnostics = asRecord(rawQueue.executionDiagnostics) ?? {};
const diagnostics = supervisorExecutionDiagnostics(rawDiagnostics);
const activity = compactCodeQueueActivity(rawQueue, diagnostics);
const activity = compactCodeQueueActivity(rawQueue, diagnostics, { snapshotRole: "supervisor-poll" });
const commanderConcurrency = asRecord(activity.commanderConcurrency) ?? {};
const runningTasks = sortRunningWatchTasks(allTasks);
const unreadCompletedTasks = sortCompletedWatchTasks(allTasks).filter((task) => taskUnreadTerminal(task));
@@ -4104,7 +4284,7 @@ function codexTasksOverviewResult(
const queuedSection = buildSupervisorTaskSection(queuedTasks, summaries, sectionLimit, sectionNextCommand(queuedTasks, sectionLimit, options, nextCommand), fullCommand);
const pagination = taskPage.pagination;
const diagnostics = supervisorExecutionDiagnostics(asRecord(taskPage.queue)?.executionDiagnostics);
const activity = compactCodeQueueActivity(asRecord(taskPage.queue) ?? {}, diagnostics);
const activity = compactCodeQueueActivity(asRecord(taskPage.queue) ?? {}, diagnostics, { snapshotRole: "supervisor-poll" });
const commanderConcurrency = asRecord(activity.commanderConcurrency) ?? {};
const activeRunning = supervisorActiveRunningSummary(taskPage, options, runningSection, diagnostics);
const visibleSupervisorItems = [...runningSection.items, ...unreadSection.items, ...recentSection.items, ...queuedSection.items];
@@ -4509,8 +4689,8 @@ function compactQueuesResponse(body: Record<string, unknown>, options: CodexQueu
const activeQueues = queues.filter((row) => typeof row.id === "string" && activeIds.includes(row.id));
const selected = options.full ? queues : Array.from(new Map([...activeQueues, ...unreadQueues, ...runnableQueues, ...nonemptyQueues].map((row) => [String(row.id), row])).values());
const visible = selected.slice(options.offset, options.offset + options.limit);
const diagnostics = compactQueueExecutionDiagnostics(queue.executionDiagnostics);
const activity = compactCodeQueueActivity(queue, diagnostics, { schedulerLocalActiveQueueIds: activeIds, runnableQueueCount: runnableQueues.length });
const diagnostics = compactQueueExecutionDiagnostics(queue.executionDiagnostics, { snapshotRole: "queue-summary" });
const activity = compactCodeQueueActivity(queue, diagnostics, { schedulerLocalActiveQueueIds: activeIds, runnableQueueCount: runnableQueues.length, snapshotRole: "queue-summary" });
const commanderConcurrency = asRecord(activity.commanderConcurrency) ?? {};
const activeTaskIds = boundedUniqueStringList(queue.activeTaskIds, Math.min(options.limit, maxTasksLimit));
const queuedTaskIds = boundedUniqueStringList(queue.queuedTaskIds, Math.min(options.limit, maxTasksLimit));
@@ -5195,8 +5375,16 @@ function compactSubmitQueueConfirmation(value: unknown, options: CompactSubmitQu
|| databaseActivePreview.truncated === true
|| queuedPreview.truncated === true
|| submittedPreview.truncated === true;
const diagnostics = compactQueueExecutionDiagnostics(record.executionDiagnostics);
const activity = compactCodeQueueActivity(record, diagnostics);
const diagnostics = compactQueueExecutionDiagnostics(record.executionDiagnostics, {
snapshotRole: "submit-confirmation",
snapshotAt: options.submittedAt ?? null,
submittedAt: options.submittedAt ?? null,
});
const activity = compactCodeQueueActivity(record, diagnostics, {
snapshotRole: "submit-confirmation",
snapshotAt: options.submittedAt ?? null,
submittedAt: options.submittedAt ?? null,
});
const commanderConcurrency = asRecord(activity.commanderConcurrency) ?? {};
const unavailableIdLists = {
activeTaskIds: activePreview.idsUnavailable === true,
@@ -5245,6 +5433,13 @@ function compactSubmitQueueConfirmation(value: unknown, options: CompactSubmitQu
queueCountsSource: "response.queue.counts",
activeCountField: "queue.countContext.active",
commanderActiveRunnerCountField: "queue.activity.effectiveActiveTaskCount",
snapshotRole: "submit-confirmation",
boundedSnapshot: true,
submittedAt: options.submittedAt ?? null,
schedulerHeartbeatFreshnessField: "queue.activity.schedulerHeartbeatFreshness",
databaseActiveField: "queue.countContext.databaseActive",
queuedSubmittedTaskStateField: "submitted.taskStates[]",
transientRiskHint: asRecord(activity.recovery)?.hint ?? null,
splitBrainLive: diagnostics?.splitBrainLive ?? false,
splitBrainDisposition: diagnostics?.splitBrainLive === true ? "live-counts-remain-active; continue supervision unless commanderConcurrency.interventionRequired=true" : "not-split-brain-live",
idsUnavailableMeaning: "A nonzero count with idsUnavailable=true means ids were omitted or unavailable in the bounded submit summary, not that there are no tasks.",
@@ -5277,6 +5472,7 @@ function compactSubmitSuccessResponse(body: Record<string, unknown>, upstream: R
const firstTaskId = taskIds[0] ?? null;
const firstQueueId = queueIds[0] ?? null;
const firstSubmittedTask = submittedTasks[0] ?? {};
const submittedAt = maxIsoTimestamp(submittedTasks.flatMap((task) => [task.createdAt, task.updatedAt]));
const queueRecord = asRecord(body.queue);
const runnerPermissions = compactRunnerPermissions(queueRecord?.runnerPermissions);
return {
@@ -5305,7 +5501,7 @@ function compactSubmitSuccessResponse(body: Record<string, unknown>, upstream: R
reason: "codex submit is a write operation; default output confirms persistence and provides drill-down commands without echoing prompt text.",
},
},
queue: compactSubmitQueueConfirmation(body.queue, { submittedTasks }),
queue: compactSubmitQueueConfirmation(body.queue, { submittedTasks, submittedAt }),
submitConcurrencyGuard: compactSubmitConcurrencyGuard(lock),
commands: {
firstTask: firstTaskId === null ? null : `bun scripts/cli.ts codex task ${firstTaskId}`,