Skip to content

fix (codex harness): Codex app-server: forward OpenClaw persona bootstrap into developer instructions #77363

@wingleungron

Description

@wingleungron

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

When using the native Codex app-server runtime, OpenClaw workspace persona files are loaded but do not reliably shape Codex behavior.

The harness already builds a bootstrap block from user-editable workspace files such as SOUL.md, IDENTITY.md, USER.md, TOOLS.md, BOOTSTRAP.md, MEMORY.md, and HEARTBEAT.md. However, that block was only forwarded through Codex config.instructions.

In practice, the Codex app-server path consistently applies the explicit developerInstructions field used by the OpenClaw runtime overlay. This means persona/style guidance can be present in the workspace but fail to persist into Codex behavior after a reset or new session.

This PR keeps the existing config.instructions path and also forwards the same workspace bootstrap block through developerInstructions.

Steps to reproduce

Codex receives the generic OpenClaw/Codex runtime developer instructions, but the workspace persona bootstrap is only attached through config.instructions.

Expected behavior

Workspace bootstrap persona files should be included in the Codex developer instruction stream for the app-server harness.

That means:

  • SOUL.md persona/tone guidance reaches Codex as standing behavior.
  • IDENTITY.md and other bootstrap context files continue to be included.
  • AGENTS.md remains excluded from the explicit bootstrap block because Codex loads it natively.
  • Existing config.instructions behavior remains intact.

Actual behavior

Codex continues replying in generic Codex style instead of following SOUL.md / IDENTITY.md, even though those files exist and are loaded.

OpenClaw version

openclaw 2026.5.3

Operating system

macOS / Apple Silicon

Install method

No response

Model

openai/gpt-5.5

Provider / routing chain

openclaw -> codex runtime -> Codex app-server

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

No response

Additional information

Code Changes

extensions/codex/src/app-server/run-attempt.ts

Workspace bootstrap instructions are now built before developerInstructions is finalized:

const baseDeveloperInstructions = buildDeveloperInstructions(params);
const workspaceBootstrapInstructions = await buildCodexWorkspaceBootstrapInstructions({
  params,
  resolvedWorkspace,
  effectiveWorkspace,
  sessionKey: sandboxSessionKey,
  sessionAgentId,
});
let promptText = params.prompt;
let developerInstructions = joinPresentSections(
  baseDeveloperInstructions,
  workspaceBootstrapInstructions,
);
let prePromptMessageCount = historyMessages.length;

When the context engine is active, the workspace bootstrap is preserved alongside the context-engine system addition:

developerInstructions = joinPresentSections(
  baseDeveloperInstructions,
  workspaceBootstrapInstructions,
  projection.developerInstructionAddition,
);

The existing config.instructions path remains unchanged:

const threadConfig = mergeCodexConfigInstructions(
  nativeHookRelayConfig,
  workspaceBootstrapInstructions,
);

extensions/codex/src/app-server/run-attempt.test.ts

The bootstrap-file test now verifies that SOUL.md content reaches both Codex instruction paths:

const threadStart = harness.requests.find((request) => request.method === "thread/start");
const params = threadStart?.params as {
  config?: { instructions?: string };
  developerInstructions?: string;
};
const config = params.config;

expect(params.developerInstructions).toContain("Soul voice goes here.");
expect(params.developerInstructions).toContain("Codex loads AGENTS.md natively");
expect(params.developerInstructions).not.toContain("Follow AGENTS guidance.");

expect(config).toEqual(
  expect.objectContaining({
    instructions: expect.stringContaining("Soul voice goes here."),
  }),
);
expect(config?.instructions).toContain("Codex loads AGENTS.md natively");
expect(config?.instructions).not.toContain("Follow AGENTS guidance.");

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingbug:behaviorIncorrect behavior without a crash

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions