blob: 513d7570c922d1f07234be9982950f472fc33a24 [file]
import { describe, test } from 'node:test';
import assert from 'node:assert/strict';
import { GoalManager, type GoalManagerDeps } from '../goal-state.js';
import {
buildGoalTools,
GOAL_CLEAR_TOOL_NAME,
GOAL_PAUSE_TOOL_NAME,
GOAL_RESUME_TOOL_NAME,
GOAL_SET_TOOL_NAME,
} from '../goal-tools.js';
import {
GoalContinuationCoordinator,
type GoalContinuationDeps,
type GoalContinuationScheduler,
type GoalTurnAdmission,
type GoalTurnOutcome,
} from '../goal-continuation.js';
import type { GoalEvaluation } from '../goal-evaluator.js';
import type { MakaToolContext } from '../tool-runtime.js';
const SESSION = 'sess-1';
function deferred<T>() {
let resolve!: (value: T | PromiseLike<T>) => void;
let reject!: (reason?: unknown) => void;
const promise = new Promise<T>((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
function controlledCall<T>() {
const result = deferred<T>();
let markStarted!: () => void;
const started = new Promise<void>((resolve) => {
markStarted = resolve;
});
return {
invoke: () => {
markStarted();
return result.promise;
},
started,
settled: result.promise.then(
() => undefined,
() => undefined,
),
resolve: result.resolve,
reject: result.reject,
};
}
class ManualScheduler implements GoalContinuationScheduler {
private nextId = 0;
readonly entries: Array<{
id: number;
callback: () => void;
delayMs: number;
cleared: boolean;
}> = [];
setTimeout(callback: () => void, delayMs: number): number {
const id = ++this.nextId;
this.entries.push({ id, callback, delayMs, cleared: false });
return id;
}
clearTimeout(handle: unknown): void {
const entry = this.entries.find((candidate) => candidate.id === handle);
if (entry) entry.cleared = true;
}
pendingDelays(): number[] {
return this.entries.filter((entry) => !entry.cleared).map((entry) => entry.delayMs);
}
fireNext(): void {
const entry = this.entries.find((candidate) => !candidate.cleared);
assert.ok(entry, 'expected a pending timer');
entry.cleared = true;
entry.callback();
}
}
interface AdmittedTurn {
sessionId: string;
prompt: string;
turnId: string;
completion: ReturnType<typeof deferred<GoalTurnOutcome>>;
}
function prepareAdmission(
admitted: AdmittedTurn[],
sessionId: string,
prompt: string,
turnId: string,
): GoalTurnAdmission {
const completion = deferred<GoalTurnOutcome>();
return {
kind: 'prepared',
turnId,
start: () => {
admitted.push({ sessionId, prompt, turnId, completion });
return completion.promise;
},
};
}
function setup(opts?: {
evaluations?: Partial<GoalEvaluation>[];
tokenCount?: number;
onChange?: GoalManagerDeps['onChange'];
taskGate?: GoalContinuationDeps['taskGate'];
}) {
let id = 0;
const manager = new GoalManager({
generateId: () => `g-${++id}`,
now: () => 1000,
onChange: opts?.onChange,
});
const scheduler = new ManualScheduler();
const evaluationQueue = [...(opts?.evaluations ?? [])];
const defaultEvaluation: GoalEvaluation = {
met: false,
impossible: false,
progress: true,
waiting: false,
evaluatorFailed: false,
reason: 'keep going',
};
const attemptedPrompts: string[] = [];
const admitted: AdmittedTurn[] = [];
let ownedTurnSequence = 0;
let admissionImpl: (sessionId: string, prompt: string) => GoalTurnAdmission = (
sessionId,
prompt,
) => {
const turnId = `turn-owned-${++ownedTurnSequence}`;
return prepareAdmission(admitted, sessionId, prompt, turnId);
};
const deps: GoalContinuationDeps = {
goalManager: manager,
evaluator: {
evaluate: async () => {
const next = { ...defaultEvaluation, ...evaluationQueue.shift() };
return JSON.stringify(next);
},
close: async () => {},
},
getRecentContext: async () => 'recent context',
getTokenCount: opts?.tokenCount !== undefined ? () => opts.tokenCount! : undefined,
admitTurn: (sessionId, prompt) => {
attemptedPrompts.push(prompt);
return admissionImpl(sessionId, prompt);
},
scheduler,
...(opts?.taskGate ? { taskGate: opts.taskGate } : {}),
};
const coordinator = new GoalContinuationCoordinator(deps);
return {
manager,
scheduler,
deps,
coordinator,
attemptedPrompts,
admitted,
setAdmission: (next: typeof admissionImpl) => {
admissionImpl = next;
},
queueEvaluations: (...next: Partial<GoalEvaluation>[]) => evaluationQueue.push(...next),
};
}
async function waitFor(condition: () => boolean, message = 'condition was not met'): Promise<void> {
const deadline = Date.now() + 1_000;
while (!condition()) {
if (Date.now() >= deadline) assert.fail(message);
await new Promise<void>((resolve) => setImmediate(resolve));
}
}
function settleExternal(
coordinator: GoalContinuationCoordinator,
sessionId: string,
outcome: GoalTurnOutcome,
): Promise<void> {
assert.ok(outcome.turnId, 'an external turn must have a stable identity before it starts');
const registration = coordinator.beginObservedTurn(sessionId, outcome.turnId);
assert.equal(registration.kind, 'registered');
return registration.settle(outcome);
}
function registerObservedTurn(
coordinator: GoalContinuationCoordinator,
sessionId: string,
turnId: string,
) {
const registration = coordinator.beginObservedTurn(sessionId, turnId);
assert.equal(registration.kind, 'registered');
return registration.settle;
}
function goalToolContext(turnId: string): MakaToolContext {
return {
sessionId: SESSION,
turnId,
cwd: '/',
toolCallId: `tool-${turnId}`,
abortSignal: new AbortController().signal,
emitOutput: () => {},
};
}
function goalToolsFor(manager: GoalManager, coordinator: GoalContinuationCoordinator) {
return buildGoalTools({
goalManager: manager,
goalContinuation: coordinator,
});
}
describe('GoalContinuationCoordinator settlement', () => {
test('binds a Goal created by the same external turn before it settles', async () => {
const { manager, coordinator } = setup({
evaluations: [{ met: true, reason: 'same-turn Goal verified' }],
});
const settle = registerObservedTurn(coordinator, SESSION, 'turn-owner');
const tools = goalToolsFor(manager, coordinator);
const set = tools.find((tool) => tool.name === GOAL_SET_TOOL_NAME);
assert.ok(set);
await set.impl({ condition: 'ship' }, goalToolContext('turn-owner'));
await settle({ kind: 'completed', turnId: 'turn-owner' });
assert.equal(manager.get(SESSION)?.status, 'achieved');
});
test('an unbound turn cannot settle a Goal created by a concurrent turn', async () => {
const { manager, coordinator, deps } = setup({
evaluations: [{ met: true, reason: 'owner verified' }],
});
let evaluations = 0;
const evaluate = deps.evaluator.evaluate;
deps.evaluator.evaluate = (...args) => {
evaluations++;
return evaluate(...args);
};
const settleOther = registerObservedTurn(coordinator, SESSION, 'turn-other');
const settleOwner = registerObservedTurn(coordinator, SESSION, 'turn-owner');
const set = goalToolsFor(manager, coordinator).find((tool) => tool.name === GOAL_SET_TOOL_NAME);
assert.ok(set);
await set.impl({ condition: 'ship' }, goalToolContext('turn-owner'));
await settleOther({
kind: 'completed',
turnId: 'turn-other',
});
assert.equal(evaluations, 0);
await settleOwner({
kind: 'completed',
turnId: 'turn-owner',
});
assert.equal(evaluations, 1);
assert.equal(manager.get(SESSION)?.status, 'achieved');
});
test('an older unbound turn cannot activate a Goal after another turn activated and cleared one', async () => {
const { manager, coordinator } = setup();
registerObservedTurn(coordinator, SESSION, 'turn-old');
registerObservedTurn(coordinator, SESSION, 'turn-owner');
const tools = goalToolsFor(manager, coordinator);
const set = tools.find((tool) => tool.name === GOAL_SET_TOOL_NAME);
const clear = tools.find((tool) => tool.name === GOAL_CLEAR_TOOL_NAME);
assert.ok(set);
assert.ok(clear);
await set.impl({ condition: 'first' }, goalToolContext('turn-owner'));
await clear.impl({}, goalToolContext('turn-owner'));
const output = String(
await set.impl({ condition: 'replacement' }, goalToolContext('turn-old')),
);
// A real race: another turn armed and cleared a goal, so the generation
// this turn observed is gone. Reading the current goal is worth doing and
// can change what the model does next, so this is where a look-again
// instruction is honest.
assert.match(output, /the session goal changed while this turn was running/);
assert.match(output, /Call GoalStatus/);
assert.equal(manager.get(SESSION)?.status, 'cleared');
assert.equal(manager.get(SESSION)?.condition, 'first');
});
test('a turn registered against a paused Goal cannot activate after another turn clears it', async () => {
const { manager, coordinator } = setup();
manager.create(SESSION, 'paused goal');
manager.pause(SESSION);
registerObservedTurn(coordinator, SESSION, 'turn-old');
registerObservedTurn(coordinator, SESSION, 'turn-clear');
const tools = goalToolsFor(manager, coordinator);
const clear = tools.find((tool) => tool.name === GOAL_CLEAR_TOOL_NAME);
const set = tools.find((tool) => tool.name === GOAL_SET_TOOL_NAME);
assert.ok(clear);
assert.ok(set);
assert.match(String(await clear.impl({}, goalToolContext('turn-clear'))), /Goal cleared/);
const output = String(
await set.impl({ condition: 'replacement' }, goalToolContext('turn-old')),
);
assert.match(output, /the session goal changed while this turn was running/);
assert.equal(manager.get(SESSION)?.condition, 'paused goal');
assert.equal(manager.get(SESSION)?.status, 'cleared');
});
test('an old Goal turn cannot pause or clear a replacement Goal', async () => {
const { manager, coordinator } = setup();
manager.create(SESSION, 'first');
registerObservedTurn(coordinator, SESSION, 'turn-old');
registerObservedTurn(coordinator, SESSION, 'turn-clear');
const tools = goalToolsFor(manager, coordinator);
const clear = tools.find((tool) => tool.name === GOAL_CLEAR_TOOL_NAME);
const pause = tools.find((tool) => tool.name === GOAL_PAUSE_TOOL_NAME);
const set = tools.find((tool) => tool.name === GOAL_SET_TOOL_NAME);
assert.ok(clear);
assert.ok(pause);
assert.ok(set);
await clear.impl({}, goalToolContext('turn-clear'));
registerObservedTurn(coordinator, SESSION, 'turn-replacement');
await set.impl({ condition: 'replacement' }, goalToolContext('turn-replacement'));
assert.match(
String(await pause.impl({}, goalToolContext('turn-old'))),
/the session goal changed while this turn was running/,
);
assert.match(
String(await clear.impl({}, goalToolContext('turn-old'))),
/the session goal changed while this turn was running/,
);
assert.equal(manager.get(SESSION)?.condition, 'replacement');
assert.equal(manager.get(SESSION)?.status, 'active');
});
test('a removed external turn cannot create or resume a Goal through the real tools', async (t) => {
await t.test('GoalSet after permanent removal', async () => {
const { manager, coordinator } = setup();
registerObservedTurn(coordinator, SESSION, 'turn-deleted');
const set = goalToolsFor(manager, coordinator).find(
(tool) => tool.name === GOAL_SET_TOOL_NAME,
);
assert.ok(set);
const removal = coordinator.beginSessionClose(SESSION, 'remove');
manager.remove(SESSION);
removal.commit();
const output = String(
await set.impl({ condition: 'must not exist' }, goalToolContext('turn-deleted')),
);
// The loop this replaced: the session was closed and removed, so this
// turn has no registration and never will. Told to call GoalStatus and
// retry "if there is still no active goal", the model gets "No goal set
// for this session", satisfies the condition, retries, and receives the
// identical refusal forever. The refusal must not ask for that.
assert.match(output, /does not run under the session goal boundary/);
assert.match(output, /Do not call this tool again in this turn/);
assert.doesNotMatch(output, /call GoalSet again/i);
assert.equal(manager.get(SESSION), undefined);
});
await t.test('GoalResume after archive and replacement', async () => {
const { manager, coordinator } = setup();
manager.create(SESSION, 'old');
manager.pause(SESSION);
registerObservedTurn(coordinator, SESSION, 'turn-archived');
const resume = goalToolsFor(manager, coordinator).find(
(tool) => tool.name === GOAL_RESUME_TOOL_NAME,
);
assert.ok(resume);
const archive = coordinator.beginSessionClose(SESSION, 'archive');
manager.remove(SESSION);
archive.commit();
coordinator.unarchiveSession(SESSION);
manager.create(SESSION, 'replacement');
manager.pause(SESSION);
const output = String(await resume.impl({}, goalToolContext('turn-archived')));
assert.match(output, /does not run under the session goal boundary/);
assert.match(output, /Do not call this tool again in this turn/);
assert.doesNotMatch(output, /call GoalResume again/i);
assert.equal(manager.get(SESSION)?.condition, 'replacement');
assert.equal(manager.get(SESSION)?.status, 'paused');
});
});
/**
* Every cause the refusal text can name, produced by the real coordinator.
*
* The refusal-text suite drives these through a fake whose `activationStanding`
* and `mutationStanding` return whatever they are handed, which proves the
* sentences and nothing about whether the coordinator can reach them. Three of
* the five had no test that it can, and one of those three could not: the
* shutdown sentence was written for a branch that `dispose()` had already made
* unreachable, and the turn read a different sentence that was false about it.
*/
describe('every decline cause is reachable from the real coordinator', () => {
test('a shut-down coordinator says so, instead of denying the turn was registered', async () => {
const { manager, coordinator } = setup();
registerObservedTurn(coordinator, SESSION, 'turn-live');
const tools = goalToolsFor(manager, coordinator);
const set = tools.find((tool) => tool.name === GOAL_SET_TOOL_NAME);
const clear = tools.find((tool) => tool.name === GOAL_CLEAR_TOOL_NAME);
assert.ok(set);
assert.ok(clear);
await set.impl({ condition: 'ship' }, goalToolContext('turn-live'));
coordinator.dispose();
const output = String(await clear.impl({}, goalToolContext('turn-live')));
assert.match(output, /the goal system is shutting down/);
// The sentence this turn used to get. It was registered under the Goal
// boundary — it armed the goal it is now trying to clear.
assert.doesNotMatch(output, /does not run under the session goal boundary/);
});
test('a turn already bound to a goal is not told it tried to arm a second one', async () => {
const { manager, coordinator } = setup();
// Two things have to hold at once, and neither involves the model arming
// anything. `beginObservedTurn` binds the lease by itself when a goal is
// already active, and only `mutateGoal` releases it — so the pause has to
// come from somewhere that is not a Goal tool. The autonomous evaluation
// loop and the host-side pause control are both exactly that.
manager.create(SESSION, 'ship');
registerObservedTurn(coordinator, SESSION, 'turn-inherited');
manager.pause(SESSION);
const resume = goalToolsFor(manager, coordinator).find(
(tool) => tool.name === GOAL_RESUME_TOOL_NAME,
);
assert.ok(resume);
const output = String(await resume.impl({}, goalToolContext('turn-inherited')));
assert.equal(manager.get(SESSION)?.status, 'paused');
// GoalResume asked to arm nothing, and this turn armed nothing.
assert.doesNotMatch(output, /arm a second one/);
assert.doesNotMatch(output, /already armed/);
assert.match(output, /already bound to a goal/);
assert.match(output, /Do not call GoalResume again in this turn/);
});
test('GoalSet on a turn that is still bound to a finished goal is refused as a second arming', async () => {
const { manager, coordinator } = setup();
manager.create(SESSION, 'first');
registerObservedTurn(coordinator, SESSION, 'turn-inherited');
// Same shape: the goal reaches a terminal status without passing through
// `mutateGoal`, so the turn keeps the lease it was bound to at
// registration and GoalSet gets past its own unfinished-goal guard.
manager.clear(SESSION);
const set = goalToolsFor(manager, coordinator).find(
(tool) => tool.name === GOAL_SET_TOOL_NAME,
);
assert.ok(set);
const output = String(
await set.impl({ condition: 'second' }, goalToolContext('turn-inherited')),
);
assert.match(output, /cannot arm a second one/);
assert.match(output, /Call GoalStatus/);
assert.equal(manager.get(SESSION)?.status, 'cleared');
});
test('a turn that started before the goal existed is told that, not that it is unregistered', async () => {
const { manager, coordinator } = setup();
registerObservedTurn(coordinator, SESSION, 'turn-early');
registerObservedTurn(coordinator, SESSION, 'turn-later');
const tools = goalToolsFor(manager, coordinator);
const set = tools.find((tool) => tool.name === GOAL_SET_TOOL_NAME);
const clear = tools.find((tool) => tool.name === GOAL_CLEAR_TOOL_NAME);
assert.ok(set);
assert.ok(clear);
await set.impl({ condition: 'later goal' }, goalToolContext('turn-later'));
const output = String(await clear.impl({}, goalToolContext('turn-early')));
assert.match(output, /began before the current goal existed/);
assert.match(output, /Do not call this tool again in this turn/);
assert.equal(manager.get(SESSION)?.status, 'active');
});
});
test('closed sessions reject fresh turns until explicitly reopened', () => {
const { coordinator } = setup();
coordinator.beginSessionClose(SESSION, 'archive').commit();
assert.deepEqual(coordinator.beginObservedTurn(SESSION, 'turn-closed'), {
kind: 'unavailable',
reason: 'Goal continuation session is closed.',
});
coordinator.unarchiveSession(SESSION);
assert.equal(coordinator.beginObservedTurn(SESSION, 'turn-reopened').kind, 'registered');
});
test('a rolled-back session close leaves revoked continuation visibly paused', async (t) => {
await t.test('busy continuation intent', async () => {
const { manager, coordinator, setAdmission, attemptedPrompts } = setup();
const idle = deferred<void>();
setAdmission(() => ({ kind: 'busy', whenIdle: idle.promise }));
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-external',
});
await waitFor(
() => attemptedPrompts.length === 1,
'continuation did not reach the busy gate',
);
const archive = coordinator.beginSessionClose(SESSION, 'archive');
archive.rollback();
idle.resolve();
await new Promise<void>((resolve) => setImmediate(resolve));
assert.equal(manager.get(SESSION)?.status, 'paused');
assert.equal(
manager.get(SESSION)?.lastReason,
'Goal continuation paused because session archive did not complete.',
);
assert.equal(attemptedPrompts.length, 1);
registerObservedTurn(coordinator, SESSION, 'turn-resume');
const resume = goalToolsFor(manager, coordinator).find(
(tool) => tool.name === GOAL_RESUME_TOOL_NAME,
);
assert.ok(resume);
assert.match(String(await resume.impl({}, goalToolContext('turn-resume'))), /Goal resumed/);
assert.equal(manager.get(SESSION)?.status, 'active');
});
await t.test('in-flight evaluator', async () => {
const { manager, coordinator, deps, admitted } = setup();
const evaluation = controlledCall<string>();
deps.evaluator.evaluate = evaluation.invoke;
manager.create(SESSION, 'ship');
const settlement = settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-evaluating',
});
await evaluation.started;
const removal = coordinator.beginSessionClose(SESSION, 'remove');
removal.rollback();
await settlement;
evaluation.resolve('{"met":true,"reason":"late"}');
await new Promise<void>((resolve) => setImmediate(resolve));
assert.equal(manager.get(SESSION)?.status, 'paused');
assert.equal(
manager.get(SESSION)?.lastReason,
'Goal continuation paused because session removal did not complete.',
);
assert.equal(admitted.length, 0);
});
});
test('transfers same-turn authority across its own lifecycle mutation', async (t) => {
await t.test('pause then resume', async () => {
const { manager, coordinator } = setup({
evaluations: [{ met: true, reason: 'resumed Goal verified' }],
});
const settle = registerObservedTurn(coordinator, SESSION, 'turn-control');
const tools = goalToolsFor(manager, coordinator);
const context = goalToolContext('turn-control');
const set = tools.find((tool) => tool.name === GOAL_SET_TOOL_NAME);
const pause = tools.find((tool) => tool.name === GOAL_PAUSE_TOOL_NAME);
const resume = tools.find((tool) => tool.name === GOAL_RESUME_TOOL_NAME);
assert.ok(set);
assert.ok(pause);
assert.ok(resume);
await set.impl({ condition: 'ship' }, context);
await pause.impl({}, context);
assert.match(String(await resume.impl({}, context)), /Goal resumed/);
await settle({ kind: 'completed', turnId: 'turn-control' });
assert.equal(manager.get(SESSION)?.status, 'achieved');
});
await t.test('clear then replace', async () => {
const { manager, coordinator } = setup({
evaluations: [{ met: true, reason: 'replacement Goal verified' }],
});
manager.create(SESSION, 'old Goal');
const settle = registerObservedTurn(coordinator, SESSION, 'turn-control');
const tools = goalToolsFor(manager, coordinator);
const context = goalToolContext('turn-control');
const clear = tools.find((tool) => tool.name === GOAL_CLEAR_TOOL_NAME);
const set = tools.find((tool) => tool.name === GOAL_SET_TOOL_NAME);
assert.ok(clear);
assert.ok(set);
await clear.impl({}, context);
assert.match(String(await set.impl({ condition: 'replacement Goal' }, context)), /Goal set/);
await settle({ kind: 'completed', turnId: 'turn-control' });
assert.equal(manager.get(SESSION)?.condition, 'replacement Goal');
assert.equal(manager.get(SESSION)?.status, 'achieved');
});
});
test('an impossible verdict terminates without admission', async () => {
const { manager, coordinator, admitted } = setup({
evaluations: [{ impossible: true, reason: 'required dependency does not exist' }],
});
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-impossible',
});
assert.equal(manager.get(SESSION)?.status, 'impossible');
assert.equal(admitted.length, 0);
});
test('nonterminal settlement updates counters and admits one real continuation', async () => {
const { manager, coordinator, admitted } = setup({
evaluations: [{ progress: false, reason: 'one check remains' }],
});
manager.create(SESSION, 'ship', { blockCap: 3 });
await settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-1',
});
await waitFor(() => admitted.length === 1, 'continuation was not admitted');
assert.equal(manager.get(SESSION)?.iterations, 1);
assert.equal(manager.get(SESSION)?.consecutiveNoProgress, 1);
assert.equal(admitted.length, 1);
assert.match(admitted[0]!.prompt, /one check remains/);
});
test('evaluator failure remains neutral and fail-open', async () => {
const { manager, coordinator, deps, admitted } = setup();
deps.evaluator.evaluate = async () => {
throw new Error('provider outage');
};
manager.create(SESSION, 'ship', { blockCap: 1 });
await settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-1',
});
await waitFor(() => admitted.length === 1, 'fail-open continuation was not admitted');
assert.equal(manager.get(SESSION)?.status, 'active');
assert.equal(manager.get(SESSION)?.consecutiveNoProgress, 0);
assert.equal(admitted.length, 1);
});
test('context failure pauses the exact Goal with a visible reason', async () => {
const { manager, coordinator, deps, admitted } = setup();
deps.getRecentContext = async () => {
throw new Error('storage unavailable');
};
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-1',
});
assert.equal(manager.get(SESSION)?.status, 'paused');
assert.match(manager.get(SESSION)?.lastReason ?? '', /storage unavailable/);
assert.equal(admitted.length, 0);
});
test('queued completions are evaluated FIFO and collapse to the newest pending intent', async () => {
const { manager, coordinator, deps, admitted } = setup();
const firstEvaluation = controlledCall<string>();
let calls = 0;
deps.evaluator.evaluate = async () => {
calls++;
if (calls === 1) return firstEvaluation.invoke();
return JSON.stringify({
met: false,
impossible: false,
progress: true,
waiting: false,
reason: 'second result',
});
};
manager.create(SESSION, 'ship');
const first = settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await firstEvaluation.started;
const second = settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-2' });
firstEvaluation.resolve(
JSON.stringify({
met: false,
impossible: false,
progress: true,
waiting: false,
reason: 'first result',
}),
);
await Promise.all([first, second]);
await waitFor(() => admitted.length === 1, 'newest continuation was not admitted');
assert.equal(manager.get(SESSION)?.iterations, 2);
assert.equal(admitted.length, 1);
assert.match(admitted[0]!.prompt, /second result/);
assert.doesNotMatch(admitted[0]!.prompt, /first result/);
});
test('queues failures behind earlier evidence and discards later queued outcomes', async () => {
const { manager, coordinator, deps, admitted } = setup();
const evaluation = controlledCall<string>();
let evaluations = 0;
deps.evaluator.evaluate = () => {
evaluations++;
return evaluation.invoke();
};
manager.create(SESSION, 'ship');
const first = settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-first' });
await evaluation.started;
const failure = settleExternal(coordinator, SESSION, {
kind: 'errored',
turnId: 'turn-failure',
reason: 'provider failed',
});
const later = settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-later' });
assert.equal(manager.get(SESSION)?.status, 'active');
evaluation.resolve(
JSON.stringify({
met: false,
impossible: false,
progress: true,
waiting: false,
reason: 'first result',
}),
);
await Promise.all([first, failure, later]);
assert.equal(manager.get(SESSION)?.status, 'paused');
assert.equal(evaluations, 1);
assert.equal(admitted.length, 0);
});
test('pause and resume invalidate every outcome queued under the previous control lease', async () => {
const { manager, coordinator, deps, admitted } = setup();
const evaluation = controlledCall<string>();
let evaluations = 0;
deps.evaluator.evaluate = () => {
evaluations++;
return evaluation.invoke();
};
manager.create(SESSION, 'ship');
const first = settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-first',
});
await evaluation.started;
const failure = settleExternal(coordinator, SESSION, {
kind: 'errored',
turnId: 'turn-failure',
reason: 'provider failed',
});
const later = settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-later',
});
assert.ok(manager.pause(SESSION));
assert.ok(manager.resume(SESSION));
evaluation.resolve(
JSON.stringify({
met: true,
impossible: false,
progress: true,
waiting: false,
reason: 'old evidence must not apply',
}),
);
await Promise.all([first, failure, later]);
assert.equal(manager.get(SESSION)?.status, 'active');
assert.equal(manager.get(SESSION)?.iterations, 0);
assert.equal(evaluations, 1);
assert.equal(admitted.length, 0);
});
test('a pre-pause external turn cannot settle the resumed Goal', async () => {
const { manager, coordinator, deps } = setup();
let evaluations = 0;
deps.evaluator.evaluate = async () => {
evaluations++;
return '{"met":true,"reason":"must not evaluate"}';
};
manager.create(SESSION, 'ship');
const settleLate = registerObservedTurn(coordinator, SESSION, 'turn-late');
await settleExternal(coordinator, SESSION, {
kind: 'errored',
turnId: 'turn-failure',
reason: 'provider failed',
});
assert.ok(manager.resume(SESSION));
await settleLate({
kind: 'completed',
turnId: 'turn-late',
});
assert.equal(manager.get(SESSION)?.status, 'active');
assert.equal(evaluations, 0);
});
test('archive invalidates queued and in-flight outcomes before Goal replacement', async () => {
const { manager, coordinator, deps, admitted } = setup();
const evaluation = controlledCall<string>();
let evaluationSignal: AbortSignal | undefined;
deps.evaluator.evaluate = (_prompt, _sessionId, signal) => {
evaluationSignal = signal;
return evaluation.invoke();
};
manager.create(SESSION, 'old');
const inFlight = settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-in-flight',
});
await evaluation.started;
const queued = settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-queued',
});
const archive = coordinator.beginSessionClose(SESSION, 'archive');
assert.equal(evaluationSignal?.aborted, true);
assert.equal(manager.remove(SESSION), true);
archive.commit();
coordinator.unarchiveSession(SESSION);
assert.equal(manager.create(SESSION, 'replacement').kind, 'created');
await Promise.all([inFlight, queued]);
evaluation.resolve(
JSON.stringify({
met: true,
impossible: false,
progress: true,
waiting: false,
reason: 'old evaluator must not apply',
}),
);
await new Promise<void>((resolve) => setImmediate(resolve));
assert.equal(manager.get(SESSION)?.condition, 'replacement');
assert.equal(manager.get(SESSION)?.status, 'active');
assert.equal(admitted.length, 0);
});
test('model pause and clear abort an older evaluator without revoking their own turn', async (t) => {
for (const action of ['pause', 'clear'] as const) {
await t.test(action, async () => {
const { manager, coordinator, deps, admitted } = setup();
const evaluation = controlledCall<string>();
let evaluationSignal: AbortSignal | undefined;
deps.evaluator.evaluate = (_prompt, _sessionId, signal) => {
evaluationSignal = signal;
return evaluation.invoke();
};
manager.create(SESSION, 'ship');
const priorSettlement = settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-evaluating',
});
await evaluation.started;
const settleControl = registerObservedTurn(coordinator, SESSION, 'turn-control');
const tools = goalToolsFor(manager, coordinator);
const context = goalToolContext('turn-control');
const toolName = action === 'pause' ? GOAL_PAUSE_TOOL_NAME : GOAL_CLEAR_TOOL_NAME;
const tool = tools.find((candidate) => candidate.name === toolName);
assert.ok(tool);
assert.match(String(await tool.impl({}, context)), /Goal/);
assert.equal(evaluationSignal?.aborted, true);
await priorSettlement;
if (action === 'pause') {
const resume = tools.find((candidate) => candidate.name === GOAL_RESUME_TOOL_NAME);
assert.ok(resume);
assert.match(String(await resume.impl({}, context)), /Goal resumed/);
assert.match(String(await tool.impl({}, context)), /Goal paused/);
} else {
const set = tools.find((candidate) => candidate.name === GOAL_SET_TOOL_NAME);
assert.ok(set);
assert.match(String(await set.impl({ condition: 'replacement' }, context)), /Goal set/);
assert.match(String(await tool.impl({}, context)), /Goal cleared/);
}
await settleControl({ kind: 'completed', turnId: 'turn-control' });
assert.equal(manager.get(SESSION)?.status, action === 'pause' ? 'paused' : 'cleared');
assert.equal(admitted.length, 0);
});
}
});
test('archive consumes an external turn that has not reached the FIFO', async () => {
const { manager, coordinator, deps } = setup();
let evaluations = 0;
deps.evaluator.evaluate = async () => {
evaluations++;
return '{"met":true,"reason":"old turn must not evaluate"}';
};
manager.create(SESSION, 'old');
const settleOld = registerObservedTurn(coordinator, SESSION, 'turn-still-draining');
const archive = coordinator.beginSessionClose(SESSION, 'archive');
assert.equal(manager.remove(SESSION), true);
archive.commit();
coordinator.unarchiveSession(SESSION);
assert.equal(manager.create(SESSION, 'replacement').kind, 'created');
await settleOld({
kind: 'completed',
turnId: 'turn-still-draining',
});
assert.equal(manager.get(SESSION)?.condition, 'replacement');
assert.equal(manager.get(SESSION)?.status, 'active');
assert.equal(evaluations, 0);
});
test('dispose revokes an evaluator and all later injection', async () => {
const { manager, coordinator, deps, admitted } = setup();
const evaluation = controlledCall<string>();
deps.evaluator.evaluate = evaluation.invoke;
manager.create(SESSION, 'ship');
const pending = settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await evaluation.started;
coordinator.dispose();
evaluation.resolve(
'{"met":false,"impossible":false,"progress":true,"waiting":false,"reason":"late"}',
);
await pending;
assert.equal(manager.get(SESSION)?.iterations, 0);
assert.equal(admitted.length, 0);
});
test('close waits for accepted evaluator resource cleanup', async () => {
const { manager, coordinator, deps, admitted } = setup();
const evaluation = controlledCall<string>();
deps.evaluator.evaluate = evaluation.invoke;
deps.evaluator.close = () => evaluation.settled;
manager.create(SESSION, 'ship');
const pending = settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-1',
});
await evaluation.started;
let closeSettled = false;
const closing = coordinator.close().then(() => {
closeSettled = true;
});
await new Promise<void>((resolve) => setImmediate(resolve));
assert.equal(closeSettled, false);
evaluation.resolve(
'{"met":false,"impossible":false,"progress":true,"waiting":false,"reason":"late"}',
);
await closing;
await pending;
assert.equal(manager.get(SESSION)?.iterations, 0);
assert.equal(admitted.length, 0);
});
});
describe('GoalContinuationCoordinator admission and completion', () => {
test('aborted, suspended, and errored external turns pause the current Goal without evaluation', async (t) => {
const outcomes: GoalTurnOutcome[] = [
{ kind: 'aborted', turnId: 'turn-aborted' },
{
kind: 'suspended',
turnId: 'turn-suspended',
reason: 'Turn is waiting for user permission.',
},
{ kind: 'errored', turnId: 'turn-errored', reason: 'provider failed' },
];
for (const outcome of outcomes) {
await t.test(outcome.kind, async () => {
const { manager, coordinator, deps, admitted } = setup();
let evaluations = 0;
deps.evaluator.evaluate = async () => {
evaluations++;
throw new Error('must not evaluate');
};
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, outcome);
assert.equal(manager.get(SESSION)?.status, 'paused');
assert.match(
manager.get(SESSION)?.lastReason ?? '',
/aborted|waiting for user permission|provider failed/,
);
assert.equal(evaluations, 0);
assert.equal(admitted.length, 0);
});
}
});
test('busy preserves the intent and retries only after the host becomes idle', async () => {
const { manager, coordinator, admitted, setAdmission, attemptedPrompts } = setup({
evaluations: [{ reason: 'ready to continue' }],
});
const idle = deferred<void>();
let attempts = 0;
setAdmission((sessionId, prompt) => {
attempts++;
if (attempts === 1) return { kind: 'busy', whenIdle: idle.promise };
return prepareAdmission(admitted, sessionId, prompt, `turn-owned-${attempts}`);
});
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => attempts === 1, 'busy admission was not attempted');
assert.equal(attempts, 1);
assert.equal(manager.get(SESSION)?.status, 'active');
assert.equal(admitted.length, 0);
idle.resolve();
await waitFor(() => attempts === 2, 'idle wake did not retry admission');
assert.equal(attempts, 2);
assert.equal(admitted.length, 1);
assert.equal(attemptedPrompts.length, 2);
});
test('new completion evidence outranks an intent waiting on busy', async () => {
const { manager, coordinator, admitted, setAdmission } = setup({
evaluations: [{ reason: 'old intent' }, { reason: 'new intent' }],
});
const idle = deferred<void>();
let attempts = 0;
setAdmission((sessionId, prompt) => {
attempts++;
if (attempts === 1) return { kind: 'busy', whenIdle: idle.promise };
return prepareAdmission(admitted, sessionId, prompt, `turn-owned-${attempts}`);
});
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => attempts === 1, 'first admission was not attempted');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-2' });
idle.resolve();
await waitFor(() => admitted.length === 1, 'new evidence was not admitted after idle');
assert.equal(manager.get(SESSION)?.iterations, 2);
assert.equal(admitted.length, 1);
assert.match(admitted[0]!.prompt, /new intent/);
assert.doesNotMatch(admitted[0]!.prompt, /old intent/);
});
test('a stale owned-turn failure cannot erase a newer intent waiting on busy', async () => {
const { manager, coordinator, admitted, setAdmission } = setup({
evaluations: [{ reason: 'owned turn' }, { reason: 'new external evidence' }],
});
const idle = deferred<void>();
let attempts = 0;
setAdmission((sessionId, prompt) => {
attempts++;
if (attempts === 2) return { kind: 'busy', whenIdle: idle.promise };
return prepareAdmission(admitted, sessionId, prompt, `turn-owned-${attempts}`);
});
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => admitted.length === 1, 'owned turn was not admitted');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-2' });
await waitFor(() => attempts === 2, 'newer intent did not reach the busy host');
admitted[0]!.completion.resolve({ kind: 'aborted', turnId: admitted[0]!.turnId });
await new Promise<void>((resolve) => setImmediate(resolve));
assert.equal(manager.get(SESSION)?.status, 'active');
idle.resolve();
await waitFor(() => attempts === 3, 'stale failure erased the newer busy intent');
assert.equal(admitted.length, 2);
assert.match(admitted[1]!.prompt, /new external evidence/);
});
test('unavailable admission pauses instead of leaving a false active Goal', async () => {
const { manager, coordinator, setAdmission } = setup();
setAdmission(() => ({ kind: 'unavailable', reason: 'TUI switched sessions' }));
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(
() => manager.get(SESSION)?.status === 'paused',
'unavailable host did not pause Goal',
);
assert.equal(manager.get(SESSION)?.status, 'paused');
assert.equal(manager.get(SESSION)?.lastReason, 'TUI switched sessions');
});
test('a checkpoint change during task inspection discards the stale intent', async () => {
const taskRead = controlledCall<string[]>();
let taskReads = 0;
const { manager, coordinator, admitted } = setup({
taskGate: {
listActionableTaskKeys: () => {
taskReads++;
return taskRead.invoke();
},
},
});
manager.create(SESSION, 'ship');
const settlement = settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-1',
});
await taskRead.started;
manager.pause(SESSION);
manager.resume(SESSION);
taskRead.resolve([]);
await settlement;
await new Promise<void>((resolve) => setImmediate(resolve));
assert.equal(manager.get(SESSION)?.status, 'active');
assert.equal(taskReads, 1);
assert.equal(admitted.length, 0);
});
test('a completed Goal-owned turn re-enters the FIFO with its real turn id', async () => {
const { manager, coordinator, admitted, queueEvaluations } = setup({
evaluations: [{ reason: 'first' }],
});
queueEvaluations({ met: true, reason: 'verified by second turn' });
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => admitted.length === 1, 'continuation was not admitted');
assert.equal(admitted.length, 1);
admitted[0]!.completion.resolve({ kind: 'completed', turnId: admitted[0]!.turnId });
await waitFor(() => manager.get(SESSION)?.status === 'achieved', 'owned turn was not settled');
assert.equal(manager.get(SESSION)?.status, 'achieved');
assert.equal(admitted.length, 1);
});
test('an admitted Goal-owned turn transfers its checkpoint across pause and resume', async () => {
const { manager, coordinator, admitted, queueEvaluations } = setup({
evaluations: [{ reason: 'continue' }],
});
queueEvaluations({ met: true, reason: 'resumed owned turn verified' });
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => admitted.length === 1, 'continuation was not admitted');
const tools = goalToolsFor(manager, coordinator);
const pause = tools.find((tool) => tool.name === GOAL_PAUSE_TOOL_NAME);
const resume = tools.find((tool) => tool.name === GOAL_RESUME_TOOL_NAME);
assert.ok(pause);
assert.ok(resume);
const context = goalToolContext(admitted[0]!.turnId);
assert.match(String(await pause.impl({}, context)), /Goal paused/);
assert.match(String(await resume.impl({}, context)), /Goal resumed/);
admitted[0]!.completion.resolve({ kind: 'completed', turnId: admitted[0]!.turnId });
await waitFor(() => manager.get(SESSION)?.status === 'achieved');
assert.equal(manager.get(SESSION)?.status, 'achieved');
});
test('archive consumes an admitted Goal-owned turn before its completion arrives', async () => {
const { manager, coordinator, admitted } = setup();
manager.create(SESSION, 'first');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => admitted.length === 1, 'continuation was not admitted');
const ownedTurnId = admitted[0]!.turnId;
const archive = coordinator.beginSessionClose(SESSION, 'archive');
manager.remove(SESSION);
archive.commit();
coordinator.unarchiveSession(SESSION);
manager.create(SESSION, 'replacement');
admitted[0]!.completion.resolve({ kind: 'completed', turnId: ownedTurnId });
await new Promise<void>((resolve) => setImmediate(resolve));
assert.equal(manager.get(SESSION)?.condition, 'replacement');
assert.equal(manager.get(SESSION)?.iterations, 0);
});
test('a completed Goal-owned turn is consumed without crossing pause and resume', async () => {
const { manager, coordinator, admitted, deps } = setup({
evaluations: [
{ reason: 'first' },
{ met: true, reason: 'stale owned completion must not evaluate' },
],
});
let evaluations = 0;
const evaluate = deps.evaluator.evaluate;
deps.evaluator.evaluate = (...args) => {
evaluations++;
return evaluate(...args);
};
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => admitted.length === 1, 'owned turn was not admitted');
manager.pause(SESSION);
manager.resume(SESSION);
admitted[0]!.completion.resolve({ kind: 'completed', turnId: admitted[0]!.turnId });
await new Promise<void>((resolve) => setImmediate(resolve));
assert.equal(evaluations, 1);
assert.equal(manager.get(SESSION)?.status, 'active');
assert.equal(manager.get(SESSION)?.iterations, 1);
assert.equal(admitted.length, 1);
});
test('resolved failure and rejected Goal-owned turns pause without retrying', async (t) => {
for (const scenario of ['aborted', 'rejected'] as const) {
await t.test(scenario, async () => {
const { manager, coordinator, admitted } = setup();
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => admitted.length === 1, 'continuation was not admitted');
if (scenario === 'aborted') {
admitted[0]!.completion.resolve({ kind: 'aborted', turnId: admitted[0]!.turnId });
} else {
admitted[0]!.completion.reject(new Error('stream rejected'));
}
await waitFor(
() => manager.get(SESSION)?.status === 'paused',
`${scenario} did not pause Goal`,
);
assert.equal(manager.get(SESSION)?.status, 'paused');
assert.equal(admitted.length, 1);
assert.match(manager.get(SESSION)?.lastReason ?? '', /aborted|stream rejected/);
});
}
});
});
describe('GoalContinuationCoordinator waiting and task gate', () => {
test('waiting is visible and uses 5s → 10s backoff instead of immediate turns', async () => {
const { manager, coordinator, scheduler, admitted, queueEvaluations } = setup({
evaluations: [{ waiting: true, progress: false, reason: 'CI running' }],
});
queueEvaluations({ waiting: true, progress: false, reason: 'CI still running' });
manager.create(SESSION, 'CI passes');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => scheduler.pendingDelays().length === 1, 'waiting retry was not scheduled');
assert.equal(manager.get(SESSION)?.status, 'waiting');
assert.deepEqual(scheduler.pendingDelays(), [5_000]);
assert.equal(admitted.length, 0);
scheduler.fireNext();
await waitFor(() => admitted.length === 1, 'waiting retry did not admit a turn');
assert.equal(manager.get(SESSION)?.status, 'active');
assert.equal(admitted.length, 1);
admitted[0]!.completion.resolve({ kind: 'completed', turnId: admitted[0]!.turnId });
await waitFor(() => scheduler.pendingDelays()[0] === 10_000, 'second wait did not back off');
assert.equal(manager.get(SESSION)?.status, 'waiting');
assert.deepEqual(scheduler.pendingDelays(), [10_000]);
assert.equal(manager.get(SESSION)?.consecutiveNoProgress, 0);
});
test('a real user turn preempts waiting and cancels its retry', async () => {
const { manager, coordinator, scheduler, admitted, queueEvaluations } = setup({
evaluations: [{ waiting: true, progress: false, reason: 'CI running' }],
});
queueEvaluations({ waiting: false, progress: true, reason: 'CI passed' });
manager.create(SESSION, 'CI passes');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => scheduler.pendingDelays().length === 1, 'waiting retry was not scheduled');
assert.deepEqual(scheduler.pendingDelays(), [5_000]);
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-user' });
await waitFor(() => admitted.length === 1, 'user evidence did not preempt waiting');
assert.equal(manager.get(SESSION)?.status, 'active');
assert.equal(admitted.length, 1);
assert.match(admitted[0]!.prompt, /CI passed/);
assert.deepEqual(scheduler.pendingDelays(), []);
});
test('task reminder is consumed and traced only after admission starts', async () => {
const idle = deferred<void>();
const decisions: string[] = [];
const { manager, coordinator, admitted, setAdmission } = setup({
taskGate: {
listActionableTaskKeys: async () => ['T1'],
recordDecision: async (trace) => {
decisions.push(trace.decision);
},
},
});
let attempts = 0;
setAdmission((sessionId, prompt) => {
attempts++;
if (attempts === 1) return { kind: 'busy', whenIdle: idle.promise };
return prepareAdmission(admitted, sessionId, prompt, `turn-owned-${attempts}`);
});
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => attempts === 1, 'busy admission was not attempted');
assert.deepEqual(decisions, []);
idle.resolve();
await waitFor(() => decisions.length === 1, 'started admission was not traced');
assert.deepEqual(decisions, ['reminder_injected']);
assert.match(admitted[0]!.prompt, /Actionable task keys: T1/);
});
test('task reminder is injected once per Goal across chained turns', async () => {
const decisions: string[] = [];
const { manager, coordinator, admitted } = setup({
taskGate: {
listActionableTaskKeys: async () => ['T1'],
recordDecision: async (trace) => {
decisions.push(trace.decision);
},
},
});
manager.create(SESSION, 'ship');
await settleExternal(coordinator, SESSION, { kind: 'completed', turnId: 'turn-1' });
await waitFor(() => admitted.length === 1, 'first continuation was not admitted');
admitted[0]!.completion.resolve({ kind: 'completed', turnId: admitted[0]!.turnId });
await waitFor(() => admitted.length === 2, 'chained continuation was not admitted');
assert.match(admitted[0]!.prompt, /\[Task reminder\]/);
assert.doesNotMatch(admitted[1]!.prompt, /\[Task reminder\]/);
assert.deepEqual(decisions, ['reminder_injected', 'reminder_limit_reached']);
});
test('a pending diagnostic trace cannot block a completed owned turn behind it', async () => {
const trace = controlledCall<void>();
const { manager, coordinator, admitted } = setup({
taskGate: {
listActionableTaskKeys: async () => [],
recordDecision: () => trace.invoke(),
},
});
manager.create(SESSION, 'ship');
const settlement = settleExternal(coordinator, SESSION, {
kind: 'completed',
turnId: 'turn-1',
});
await trace.started;
await waitFor(() => admitted.length === 1, 'first continuation was not admitted');
admitted[0]!.completion.resolve({
kind: 'completed',
turnId: admitted[0]!.turnId,
});
await waitFor(() => admitted.length === 2, 'pending trace retained the session lane');
await settlement;
});
});