fix: stop marking Claude CLI runs as host-managed

Stop injecting CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST into Claude CLI runs and strip inherited/backend overrides before spawn.\n\nAlso repairs the Zalo setup allowlist prompt wiring needed by the current main check gate.\n\nThanks @Alex-Alaniz.
This commit is contained in:
Alex Alaniz
2026-04-10 04:14:15 -04:00
committed by GitHub
parent e3e2a19ab7
commit 6bd64ca4a7
10 changed files with 16 additions and 22 deletions

View File

@@ -77,6 +77,7 @@ Docs: https://docs.openclaw.ai
- ACP/stream relay: pass parent delivery context to ACP stream relay system events so `streamTo="parent"` updates route to the correct thread or topic instead of falling back to the main DM. (#57056) Thanks @pingren.
- Agents/sessions: preserve announce `threadId` when `sessions.list` fallback rehydrates agent-to-agent announce targets so final announce messages stay in the originating thread/topic. (#63506) Thanks @SnowSky1.
- iMessage/self-chat: remember ambiguous `sender === chat_identifier` outbound rows with missing `destination_caller_id` in self-chat dedupe state so the later reflected inbound copy still drops instead of re-entering inbound handling when the echo cache misses. Thanks @neeravmakwana.
- Claude CLI: stop marking spawned Claude Code runs as host-managed so they keep using normal CLI subscription behavior. (#64023) Thanks @Alex-Alaniz.
## 2026.4.9

View File

@@ -7,7 +7,6 @@ import {
CLAUDE_CLI_BACKEND_ID,
CLAUDE_CLI_DEFAULT_MODEL_REF,
CLAUDE_CLI_CLEAR_ENV,
CLAUDE_CLI_HOST_MANAGED_ENV,
CLAUDE_CLI_MODEL_ALIASES,
CLAUDE_CLI_SESSION_ID_FIELDS,
normalizeClaudeBackendConfig,
@@ -63,7 +62,6 @@ export function buildAnthropicCliBackend(): CliBackendPlugin {
systemPromptArg: "--append-system-prompt",
systemPromptMode: "append",
systemPromptWhen: "first",
env: { ...CLAUDE_CLI_HOST_MANAGED_ENV },
clearEnv: [...CLAUDE_CLI_CLEAR_ENV],
reliability: {
watchdog: {

View File

@@ -2,7 +2,6 @@ import { describe, expect, it } from "vitest";
import { buildAnthropicCliBackend } from "./cli-backend.js";
import {
CLAUDE_CLI_CLEAR_ENV,
CLAUDE_CLI_HOST_MANAGED_ENV,
normalizeClaudeBackendConfig,
normalizeClaudePermissionArgs,
normalizeClaudeSettingSourcesArgs,
@@ -132,10 +131,10 @@ describe("normalizeClaudeBackendConfig", () => {
expect(normalized?.resumeArgs).toContain("user");
});
it("marks claude cli as host-managed, restricts setting sources, and clears inherited env overrides", () => {
it("leaves claude cli subscription-managed, restricts setting sources, and clears inherited env overrides", () => {
const backend = buildAnthropicCliBackend();
expect(backend.config.env).toEqual(CLAUDE_CLI_HOST_MANAGED_ENV);
expect(backend.config.env).toBeUndefined();
expect(backend.config.args).toContain("--setting-sources");
expect(backend.config.args).toContain("user");
expect(backend.config.resumeArgs).toContain("--setting-sources");

View File

@@ -40,10 +40,6 @@ export const CLAUDE_CLI_SESSION_ID_FIELDS = [
"conversationId",
] as const;
export const CLAUDE_CLI_HOST_MANAGED_ENV = {
CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST: "1",
} as const;
// Claude Code honors provider-routing, auth, and config-root env before
// consulting its local login state, so inherited shell overrides must not
// steer OpenClaw-managed Claude CLI runs toward a different provider,

View File

@@ -30,9 +30,9 @@ export async function noteZaloTokenHelp(
export async function promptZaloAllowFrom(params: {
cfg: OpenClawConfig;
prompter: Parameters<NonNullable<ChannelSetupDmPolicy["promptAllowFrom"]>>[0]["prompter"];
accountId: string;
accountId?: string;
}): Promise<OpenClawConfig> {
const { cfg, prompter, accountId } = params;
const { cfg, prompter, accountId = DEFAULT_ACCOUNT_ID } = params;
const resolved = resolveZaloAccount({ cfg, accountId });
const existingAllowFrom = resolved.config.allowFrom ?? [];
const entry = await prompter.text({

View File

@@ -10,7 +10,7 @@ import {
type SecretInput,
} from "openclaw/plugin-sdk/setup";
import { resolveZaloAccount } from "./accounts.js";
import { noteZaloTokenHelp } from "./setup-allow-from.js";
import { noteZaloTokenHelp, promptZaloAllowFrom } from "./setup-allow-from.js";
import { zaloDmPolicy } from "./setup-core.js";
const channel = "zalo" as const;

View File

@@ -139,9 +139,6 @@ beforeEach(() => {
],
output: "jsonl",
input: "stdin",
env: {
CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST: "1",
},
clearEnv: [
"ANTHROPIC_API_KEY",
"ANTHROPIC_API_KEY_OLD",
@@ -364,7 +361,7 @@ describe("resolveCliBackendConfig claude-cli defaults", () => {
expect(resolved?.config.resumeArgs).toContain("user");
expect(resolved?.config.resumeArgs).toContain("--permission-mode");
expect(resolved?.config.resumeArgs).toContain("bypassPermissions");
expect(resolved?.config.env).toEqual({ CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST: "1" });
expect(resolved?.config.env).not.toHaveProperty("CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST");
expect(resolved?.config.clearEnv).toContain("ANTHROPIC_API_TOKEN");
expect(resolved?.config.clearEnv).toContain("ANTHROPIC_BASE_URL");
expect(resolved?.config.clearEnv).toContain("ANTHROPIC_CUSTOM_HEADERS");
@@ -580,7 +577,6 @@ describe("resolveCliBackendConfig claude-cli defaults", () => {
expect(resolved).not.toBeNull();
expect(resolved?.config.env).toEqual({
CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST: "1",
SAFE_CUSTOM: "ok",
ANTHROPIC_BASE_URL: "https://evil.example.com/v1",
});

View File

@@ -558,7 +558,7 @@ describe("runCliAgent spawn path", () => {
expect(input.env?.SAFE_OVERRIDE).toBe("from-override");
});
it("clears claude-cli provider-routing, auth, and telemetry env while keeping host-managed hardening", async () => {
it("clears claude-cli provider-routing, auth, telemetry, and host-managed env", async () => {
vi.stubEnv("ANTHROPIC_BASE_URL", "https://proxy.example.com/v1");
vi.stubEnv("ANTHROPIC_API_TOKEN", "env-api-token");
vi.stubEnv("ANTHROPIC_CUSTOM_HEADERS", "x-test-header: env");
@@ -573,6 +573,7 @@ describe("runCliAgent spawn path", () => {
vi.stubEnv("OTEL_TRACES_EXPORTER", "none");
vi.stubEnv("OTEL_EXPORTER_OTLP_PROTOCOL", "none");
vi.stubEnv("OTEL_SDK_DISABLED", "true");
vi.stubEnv("CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST", "1");
mockSuccessfulCliRun();
await executePreparedCliRun(
@@ -611,7 +612,7 @@ describe("runCliAgent spawn path", () => {
env?: Record<string, string | undefined>;
};
expect(input.env?.SAFE_KEEP).toBe("ok");
expect(input.env?.CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST).toBe("1");
expect(input.env?.CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST).toBeUndefined();
expect(input.env?.ANTHROPIC_BASE_URL).toBe("https://override.example.com/v1");
expect(input.env?.ANTHROPIC_API_TOKEN).toBeUndefined();
expect(input.env?.ANTHROPIC_CUSTOM_HEADERS).toBeUndefined();

View File

@@ -240,9 +240,6 @@ function buildAnthropicCliBackendFixture(): CliBackendPlugin {
systemPromptArg: "--append-system-prompt",
systemPromptMode: "append",
systemPromptWhen: "first",
env: {
CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST: "1",
},
clearEnv: [...clearEnv],
reliability: {
watchdog: {

View File

@@ -234,6 +234,12 @@ export async function executePreparedCliRun(
);
}
Object.assign(next, context.preparedBackend.env);
// Never mark Claude CLI as host-managed. That marker routes runs into
// Anthropic's separate host-managed usage tier instead of normal CLI
// subscription behavior.
delete next["CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST"];
return next;
})();
if (logOutputText) {