Integrate current master Docker cache and run-event compatibility

* codex/work-folders-remote-recovery-refresh:
  ci: cache compiled Docker Rust dependencies separately from source (#13329)
  ci: rebalance serialized tests with current suite durations (#13328)
  fix: preserve NUL characters in run-event payloads (#13325)
  ci: run release Runner protocol and Rust checks in parallel (#13326)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-09-12 14:21:35 -05:00
commit 08dd27ecb0
15 files changed
+554 -182

No files matched your search

@@ -107,3 +107,31 @@ describe("staging dependency integrity", () => {
}
});
});
describe("Docker Rust dependency cache", () => {
it("caches the locked dependency recipe separately from source and per-build metadata", () => {
const chef = stageBody(dockerfile, "rust-chef");
const planner = stageBody(dockerfile, "runner-plan");
const dependencies = stageBody(dockerfile, "runner-deps");
expect(chef).toContain("FROM rust-toolchain AS rust-chef");
expect(chef).toMatch(/cargo install cargo-chef --version \d+\.\d+\.\d+ --locked/);
expect(planner).toContain("COPY packages/paperclip-runner/runner ./runner");
expect(planner).toContain("cargo chef prepare --recipe-path /tmp/runner-recipe.json");
expect(dependencies).toContain("FROM rust-chef AS runner-deps");
expect(dependencies).toContain("COPY --from=runner-plan /tmp/runner-recipe.json /tmp/runner-recipe.json");
expect(dependencies).toContain("cargo chef cook --release --locked --package paperclip-runner-core --bin paperclip-runnerd");
expect(dependencies).not.toMatch(/COPY .*\.\/runner|COPY .*\.\/protocol|COPY \. \.|PAPERCLIP_BUILD_COMMIT/);
});
it("rebuilds real workspace code and embedded protocol inputs after cooking dependencies", () => {
const native = stageBody(dockerfile, "runner-build");
expect(native).toContain("FROM runner-deps AS runner-build");
for (const source of ["runner", "protocol"]) {
expect(native.indexOf(`COPY packages/paperclip-runner/${source} ./${source}`))
.toBeLessThan(native.indexOf("cargo build --release"));
expect(native).toContain(`COPY packages/paperclip-runner/${source} ./${source}`);
}
expect(native).toContain("cargo build --release --manifest-path runner/Cargo.toml --locked -p paperclip-runner-core --bin paperclip-runnerd");
expect(stageBody(dockerfile, "build")).toContain("FROM runner-build AS build");
});
});
@@ -1,10 +1,10 @@
import { randomUUID } from "node:crypto";
import { createHash, randomUUID } from "node:crypto";
import { mkdtempSync, rmSync } from "node:fs";
import { createServer } from "node:http";
import { tmpdir } from "node:os";
import { resolve } from "node:path";
import { eq } from "drizzle-orm";
import { eq, sql } from "drizzle-orm";
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
import {
@@ -36,6 +36,7 @@ import {
import { NativeRunCoordinatorStore } from "./native-run-coordinator-store.js";
import { runnerPrpCoordinator } from "./runner-prp-coordinator.js";
import { PaperclipRunnerSemanticAuthority } from "./runner-semantic-authority.js";
import { nativeSha256 } from "./canonical.js";
const embeddedPostgresSupport = await getEmbeddedPostgresTestSupport();
const describeEmbeddedPostgres = embeddedPostgresSupport.supported
@@ -339,6 +340,59 @@ describeEmbeddedPostgres("hidden runner PRP coordinator", () => {
});
});
it("persists NUL-containing command output without changing replay identity", async () => {
const seed = await seedNativeRun();
const nativeStore = store(seed);
const output = "transforming (6) ../\u0000virtual:/@storybook/builder-vite/storybook-stories.js";
const payload = {
schema: "paperclip.tool.execution.v1",
executionId: "storybook-build",
transport: "process",
operation: "execute",
status: "completed",
output,
outputBytes: Buffer.byteLength(output),
outputTruncated: false,
outputDigest: `sha256:${createHash("sha256").update(output).digest("hex")}`,
exitCode: 0,
};
const event: PrpEvent = {
...runnerEvent(seed),
eventType: "tool.execution.completed",
payload,
};
// The provider's valid JSON cannot be inserted directly into PostgreSQL JSONB.
await expect(db.execute(sql`select ${JSON.stringify(event)}::jsonb`))
.rejects.toMatchObject({ cause: { code: "22P05" } });
await expect(nativeStore.appendEvent(event)).resolves.toMatchObject({
disposition: "committed",
cursor: 1,
});
const [row] = await db.select().from(heartbeatRunEvents)
.where(eq(heartbeatRunEvents.runId, seed.runId));
expect(row.payload).toEqual({ prpEvent: event });
expect(row.sourcePayloadSha256).toBe(`sha256:${nativeSha256(row.payload?.prpEvent)}`);
// Existing SQL selectors still see the event's ordinary routing fields.
const [projection] = await db.select({
sourceKind: sql<string>`${heartbeatRunEvents.payload}->'prpEvent'->>'sourceKind'`,
}).from(heartbeatRunEvents).where(eq(heartbeatRunEvents.runId, seed.runId));
expect(projection.sourceKind).toBe("runner");
await expect(nativeStore.appendEvent(event)).resolves.toMatchObject({
disposition: "duplicate",
cursor: 1,
});
await expect(nativeStore.appendEvent({
...event,
payload: { ...payload, output: output.replaceAll("\u0000", "\\u0000") },
})).rejects.toBeInstanceOf(NativeSessionProtocolIntegrityError);
await expect(nativeStore.appendEvent(runnerEvent(seed, 2))).resolves.toMatchObject({
disposition: "committed",
cursor: 2,
});
});
it("persists events and results idempotently and leases finalization", async () => {
const seed = await seedNativeRun();
const nativeStore = store(seed);