fix(runner): allow projectless local tasks

This commit is contained in:
Dotta committed 2026-08-21 09:52:55 -05:00
1 parent b6ca925dd7
commit 22e244dc92
3 files changed
+22 -5

No files matched your search

+8 -4
View File
@@ -15845,9 +15845,10 @@ export function heartbeatService(db: Db, options: HeartbeatServiceOptions = {})
let nativeExecution: ReturnType<typeof buildNativeExecutionInput> | null = null;
let nativeRunnerInstanceId: string | null = null;
if (nativeRuntimeResolution.kind === "native") {
if (!issueRef || !persistedExecutionWorkspace) {
throw new Error("native_runtime_ineligible: issue and realized workspace are required");
if (!issueRef) {
throw new Error("native_runtime_ineligible: issue is required");
}
const nativeExecutionWorkspaceId = persistedExecutionWorkspace?.id ?? run.id;
const persistedContract = run.completionContractId
? await db.select().from(completionContracts)
.where(and(
@@ -15876,7 +15877,7 @@ export function heartbeatService(db: Db, options: HeartbeatServiceOptions = {})
|| nativeExecution.binding.runId !== run.id
|| nativeExecution.binding.issueId !== issueRef.id
|| nativeExecution.binding.agentId !== agent.id
|| nativeExecution.binding.executionWorkspaceId !== persistedExecutionWorkspace.id
|| nativeExecution.binding.executionWorkspaceId !== nativeExecutionWorkspaceId
|| nativeExecution.completionContract.id !== completionContract.row.id
|| nativeExecution.completionContract.sha256 !== completionContract.row.canonicalSha256
) throw new Error("native_execution_input_persisted_binding_mismatch");
@@ -15896,7 +15897,10 @@ export function heartbeatService(db: Db, options: HeartbeatServiceOptions = {})
issue: issueRef,
agentId: agent.id,
workspace: {
id: persistedExecutionWorkspace.id,
// Projectless paperclip_runner tasks still have a resolved local cwd. Bind that
// transient workspace to the run id so the native input remains durable and replayable
// without fabricating a project-scoped execution_workspaces row.
id: nativeExecutionWorkspaceId,
cwd: executionWorkspace.cwd,
repoUrl: executionWorkspace.repoUrl,
repoRef: executionWorkspace.repoRef,
@@ -82,4 +82,14 @@ describe("resolveNativeRuntimeMode", () => {
expect(() => resolveNativeRuntimeMode({ ...eligible, target: { kind: "remote" } }))
.toThrow(NativeRuntimeEligibilityError);
});
it("allows paperclip_runner to use a transient local workspace for projectless issues", () => {
expect(resolveNativeRuntimeMode({
...eligible,
workspaceId: null,
agent: { ...eligible.agent, adapterType: "paperclip_runner" },
runtimeConfig: {},
adapterConfig: { provider: "codex" },
})).toEqual(expect.objectContaining({ kind: "native" }));
});
});
@@ -83,7 +83,10 @@ export function resolveNativeRuntimeMode(input: {
if (!input.issue || input.issue.workMode !== "standard") {
throw new NativeRuntimeEligibilityError("run must be bound to a standard issue");
}
if (!input.workspaceId || input.target?.kind && input.target.kind !== "local") {
if (
(!input.workspaceId && !runnerAdapterSelected)
|| input.target?.kind && input.target.kind !== "local"
) {
throw new NativeRuntimeEligibilityError("a realized local workspace is required");
}
const rollout = resolveNativeMigrationStatus({