Realize isolated computer probe workspace before readiness

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-10 08:41:05 -05:00
1 parent f9bbb866ea
commit 8b3b221cc6
2 files changed
+74 -1

No files matched your search

@@ -1,4 +1,15 @@
import { describe, it, expect, vi } from "vitest";
import {
existsSync,
mkdtempSync,
readFileSync,
realpathSync,
rmSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { spawnSync } from "node:child_process";
import { remoteProgram } from "../adapters/remote-program.js";
import { createComputerService } from "./service.js";
import type { ComputerBackend, ComputerRepository } from "./ports.js";
import { ComputerError, type ComputerRecord } from "../domain/ledger.js";
@@ -329,6 +340,56 @@ describe("computer ownership", () => {
await f.service.reconcile();
expect(f.backend.stop).toHaveBeenCalledOnce();
});
it("realizes probe cwd before readiness without consuming the initial personal-home seed", async () => {
const f = fixture();
const temp = realpathSync(mkdtempSync(join(tmpdir(), "computer-probe-")));
const local = (value: string) =>
value.replace("/home/user/paperclip/", `${temp}/`);
vi.mocked(f.backend.remote).mockImplementation(async (_record, input) => {
const result = spawnSync(
"python3",
["-c", remoteProgram.replaceAll("/home/user/paperclip/", `${temp}/`)],
{
input: JSON.stringify({
...input,
root: local(input.root as string),
}),
encoding: "utf8",
},
);
if (result.status !== 0) throw new Error(result.stderr);
return JSON.parse(result.stdout);
});
try {
await f.attach();
const probe = await f.service.admitProbe({
...f.scope,
agentId: "agent",
probeId: "probe",
idleTimeoutMs: 60_000,
});
expect(probe.remoteCwd).not.toBe(probe.agentHome);
const ready = spawnSync("sh", ["-c", "pwd"], {
cwd: local(probe.remoteCwd),
encoding: "utf8",
});
expect(ready.status).toBe(0);
expect(ready.stdout.trim()).toBe(local(probe.remoteCwd));
expect(existsSync(local(probe.agentHome))).toBe(false);
const run = await f.admit();
expect(run.remoteCwd).toBe(probe.agentHome);
expect(existsSync(local(run.agentHome))).toBe(false);
const files = await f.service.files({ ...f.scope, agentId: "agent" });
await expect(
files.seed({ "AGENTS.md": "initial managed instructions" }),
).resolves.toEqual({ seeded: true });
expect(
readFileSync(join(local(run.agentHome), "AGENTS.md"), "utf8"),
).toBe("initial managed instructions");
} finally {
rmSync(temp, { recursive: true, force: true });
}
});
it("gives harness probes a finite owner without fabricating a heartbeat run", async () => {
const f = fixture();
await f.attach();
@@ -372,7 +372,9 @@ sys.stdout.write(output);sys.stderr.write(error);sys.exit(child.returncode)
record.ledger.placements[input.sessionKey] ??= {
id: randomUUID(),
root: `${base(record)}/agents/${input.agentId}`,
cwd: `${base(record)}/agents/${input.agentId}`,
cwd: input.probeId
? `${base(record)}/probes/${input.probeId}`
: `${base(record)}/agents/${input.agentId}`,
};
return { record: structuredClone(record), owner: structuredClone(owner) };
});
@@ -380,6 +382,16 @@ sys.stdout.write(output);sys.stderr.write(error);sys.exit(child.returncode)
await backend.claim(result.record);
await backend.advance(result.record, result.owner);
await backend.renew(result.record);
if (input.probeId) {
// Readiness commands run before managed-home preparation. Give them an
// existing workspace without creating the personal home: an absent home
// must remain eligible for the first atomic managed-file seed.
await backend.remote(result.record, {
action: "seed",
root: result.record.ledger.placements[input.sessionKey]!.cwd,
files: {},
});
}
const active = await repository.update(input, (record) => {
const owner = exactOwner(record, ref(result.record, result.owner));
if (owner.phase !== "starting")