diff --git a/src/agents/builtin-agents/hephaestus-agent.ts b/src/agents/builtin-agents/hephaestus-agent.ts
index a32064c63..fc7b3d571 100644
--- a/src/agents/builtin-agents/hephaestus-agent.ts
+++ b/src/agents/builtin-agents/hephaestus-agent.ts
@@ -8,6 +8,7 @@ import { applyEnvironmentContext } from "./environment-context"
import { applyCategoryOverride, mergeAgentConfig } from "./agent-overrides"
import { applyModelResolution, getFirstFallbackModel } from "./model-resolution"
import { getGptApplyPatchPermission } from "../gpt-apply-patch-guard"
+import { getFrontierToolSchemaPermission } from "../frontier-tool-schema-guard"
export function maybeCreateHephaestusConfig(input: {
disabledAgents: string[]
@@ -89,6 +90,11 @@ export function maybeCreateHephaestusConfig(input: {
}
const resolvedModel = hephaestusConfig.model ?? ""
+ const frontierDeny = getFrontierToolSchemaPermission(resolvedModel)
+ if (Object.keys(frontierDeny).length > 0 && hephaestusConfig.permission) {
+ Object.assign(hephaestusConfig.permission, frontierDeny)
+ }
+
const gptDeny = getGptApplyPatchPermission(resolvedModel)
if (Object.keys(gptDeny).length > 0 && hephaestusConfig.permission) {
Object.assign(hephaestusConfig.permission, gptDeny)
diff --git a/src/agents/builtin-agents/sisyphus-agent.test.ts b/src/agents/builtin-agents/sisyphus-agent.test.ts
index e7289f6c0..b5d14895a 100644
--- a/src/agents/builtin-agents/sisyphus-agent.test.ts
+++ b/src/agents/builtin-agents/sisyphus-agent.test.ts
@@ -1,3 +1,5 @@
+///
+
import { describe, expect, test } from "bun:test";
import { maybeCreateSisyphusConfig } from "./sisyphus-agent";
import type { AgentOverrides } from "../types";
@@ -12,7 +14,7 @@ describe("maybeCreateSisyphusConfig", () => {
model: "openai/gpt-5.4",
permission: {
apply_patch: "allow",
- },
+ } as Record,
},
};
const mergedCategories: Record = {};
@@ -46,7 +48,7 @@ describe("maybeCreateSisyphusConfig", () => {
model: "anthropic/claude-opus-4-7",
permission: {
apply_patch: "allow",
- },
+ } as Record,
},
};
const mergedCategories: Record = {};
@@ -73,6 +75,74 @@ describe("maybeCreateSisyphusConfig", () => {
});
});
+ describe("#given Opus 4.7 model with user override allowing grep and glob", () => {
+ test("#when config is created #then grep and glob are still denied", () => {
+ // given
+ const agentOverrides: AgentOverrides = {
+ sisyphus: {
+ model: "anthropic/claude-opus-4-7",
+ permission: {
+ grep: "allow",
+ glob: "allow",
+ } as Record,
+ },
+ };
+ const mergedCategories: Record = {};
+
+ // when
+ const config = maybeCreateSisyphusConfig({
+ disabledAgents: [],
+ agentOverrides,
+ availableModels: new Set(["anthropic/claude-opus-4-7"]),
+ systemDefaultModel: "anthropic/claude-opus-4-7",
+ isFirstRunNoCache: false,
+ availableAgents: [],
+ availableSkills: [],
+ availableCategories: [],
+ mergedCategories,
+ useTaskSystem: false,
+ });
+
+ // then
+ expect(config?.permission).toHaveProperty("grep", "deny");
+ expect(config?.permission).toHaveProperty("glob", "deny");
+ });
+ });
+
+ describe("#given GPT 5.5 model with user override allowing grep and glob", () => {
+ test("#when config is created #then grep and glob are still denied", () => {
+ // given
+ const agentOverrides: AgentOverrides = {
+ sisyphus: {
+ model: "openai/gpt-5.5",
+ permission: {
+ grep: "allow",
+ glob: "allow",
+ } as Record,
+ },
+ };
+ const mergedCategories: Record = {};
+
+ // when
+ const config = maybeCreateSisyphusConfig({
+ disabledAgents: [],
+ agentOverrides,
+ availableModels: new Set(["openai/gpt-5.5"]),
+ systemDefaultModel: "openai/gpt-5.5",
+ isFirstRunNoCache: false,
+ availableAgents: [],
+ availableSkills: [],
+ availableCategories: [],
+ mergedCategories,
+ useTaskSystem: false,
+ });
+
+ // then
+ expect(config?.permission).toHaveProperty("grep", "deny");
+ expect(config?.permission).toHaveProperty("glob", "deny");
+ });
+ });
+
describe("#given generic GPT model with user override allowing apply_patch", () => {
test("#when config is created #then apply_patch is still denied", () => {
// given
@@ -81,7 +151,7 @@ describe("maybeCreateSisyphusConfig", () => {
model: "openai/gpt-4o",
permission: {
apply_patch: "allow",
- },
+ } as Record,
},
};
const mergedCategories: Record = {};
diff --git a/src/agents/builtin-agents/sisyphus-agent.ts b/src/agents/builtin-agents/sisyphus-agent.ts
index 97aef5f61..1b111d6cd 100644
--- a/src/agents/builtin-agents/sisyphus-agent.ts
+++ b/src/agents/builtin-agents/sisyphus-agent.ts
@@ -8,6 +8,7 @@ import { applyOverrides } from "./agent-overrides"
import { applyModelResolution, getFirstFallbackModel } from "./model-resolution"
import { createSisyphusAgent } from "../sisyphus"
import { getGptApplyPatchPermission } from "../gpt-apply-patch-guard"
+import { getFrontierToolSchemaPermission } from "../frontier-tool-schema-guard"
export function maybeCreateSisyphusConfig(input: {
disabledAgents: string[]
@@ -83,6 +84,11 @@ export function maybeCreateSisyphusConfig(input: {
sisyphusConfig = applyOverrides(sisyphusConfig, sisyphusOverride, mergedCategories, directory)
const resolvedModel = sisyphusConfig.model ?? ""
+ const frontierDeny = getFrontierToolSchemaPermission(resolvedModel)
+ if (Object.keys(frontierDeny).length > 0 && sisyphusConfig.permission) {
+ Object.assign(sisyphusConfig.permission, frontierDeny)
+ }
+
const gptDeny = getGptApplyPatchPermission(resolvedModel)
if (Object.keys(gptDeny).length > 0 && sisyphusConfig.permission) {
Object.assign(sisyphusConfig.permission, gptDeny)
diff --git a/src/agents/frontier-tool-schema-guard.ts b/src/agents/frontier-tool-schema-guard.ts
new file mode 100644
index 000000000..028943dd8
--- /dev/null
+++ b/src/agents/frontier-tool-schema-guard.ts
@@ -0,0 +1,12 @@
+import { isGpt5_5Model } from "./types"
+
+function isOpus47Model(model: string): boolean {
+ const modelName = model.includes("/") ? (model.split("/").pop() ?? model) : model
+ return modelName.toLowerCase().includes("claude-opus-4-7")
+}
+
+export function getFrontierToolSchemaPermission(model: string): Record {
+ return isOpus47Model(model) || isGpt5_5Model(model)
+ ? { grep: "deny" as const, glob: "deny" as const }
+ : {}
+}
diff --git a/src/agents/hephaestus/agent.test.ts b/src/agents/hephaestus/agent.test.ts
index f7d1087f6..22f1d8c81 100644
--- a/src/agents/hephaestus/agent.test.ts
+++ b/src/agents/hephaestus/agent.test.ts
@@ -1,3 +1,5 @@
+///
+
import { describe, expect, test } from "bun:test";
import {
getHephaestusPromptSource,
@@ -321,7 +323,7 @@ describe("maybeCreateHephaestusConfig GPT apply_patch guard", () => {
model: "openai/gpt-5.4",
permission: {
apply_patch: "allow",
- },
+ } as Record,
},
};
const mergedCategories: Record = {};
@@ -355,7 +357,7 @@ describe("maybeCreateHephaestusConfig GPT apply_patch guard", () => {
model: "anthropic/claude-opus-4-7",
permission: {
apply_patch: "allow",
- },
+ } as Record,
},
};
const mergedCategories: Record = {};
@@ -389,7 +391,7 @@ describe("maybeCreateHephaestusConfig GPT apply_patch guard", () => {
model: "openai/gpt-4o",
permission: {
apply_patch: "allow",
- },
+ } as Record,
},
};
const mergedCategories: Record = {};
@@ -414,4 +416,72 @@ describe("maybeCreateHephaestusConfig GPT apply_patch guard", () => {
expect(config?.permission).toHaveProperty("apply_patch", "deny");
});
});
+
+ describe("#given Opus 4.7 model with user override allowing grep and glob", () => {
+ test("#when config is created #then grep and glob are still denied", () => {
+ // given
+ const agentOverrides: AgentOverrides = {
+ hephaestus: {
+ model: "anthropic/claude-opus-4-7",
+ permission: {
+ grep: "allow",
+ glob: "allow",
+ } as Record,
+ },
+ };
+ const mergedCategories: Record = {};
+
+ // when
+ const config = maybeCreateHephaestusConfig({
+ disabledAgents: [],
+ agentOverrides,
+ availableModels: new Set(["anthropic/claude-opus-4-7"]),
+ systemDefaultModel: "anthropic/claude-opus-4-7",
+ isFirstRunNoCache: false,
+ availableAgents: [],
+ availableSkills: [],
+ availableCategories: [],
+ mergedCategories,
+ useTaskSystem: false,
+ });
+
+ // then
+ expect(config?.permission).toHaveProperty("grep", "deny");
+ expect(config?.permission).toHaveProperty("glob", "deny");
+ });
+ });
+
+ describe("#given GPT 5.5 model with user override allowing grep and glob", () => {
+ test("#when config is created #then grep and glob are still denied", () => {
+ // given
+ const agentOverrides: AgentOverrides = {
+ hephaestus: {
+ model: "openai/gpt-5.5",
+ permission: {
+ grep: "allow",
+ glob: "allow",
+ } as Record,
+ },
+ };
+ const mergedCategories: Record = {};
+
+ // when
+ const config = maybeCreateHephaestusConfig({
+ disabledAgents: [],
+ agentOverrides,
+ availableModels: new Set(["openai/gpt-5.5"]),
+ systemDefaultModel: "openai/gpt-5.5",
+ isFirstRunNoCache: false,
+ availableAgents: [],
+ availableSkills: [],
+ availableCategories: [],
+ mergedCategories,
+ useTaskSystem: false,
+ });
+
+ // then
+ expect(config?.permission).toHaveProperty("grep", "deny");
+ expect(config?.permission).toHaveProperty("glob", "deny");
+ });
+ });
});
diff --git a/src/agents/hephaestus/agent.ts b/src/agents/hephaestus/agent.ts
index b348f30b7..3aa773bac 100644
--- a/src/agents/hephaestus/agent.ts
+++ b/src/agents/hephaestus/agent.ts
@@ -9,6 +9,7 @@ import type {
} from "../dynamic-agent-prompt-builder";
import { categorizeTools, buildAgentIdentitySection } from "../dynamic-agent-prompt-builder";
import { getGptApplyPatchPermission } from "../gpt-apply-patch-guard";
+import { getFrontierToolSchemaPermission } from "../frontier-tool-schema-guard";
import { buildHephaestusPrompt as buildGptPrompt } from "./gpt";
import { buildHephaestusPrompt as buildGpt53CodexPrompt } from "./gpt-5-3-codex";
@@ -139,6 +140,7 @@ export function createHephaestusAgent(
permission: {
question: "allow",
call_omo_agent: "deny",
+ ...getFrontierToolSchemaPermission(model),
...getGptApplyPatchPermission(model),
} as AgentConfig["permission"],
reasoningEffort: "medium",
diff --git a/src/agents/sisyphus.ts b/src/agents/sisyphus.ts
index 21a36b8a0..d0bfb0979 100644
--- a/src/agents/sisyphus.ts
+++ b/src/agents/sisyphus.ts
@@ -13,6 +13,7 @@ import { buildGpt54SisyphusPrompt } from "./sisyphus/gpt-5-4";
import { buildGpt55SisyphusPrompt } from "./sisyphus/gpt-5-5";
import { buildTaskManagementSection } from "./sisyphus/default";
import { getGptApplyPatchPermission } from "./gpt-apply-patch-guard";
+import { getFrontierToolSchemaPermission } from "./frontier-tool-schema-guard";
const MODE: AgentMode = "primary";
export const SISYPHUS_PROMPT_METADATA: AgentPromptMetadata = {
@@ -501,6 +502,7 @@ export function createSisyphusAgent(
permission: {
question: "allow",
call_omo_agent: "deny",
+ ...getFrontierToolSchemaPermission(model),
...getGptApplyPatchPermission(model),
} as AgentConfig["permission"],
reasoningEffort: "medium",
@@ -527,6 +529,7 @@ export function createSisyphusAgent(
permission: {
question: "allow",
call_omo_agent: "deny",
+ ...getFrontierToolSchemaPermission(model),
...getGptApplyPatchPermission(model),
} as AgentConfig["permission"],
reasoningEffort: "medium",
@@ -567,6 +570,7 @@ export function createSisyphusAgent(
const permission = {
question: "allow",
call_omo_agent: "deny",
+ ...getFrontierToolSchemaPermission(model),
...getGptApplyPatchPermission(model),
} as AgentConfig["permission"];
const base = {
diff --git a/src/agents/tool-restrictions.test.ts b/src/agents/tool-restrictions.test.ts
index 3ae7bfcfe..1d0fed4fd 100644
--- a/src/agents/tool-restrictions.test.ts
+++ b/src/agents/tool-restrictions.test.ts
@@ -1,3 +1,5 @@
+///
+
import { describe, test, expect } from "bun:test"
import { createOracleAgent } from "./oracle"
import { createLibrarianAgent } from "./librarian"
@@ -6,6 +8,7 @@ import { createMomusAgent } from "./momus"
import { createMetisAgent } from "./metis"
import { createAtlasAgent } from "./atlas"
import { createSisyphusAgent } from "./sisyphus"
+import { createHephaestusAgent } from "./hephaestus"
const TEST_MODEL = "anthropic/claude-sonnet-4-5"
@@ -131,4 +134,47 @@ describe("read-only agent tool restrictions", () => {
expect(claudePermission["apply_patch"]).toBeUndefined()
})
})
+
+ describe("Sisyphus and Hephaestus frontier tool schema restrictions", () => {
+ test("deny grep and glob for Opus 4.7 and GPT 5.5 models", () => {
+ // given
+ const frontierAgents = [
+ createSisyphusAgent("anthropic/claude-opus-4-7"),
+ createSisyphusAgent("openai/gpt-5.5"),
+ createHephaestusAgent("anthropic/claude-opus-4-7"),
+ createHephaestusAgent("openai/gpt-5.5"),
+ ]
+
+ // when
+ const permissions = frontierAgents.map(
+ (agent) => (agent.permission ?? {}) as Record,
+ )
+
+ // then
+ for (const permission of permissions) {
+ expect(permission.grep).toBe("deny")
+ expect(permission.glob).toBe("deny")
+ }
+ })
+
+ test("keeps grep and glob available for other models", () => {
+ // given
+ const otherAgents = [
+ createSisyphusAgent("anthropic/claude-sonnet-4-5"),
+ createSisyphusAgent("openai/gpt-5.4"),
+ createHephaestusAgent("openai/gpt-5.4"),
+ ]
+
+ // when
+ const permissions = otherAgents.map(
+ (agent) => (agent.permission ?? {}) as Record,
+ )
+
+ // then
+ for (const permission of permissions) {
+ expect(permission.grep).toBeUndefined()
+ expect(permission.glob).toBeUndefined()
+ }
+ })
+ })
})