refactor(worker): delete per-job OpenCode container path, host_port split, and dead docker helpers

Claude-Session: https://claude.ai/code/session_01ScyZ1NhfN84LAnHpwhfEQk
This commit is contained in:
Gabriel Brown
2026-07-11 10:26:58 -04:00
parent ff0425cf4b
commit c9ee2e6cde
6 changed files with 172 additions and 763 deletions
@@ -8,7 +8,6 @@ const mocks = vi.hoisted(() => ({
Promise.resolve({ exitCode: 0, output: 'unexpected diff' }),
),
mutation: vi.fn(),
stopWorkspaceContainer: vi.fn(() => Promise.resolve()),
streamExecInContainer: vi.fn(),
}));
@@ -23,7 +22,6 @@ vi.mock('../../src/env', () => ({
env: {
buildCreatedAt: 'test',
buildSha: 'test',
containerAccess: 'network',
convexUrl: 'http://convex.test',
jobTimeoutMs: 1000,
runtime: 'docker',
@@ -42,19 +40,11 @@ vi.mock('../../src/github', () => ({
getInstallationToken: vi.fn(),
openDraftPullRequest: vi.fn(),
}));
vi.mock('../../src/opencode-session', () => ({
abortOpenCodeSession: vi.fn(),
createOpenCodeSession: vi.fn(),
promptOpenCodeSession: vi.fn(),
replyOpenCodePermission: vi.fn(),
}));
vi.mock('../../src/runtime/docker', () => ({
buildMarkedCommand: vi.fn(() => ['setsid', 'bash', '-lc', '# marker']),
killBoxProcessesByMarker: vi.fn(() => Promise.resolve()),
listWorkspaceContainerNames: vi.fn(() => Promise.resolve([])),
runExecInContainer: vi.fn(),
startWorkspaceContainer: vi.fn(),
stopWorkspaceContainer: mocks.stopWorkspaceContainer,
streamExecInContainer: mocks.streamExecInContainer,
}));
vi.mock('../../src/user-container', () => ({
@@ -86,105 +76,85 @@ afterEach(async () => {
});
describe('maintenance workspace cleanup', () => {
test.each(['mark', 'container'] as const)(
'releases and removes the workspace when %s teardown fails',
async (failingStep) => {
const worker = await load();
const release = vi.fn();
const close = vi.fn();
const jobId = `maintenance-${failingStep}`;
mocks.mutation.mockImplementation((reference) => {
if (
failingStep === 'mark' &&
getFunctionName(reference) === 'agentJobs:markWorkspaceStopped'
) {
return Promise.reject(new Error('status teardown failed'));
}
return Promise.resolve('message-1');
});
mocks.stopWorkspaceContainer.mockImplementation(() =>
failingStep === 'container'
? Promise.reject(new Error('container teardown failed'))
: Promise.resolve(),
test('releases and removes the workspace when status teardown fails', async () => {
const worker = await load();
const release = vi.fn();
const jobId = 'maintenance-mark';
mocks.mutation.mockImplementation((reference) => {
if (getFunctionName(reference) === 'agentJobs:markWorkspaceStopped') {
return Promise.reject(new Error('status teardown failed'));
}
return Promise.resolve('message-1');
});
mocks.streamExecInContainer.mockImplementation(async (args) => {
await args.onStdoutLine(
JSON.stringify({
type: 'item.completed',
item: {
type: 'agent_message',
text: JSON.stringify(decision),
},
}),
);
mocks.streamExecInContainer.mockImplementation(async (args) => {
await args.onStdoutLine(
JSON.stringify({
type: 'item.completed',
item: {
type: 'agent_message',
text: JSON.stringify(decision),
},
}),
);
return { exitCode: 0, output: '' };
});
worker._setActiveWorkspaceForTests(jobId, {
claim: {
job: {
_id: jobId as Id<'agentJobs'>,
prompt: 'Review maintenance changes',
jobType: 'maintenance_review',
baseBranch: 'main',
workBranch: 'spoon/maintenance',
forkOwner: 'team',
forkRepo: 'spoon',
upstreamOwner: 'upstream',
upstreamRepo: 'spoon',
},
spoon: { name: 'Spoon' },
openai: {
model: 'gpt-5',
reasoningEffort: 'medium',
},
aiProviderProfile: {
id: 'profile-1',
name: 'Codex',
provider: 'opencode_openai_login',
authType: 'opencode_auth_json',
model: 'gpt-5',
reasoningEffort: 'medium',
},
github: {},
secrets: [],
return { exitCode: 0, output: '' };
});
worker._setActiveWorkspaceForTests(jobId, {
claim: {
job: {
_id: jobId as Id<'agentJobs'>,
prompt: 'Review maintenance changes',
jobType: 'maintenance_review',
baseBranch: 'main',
workBranch: 'spoon/maintenance',
forkOwner: 'team',
forkRepo: 'spoon',
upstreamOwner: 'upstream',
upstreamRepo: 'spoon',
},
workdir: '/tmp/workspace',
homeDir: '/tmp/workspace',
username: 'tester',
containerHome: '/home/tester',
containerRepo: '/home/tester/Code/spoon',
repoDir: '/tmp/workspace/Code/spoon',
boxName: 'spoon-box-tester',
boxHandle: { boxName: 'spoon-box-tester', release },
githubToken: 'github-token',
redact: (value: string) => value,
runtime: 'codex',
containerName: 'spoon-agent-job-maintenance',
opencodeSession: {
client: {} as never,
sessionId: 'session-1',
close,
spoon: { name: 'Spoon' },
openai: {
model: 'gpt-5',
reasoningEffort: 'medium',
},
});
const consoleError = vi
.spyOn(console, 'error')
.mockImplementation(() => undefined);
aiProviderProfile: {
id: 'profile-1',
name: 'Codex',
provider: 'opencode_openai_login',
authType: 'opencode_auth_json',
model: 'gpt-5',
reasoningEffort: 'medium',
},
github: {},
secrets: [],
},
workdir: '/tmp/workspace',
homeDir: '/tmp/workspace',
username: 'tester',
containerHome: '/home/tester',
containerRepo: '/home/tester/Code/spoon',
repoDir: '/tmp/workspace/Code/spoon',
boxName: 'spoon-box-tester',
boxHandle: { boxName: 'spoon-box-tester', release },
githubToken: 'github-token',
redact: (value: string) => value,
runtime: 'codex',
});
const consoleError = vi
.spyOn(console, 'error')
.mockImplementation(() => undefined);
await expect(
worker.sendWorkspaceMessage(jobId, 'Review maintenance changes'),
).resolves.toBeUndefined();
await expect(
worker.sendWorkspaceMessage(jobId, 'Review maintenance changes'),
).resolves.toBeUndefined();
expect(release).toHaveBeenCalledTimes(1);
expect(close).toHaveBeenCalledTimes(1);
expect(mocks.stopWorkspaceContainer).toHaveBeenCalledTimes(1);
expect(mocks.getWorktreeDiff).not.toHaveBeenCalled();
expect(
mocks.mutation.mock.calls.some(([, args]) => args.kind === 'diff'),
).toBe(false);
await expect(worker.stopWorkspace(jobId)).rejects.toThrow(
'Agent workspace is not active on this worker.',
);
expect(consoleError).toHaveBeenCalledTimes(1);
},
);
expect(release).toHaveBeenCalledTimes(1);
expect(mocks.getWorktreeDiff).not.toHaveBeenCalled();
expect(
mocks.mutation.mock.calls.some(([, args]) => args.kind === 'diff'),
).toBe(false);
await expect(worker.stopWorkspace(jobId)).rejects.toThrow(
'Agent workspace is not active on this worker.',
);
expect(consoleError).toHaveBeenCalledTimes(1);
});
});