Merge current master for native recovery qualification

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-30 15:37:16 -05:00
commit 5ea45f8d17
322 files changed
+21745 -1361

No files matched your search

@@ -111,6 +111,10 @@ vi.mock("../usage-receipts.js", async (importOriginal) => ({
createRunUsageRecorder: usageRecorder.create,
}));
vi.mock("./native-usage-delivery.js", () => ({
createNativeUsageDelivery: vi.fn(async () => ({ capture: async () => undefined })),
}));
const githubAccess = vi.hoisted(() => ({
activate: vi.fn((_binding: { runId: string }) => vi.fn()),
stop: vi.fn(async () => undefined),
@@ -141,6 +145,7 @@ type BackendFactoryOptions = {
};
type RunnerTransportOptions = {
onAccountingEvent?: (event: PrpEvent) => Promise<void>;
environment?: NodeJS.ProcessEnv;
acpxRuntimeDirectory?: string;
adoptExistingRunner?: { pid: number; isAlive: () => Promise<boolean> | boolean };
@@ -250,8 +255,8 @@ vi.mock("./paperclip-control-plane-port.js", async importOriginal => {
return { ...original, PaperclipControlPlanePort: class extends original.PaperclipControlPlanePort {
constructor(...args: ConstructorParameters<typeof original.PaperclipControlPlanePort>) {
super(...args);
accountingEvents.committed = args[2]?.onCommittedEvent;
accountingEvents.duplicate = args[2]?.onDuplicateEvent;
accountingEvents.committed = args[2]?.onCommittedEvent ? event => args[2]!.onCommittedEvent!(event, 1) : undefined;
accountingEvents.duplicate = args[2]?.onDuplicateEvent ? event => args[2]!.onDuplicateEvent!(event, 1) : undefined;
}
} };
});
@@ -7159,6 +7164,36 @@ describe("native terminal-turn accounting", () => {
expect(onUsage).toHaveBeenLastCalledWith(expect.objectContaining({ complete: true }));
expect(usageRecorder.create).not.toHaveBeenCalled();
});
it("binds retained warm transport usage to the successor run authority", async () => {
const directory = await mkdtemp(join(tmpdir(), "native-warm-usage-"));
const previous = process.env.PAPERCLIP_RUNNER_STATE_DIR;
process.env.PAPERCLIP_RUNNER_STATE_DIR = directory;
const first = { ...execution, binding: { ...execution.binding, runId: "first-warm-usage", executionWorkspaceId: "warm-usage-workspace" },
session: { ...execution.session, normalizedSessionId: "warm-usage-session", lifecyclePolicy: { mode: "warm" as const, idleTimeoutMs: 60000 } } } as NativeExecutionInputV1;
const second = { ...first, binding: { ...first.binding, runId: "second-warm-usage" } };
const firstCapture = vi.fn(async (_event: PrpEvent) => {}), secondCapture = vi.fn(async (_event: PrpEvent) => {});
try {
await createRunnerdBackend({ db: leaseDb(first), execution: first, runnerInstanceId: "warm-producer", onAccountingEvent: firstCapture });
state.createBackend.mock.calls.at(-1)![1].codexTransportFactory!();
const retainedHook = state.createTransport.mock.calls.at(-1)![0].onAccountingEvent!;
const firstReport = { eventType: "usage.reported", runId: first.binding.runId, sourceInstanceId: "warm-producer" } as PrpEvent;
await retainedHook(firstReport);
expect(firstCapture).toHaveBeenCalledExactlyOnceWith(firstReport);
await rm(state.createTransport.mock.calls.at(-1)![0].stateDirectory!, { recursive: true, force: true });
await createRunnerdBackend({ db: leaseDb(second), execution: second, runnerInstanceId: "warm-producer", onAccountingEvent: secondCapture });
await expect(retainedHook({ ...firstReport, eventType: "run.attached" })).resolves.toBeUndefined();
expect(secondCapture).not.toHaveBeenCalled();
const secondReport = { ...firstReport, runId: second.binding.runId };
await retainedHook(secondReport);
expect(secondCapture).toHaveBeenCalledExactlyOnceWith(secondReport);
expect(firstCapture).toHaveBeenCalledTimes(1);
await expect(retainedHook(firstReport)).rejects.toThrow("native_usage_run_binding_mismatch");
} finally {
if (previous === undefined) delete process.env.PAPERCLIP_RUNNER_STATE_DIR; else process.env.PAPERCLIP_RUNNER_STATE_DIR = previous;
await rm(directory, { recursive: true, force: true });
}
});
it("uses the canonical recorder for partial and completed usage when no onUsage callback is supplied", async () => {
const updates: Array<{ table: unknown; values: Record<string, unknown> }> = [];
state.execute.mockReset().mockImplementationOnce(async () => {
@@ -12367,7 +12402,14 @@ describe("runnerd provider runtime wiring", () => {
}
});
it.each(["github", "assigned"] as const)("cleans run-owned access after overlapping executor failure: %s", async failure => {
it.each((["codex", "opencode"] as const).flatMap(provider =>
(["github", "assigned"] as const).map(failure => ({ provider, failure })),
))("cleans run-owned access after overlapping $provider executor failure: $failure", async ({ provider, failure }) => {
const current = {
...execution,
provider: provider === "codex" ? execution.provider : { kind: "opencode", model: null },
session: { ...execution.session, driverKind: provider === "codex" ? "codex_app_server" : "opencode_server" },
} as NativeExecutionInputV1;
const issueService = vi.spyOn(issueServiceModule, "issueService").mockReturnValue({
update: vi.fn(async () => ({ status: "blocked", statusVersion: 1 })),
} as unknown as ReturnType<typeof issueServiceModule.issueService>);
@@ -12393,7 +12435,7 @@ describe("runnerd provider runtime wiring", () => {
state.createBackend.mockClear();
let settled = false;
const running = executePaperclipNativeSession({
db: leaseDb(execution), execution, runnerInstanceId: "runner-overlap-cleanup",
db: leaseDb(current), execution: current, runnerInstanceId: "runner-overlap-cleanup",
useRunnerd: true, managedGitHub: true,
runnerEnvironment: {
PAPERCLIP_NATIVE_MCP_NAME: "paperclip-assigned",
@@ -12419,7 +12461,7 @@ describe("runnerd provider runtime wiring", () => {
expect(state.execute).not.toHaveBeenCalled();
expect(state.createBackend).not.toHaveBeenCalled();
if (failure === "assigned") {
expect(activate).toHaveBeenCalledWith(execution.binding);
expect(activate).toHaveBeenCalledWith(current.binding);
expect(deactivate).toHaveBeenCalledOnce();
expect(stop).toHaveBeenCalledOnce();
}