test: verify staging actor and terminal run outcomes

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Dotta 2026-09-08 12:20:08 -05:00
parent 56169f3e00
commit 0c4810ea7b
2 changed files with 9 additions and 2 deletions

View File

@ -5,6 +5,8 @@ Set `PAPERCLIP_DEPLOYED_STACK_MANIFEST` to a JSON manifest matching
`tests/runner-e2e/deployed-stack.ts`, `PAPERCLIP_DEPLOYED_STACK_AUTH` to a private
0600 JSON file containing `baseURL` and a normally authorized `boardApiToken`,
and `PAPERCLIP_DEPLOYED_STACK_EVIDENCE` to an absolute output directory.
The token must belong to the manifest's `userId` and have company access. The
harness verifies that identity before file operations or paid agent execution.
The harness never launches a local server. It checks the deployed commit and
adapter inventory, exercises scoped file APIs, and starts real sandbox tasks
for every configured profile, including cold/warm Git state and real timed saves.

View File

@ -14,6 +14,9 @@ const folder = (scope: string, ownerId: string) => `/api/companies/${stack.compa
test.beforeAll(async () => {
const health = await api.json<{ commit: string }>("/api/health");
expect(health.commit, "Only exercise the declared deployed candidate").toBe(stack.commit);
const identity = await api.json<{ userId: string; companyIds: string[] }>("/api/cli-auth/me");
expect(identity.userId, "The board token must belong to the manifest's responsible user").toBe(stack.userId);
expect(identity.companyIds, "The board token must have access to the acceptance company").toContain(stack.companyId);
});
test("deployed candidate and complete supported adapter inventory", async ({}, info) => {
@ -95,7 +98,8 @@ for (const profile of stack.profiles) {
expect(content.status).toBe(200); expect(await content.text()).toBe(nonce);
const coldRunIds = new Set(cold.saves.map((save) => save.runId));
const coldSave = cold.saves.find((save) => !save.active && save.state === "saved")!;
const coldRun = await api.json<{ contextSnapshot: { paperclipWorkFolders: SandboxWorkFolderManifest } }>(`/api/heartbeat-runs/${coldSave.runId}`);
const coldRun = await api.json<{ status: string; contextSnapshot: { paperclipWorkFolders: SandboxWorkFolderManifest } }>(`/api/heartbeat-runs/${coldSave.runId}`);
expect(coldRun.status, "A saved checkpoint must not hide a failed adapter run").toBe("succeeded");
const coldManifest = coldRun.contextSnapshot.paperclipWorkFolders;
expect(coldManifest.sandboxKey).toBeTruthy();
const owners = {task: issue.id, agent: profile.agentId, user: stack.userId, project: stack.projectId};
@ -121,7 +125,8 @@ for (const profile of stack.profiles) {
const warmContent = await api.request(`${base}/content?path=warm.txt`);
expect(warmContent.status).toBe(200); expect(await warmContent.text()).toBe(nonce);
const warmSave = warm.saves.find((save) => !save.active && save.state === "saved")!;
const warmRun = await api.json<{ contextSnapshot: { paperclipWorkFolders: SandboxWorkFolderManifest } }>(`/api/heartbeat-runs/${warmSave.runId}`);
const warmRun = await api.json<{ status: string; contextSnapshot: { paperclipWorkFolders: SandboxWorkFolderManifest } }>(`/api/heartbeat-runs/${warmSave.runId}`);
expect(warmRun.status, "The warm adapter run must also succeed").toBe("succeeded");
const warmManifest = warmRun.contextSnapshot.paperclipWorkFolders;
expect(warmManifest.sandboxKey, "Warm acceptance requires the same physical sandbox").toBe(coldManifest.sandboxKey);
await info.attach("cold-and-warm-checkpoints", { contentType: "application/json", body: Buffer.from(JSON.stringify({ cold: cold.saves, warm: warm.saves, coldManifest, warmManifest })) });