blob: 03a6cf4fc10581ebd85177e238503aafa9d6252b [file]
import assert from 'node:assert/strict';
import { fork, type ChildProcess } from 'node:child_process';
import { randomUUID } from 'node:crypto';
import {
appendFile,
chmod,
mkdir,
mkdtemp,
readFile,
readdir,
rm,
writeFile,
} from 'node:fs/promises';
import { createServer, type Server } from 'node:http';
import { connect, type Socket } from 'node:net';
import { tmpdir } from 'node:os';
import { dirname, join } from 'node:path';
import { test } from 'node:test';
import { TOOL_BOUNDARY_PROTOCOL_V1 } from '@maka/core';
import { canonicalToolArgsHash } from '@maka/core';
import type { AgentRunHeader } from '@maka/core';
import type { MessageContent } from '@maka/core';
import type { ConnectionCatalogEntry } from '@maka/core';
import { decodeStoredMessageForRead, type StoredMessage } from '@maka/core';
import type { Task } from '@maka/core';
import { isTerminalRuntimeEvent } from '@maka/core';
import type { RuntimeEvent } from '@maka/core';
import {
buildTaskLedgerTools,
buildRecoveredTerminalRuntimeEvent,
classifyTerminalRuntimeLedger,
commitTerminalRunWithRuntimeFact,
FAKE_ASK_SANDBOX_BOUNDARY_PROMPT,
FAKE_ASK_USER_QUESTION_PROMPT,
FAKE_WAIT_FOR_STEERING_PROMPT,
type MakaTool,
type MakaToolContext,
} from '@maka/runtime';
import {
openInteractiveExecutionStoresForRead,
openInteractiveExecutionStoresForWrite,
} from '@maka/storage/execution-stores';
import { openInteractiveRuntimePolicyStoresForWrite } from '@maka/storage/runtime-policy-stores';
import {
resolveRootControlNamespace,
resolveStorageRoot,
tryAcquireInteractiveRootOwner,
tryAcquireInteractiveRootReader,
type StorageRootCapability,
} from '@maka/storage/root-authority';
import { openInteractiveTaskLedgerStoreForWrite } from '@maka/storage/task-ledger-authority';
import {
connectRuntimeHost,
RuntimeHostOperationError,
RuntimeHostSubscriptionError,
type RuntimeHostConnection,
type RuntimeHostSessionSubscription,
} from '../client/index.js';
import {
decodeHostFrame,
RUNTIME_HOST_PROTOCOL_VERSION,
TASK_LEDGER_PAGE_MAX_ITEMS,
type AutomationProjection,
type ConnectionCatalogQueryResult,
type InteractionPendingSnapshot,
type SubscriptionFrame,
type TaskLedgerQueryResult,
type TaskLedgerRevision,
type TurnMessageSubmitInput,
type TurnSnapshot,
} from '../protocol/index.js';
import { SessionAdmissionGate } from '../server/session-admission-gate.js';
import { HostTaskLedgerCoordinator } from '../server/task-ledger-coordinator.js';
import { FramedTransport } from '../transport/framed-transport.js';
import {
CONNECTION_EFFECT_MODEL_IDS,
type ExecutionFixture,
PROCESS_TIMEOUT_MS,
SubscriptionProbe,
assertJsonLines,
attachment,
connectClient,
requireStartedTurn,
operationError,
quotedContent,
sendStartWithoutReadingResponse,
startConnectionEffectProvider,
userRuntimeContent,
waitForDurableMessageConflict,
waitForPendingInteraction,
waitForRunningTurn,
waitForTerminalTurn,
waitForTurn,
withExecutionRoot,
withTimeout,
} from './fixtures/execution-host-suite.js';
test('production Host executes admitted heartbeat and cron fires through one durable root authority', {
timeout: 30_000,
}, async () => {
await withExecutionRoot(async (fixture) => {
const host = await fixture.startHost();
const desktop = await connectClient(fixture.root, 'desktop');
const tui = await connectClient(fixture.root, 'tui');
try {
const heartbeat = await desktop.request('automation.mutate', {
kind: 'create',
sessionId: fixture.sessionId,
automationKind: 'heartbeat',
name: 'heartbeat execution proof',
prompt: 'Complete the heartbeat execution proof.',
schedule: { type: 'once', delaySeconds: 5 },
});
const cron = await tui.request('automation.mutate', {
kind: 'create',
sessionId: fixture.sessionId,
automationKind: 'cron',
name: 'cron execution proof',
prompt: 'Complete the cron execution proof.',
schedule: { type: 'once', delaySeconds: 5 },
});
assert.equal(heartbeat.kind, 'committed');
assert.equal(cron.kind, 'committed');
if (
heartbeat.kind !== 'committed' ||
!heartbeat.automation ||
cron.kind !== 'committed' ||
!cron.automation
) {
return;
}
const [observedHeartbeat, observedCron] = await Promise.all([
waitForAutomationCompletion(tui, fixture.sessionId, heartbeat.automation.id),
waitForAutomationCompletion(desktop, fixture.sessionId, cron.automation.id),
]);
assert.ok(observedHeartbeat.lastRunId);
assert.ok(observedCron.lastRunId);
assert.equal(observedHeartbeat.lastError, null);
assert.equal(observedCron.lastError, null);
assert.equal(observedHeartbeat.firePending, false);
assert.equal(observedCron.firePending, false);
const cronSessions = await desktop.request('session.catalog.query', {
kind: 'list_start',
filter: { labelSlug: 'cron' },
});
assert.equal(cronSessions.kind, 'page');
if (cronSessions.kind === 'page') {
assert.equal(cronSessions.sessions.length, 1);
const cronSession = cronSessions.sessions[0];
assert.ok(cronSession && !('kind' in cronSession));
if (cronSession && !('kind' in cronSession)) {
assert.deepEqual([...cronSession.labels].sort(), ['automation', 'cron']);
assert.ok(cronSession.lastMessageAt);
}
}
const deletedHeartbeat = await tui.request('automation.mutate', {
kind: 'delete',
sessionId: fixture.sessionId,
automationId: heartbeat.automation.id,
});
assert.equal(deletedHeartbeat.kind, 'committed');
assert.equal(deletedHeartbeat.kind === 'committed' && deletedHeartbeat.automation, null);
const deletedCron = await desktop.request('automation.mutate', {
kind: 'delete',
sessionId: fixture.sessionId,
automationId: cron.automation.id,
});
assert.equal(deletedCron.kind, 'committed');
assert.equal(deletedCron.kind === 'committed' && deletedCron.automation, null);
} finally {
await Promise.allSettled([desktop.close(), tui.close()]);
await fixture.stopHost(host);
}
});
});
test('production Host settles dispatched Client Capabilities before publishing Ready', async () => {
await withExecutionRoot(async (fixture) => {
const prepared = await seedDispatchedClientCapability(fixture);
const host = await fixture.startHost({
sessionId: fixture.sessionId,
runId: prepared.runId,
});
try {
const outcome = host.recoveryOutcome;
assert.equal(outcome?.content?.kind, 'function_response');
if (outcome?.content?.kind !== 'function_response') return;
assert.equal(outcome.content.name, prepared.toolName);
assert.equal(outcome.content.isError, true);
assert.ok(outcome.content.result && typeof outcome.content.result === 'object');
const recovered = outcome.content.result as {
kind?: unknown;
uncertainOutcome?: unknown;
};
assert.equal(recovered.kind, 'text');
assert.deepEqual(recovered.uncertainOutcome, {
code: 'outcome_unknown',
retrySafe: false,
});
} finally {
await fixture.stopHost(host);
}
});
});
test('dual UDS Clients query persisted Task Ledger tool-port mutations across Host restart', async () => {
await withExecutionRoot(async (fixture) => {
const initialRunId = randomUUID();
const initialTurnId = randomUUID();
// Exercise the Runtime-facing port before Host startup; Hosted tool composition is separate.
const toolPortProjection = await withOwnedTaskLedgerToolPort(
fixture,
async (coordinator, tools) => {
const context = taskLedgerToolContext(fixture, {
runId: initialRunId,
turnId: initialTurnId,
toolCallId: randomUUID(),
});
const create = requireTaskLedgerTool<TaskCreateInput>(tools, 'task_create');
const createInput = create.parameters.parse({
tasks: Array.from({ length: TASK_LEDGER_PAGE_MAX_ITEMS + 1 }, (_, index) => ({
subject: `Authority acceptance task ${index + 1}`,
})),
});
await create.impl(createInput, context);
const update = requireTaskLedgerTool<TaskUpdateInput>(tools, 'task_update');
const updateInput = update.parameters.parse({ id: 'T1', status: 'in_progress' });
await update.impl(updateInput, {
...context,
toolCallId: randomUUID(),
});
return coordinator.list(fixture.sessionId, {
includeTerminal: true,
includeArchived: false,
classifyResumeTrust: true,
});
},
);
assert.equal(toolPortProjection.length, TASK_LEDGER_PAGE_MAX_ITEMS + 1);
assert.deepEqual(toolPortProjection[0]?.owner, {
actor: 'main_agent',
runId: initialRunId,
turnId: initialTurnId,
});
const host = await fixture.startHost();
const desktop = await connectClient(fixture.root, 'desktop');
const tui = await connectClient(fixture.root, 'tui');
let staleContinuation:
| {
revision: TaskLedgerRevision;
cursor: string;
task: Task;
}
| undefined;
try {
const desktopProjection = await collectTaskLedgerProjection(desktop, fixture.sessionId);
const tuiProjection = await collectTaskLedgerProjection(tui, fixture.sessionId);
assert.deepEqual(
desktopProjection.pages.map((page) => page.tasks.length),
[TASK_LEDGER_PAGE_MAX_ITEMS, 1],
);
assert.deepEqual(tuiProjection, desktopProjection);
assert.deepEqual(desktopProjection.tasks, toolPortProjection);
const byKey = await tui.request('task.ledger.query', {
kind: 'get',
sessionId: fixture.sessionId,
taskRef: 'T1',
});
assert.equal(byKey.kind, 'task');
if (byKey.kind !== 'task') throw new Error('Expected Task Ledger get result');
assert.equal(byKey.sessionId, fixture.sessionId);
assert.deepEqual(byKey.task, desktopProjection.tasks[0]);
assert.equal(byKey.task?.owner?.runId, initialRunId);
assert.equal(byKey.task?.owner?.turnId, initialTurnId);
const firstPage = desktopProjection.pages[0];
assert.ok(firstPage?.nextCursor);
staleContinuation = {
revision: firstPage.revision,
cursor: firstPage.nextCursor,
task: desktopProjection.tasks[1]!,
};
} finally {
await Promise.allSettled([desktop.close(), tui.close()]);
await fixture.stopHost(host);
}
assert.ok(staleContinuation);
const { revision: staleRevision, cursor: staleCursor, task: taskToChange } = staleContinuation;
const successorTurnId = randomUUID();
const changedSubject = `${taskToChange.subject} after authority reacquisition`;
await withOwnedTaskLedgerToolPort(fixture, async (_coordinator, tools) => {
const update = requireTaskLedgerTool<TaskUpdateInput>(tools, 'task_update');
const input = update.parameters.parse({
id: taskToChange.key,
subject: changedSubject,
});
await update.impl(
input,
taskLedgerToolContext(fixture, {
runId: randomUUID(),
turnId: successorTurnId,
toolCallId: randomUUID(),
}),
);
});
const successorHost = await fixture.startHost();
const successor = await connectClient(fixture.root, 'desktop');
try {
const continued = await successor.request('task.ledger.query', {
kind: 'list_continue',
sessionId: fixture.sessionId,
revision: staleRevision,
cursor: staleCursor,
});
assert.equal(continued.kind, 'revision_changed');
if (continued.kind !== 'revision_changed') {
throw new Error('Expected stale Task Ledger continuation to report revision_changed');
}
assert.equal(continued.expected, staleRevision);
assert.notEqual(continued.actual, staleRevision);
const changed = await successor.request('task.ledger.query', {
kind: 'get',
sessionId: fixture.sessionId,
taskRef: taskToChange.key,
});
assert.equal(changed.kind, 'task');
if (changed.kind !== 'task') throw new Error('Expected changed Task Ledger task result');
assert.equal(changed.sessionId, fixture.sessionId);
assert.equal(changed.task?.subject, changedSubject);
assert.equal(changed.revision, continued.actual);
} finally {
await successor.close();
await fixture.stopHost(successorHost);
}
});
});
async function seedDispatchedClientCapability(
fixture: ExecutionFixture,
): Promise<{ runId: string; toolName: string }> {
const owner = await tryAcquireInteractiveRootOwner(fixture.capability);
assert.ok(owner);
if (!owner) throw new Error('Unable to acquire execution root for Client Capability setup');
let stores: Awaited<ReturnType<typeof openInteractiveExecutionStoresForWrite>> | undefined;
try {
stores = await openInteractiveExecutionStoresForWrite(owner.lease);
const operationId = 'client-capability-before-ready';
const invocationId = `${operationId}-invocation`;
const runId = `${operationId}-run`;
const turnId = `${operationId}-turn`;
const providerToolCallId = `${operationId}-call`;
const toolName = 'mcp__client_fixture__navigate';
const args = { url: 'https://example.test/recovery' };
const canonicalArgsHash = canonicalToolArgsHash(toolName, args);
const call: RuntimeEvent = {
id: `${operationId}_call`,
invocationId,
runId,
sessionId: fixture.sessionId,
turnId,
ts: 10,
partial: false,
role: 'model',
author: 'agent',
content: {
kind: 'function_call',
id: providerToolCallId,
name: toolName,
args,
},
refs: { operationId, toolCallId: providerToolCallId },
};
const dispatch: RuntimeEvent = {
id: `${operationId}_dispatch`,
invocationId,
runId,
sessionId: fixture.sessionId,
turnId,
ts: 10,
partial: false,
role: 'system',
author: 'system',
actions: {
toolDispatch: {
protocol: TOOL_BOUNDARY_PROTOCOL_V1,
operationId,
providerToolCallId,
toolName,
canonicalArgsHash,
recoveryMode: 'outcome_unknown',
},
},
refs: { operationId, toolCallId: providerToolCallId },
};
await stores.runtimeEventStore.commitToolPrepared({
operationId,
journalEventId: `${operationId}_prepared`,
runtimeEvent: call,
dispatchRuntimeEvent: dispatch,
providerToolCallId,
toolName,
canonicalArgsHash,
recoveryMode: 'outcome_unknown',
committedAt: 10,
});
return { runId, toolName };
} finally {
await stores?.sessionStore.close?.();
await owner.close();
}
}
test('two UDS Clients share one Runtime Policy authority and CAS winner', async () => {
await withExecutionRoot(async (fixture) => {
const host = await fixture.startHost();
const first = await connectClient(fixture.root, 'desktop');
const second = await connectClient(fixture.root, 'tui');
try {
const initial = await first.request('runtime.policy.query', {});
assert.deepEqual(await second.request('runtime.policy.query', {}), initial);
const outcomes = await Promise.all([
first.request('runtime.policy.mutate', {
expectedRevision: initial.revision,
operation: {
kind: 'set_personalization',
value: { displayName: 'Desktop', assistantTone: 'precise' },
},
}),
second.request('runtime.policy.mutate', {
expectedRevision: initial.revision,
operation: {
kind: 'set_memory',
value: { enabled: false, agentReadEnabled: false },
},
}),
]);
assert.deepEqual(outcomes.map((outcome) => outcome.kind).sort(), [
'committed',
'revision_conflict',
]);
assert.deepEqual(
await first.request('runtime.policy.query', {}),
await second.request('runtime.policy.query', {}),
);
} finally {
await Promise.allSettled([first.close(), second.close()]);
await fixture.stopHost(host);
}
});
});
test('two UDS Clients await slow connection effects against one canonical catalog', async () => {
const provider = await startConnectionEffectProvider({ responseDelayMs: 2_100 });
try {
await withExecutionRoot(async (fixture) => {
const secret = 'connection-effect-secret';
const connection = await fixture.seedConnectionEffect(provider.baseUrl, secret);
const host = await fixture.startHost();
const desktop = await connectClient(fixture.root, 'desktop');
const tui = await connectClient(fixture.root, 'tui');
try {
assert.equal(desktop.hostEpoch, tui.hostEpoch);
assert.notEqual(desktop.connectionId, tui.connectionId);
const fetchInput = { connectionId: connection.connectionId };
const fetched = await desktop.request('connection.models.fetch', {
...fetchInput,
});
assert.equal(fetched.kind, 'committed');
if (fetched.kind !== 'committed') return;
assert.equal(fetched.modelCount, CONNECTION_EFFECT_MODEL_IDS.length);
assert.equal(fetched.source, 'fetched');
const firstPage = await tui.request('connection.catalog.query', { kind: 'start' });
assert.equal(firstPage.kind, 'page');
if (firstPage.kind !== 'page') return;
type CatalogPage = Extract<ConnectionCatalogQueryResult, { readonly kind: 'page' }>;
const pages: CatalogPage[] = [firstPage];
let observed: CatalogPage = firstPage;
while (observed.nextCursor) {
const nextResult: ConnectionCatalogQueryResult = await tui.request(
'connection.catalog.query',
{
kind: 'continue',
revision: observed.revision,
cursor: observed.nextCursor,
},
);
assert.equal(nextResult.kind, 'page');
if (nextResult.kind !== 'page') return;
pages.push(nextResult);
observed = nextResult;
}
assert.ok(pages.length > 1);
assert.ok(pages.every((page) => page.revision === fetched.catalogRevision));
assert.deepEqual(
pages.flatMap((page) =>
page.items.flatMap((item) => (item.kind === 'model' ? [item.model.id] : [])),
),
CONNECTION_EFFECT_MODEL_IDS,
);
const testInput = {
connectionId: connection.connectionId,
modelId: CONNECTION_EFFECT_MODEL_IDS[0]!,
};
const tested = await tui.request('connection.test.run', {
...testInput,
});
assert.equal(tested.kind, 'committed');
if (tested.kind !== 'committed') return;
assert.equal(tested.test.kind, 'verified');
const canonical = await desktop.request('connection.catalog.query', { kind: 'start' });
assert.equal(canonical.kind, 'page');
if (canonical.kind !== 'page') return;
const header = canonical.items.find(
(item) => item.kind === 'connection' && item.connectionId === connection.connectionId,
);
assert.equal(header?.kind, 'connection');
if (header?.kind === 'connection') {
assert.deepEqual(header.lastTest, {
status: 'verified',
checkedAt: tested.test.checkedAt,
});
}
assert.equal(
JSON.stringify([fetchInput, fetched, pages, testInput, tested, canonical]).includes(
secret,
),
false,
);
assert.equal(provider.requests.length, 2);
assert.ok(
provider.requests.every(({ authorization }) => authorization === `Bearer ${secret}`),
);
assert.deepEqual(
provider.requests.map(({ method, url }) => ({
method,
url,
})),
[
{
method: 'GET',
url: '/v1/models',
},
{
method: 'POST',
url: '/v1/chat/completions',
},
],
);
} finally {
await Promise.allSettled([desktop.close(), tui.close()]);
await fixture.stopHost(host);
}
});
} finally {
await provider.close();
}
});
test('two Clients share one execution after the starting Client disconnects', async () => {
await withExecutionRoot(async (fixture) => {
const host = await fixture.startHost();
const first = await connectClient(fixture.root, 'desktop');
const second = await connectClient(fixture.root, 'tui');
const turnId = randomUUID();
const started = requireStartedTurn(
await first.startTurn(
{
sessionId: fixture.sessionId,
turnId,
content: { text: FAKE_ASK_USER_QUESTION_PROMPT },
},
PROCESS_TIMEOUT_MS,
),
);
assert.equal(started.turnId, turnId);
const secondSubscription = await second.openSessionSubscription({
sessionId: fixture.sessionId,
});
const transcript = await secondSubscription.loadTranscript(decodeStoredMessageForRead);
assert.ok(
transcript.some(
(message) =>
message.type === 'user' &&
message.turnId === turnId &&
message.text === FAKE_ASK_USER_QUESTION_PROMPT,
),
);
const secondProbe = new SubscriptionProbe(secondSubscription);
await assert.rejects(
() =>
second.startTurn(
{
sessionId: fixture.sessionId,
turnId: randomUUID(),
content: { text: 'must stay busy' },
},
PROCESS_TIMEOUT_MS,
),
operationError('session_busy'),
);
await first.close();
const pending = await waitForPendingInteraction(secondSubscription, secondProbe, started.runId);
assert.equal(pending.sessionId, fixture.sessionId);
assert.equal(pending.turnId, turnId);
assert.equal(pending.runId, started.runId);
const questionRequest = pending.request;
assert.ok(questionRequest.kind === 'question');
assert.deepEqual(
await second.request('interaction.query', {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
}),
pending,
);
const observed = await second.queryTurn({
sessionId: fixture.sessionId,
turnId,
});
assert.equal(observed.runId, started.runId);
assert.ok(observed.status === 'running' || observed.status === 'waiting_for_user');
const stopped = await second.stopTurn(
{
sessionId: fixture.sessionId,
turnId,
runId: started.runId,
},
PROCESS_TIMEOUT_MS,
);
assert.equal(stopped.status, 'cancelled');
const closed = await second.request('interaction.query', {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
});
assert.equal(closed.sessionId, fixture.sessionId);
assert.equal(closed.turnId, turnId);
assert.equal(closed.runId, started.runId);
assert.equal(closed.status, 'closed');
assert.equal(closed.outcome.kind, 'closure');
if (closed.outcome.kind === 'closure') assert.equal(closed.outcome.reason, 'turn_stopped');
await assert.rejects(
() =>
second.request('interaction.answer', {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
answer: {
kind: 'question',
answers: questionRequest.questions.map(() => null),
},
}),
operationError('already_resolved'),
);
const nextTurnId = randomUUID();
const next = requireStartedTurn(
await second.startTurn(
{
sessionId: fixture.sessionId,
turnId: nextTurnId,
content: { text: FAKE_ASK_USER_QUESTION_PROMPT },
},
PROCESS_TIMEOUT_MS,
),
);
assert.deepEqual(
requireStartedTurn(
await second.startTurn(
{
sessionId: fixture.sessionId,
turnId,
content: { text: FAKE_ASK_USER_QUESTION_PROMPT },
},
PROCESS_TIMEOUT_MS,
),
),
stopped,
);
assert.deepEqual(
await second.stopTurn({
sessionId: fixture.sessionId,
turnId,
runId: started.runId,
}),
stopped,
);
const nextObserved = await second.queryTurn({
sessionId: fixture.sessionId,
turnId: nextTurnId,
});
assert.equal(nextObserved.runId, next.runId);
assert.ok(nextObserved.status === 'running' || nextObserved.status === 'waiting_for_user');
await second.stopTurn(
{
sessionId: fixture.sessionId,
turnId: nextTurnId,
runId: next.runId,
},
PROCESS_TIMEOUT_MS,
);
await secondSubscription.close();
await secondProbe.done;
await second.close();
await fixture.stopHost(host);
const ledger = await fixture.readTurn(turnId);
assert.equal(ledger.runs.length, 1);
assert.equal(ledger.userMessages.length, 1);
assert.equal(ledger.terminalEvents.length, 1);
assert.equal(ledger.classification.kind, 'fact');
if (ledger.classification.kind === 'fact') {
assert.equal(ledger.classification.fact.runStatus, 'cancelled');
assert.notEqual(ledger.classification.fact.failureClass, 'app_restarted');
}
});
});
test('regenerate replays the durable source content with one recoverable root identity', async () => {
await withExecutionRoot(async (fixture) => {
const host = await fixture.startHost();
const client = await connectClient(fixture.root, 'tui');
const sourceTurnId = randomUUID();
const regeneratedTurnId = randomUUID();
try {
await client.startTurn(
{
sessionId: fixture.sessionId,
turnId: sourceTurnId,
content: quotedContent('repeat this request'),
},
PROCESS_TIMEOUT_MS,
);
await waitForTerminalTurn(client, fixture.sessionId, sourceTurnId);
const started = await client.regenerateTurn(
{
sessionId: fixture.sessionId,
sourceTurnId,
turnId: regeneratedTurnId,
},
PROCESS_TIMEOUT_MS,
);
const terminal = await waitForTerminalTurn(client, fixture.sessionId, regeneratedTurnId);
assert.equal(terminal.runId, started.runId);
assert.deepEqual(
await client.regenerateTurn({
sessionId: fixture.sessionId,
sourceTurnId,
turnId: regeneratedTurnId,
}),
terminal,
);
} finally {
await client.close();
await fixture.stopHost(host);
}
const ledger = await fixture.readTurn(regeneratedTurnId);
assert.equal(ledger.runs.length, 1);
assert.equal(ledger.userMessages.length, 1);
assert.equal(ledger.runs[0]?.parentTurnId, sourceTurnId);
assert.equal(ledger.runs[0]?.regeneratedFromTurnId, sourceTurnId);
assert.deepEqual(
{
text: ledger.userMessages[0]?.text,
quotes: ledger.userMessages[0]?.quotes,
},
quotedContent('repeat this request'),
);
});
});
test('regenerate rejects self-source and legacy target collisions without draining Host', async () => {
await withExecutionRoot(async (fixture) => {
const firstHost = await fixture.startHost();
const first = await connectClient(fixture.root, 'tui');
const sourceTurnId = randomUUID();
await first.startTurn({
sessionId: fixture.sessionId,
turnId: sourceTurnId,
content: { text: 'source request' },
});
await waitForTerminalTurn(first, fixture.sessionId, sourceTurnId);
await assert.rejects(
first.regenerateTurn({
sessionId: fixture.sessionId,
sourceTurnId,
turnId: sourceTurnId,
}),
operationError('operation_conflict'),
);
await first.close();
await fixture.stopHost(firstHost);
const legacy = await fixture.seedSafeBoundaryContinuationSource();
const secondHost = await fixture.startHost();
const second = await connectClient(fixture.root, 'desktop');
try {
await assert.rejects(
second.regenerateTurn({
sessionId: fixture.sessionId,
sourceTurnId,
turnId: legacy.sourceTurnId,
}),
operationError('operation_conflict'),
);
const followingTurnId = randomUUID();
await second.startTurn({
sessionId: fixture.sessionId,
turnId: followingTurnId,
content: { text: 'Host remains available' },
});
assert.equal(
(await waitForTerminalTurn(second, fixture.sessionId, followingTurnId)).status,
'completed',
);
} finally {
await second.close();
await fixture.stopHost(secondHost);
}
assert.deepEqual(await fixture.readTurnFootprint(legacy.sourceTurnId), {
admitted: false,
runCount: 1,
userMessageCount: 0,
});
});
});
test('context actions share root admission and expose backend capability honestly', async () => {
await withExecutionRoot(async (fixture) => {
const host = await fixture.startHost();
const first = await connectClient(fixture.root, 'desktop');
const second = await connectClient(fixture.root, 'tui');
const turnId = randomUUID();
const unavailableTurnId = randomUUID();
try {
assert.deepEqual(await first.queryContextDiagnostics({ sessionId: fixture.sessionId }), {
status: 'unavailable',
reason: 'no_completed_request',
});
const started = requireStartedTurn(
await first.startTurn({
sessionId: fixture.sessionId,
turnId,
content: { text: FAKE_ASK_USER_QUESTION_PROMPT },
}),
);
await waitForRunningTurn(second, fixture.sessionId, turnId);
await assert.rejects(
second.compactContext({
sessionId: fixture.sessionId,
turnId: randomUUID(),
}),
operationError('session_busy'),
);
await second.stopTurn({
sessionId: fixture.sessionId,
turnId,
runId: started.runId,
});
await assert.rejects(
second.compactContext({
sessionId: fixture.sessionId,
turnId: unavailableTurnId,
}),
operationError('operation_unavailable'),
);
await assert.rejects(
second.queryContextDiagnostics({ sessionId: 'missing-session' }),
operationError('not_found'),
);
} finally {
await Promise.allSettled([first.close(), second.close()]);
await fixture.stopHost(host);
}
assert.deepEqual(await fixture.readTurnFootprint(unavailableTurnId), {
admitted: false,
runCount: 0,
userMessageCount: 0,
});
});
});
test('a disconnected Client leaves a durable Interaction that another Client can answer', async () => {
await withExecutionRoot(async (fixture) => {
const firstHost = await fixture.startHost();
const first = await connectClient(fixture.root, 'desktop');
const turnId = randomUUID();
const started = requireStartedTurn(
await first.startTurn({
sessionId: fixture.sessionId,
turnId,
content: { text: FAKE_ASK_USER_QUESTION_PROMPT },
}),
);
await first.close();
const second = await connectClient(fixture.root, 'tui');
const subscription = await second.openSessionSubscription({ sessionId: fixture.sessionId });
const probe = new SubscriptionProbe(subscription);
const pending = await waitForPendingInteraction(subscription, probe, started.runId);
assert.equal(pending.sessionId, fixture.sessionId);
assert.equal(pending.turnId, turnId);
assert.equal(pending.runId, started.runId);
assert.equal(pending.status, 'pending');
const questionRequest = pending.request;
assert.ok(questionRequest.kind === 'question');
assert.deepEqual(
await second.request('interaction.query', {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
}),
pending,
);
const answer = {
kind: 'question' as const,
answers: questionRequest.questions.map((question) => question.options[0]?.label ?? null),
};
const winner = await second.request('interaction.answer', {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
answer,
});
assert.equal(winner.sessionId, fixture.sessionId);
assert.equal(winner.turnId, turnId);
assert.equal(winner.runId, started.runId);
assert.equal(winner.status, 'answered');
assert.equal(winner.outcome.kind, 'question_answer');
assert.deepEqual(winner.outcome.answers, answer.answers);
assert.deepEqual(
await second.request('interaction.query', {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
}),
winner,
);
assert.deepEqual(
await second.request('interaction.answer', {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
answer,
}),
winner,
);
const resumed = await probe.waitFor(
(frame) =>
frame.kind === 'subscription.session_projection' &&
frame.snapshot.session.status === 'running' &&
frame.snapshot.rootTurn?.runId === started.runId &&
frame.snapshot.rootTurn.status === 'running' &&
frame.snapshot.interactions.pending.length === 0,
'continuity did not publish the resumed Turn after the question answer',
);
assert.equal(resumed.kind, 'subscription.session_projection');
const completed = await waitForTerminalTurn(second, fixture.sessionId, turnId);
assert.equal(completed.runId, started.runId);
assert.equal(completed.status, 'completed');
await subscription.close();
await probe.done;
await second.close();
await fixture.stopHost(firstHost);
const secondHost = await fixture.startHost();
const observer = await connectClient(fixture.root, 'run');
assert.deepEqual(
await observer.request('interaction.query', {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
}),
winner,
);
assert.deepEqual(
await observer.request('interaction.answer', {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
answer,
}),
winner,
);
assert.deepEqual(await observer.queryTurn({ sessionId: fixture.sessionId, turnId }), completed);
await observer.close();
await fixture.stopHost(secondHost);
});
});
test('two UDS Clients settle one hosted sandbox boundary and resume its exact Run', async () => {
await withExecutionRoot(async (fixture) => {
const firstHost = await fixture.startHost();
const starter = await connectClient(fixture.root, 'desktop');
const first = await connectClient(fixture.root, 'tui');
const second = await connectClient(fixture.root, 'run');
const subscription = await first.openSessionSubscription({ sessionId: fixture.sessionId });
const probe = new SubscriptionProbe(subscription);
const turnId = randomUUID();
const started = requireStartedTurn(
await starter.startTurn({
sessionId: fixture.sessionId,
turnId,
content: { text: FAKE_ASK_SANDBOX_BOUNDARY_PROMPT },
}),
);
await starter.close();
const pending = await waitForPendingInteraction(subscription, probe, started.runId);
assert.equal(pending.sessionId, fixture.sessionId);
assert.equal(pending.turnId, turnId);
assert.equal(pending.runId, started.runId);
assert.equal(pending.status, 'pending');
assert.equal(pending.request.kind, 'sandbox_boundary');
if (pending.request.kind !== 'sandbox_boundary') return;
assert.deepEqual(pending.request.expansion, { network: { enabled: true } });
const answer = {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
answer: { kind: 'sandbox_boundary', decision: 'allow' },
} as const;
const [firstWinner, secondWinner] = await Promise.all([
first.request('interaction.answer', answer),
second.request('interaction.answer', answer),
]);
assert.deepEqual(firstWinner, secondWinner);
assert.equal(firstWinner.status, 'answered');
assert.equal(firstWinner.outcome.kind, 'sandbox_boundary_decision');
if (firstWinner.outcome.kind !== 'sandbox_boundary_decision') return;
assert.equal(firstWinner.outcome.decision, 'allow');
assert.equal(firstWinner.outcome.status, 'approved');
assert.equal(Number.isSafeInteger(firstWinner.outcome.committedAt), true);
assert.deepEqual(
await first.request('interaction.query', {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
}),
firstWinner,
);
await probe.waitFor(
(frame) =>
frame.kind === 'subscription.session_projection' &&
frame.snapshot.rootTurn?.runId === started.runId &&
frame.snapshot.interactions.pending.length === 0,
'continuity did not publish the resumed Turn after the sandbox boundary answer',
);
const completed = await waitForTerminalTurn(first, fixture.sessionId, turnId);
assert.equal(completed.runId, started.runId);
assert.equal(completed.status, 'completed');
await subscription.close();
await probe.done;
await Promise.allSettled([first.close(), second.close()]);
await fixture.stopHost(firstHost);
const secondHost = await fixture.startHost();
const observer = await connectClient(fixture.root, 'desktop');
assert.deepEqual(
await observer.request('interaction.query', {
sessionId: fixture.sessionId,
interactionId: pending.interactionId,
}),
firstWinner,
);
assert.deepEqual(await observer.queryTurn({ sessionId: fixture.sessionId, turnId }), completed);
await observer.close();
await fixture.stopHost(secondHost);
});
});
interface TaskCreateInput {
tasks: Array<{ subject: string; parent_id?: string }>;
}
interface TaskUpdateInput {
id: string;
status?: 'pending' | 'in_progress' | 'blocked' | 'completed' | 'failed' | 'cancelled';
subject?: string;
blockedReason?: string;
failureReason?: string;
completionEvidence?: string;
explicitReopen?: boolean;
}
type TaskLedgerPage = Extract<TaskLedgerQueryResult, { kind: 'page' }>;
type TaskLedgerTool<Input> = MakaTool<Input, string> & {
parameters: { parse(value: unknown): Input };
};
async function withOwnedTaskLedgerToolPort<T>(
fixture: ExecutionFixture,
run: (coordinator: HostTaskLedgerCoordinator, tools: MakaTool[]) => Promise<T>,
): Promise<T> {
const owner = await tryAcquireInteractiveRootOwner(fixture.capability);
assert.ok(owner);
if (!owner) throw new Error('Unable to acquire the interactive Task Ledger tool port');
let writer: Awaited<ReturnType<typeof openInteractiveTaskLedgerStoreForWrite>> | undefined;
try {
writer = await openInteractiveTaskLedgerStoreForWrite(owner.lease);
const coordinator = new HostTaskLedgerCoordinator(writer, new SessionAdmissionGate(), {
probeSessionRemoval: async () => ({ kind: 'present' }),
});
return await run(coordinator, buildTaskLedgerTools({ store: coordinator }));
} finally {
writer?.close();
await owner.close();
}
}
function requireTaskLedgerTool<Input>(
tools: readonly MakaTool[],
name: 'task_create' | 'task_update',
): TaskLedgerTool<Input> {
const tool = tools.find((candidate) => candidate.name === name);
assert.ok(tool, `Expected ${name} Runtime tool`);
return tool as TaskLedgerTool<Input>;
}
function taskLedgerToolContext(
fixture: ExecutionFixture,
identity: Pick<MakaToolContext, 'runId' | 'turnId' | 'toolCallId'>,
): MakaToolContext {
return {
sessionId: fixture.sessionId,
cwd: fixture.root,
...identity,
abortSignal: new AbortController().signal,
emitOutput: () => {},
};
}
async function collectTaskLedgerProjection(
client: RuntimeHostConnection,
sessionId: string,
): Promise<{
revision: TaskLedgerRevision;
pages: TaskLedgerPage[];
tasks: Task[];
}> {
const pages: TaskLedgerPage[] = [];
let result = await client.request('task.ledger.query', {
kind: 'list_start',
sessionId,
});
assert.equal(result.kind, 'page');
if (result.kind !== 'page') throw new Error('Expected initial Task Ledger page');
const revision = result.revision;
while (true) {
assert.equal(result.sessionId, sessionId);
assert.equal(result.revision, revision);
pages.push(result);
if (result.nextCursor === null) break;
result = await client.request('task.ledger.query', {
kind: 'list_continue',
sessionId,
revision,
cursor: result.nextCursor,
});
assert.equal(result.kind, 'page');
if (result.kind !== 'page') {
throw new Error('Task Ledger changed while collecting a stable projection');
}
}
return {
revision,
pages,
tasks: pages.flatMap((page) => page.tasks),
};
}
async function waitForAutomationCompletion(
client: RuntimeHostConnection,
sessionId: string,
automationId: string,
): Promise<AutomationProjection> {
const deadline = Date.now() + 20_000;
let last: AutomationProjection | null = null;
while (Date.now() < deadline) {
const result = await client.request('automation.query', {
kind: 'get',
sessionId,
automationId,
});
if (
result.kind === 'automation' &&
result.automation?.status === 'completed' &&
!result.automation.firePending
) {
return result.automation;
}
if (result.kind === 'automation') last = result.automation;
if (
result.kind === 'automation' &&
result.automation &&
!result.automation.firePending &&
result.automation.lastError
) {
throw new Error(`Automation execution failed: ${result.automation.lastError}`);
}
await new Promise((resolve) => setTimeout(resolve, 50));
}
throw new Error(
`Automation ${automationId} did not settle before the deadline: ${JSON.stringify(last)}`,
);
}