diff --git a/src/handlers/identity-neutralize.js b/src/handlers/identity-neutralize.js
index 28e1179..8773361 100644
--- a/src/handlers/identity-neutralize.js
+++ b/src/handlers/identity-neutralize.js
@@ -110,6 +110,26 @@ export function neutralizeClientIdentity(text, env = process.env, opts = {}) {
/You are ([A-Z][\w.-]*), a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns,? and best practices\./g,
'You are $1, a software engineer.',
);
+ // (a6-grok) Grok / xAI self-identification (2026-07-16, live-confirmed to
+ // trip Devin's content policy → permission_denied). Grok CLI opens with
+ // "You are Grok 4.5 released by xAI. You are an interactive CLI tool that
+ // helps users with software engineering tasks." A/B on the live upstream:
+ // this exact line is what triggers the block — the same request with a
+ // generic assistant line passes. Match the full "You are Grok ... released
+ // by xAI" form and the bare noun phrase, any Grok version digit.
+ out = out.replace(
+ /You are Grok[\w .-]* released by xAI\.?/gi,
+ 'You are an AI coding assistant.',
+ );
+ out = out.replace(
+ /\bGrok[\w .-]* released by xAI\.?/gi,
+ 'an AI coding assistant.',
+ );
+ // (a6-grok2) Grok's executing_actions_with_care safety paragraph — a
+ // competitor-specific safety/policy framing that rides in the prompt body
+ // and has been observed in the same blocked request. Strip the whole
+ // ... block.
+ out = out.replace(/[\s\S]*?<\/executing_actions_with_care>/gi, '');
// (a6) SPECULATIVE / HYPOTHESIS-ONLY (2026-07-15), DEFAULT-OFF. Unlike a1-a5
// which are live-bisected confirmed triggers, this OBJECTIVE boast sentence is
// only SUSPECTED to be in the same content-policy trigger family — NOT verified,
diff --git a/test/client-identity-neutralize.test.js b/test/client-identity-neutralize.test.js
index 1d2cb44..243c36c 100644
--- a/test/client-identity-neutralize.test.js
+++ b/test/client-identity-neutralize.test.js
@@ -211,6 +211,73 @@ describe('neutralizeClientIdentity', () => {
});
});
+// 2026-07-16 (a6-grok/a6-grok2): Grok CLI's system prompt opens with "You are
+// Grok 4.5 released by xAI. You are an interactive CLI tool that helps users
+// with software engineering tasks." Live A/B on the Devin upstream proved that
+// exact self-ID line trips the content policy (permission_denied); the same
+// request with a generic assistant line passes. The competitor-specific
+// safety paragraph rides in the same blocked
+// prompt body and is stripped whole. Both rules are unconditional like a1-a5,
+// gated only by the main WINDSURFAPI_NEUTRALIZE_CLIENT_ID switch (default on).
+describe('neutralizeClientIdentity — Grok / xAI rules (a6-grok)', () => {
+ const GROK_ID = 'You are Grok 4.5 released by xAI.';
+
+ it('rewrites the exact Grok self-identification', () => {
+ const out = neutralizeClientIdentity(GROK_ID + ' You are an interactive CLI tool that helps users with software engineering tasks.');
+ assert.ok(!/Grok/.test(out), 'no Grok');
+ assert.ok(!/xAI/.test(out), 'no xAI');
+ assert.match(out, /^You are an AI coding assistant\./, 'opens with the generic identity line');
+ assert.match(out, /You are an interactive CLI tool that helps users with software engineering tasks\./, 'rest of prompt preserved');
+ });
+
+ it('neutralizes the bare noun phrase without the leading "You are"', () => {
+ const out = neutralizeClientIdentity('Note: Grok 4 released by xAI is running.');
+ assert.ok(!/Grok/.test(out), 'no Grok');
+ assert.ok(!/released by xAI/i.test(out), 'no xAI attribution');
+ assert.match(out, /an AI coding assistant\./, 'generic noun phrase substituted');
+ });
+
+ it('matches any Grok version variant (4.5.1, 3 mini, ...)', () => {
+ assert.equal(
+ neutralizeClientIdentity('You are Grok 4.5.1 released by xAI.'),
+ 'You are an AI coding assistant.',
+ );
+ assert.equal(
+ neutralizeClientIdentity('You are Grok 3 mini released by xAI.'),
+ 'You are an AI coding assistant.',
+ );
+ });
+
+ it('strips the block entirely', () => {
+ const out = neutralizeClientIdentity('foo bar');
+ assert.equal(out, '', 'inline block fully removed');
+ });
+
+ it('strips a multiline block and keeps surrounding text', () => {
+ const src = 'Before.\n\nfoo bar\nDouble-check destructive commands before running them.\n\nAfter.';
+ const out = neutralizeClientIdentity(src);
+ assert.ok(!/executing_actions_with_care/i.test(out), 'tags removed');
+ assert.ok(!/foo bar/.test(out), 'block content removed');
+ assert.ok(!/destructive commands/.test(out), 'multiline content removed');
+ assert.match(out, /Before\./, 'content before kept');
+ assert.match(out, /After\./, 'content after kept');
+ });
+
+ it('leaves unrelated mentions of "Grok" alone (no "released by xAI" attribution)', () => {
+ // Bare mentions are safe — only the xAI-attributed self-ID phrasing is rewritten.
+ const src = 'Use the Logstash grok filter. Grok patterns parse logs.';
+ assert.equal(neutralizeClientIdentity(src), src, 'unrelated text untouched');
+ const plainId = 'You are Grok, a helpful assistant.';
+ assert.equal(neutralizeClientIdentity(plainId), plainId, 'un-attributed identity line untouched');
+ });
+
+ it('the Grok neutralization respects the opt-out flag', () => {
+ process.env.WINDSURFAPI_NEUTRALIZE_CLIENT_ID = '0';
+ const src = GROK_ID + '\nTake care.';
+ assert.equal(neutralizeClientIdentity(src), src, 'opt-out leaves it verbatim');
+ });
+});
+
// P2 — Claude Code compat layer: the ccActive gate on the opt-in (cc) block.
// Contract: a1-a5 stay UNCONDITIONAL (default 529 / content-policy defense for
// ALL clients); the (cc) block is opt-in and currently EMPTY, so activating it