feat(mosaic): add correlated lease promotion CLI

This commit is contained in:
Jason Woltje
2026-08-11 20:51:03 -05:00
parent 77edb0dea2
commit 4f7f6b3281
7 changed files with 798 additions and 6 deletions
@@ -0,0 +1,219 @@
import { Command } from 'commander';
import { describe, expect, it, vi } from 'vitest';
import {
promoteSeat,
registerPromoteCommand,
type PromotionBreadcrumbStore,
type PromotionTransport,
} from './promote.js';
const attemptId = 'a'.repeat(64);
const target = {
bundle: 'local',
seat: 'claude-seat',
sessionId: 'b'.repeat(64),
};
function transport(): PromotionTransport {
return {
resolve: vi.fn(async () => target),
sendPromotion: vi.fn(async () => {}),
};
}
describe('mosaic promote', () => {
it('accepts only a fresh result correlated to this attempt', async () => {
const promotionTransport = transport();
const store: PromotionBreadcrumbStore = {
readAttemptId: vi.fn().mockResolvedValueOnce(null).mockResolvedValue(attemptId),
readResult: vi
.fn()
.mockResolvedValueOnce({
attempt_id: 'c'.repeat(64),
expires_at_wallclock: 4_600,
reason: null,
session_id: target.sessionId,
ts: 1_001,
verified: true,
})
.mockResolvedValueOnce({
attempt_id: attemptId,
expires_at_wallclock: 4_600,
reason: null,
session_id: target.sessionId,
ts: 1_001,
verified: true,
}),
};
const result = await promoteSeat('claude-seat', {
clock: () => 1_000,
sleep: async () => {},
store,
timeoutMs: 1,
transport: promotionTransport,
});
expect(result).toEqual({
bundle: 'local',
expiresAtWallclock: 4_600,
reason: null,
seat: 'claude-seat',
sessionId: 'b'.repeat(64),
status: 'VERIFIED',
});
expect(promotionTransport.sendPromotion).toHaveBeenCalledWith(target);
expect(store.readResult).toHaveBeenCalledTimes(2);
});
it('accepts a fresh result for this session when completion consumed the pending nonce', async () => {
const promotionTransport = transport();
let now = 1_000;
const store: PromotionBreadcrumbStore = {
readAttemptId: vi.fn(async () => null),
readResult: vi.fn(async () => ({
attempt_id: attemptId,
expires_at_wallclock: 4_600,
reason: null,
session_id: target.sessionId,
ts: 1_001,
verified: true,
})),
};
const result = await promoteSeat('claude-seat', {
clock: () => now,
sleep: async () => {
now += 10;
},
store,
timeoutMs: 10,
transport: promotionTransport,
});
expect(result.status).toBe('VERIFIED');
});
it('prints VERIFIED with the resolved seat, session, bundle, and wall-clock expiry', async () => {
const promotionTransport = transport();
const store: PromotionBreadcrumbStore = {
readAttemptId: vi.fn().mockResolvedValueOnce(null).mockResolvedValue(attemptId),
readResult: vi.fn(async () => ({
attempt_id: attemptId,
expires_at_wallclock: 4_600,
reason: null,
session_id: target.sessionId,
ts: Number.MAX_SAFE_INTEGER,
verified: true,
})),
};
const output = vi.spyOn(console, 'log').mockImplementation(() => {});
const program = new Command().exitOverride();
registerPromoteCommand(program, { store, transport: promotionTransport });
try {
await program.parseAsync(['node', 'mosaic', 'promote', 'claude-seat']);
expect(output).toHaveBeenCalledWith(
`VERIFIED seat=claude-seat session=${target.sessionId} bundle=local expiry=1970-01-01T01:16:40.000Z`,
);
expect(process.exitCode).not.toBe(1);
} finally {
output.mockRestore();
process.exitCode = undefined;
}
});
it('rejects a stale result even when its nonce matches', async () => {
const promotionTransport = transport();
let now = 1_000;
const store: PromotionBreadcrumbStore = {
readAttemptId: vi.fn().mockResolvedValueOnce(null).mockResolvedValue(attemptId),
readResult: vi.fn(async () => ({
attempt_id: attemptId,
expires_at_wallclock: 4_600,
reason: null,
session_id: target.sessionId,
ts: 1_000,
verified: true,
})),
};
const result = await promoteSeat('claude-seat', {
clock: () => now,
sleep: async () => {
now += 10;
},
store,
timeoutMs: 10,
transport: promotionTransport,
});
expect(result).toEqual({
bundle: 'local',
expiresAtWallclock: null,
reason: 'PROMOTION_TIMEOUT',
seat: 'claude-seat',
sessionId: 'b'.repeat(64),
status: 'UNVERIFIED',
});
});
it('does not accept a result for a pending attempt that existed before send', async () => {
const promotionTransport = transport();
let now = 1_000;
const store: PromotionBreadcrumbStore = {
readAttemptId: vi.fn(async () => attemptId),
readResult: vi.fn(async () => ({
attempt_id: attemptId,
expires_at_wallclock: 4_600,
reason: null,
session_id: target.sessionId,
ts: 1_001,
verified: true,
})),
};
const result = await promoteSeat('claude-seat', {
clock: () => now,
sleep: async () => {
now += 10;
},
store,
timeoutMs: 10,
transport: promotionTransport,
});
expect(result.status).toBe('UNVERIFIED');
expect(store.readResult).not.toHaveBeenCalled();
});
it('returns UNVERIFIED after a bounded timeout without reading stdin', async () => {
const promotionTransport = transport();
let now = 1_000;
const store: PromotionBreadcrumbStore = {
readAttemptId: vi.fn(async () => null),
readResult: vi.fn(async () => null),
};
const result = await promoteSeat('claude-seat', {
clock: () => now,
sleep: async () => {
now += 10;
},
store,
timeoutMs: 10,
transport: promotionTransport,
});
expect(result).toEqual({
bundle: 'local',
expiresAtWallclock: null,
reason: 'PROMOTION_TIMEOUT',
seat: 'claude-seat',
sessionId: 'b'.repeat(64),
status: 'UNVERIFIED',
});
expect(promotionTransport.sendPromotion).toHaveBeenCalledOnce();
expect(store.readResult).toHaveBeenCalledTimes(2);
});
});