fix(mosaic): bound promotion transport delivery

This commit is contained in:
Jason Woltje
2026-08-11 20:51:03 -05:00
parent 4f7f6b3281
commit c136baa052
5 changed files with 197 additions and 20 deletions
+38 -3
View File
@@ -15,6 +15,7 @@ import { resolveFleetPaths, type CommandRunner } from './fleet.js';
const ATTEMPT_ID_PATTERN = /^[a-f0-9]{64}$/;
const DEFAULT_POLL_INTERVAL_MS = 250;
const DEFAULT_TIMEOUT_MS = 30_000;
const SUBPROCESS_TIMEOUT_MS = 4_500;
const PENDING_DIRECTORY = 'mosaic-lease';
const RESULT_FILE = 'last-result.json';
@@ -92,7 +93,12 @@ export async function promoteSeat(
const sleep = options.sleep ?? defaultSleep;
const timeoutMs = normalizeTimeout(options.timeoutMs);
const pollIntervalMs = normalizePollInterval(options.pollIntervalMs);
const target = await options.transport.resolve(seat);
let target: PromotionTarget;
try {
target = await options.transport.resolve(seat);
} catch (error: unknown) {
return unverifiedUnresolvedSeat(seat, `RESOLVE_FAILED: ${errorMessage(error)}`);
}
const previousAttemptId = await options.store.readAttemptId(target.sessionId);
const preSendTimestamp = clock();
try {
@@ -109,6 +115,9 @@ export async function promoteSeat(
attemptId = currentAttemptId;
}
if (attemptId !== null || previousAttemptId === null) {
// Completion can consume a first attempt's nonce before this poll observes it.
// In that branch, correlation degrades to session_id + fresh timestamp, which
// is acceptable for this 0600, same-UID local trust boundary.
const breadcrumb = await options.store.readResult();
if (
breadcrumb !== null &&
@@ -233,6 +242,17 @@ function parseOptionTimeout(value: string | undefined): number | undefined {
return Number.isFinite(parsed) ? parsed : undefined;
}
function unverifiedUnresolvedSeat(seat: string, reason: string): PromotionResult {
return {
bundle: 'unresolved',
expiresAtWallclock: null,
reason,
seat,
sessionId: 'unresolved',
status: 'UNVERIFIED',
};
}
function unverified(target: PromotionTarget, reason: string): PromotionResult {
return {
bundle: target.bundle,
@@ -268,6 +288,21 @@ function runCommand(
const child = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'] });
let stdout = '';
let stderr = '';
let settled = false;
const finish = (result: { exitCode: number; stderr: string; stdout: string }): void => {
if (settled) return;
settled = true;
clearTimeout(timeout);
resolve(result);
};
const timeout = setTimeout(() => {
child.kill('SIGKILL');
finish({
exitCode: 124,
stderr: `Promotion transport subprocess timed out after ${SUBPROCESS_TIMEOUT_MS}ms.`,
stdout,
});
}, SUBPROCESS_TIMEOUT_MS);
child.stdout.on('data', (chunk: Buffer) => {
stdout += chunk.toString('utf8');
});
@@ -275,10 +310,10 @@ function runCommand(
stderr += chunk.toString('utf8');
});
child.on('error', (error: Error) => {
resolve({ exitCode: 127, stderr: error.message, stdout });
finish({ exitCode: 127, stderr: error.message, stdout });
});
child.on('close', (code: number | null) => {
resolve({ exitCode: code ?? 1, stderr, stdout });
finish({ exitCode: code ?? 1, stderr, stdout });
});
});
}