diff --git a/tests/acceptance/workday/support/assignment-authority.ts b/tests/acceptance/workday/support/assignment-authority.ts index 6887431e..ac7b9635 100644 --- a/tests/acceptance/workday/support/assignment-authority.ts +++ b/tests/acceptance/workday/support/assignment-authority.ts @@ -45,6 +45,9 @@ export function modelExecutionInventory(items: Row[], events: Row[], run: Row): }); for (const event of events.filter(event => ['provider.execution.completed', 'provider.execution.failed'].includes(String(event.eventType)) && modelEvent(event))) assert.ok(seen.has(String(event.assignmentId)), 'ACCEPTANCE_MODEL_INVENTORY_MISSING_START'); + for (const item of items) if (item.status === 'completed' && Object.hasOwn(row(item.lifecycleOutput), 'sandboxId')) + assert.ok(typeof row(item.lifecycleOutput).sandboxId === 'string' && String(row(item.lifecycleOutput).sandboxId).trim() + && seen.has(String(item.id)), 'ACCEPTANCE_MODEL_INVENTORY_MISSING_START'); return inventory; } diff --git a/tests/modern/execution/timing/guest-clock-contract.test.ts b/tests/modern/execution/timing/guest-clock-contract.test.ts index 41e767e3..da961719 100644 --- a/tests/modern/execution/timing/guest-clock-contract.test.ts +++ b/tests/modern/execution/timing/guest-clock-contract.test.ts @@ -104,12 +104,23 @@ describe('Codex chat executor', () => { }; const f = fixture(), before = structuredClone(f); expect(modelExecutionInventory(f.items, f.events, f.run).map(value => value.item.status)).toEqual(['completed', 'failed', 'returned']); expect(f).toEqual(before); - for (const mode of ['empty', 'missing-start', 'missing-terminal', 'duplicate-start', 'duplicate-terminal', 'duplicate-owner', 'missing-owner', + const sandbox = fixture(); Object.assign(sandbox.items[0]!, { lifecycleOutput: { sandboxId: 'original-completed-sandbox' } }); + expect(modelExecutionInventory(sandbox.items, sandbox.events, sandbox.run)).toHaveLength(3); + const preparation = Object.assign(structuredClone(sandbox.items[1]!), { id: 'failed-before-model-start', lifecycleOutput: { sandboxId: 'prepared-only' } }); + expect(modelExecutionInventory([...sandbox.items, preparation], sandbox.events, sandbox.run)).toHaveLength(3); + for (const sandboxId of ['', null, false, {}, []]) { + const malformed = fixture(); Object.assign(malformed.items[0]!, { lifecycleOutput: { sandboxId } }); + expect(() => modelExecutionInventory(malformed.items, malformed.events, malformed.run)).toThrow('ACCEPTANCE_MODEL_INVENTORY_MISSING_START'); + } + for (const mode of ['empty', 'missing-start', 'missing-terminal', 'omitted-sandbox-start', 'duplicate-start', 'duplicate-terminal', 'duplicate-owner', 'missing-owner', 'foreign-run', 'foreign-team', 'foreign-project', 'foreign-attempt', 'empty-model', 'missing-model', 'payload-only', 'stripped-raw', 'stripped-empty-raw', 'stripped-malformed-raw', 'bad-clock', 'reversed', 'duplicate-index']) { const supplied = fixture(); if (mode === 'empty') supplied.events = []; if (mode === 'missing-start') supplied.events.splice(0, 1); if (mode === 'missing-terminal') supplied.events.splice(1, 1); + if (mode === 'omitted-sandbox-start') supplied.items.push(Object.assign(structuredClone(supplied.items[0]!), { + id: 'omitted-completed-model', assignmentAttempt: { ...supplied.items[0]!.assignmentAttempt, id: 'omitted-completed-model' }, + lifecycleOutput: { sandboxId: 'original-completed-sandbox' } })); if (mode.startsWith('duplicate-') && ['duplicate-start', 'duplicate-terminal'].includes(mode)) supplied.events.push({ ...supplied.events[mode === 'duplicate-start' ? 0 : 1]!, id: 'additional-event', eventIndex: 6 }); if (mode === 'duplicate-owner') supplied.items.push(structuredClone(supplied.items[0]!)); diff --git a/tests/modern/guarantees/preflight/campaign-freeze-native.test.ts b/tests/modern/guarantees/preflight/campaign-freeze-native.test.ts index 8d0da6f3..68a08136 100644 --- a/tests/modern/guarantees/preflight/campaign-freeze-native.test.ts +++ b/tests/modern/guarantees/preflight/campaign-freeze-native.test.ts @@ -296,15 +296,17 @@ it('native public SDK event reads retain completed failed and returned model inv const page = row((await client.invoke(controlPlaneOperation('workdays.events.list'), input)).data); expect(input).toEqual(before); if (!Array.isArray(page.items)) throw new Error('Native original event collection required'); observed.push(...page.items.map(row)); } - const inventory = modelExecutionInventory(items, observed, run); + const suppliedItems = mode === 'omitted-sandbox-start' ? [...items, { ...items[0]!, id: 'omitted-completed-model', + assignmentAttempt: { ...items[0]!.assignmentAttempt, id: 'omitted-completed-model' }, lifecycleOutput: { sandboxId: 'native-completed-sandbox' } }] : items; + const inventory = modelExecutionInventory(suppliedItems, observed, run); if (!mode.startsWith('stripped-')) expect(inventory.map(value => value.item.status)).toEqual(['completed', 'failed', 'returned']); if (mode === 'exact') expect(observed).toEqual(events); } catch (failure) { denied = true; error = failure instanceof Error ? failure.message : String(failure); } - if (['missing-start', 'foreign', 'duplicate', 'empty-model', 'payload-only'].includes(mode)) expect(error).toMatch(/ACCEPTANCE_MODEL_INVENTORY|Expected values to be strictly equal/u); + if (['missing-start', 'omitted-sandbox-start', 'foreign', 'duplicate', 'empty-model', 'payload-only'].includes(mode)) expect(error).toMatch(/ACCEPTANCE_MODEL_INVENTORY|Expected values to be strictly equal/u); observations.push({ mode, denied, error }); return denied; }; expect(await execute(), JSON.stringify(observations)).toBe(false); - for (const fault of ['missing-start', 'foreign', 'duplicate', 'empty-model', 'payload-only', '403', '503', 'json']) { mode = fault; expect(await execute(), mode).toBe(true); } + for (const fault of ['missing-start', 'omitted-sandbox-start', 'foreign', 'duplicate', 'empty-model', 'payload-only', '403', '503', 'json']) { mode = fault; expect(await execute(), mode).toBe(true); } for (const fault of ['stripped-raw', 'stripped-empty-raw', 'stripped-malformed-raw']) { mode = fault; await execute(); } const retained = structuredClone(observations), requests = structuredClone(history); mode = 'exact'; expect(await execute(), JSON.stringify(observations)).toBe(false); expect(observations.slice(0, retained.length)).toEqual(retained); expect(history.slice(0, requests.length)).toEqual(requests);