Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/adapters/identity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,19 @@
* to be a specific first-party client.
*/

/** The exact identity line Codex injects for every model. */
/** Historical exact identity line Codex injected for every model. */
export const CODEX_GPT5_IDENTITY_LINE = "You are Codex, a coding agent based on GPT-5.";

/** Codex CLI 0.145.0+ wording (#622) — still GPT-5 identity, slightly different phrasing. */
export const CODEX_GPT5_IDENTITY_LINE_AGENT = "You are Codex, an agent based on GPT-5.";
Comment on lines +20 to +21

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use the new identity variant when deriving catalog entries

When the active Codex 0.145 catalog supplies the new You are Codex, an agent based on GPT-5. template, deriveEntry still replaces only CODEX_GPT5_IDENTITY_LINE at src/codex/catalog/sync.ts:176-178. Because routed entries retain base_instructions, every entry cloned from that template keeps the incorrect GPT-5 identity despite the catalog's stated neutralization invariant; reuse the generalized matcher for catalog replacement and add a catalog regression using the new template.

AGENTS.md reference: AGENTS.md:L93-L95

Useful? React with 👍 / 👎.


/**
* Known Codex GPT-5 identity sentences. Narrow: only "coding agent" / "an agent" + GPT-5(.x)?
* Avoid a broad `You are Codex.*` rewrite that could touch unrelated content.
*/
const CODEX_GPT5_IDENTITY_RE =
/You are Codex, (?:a coding agent|an agent) based on GPT-5(?:\.[0-9]+)*\./g;

/** Proxy-neutral replacement: no "opencodex proxy" mention, just the GPT-5/OpenAI disclaimer. */
export const NEUTRAL_IDENTITY_LINE = "You are a coding agent. Do not claim to be GPT-5 or to be made by OpenAI.";

Expand All @@ -27,7 +37,7 @@ export const NEUTRAL_IDENTITY_LINE = "You are a coding agent. Do not claim to be
* the leak can't reappear in one adapter while being fixed in another.
*/
export function neutralizeIdentity(systemText: string): string {
return systemText.replace(CODEX_GPT5_IDENTITY_LINE, NEUTRAL_IDENTITY_LINE);
return systemText.replace(CODEX_GPT5_IDENTITY_RE, NEUTRAL_IDENTITY_LINE);
}

/** The catalog (static, on-disk) replacement for `base_instructions`. Same neutral wording. */
Expand Down
16 changes: 15 additions & 1 deletion tests/identity-neutralize.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { CODEX_GPT5_IDENTITY_LINE, NEUTRAL_IDENTITY_LINE, neutralizeIdentity } from "../src/adapters/identity";
import {
CODEX_GPT5_IDENTITY_LINE,
CODEX_GPT5_IDENTITY_LINE_AGENT,
NEUTRAL_IDENTITY_LINE,
neutralizeIdentity,
} from "../src/adapters/identity";
import { createGoogleAdapter } from "../src/adapters/google";
import { createKiroAdapter } from "../src/adapters/kiro";
import { createOpenAIChatAdapter } from "../src/adapters/openai-chat";
Expand All @@ -23,6 +28,12 @@ describe("identity neutralization — central helper", () => {
expect(neutralizeIdentity(SYS)).toBe(NEUTRAL_IDENTITY_LINE);
});

test("replaces the Codex CLI 0.145 'an agent' identity variant (#622)", () => {
expect(neutralizeIdentity(CODEX_GPT5_IDENTITY_LINE_AGENT)).toBe(NEUTRAL_IDENTITY_LINE);
expect(neutralizeIdentity("You are Codex, an agent based on GPT-5.4.")).toBe(NEUTRAL_IDENTITY_LINE);
expect(neutralizeIdentity("You are Codex, an agent based on GPT-5.4.1.")).toBe(NEUTRAL_IDENTITY_LINE);
});

test("never emits the opencodex proxy identity", () => {
const out = neutralizeIdentity(`${SYS}\n\nmore context`);
expect(out).not.toMatch(/opencodex proxy/i);
Expand All @@ -32,6 +43,9 @@ describe("identity neutralization — central helper", () => {

test("leaves text without the GPT-5 line unchanged", () => {
expect(neutralizeIdentity("plain system text")).toBe("plain system text");
expect(neutralizeIdentity("You are Codex, helpful for reviewing PRs.")).toBe(
"You are Codex, helpful for reviewing PRs.",
);
});

test("neutral line still forbids GPT-5 / OpenAI self-reporting", () => {
Expand Down
Loading