From 559644635db8deccd92e4288081b763be194465b Mon Sep 17 00:00:00 2001 From: Dotta Date: Mon, 12 Oct 2026 16:01:22 -0500 Subject: [PATCH] feat(claude): default qualified macOS and Linux targets to Runner Enable Intel Mac, Linux x64, and Linux ARM64 after passing package consumers and the bounded API task/continuity pairs. Keep unsupported targets, overrides, and explicit Legacy choices intact. Co-Authored-By: Paperclip --- doc/DEVELOPING.md | 6 +++--- maps/agent-access-map/agents.md | 3 ++- maps/feature-map/agents.md | 7 ++++--- packages/shared/src/agent-runner.ts | 2 -- .../services/agent-runner-selection.test.ts | 18 ++++++++++++++++-- skills/paperclip-create-agent/SKILL.md | 5 +++-- 6 files changed, 28 insertions(+), 13 deletions(-) diff --git a/doc/DEVELOPING.md b/doc/DEVELOPING.md index 8ddfe16cd1e..d7f128335d8 100644 --- a/doc/DEVELOPING.md +++ b/doc/DEVELOPING.md @@ -1529,9 +1529,9 @@ CLI paths that use stdin avoid that separate limit for the wake prompt. ## Paperclip Runner Adapter Conversion Paperclip Runner offers native Codex, OpenCode, and **ACPX Claude**. New -Claude Code agents default to ACPX Claude on Apple Silicon; other Claude targets -retain Legacy until platform qualification is complete. The runner override is -in Advanced. Ordinary Claude models default to `claude-opus-5-5`; explicit models +Claude Code agents default to ACPX Claude on Apple Silicon, Intel Mac, Linux x64 +and Linux ARM64 with supported glibc. Unsupported or unqualified targets retain +Legacy. The runner override is in Advanced. Ordinary Claude models default to `claude-opus-5-5`; explicit models and provider routing remain authoritative. Existing agents keep their saved runner. Converting an existing Claude, Codex, or OpenCode agent selects its corresponding provider, preserves compatible models, credentials, workspace, and instructions, and resets execution sessions while retaining run history. diff --git a/maps/agent-access-map/agents.md b/maps/agent-access-map/agents.md index f579d431b41..6625f3d02f0 100644 --- a/maps/agent-access-map/agents.md +++ b/maps/agent-access-map/agents.md @@ -23,7 +23,8 @@ native hires. Creation requests can use `runner: auto | paperclip | legacy`; the server resolves and persists execution configuration. Claude Auto selects the native ACPX profile -on qualified Apple Silicon; saved runner/model/provider overrides survive edits +on qualified macOS and GNU/Linux x64/ARM64 targets; unknown environment +qualification remains Legacy. Saved runner/model/provider overrides survive edits and approval activation. This selection does not grant connection access or bypass hiring authorization. Source: [runner resolver](../../server/src/services/agent-runner-selection.ts). diff --git a/maps/feature-map/agents.md b/maps/feature-map/agents.md index 4f4e05529d7..6fdba76ac42 100644 --- a/maps/feature-map/agents.md +++ b/maps/feature-map/agents.md @@ -39,13 +39,14 @@ Automated: [new agent page](../../ui/src/pages/NewAgent.test.tsx) and [configura Manual: Hire an agent with a distinct name and role. Complete any required approval, reload the roster, and open its configuration. Confirm manager, adapter, and model persisted; run a small task to prove execution readiness. -For Claude Code on Apple Silicon, submit without a runner override and inspect +For Claude Code on qualified macOS or GNU/Linux x64/ARM64, submit without a +runner override and inspect saved configuration: `paperclip_runner`, `provider: acpx`, `acpxAgent: claude`, and ordinary model `claude-opus-5-5`. The Advanced runner selector can explicitly choose Legacy. Keep explicit model/account choices and saved runners on edits. Verify useful output and a follow-up after a controller restart; setup success -alone does not establish session continuity. Additional target defaults remain -subject to their separate qualification gates. +alone does not establish session continuity. Unsupported architectures/libc and unknown environment qualification retain +Legacy. Linux ARM64 cloud-image production remains deferred. The current hiring wizard assigns the first hire CEO and subsequent hires General reporting to the CEO. Change manager/role afterward through supported diff --git a/packages/shared/src/agent-runner.ts b/packages/shared/src/agent-runner.ts index c49fba46896..08aefdedc22 100644 --- a/packages/shared/src/agent-runner.ts +++ b/packages/shared/src/agent-runner.ts @@ -31,8 +31,6 @@ function supportsLinuxLibc(libc?: "glibc" | "musl" | "unknown", version?: string /** Creation defaults follow GNU/Linux and macOS artifacts; Alpine/musl is deferred. */ export function paperclipRunnerSupportsPlatform(harness: string, platform: string, architecture: string, libc?: "glibc" | "musl" | "unknown", glibcVersion?: string): boolean { - // Claude graduates on Apple Silicon first; other targets await package and live qualification. - if (harness === "claude_local") return platform === "darwin" && architecture === "arm64"; return !!paperclipRunnerProfileForHarness(harness) // Omitted libc preserves platform-only callers; detected unknown Linux is not qualified. && ((platform === "linux" && supportsLinuxLibc(libc, glibcVersion) && (architecture === "x64" || architecture === "arm64")) diff --git a/server/src/services/agent-runner-selection.test.ts b/server/src/services/agent-runner-selection.test.ts index 28532d0ce16..85462b183f4 100644 --- a/server/src/services/agent-runner-selection.test.ts +++ b/server/src/services/agent-runner-selection.test.ts @@ -72,7 +72,7 @@ describe("server-owned Codex runner selection", () => { expect(resolveNewAgentRunner(resolved)).toEqual(resolved); expect(input.adapterConfig).toHaveProperty("search", false); }); - it.each(["claude_local", "opencode_local", "grok_local", "cursor", "pi_local", "process", "external"])("keeps %s default unchanged", adapterType => { + it.each(["opencode_local", "grok_local", "cursor", "pi_local", "process", "external"])("keeps %s default unchanged", adapterType => { expect(resolveNewAgentRunner({ adapterType, target, adapterConfig: { custom: "preserved" } })).toEqual({ adapterType, adapterConfig: { custom: "preserved" } }); }); it.each(qualifiedTargets)("allows an explicit legacy runner and native to legacy round trip on $platform/$architecture", target => { @@ -207,6 +207,20 @@ describe("Codex creation runner contract", () => { describe("Claude runner defaults", () => { const mac = { driver: "local", platform: "darwin", architecture: "arm64" }; beforeEach(() => { state.disabled = []; state.overridden.clear(); }); + it.each(qualifiedTargets)("defaults Claude to the qualified $platform $architecture profile", target => { + expect(agentRunnerAvailability("claude_local", target)).toEqual({ supportedRunners: ["paperclip", "legacy"], defaultRunner: "paperclip" }); + expect(resolveNewAgentRunner({ adapterType: "claude_local", target })).toEqual({ + adapterType: "paperclip_runner", adapterConfig: { provider: "acpx", acpxAgent: "claude", model: "claude-opus-5-5", acpxPermissionMode: "approve-all", lifecycleMode: "per_turn" }, + }); + expect(resolveNewAgentRunner({ adapterType: "claude_local", target, runner: "legacy", adapterConfig: { model: "custom", dangerouslySkipPermissions: true } })) + .toEqual({ adapterType: "claude_local", adapterConfig: { model: "custom", dangerouslySkipPermissions: true } }); + }); + it.each(["x64", "arm64"])("keeps incompatible Linux Claude %s targets legacy", architecture => { + for (const libc of ["musl", "unknown"] as const) { + expect(agentRunnerAvailability("claude_local", { driver: "local", platform: "linux", architecture, libc }).defaultRunner).toBe("legacy"); + } + expect(agentRunnerAvailability("claude_local", { driver: "local", platform: "linux", architecture, libc: "glibc", glibcVersion: "2.17" }).defaultRunner).toBe("legacy"); + }); it("saves native Claude with Opus 5.5, preserving credentials and shared settings", () => { const config = { env: { ANTHROPIC_API_KEY: { type: "secret_ref", secretId: "key" } }, instructionsFilePath: "/workspace/AGENTS.md", timeoutSec: 180, dangerouslySkipPermissions: true }; const result = resolveNewAgentRunner({ adapterType: "claude_local", target: mac, adapterConfig: config }); @@ -263,7 +277,7 @@ describe("Claude runner defaults", () => { expect(agentRunnerAvailability("claude_local", { driver: "sandbox" }).defaultRunner).toBe("legacy"); }); it("keeps unqualified targets and overrides legacy", () => { - expect(agentRunnerAvailability("claude_local", target).defaultRunner).toBe("legacy"); + expect(agentRunnerAvailability("claude_local", { driver: "local", platform: "win32", architecture: "x64" }).defaultRunner).toBe("legacy"); state.overridden.add("claude_local"); expect(agentRunnerAvailability("claude_local", mac).defaultRunner).toBe("legacy"); state.overridden.clear(); state.disabled = ["claude_local"]; diff --git a/skills/paperclip-create-agent/SKILL.md b/skills/paperclip-create-agent/SKILL.md index c0a7fdf1e13..330dedfb0c2 100644 --- a/skills/paperclip-create-agent/SKILL.md +++ b/skills/paperclip-create-agent/SKILL.md @@ -191,8 +191,9 @@ For each linked issue, either: Choose the underlying harness in `adapterType`, such as `codex_local` or `claude_local`. New Codex agents use Paperclip Runner automatically on supported -execution targets. New Claude Code agents use Paperclip Runner on Apple Silicon; -other Claude targets retain Legacy until qualified. The native Claude profile is +execution targets. New Claude Code agents use Paperclip Runner on Apple Silicon, +Intel Mac, Linux x64 and Linux ARM64 with supported glibc. Unknown or unsupported +targets retain Legacy. The native Claude profile is `provider: acpx`, `acpxAgent: claude`, with ordinary model `claude-opus-5-5`. Explicit models and existing saved runners remain intact. The saved response may therefore have `adapterType: paperclip_runner` and a resolved provider;