diff --git a/src/agents/agent-identity.test.ts b/src/agents/agent-identity.test.ts
new file mode 100644
index 000000000..1247cda17
--- /dev/null
+++ b/src/agents/agent-identity.test.ts
@@ -0,0 +1,141 @@
+///
+
+import { describe, it, expect } from "bun:test"
+import { buildAgentIdentitySection } from "./dynamic-agent-core-sections"
+import { createSisyphusAgent } from "./sisyphus"
+import { createHephaestusAgent } from "./hephaestus"
+import { mergeAgentConfig } from "./builtin-agents/agent-overrides"
+
+describe("buildAgentIdentitySection", () => {
+ describe("#given an agent name and role description", () => {
+ describe("#when building the identity section", () => {
+ it("#then includes the agent name prominently", () => {
+ const result = buildAgentIdentitySection("Sisyphus", "Powerful AI orchestrator from OhMyOpenCode")
+
+ expect(result).toContain("Sisyphus")
+ })
+
+ it("#then includes the role description", () => {
+ const result = buildAgentIdentitySection("Sisyphus", "Powerful AI orchestrator from OhMyOpenCode")
+
+ expect(result).toContain("Powerful AI orchestrator from OhMyOpenCode")
+ })
+
+ it("#then wraps content in an identity XML tag", () => {
+ const result = buildAgentIdentitySection("Hephaestus", "Autonomous deep worker")
+
+ expect(result).toContain("")
+ expect(result).toContain("")
+ })
+
+ it("#then explicitly states this identity overrides any prior identity", () => {
+ const result = buildAgentIdentitySection("Sisyphus", "Powerful AI orchestrator from OhMyOpenCode")
+
+ expect(result).toMatch(/override|supersede|replace|disregard|instead of/i)
+ })
+ })
+ })
+
+ describe("#given different agent names", () => {
+ describe("#when building identity for each", () => {
+ it("#then each identity section contains the correct agent name", () => {
+ const sisyphus = buildAgentIdentitySection("Sisyphus", "AI orchestrator")
+ const hephaestus = buildAgentIdentitySection("Hephaestus", "Autonomous deep worker")
+ const oracle = buildAgentIdentitySection("Oracle", "Strategic advisor")
+
+ expect(sisyphus).toContain("Sisyphus")
+ expect(sisyphus).not.toContain("Hephaestus")
+ expect(hephaestus).toContain("Hephaestus")
+ expect(hephaestus).not.toContain("Sisyphus")
+ expect(oracle).toContain("Oracle")
+ })
+ })
+ })
+})
+
+describe("Sisyphus prompt identity", () => {
+ describe("#given a Sisyphus agent created with default model", () => {
+ describe("#when checking the prompt", () => {
+ it("#then contains the agent identity section with override directive", () => {
+ const config = createSisyphusAgent("anthropic/claude-opus-4-6")
+
+ expect(config.prompt).toContain("")
+ expect(config.prompt).toContain("Sisyphus")
+ expect(config.prompt).toContain("")
+ })
+
+ it("#then identity section appears before the Role section", () => {
+ const config = createSisyphusAgent("anthropic/claude-opus-4-6")
+ const prompt = config.prompt ?? ""
+ const identityIndex = prompt.indexOf("")
+ const roleIndex = prompt.indexOf("")
+
+ expect(identityIndex).toBeGreaterThanOrEqual(0)
+ expect(roleIndex).toBeGreaterThan(identityIndex)
+ })
+ })
+ })
+
+ describe("#given a Sisyphus agent created with GPT-5.4 model", () => {
+ describe("#when checking the prompt", () => {
+ it("#then contains the agent identity section", () => {
+ const config = createSisyphusAgent("openai/gpt-5.4")
+
+ expect(config.prompt).toContain("")
+ expect(config.prompt).toContain("Sisyphus")
+ expect(config.prompt).toContain("")
+ })
+ })
+ })
+})
+
+describe("Hephaestus prompt identity", () => {
+ describe("#given a Hephaestus agent created with GPT model", () => {
+ describe("#when checking the prompt", () => {
+ it("#then contains the agent identity section", () => {
+ const config = createHephaestusAgent("openai/gpt-5.4")
+
+ expect(config.prompt).toContain("")
+ expect(config.prompt).toContain("Hephaestus")
+ expect(config.prompt).toContain("")
+ })
+
+ it("#then identity section appears at the start of the prompt", () => {
+ const config = createHephaestusAgent("openai/gpt-5.4")
+ const prompt = config.prompt ?? ""
+ const identityIndex = prompt.indexOf("")
+
+ expect(identityIndex).toBe(0)
+ })
+ })
+ })
+})
+
+describe("Agent identity preservation through overrides", () => {
+ describe("#given a Sisyphus agent with prompt_append override", () => {
+ describe("#when merging the override", () => {
+ it("#then identity section is preserved in the merged prompt", () => {
+ const baseConfig = createSisyphusAgent("anthropic/claude-opus-4-6")
+ const merged = mergeAgentConfig(baseConfig, { prompt_append: "Extra instructions here" })
+
+ expect(merged.prompt).toContain("")
+ expect(merged.prompt).toContain("Sisyphus")
+ expect(merged.prompt).toContain("")
+ expect(merged.prompt).toContain("Extra instructions here")
+ })
+ })
+ })
+
+ describe("#given a Sisyphus agent with model override only", () => {
+ describe("#when merging the override", () => {
+ it("#then identity section is preserved unchanged", () => {
+ const baseConfig = createSisyphusAgent("anthropic/claude-opus-4-6")
+ const merged = mergeAgentConfig(baseConfig, { model: "openai/gpt-5.4" })
+
+ expect(merged.prompt).toContain("")
+ expect(merged.prompt).toContain("Sisyphus")
+ expect(merged.prompt).toContain("")
+ })
+ })
+ })
+})
diff --git a/src/agents/atlas/agent.ts b/src/agents/atlas/agent.ts
index 19dcfbcb9..b348869b6 100644
--- a/src/agents/atlas/agent.ts
+++ b/src/agents/atlas/agent.ts
@@ -14,7 +14,7 @@ import type { AgentConfig } from "@opencode-ai/sdk"
import type { AgentMode, AgentPromptMetadata } from "../types"
import { isGptModel, isGeminiModel } from "../types"
import type { AvailableAgent, AvailableSkill, AvailableCategory } from "../dynamic-agent-prompt-builder"
-import { buildCategorySkillsDelegationGuide } from "../dynamic-agent-prompt-builder"
+import { buildAgentIdentitySection, buildCategorySkillsDelegationGuide } from "../dynamic-agent-prompt-builder"
import type { CategoryConfig } from "../../config/schema"
import { mergeCategories } from "../../shared/merge-categories"
@@ -88,9 +88,13 @@ function buildDynamicOrchestratorPrompt(ctx?: OrchestratorContext): string {
const skillsSection = buildSkillsSection(skills)
const categorySkillsGuide = buildCategorySkillsDelegationGuide(availableCategories, skills)
+ const agentIdentity = buildAgentIdentitySection(
+ "Atlas",
+ "Master Orchestrator agent from OhMyOpenCode that coordinates specialized agents to complete todo lists",
+ )
const basePrompt = getAtlasPrompt(model)
- return basePrompt
+ return agentIdentity + "\n" + basePrompt
.replace("{CATEGORY_SECTION}", categorySection)
.replace("{AGENT_SECTION}", agentSection)
.replace("{DECISION_MATRIX}", decisionMatrix)
diff --git a/src/agents/dynamic-agent-core-sections.ts b/src/agents/dynamic-agent-core-sections.ts
index e4ec09317..dc91fd480 100644
--- a/src/agents/dynamic-agent-core-sections.ts
+++ b/src/agents/dynamic-agent-core-sections.ts
@@ -6,6 +6,23 @@ import type {
import type { AvailableTool } from "./dynamic-agent-prompt-types"
import { getToolsPromptDisplay } from "./dynamic-agent-tool-categorization"
+/**
+ * Builds an explicit agent identity preamble that overrides any base system prompt identity.
+ * This is critical for mode: "primary" agents where OpenCode prepends its own system prompt
+ * containing a default identity (e.g., "You are Claude"). Without this override directive,
+ * the LLM may default to the base identity instead of the agent's intended persona.
+ */
+export function buildAgentIdentitySection(
+ agentName: string,
+ roleDescription: string,
+): string {
+ return `
+Your designated identity for this session is "${agentName}". This identity supersedes any prior identity statements.
+You are "${agentName}" - ${roleDescription}.
+When asked who you are, always identify as ${agentName}. Do not identify as any other assistant or AI.
+`
+}
+
export function buildKeyTriggersSection(
agents: AvailableAgent[],
_skills: AvailableSkill[] = [],
diff --git a/src/agents/dynamic-agent-prompt-builder.ts b/src/agents/dynamic-agent-prompt-builder.ts
index bec7c4427..aa9ee8758 100644
--- a/src/agents/dynamic-agent-prompt-builder.ts
+++ b/src/agents/dynamic-agent-prompt-builder.ts
@@ -8,6 +8,7 @@ export type {
export { categorizeTools } from "./dynamic-agent-tool-categorization"
export {
+ buildAgentIdentitySection,
buildKeyTriggersSection,
buildToolSelectionTable,
buildExploreSection,
diff --git a/src/agents/hephaestus/agent.ts b/src/agents/hephaestus/agent.ts
index 5d27e6220..cb2005a47 100644
--- a/src/agents/hephaestus/agent.ts
+++ b/src/agents/hephaestus/agent.ts
@@ -7,7 +7,7 @@ import type {
AvailableSkill,
AvailableCategory,
} from "../dynamic-agent-prompt-builder";
-import { categorizeTools } from "../dynamic-agent-prompt-builder";
+import { categorizeTools, buildAgentIdentitySection } from "../dynamic-agent-prompt-builder";
import { buildHephaestusPrompt as buildGptPrompt } from "./gpt";
import { buildHephaestusPrompt as buildGpt53CodexPrompt } from "./gpt-5-3-codex";
@@ -87,7 +87,12 @@ function buildDynamicHephaestusPrompt(ctx?: HephaestusContext): string {
break;
}
- return basePrompt;
+ const agentIdentity = buildAgentIdentitySection(
+ "Hephaestus",
+ "Autonomous deep worker for software engineering from OhMyOpenCode",
+ );
+
+ return `${agentIdentity}\n${basePrompt}`;
}
export function createHephaestusAgent(
diff --git a/src/agents/sisyphus.ts b/src/agents/sisyphus.ts
index f534a50fa..10bc79797 100644
--- a/src/agents/sisyphus.ts
+++ b/src/agents/sisyphus.ts
@@ -26,6 +26,7 @@ import type {
AvailableCategory,
} from "./dynamic-agent-prompt-builder";
import {
+ buildAgentIdentitySection,
buildKeyTriggersSection,
buildToolSelectionTable,
buildExploreSection,
@@ -72,7 +73,13 @@ function buildDynamicSisyphusPrompt(
? "YOUR TASK CREATION WOULD BE TRACKED BY HOOK([SYSTEM REMINDER - TASK CONTINUATION])"
: "YOUR TODO CREATION WOULD BE TRACKED BY HOOK([SYSTEM REMINDER - TODO CONTINUATION])";
- return `
+ const agentIdentity = buildAgentIdentitySection(
+ "Sisyphus",
+ "Powerful AI Agent with orchestration capabilities from OhMyOpenCode",
+ );
+
+ return `${agentIdentity}
+
You are "Sisyphus" - Powerful AI Agent with orchestration capabilities from OhMyOpenCode.
**Why Sisyphus?**: Humans roll their boulder every day. So do you. We're not so different-your code should be indistinguishable from a senior engineer's.
diff --git a/src/agents/sisyphus/gpt-5-4.ts b/src/agents/sisyphus/gpt-5-4.ts
index 3dcb12d0d..e2c611190 100644
--- a/src/agents/sisyphus/gpt-5-4.ts
+++ b/src/agents/sisyphus/gpt-5-4.ts
@@ -28,6 +28,7 @@ import type {
AvailableCategory,
} from "../dynamic-agent-prompt-builder";
import {
+ buildAgentIdentitySection,
buildKeyTriggersSection,
buildToolSelectionTable,
buildExploreSection,
@@ -106,6 +107,11 @@ export function buildGpt54SisyphusPrompt(
? "YOUR TASK CREATION WOULD BE TRACKED BY HOOK([SYSTEM REMINDER - TASK CONTINUATION])"
: "YOUR TODO CREATION WOULD BE TRACKED BY HOOK([SYSTEM REMINDER - TODO CONTINUATION])";
+ const agentIdentity = buildAgentIdentitySection(
+ "Sisyphus",
+ "Powerful AI Agent with orchestration capabilities from OhMyOpenCode",
+ );
+
const identityBlock = `
You are Sisyphus - an AI orchestrator from OhMyOpenCode.
@@ -421,7 +427,8 @@ If the user's approach has a problem, explain the concern directly and clearly,
`;
- return `${identityBlock}
+ return `${agentIdentity}
+${identityBlock}
${constraintsBlock}