fix(team): surface unreadable bootstrap journal warnings

This commit is contained in:
iliya 2026-04-07 00:46:05 +03:00
parent 8ef89eefce
commit d484f1d62d
2 changed files with 47 additions and 1 deletions

View file

@ -363,7 +363,11 @@ async function readBootstrapLockMetadata(teamName: string): Promise<BootstrapLoc
}
async function readBootstrapJournalWarnings(teamName: string): Promise<string[] | undefined> {
return (await inspectBootstrapJournal(teamName)).warnings;
const inspection = await inspectBootstrapJournal(teamName);
const warnings = [inspection.issue, ...(inspection.warnings ?? [])].filter(
(item): item is string => typeof item === 'string' && item.trim().length > 0
);
return warnings.length > 0 ? warnings : undefined;
}
async function inspectBootstrapJournal(teamName: string): Promise<BootstrapJournalInspection> {
@ -436,6 +440,13 @@ async function inspectBootstrapJournal(teamName: string): Promise<BootstrapJourn
})
.filter((item): item is string => Boolean(item));
if (lines.length > 0 && messages.length === 0) {
return {
issue:
'Persisted deterministic bootstrap journal is unreadable because bootstrap-journal.jsonl is invalid, truncated, or inaccessible.',
};
}
return {
warnings:
messages.length > 0

View file

@ -142,6 +142,41 @@ describe('TeamBootstrapStateReader', () => {
nowSpy.mockRestore();
});
it('surfaces unreadable bootstrap journal as a warning without breaking active recovery', async () => {
const killSpy = vi.spyOn(process, 'kill').mockImplementation(() => true as never);
hoisted.files.set('/mock/teams/demo/bootstrap-state.json', {
contents: JSON.stringify({
version: 1,
runId: 'run-123',
teamName: 'demo',
ownerPid: 4242,
startedAt: 1700000000000,
updatedAt: 1700000000500,
phase: 'spawning_members',
members: [{ name: 'alice', status: 'pending' }],
}),
});
hoisted.files.set('/mock/teams/demo/bootstrap-journal.jsonl', {
contents: '{invalid-json',
});
await expect(readBootstrapRuntimeState('demo')).resolves.toMatchObject({
teamName: 'demo',
isAlive: false,
runId: 'run-123',
progress: {
state: 'assembling',
message: 'Spawning teammate runtimes (1)',
warnings: [
'Persisted deterministic bootstrap journal is unreadable because bootstrap-journal.jsonl is invalid, truncated, or inaccessible.',
],
},
});
killSpy.mockRestore();
});
it('ignores terminal bootstrap-state for runtime recovery projection', async () => {
hoisted.files.set('/mock/teams/demo/bootstrap-state.json', {
contents: JSON.stringify({